clflush.diff

Patch for clflush port - davshao, 05/07/2012 02:07 PM

Download (24.2 KB)

View differences:

sys/boot/pc32/libi386/Makefile
11 11
	comconsole.c devicename.c elf32_freebsd.c \
12 12
	elf64_freebsd.c gatea20.c \
13 13
	i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.s \
14
	time.c vidconsole.c x86_64_tramp.S
14
	smbios.c time.c vidconsole.c x86_64_tramp.S
15 15

  
16 16
CFLAGS+=	-ffreestanding
17 17
BOOT_COMCONSOLE_PORT?= 0x3f8
......
25 25
CFLAGS+= -DDISK_DEBUG
26 26
.endif
27 27

  
28
.if !defined(BOOT_HIDE_SERIAL_NUMBERS)
29
# Export serial numbers, UUID, and asset tag from loader.
30
CFLAGS+= -DSMBIOS_SERIAL_NUMBERS
31
.if defined(BOOT_LITTLE_ENDIAN_UUID)
32
# Use little-endian UUID format as defined in SMBIOS 2.6.
33
CFLAGS+= -DSMBIOS_LITTLE_ENDIAN_UUID
34
.endif
35
.endif
36

  
28 37
# Include simple terminal emulation (cons25-compatible)
29 38
CFLAGS+= -DTERM_EMU
30 39

  
sys/boot/pc32/libi386/libi386.h
96 96

  
97 97
void	biosacpi_detect(void);
98 98

  
99
void	smbios_detect(void);
100

  
99 101
void	gateA20(void);
100 102

  
101 103
int	i386_autoload(void);
sys/boot/pc32/libi386/smbios.c
1
/*-
2
 * Copyright (c) 2005-2009 Jung-uk Kim <jkim@FreeBSD.org>
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *	notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *	notice, this list of conditions and the following disclaimer in the
12
 *	documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
 * SUCH DAMAGE.
25
 *
26
 * __FBSDID("$FreeBSD: stable/9/sys/boot/i386/libi386/smbios.c 190814 2009-04-07 17:58:15Z jkim $");
27
 */
28

  
29
#include <sys/cdefs.h>
30

  
31
#include <stand.h>
32
#include <bootstrap.h>
33
#include <sys/param.h>
34
#include <sys/endian.h>
35

  
36
#include "btxv86.h"
37
#include "libi386.h"
38

  
39
/*
40
 * Detect SMBIOS and export information about the SMBIOS into the
41
 * environment.
42
 *
43
 * System Management BIOS Reference Specification, v2.6 Final
44
 * http://www.dmtf.org/standards/published_documents/DSP0134_2.6.0.pdf
45
 */
46

  
47
/*
48
 * 2.1.1 SMBIOS Structure Table Entry Point
49
 *
50
 * "On non-EFI systems, the SMBIOS Entry Point structure, described below, can
51
 * be located by application software by searching for the anchor-string on
52
 * paragraph (16-byte) boundaries within the physical memory address range
53
 * 000F0000h to 000FFFFFh. This entry point encapsulates an intermediate anchor
54
 * string that is used by some existing DMI browsers."
55
 */
56
#define	SMBIOS_START		0xf0000
57
#define	SMBIOS_LENGTH		0x10000
58
#define	SMBIOS_STEP		0x10
59
#define	SMBIOS_SIG		"_SM_"
60
#define	SMBIOS_DMI_SIG		"_DMI_"
61

  
62
#define	SMBIOS_GET8(base, off)	(*(uint8_t *)((base) + (off)))
63
#define	SMBIOS_GET16(base, off)	(*(uint16_t *)((base) + (off)))
64
#define	SMBIOS_GET32(base, off)	(*(uint32_t *)((base) + (off)))
65

  
66
#define	SMBIOS_GETLEN(base)	SMBIOS_GET8(base, 0x01)
67
#define	SMBIOS_GETSTR(base)	((base) + SMBIOS_GETLEN(base))
68

  
69
static uint32_t	smbios_enabled_memory = 0;
70
static uint32_t	smbios_old_enabled_memory = 0;
71
static uint8_t	smbios_enabled_sockets = 0;
72
static uint8_t	smbios_populated_sockets = 0;
73

  
74
static uint8_t
75
smbios_checksum(const caddr_t addr, const uint8_t len)
76
{
77
	uint8_t		sum;
78
	int		i;
79

  
80
	for (sum = 0, i = 0; i < len; i++)
81
		sum += SMBIOS_GET8(addr, i);
82
	return (sum);
83
}
84

  
85
static caddr_t
86
smbios_sigsearch(const caddr_t addr, const uint32_t len)
87
{
88
	caddr_t		cp;
89

  
90
	/* Search on 16-byte boundaries. */
91
	for (cp = addr; cp < addr + len; cp += SMBIOS_STEP)
92
		if (strncmp(cp, SMBIOS_SIG, 4) == 0 &&
93
		    smbios_checksum(cp, SMBIOS_GET8(cp, 0x05)) == 0 &&
94
		    strncmp(cp + 0x10, SMBIOS_DMI_SIG, 5) == 0 &&
95
		    smbios_checksum(cp + 0x10, 0x0f) == 0)
96
			return (cp);
97
	return (NULL);
98
}
99

  
100
static void
101
smbios_setenv(const char *name, caddr_t addr, const int offset)
102
{
103
	caddr_t		cp;
104
	int		i, idx;
105

  
106
	idx = SMBIOS_GET8(addr, offset);
107
	if (idx != 0) {
108
		cp = SMBIOS_GETSTR(addr);
109
		for (i = 1; i < idx; i++)
110
			cp += strlen(cp) + 1;
111
		setenv(name, cp, 1);
112
	}
113
}
114

  
115
#ifdef SMBIOS_SERIAL_NUMBERS
116

  
117
#define	UUID_SIZE		16
118
#define	UUID_TYPE		uint32_t
119
#define	UUID_STEP		sizeof(UUID_TYPE)
120
#define	UUID_ALL_BITS		(UUID_SIZE / UUID_STEP)
121
#define	UUID_GET(base, off)	(*(UUID_TYPE *)((base) + (off)))
122

  
123
static void
124
smbios_setuuid(const char *name, const caddr_t addr, const int ver)
125
{
126
	char		uuid[37];
127
	int		i, ones, zeros;
128
	UUID_TYPE	n;
129
	uint32_t	f1;
130
	uint16_t	f2, f3;
131

  
132
	for (i = 0, ones = 0, zeros = 0; i < UUID_SIZE; i += UUID_STEP) {
133
		n = UUID_GET(addr, i) + 1;
134
		if (zeros == 0 && n == 0)
135
			ones++;
136
		else if (ones == 0 && n == 1)
137
			zeros++;
138
		else
139
			break;
140
	}
141

  
142
	if (ones != UUID_ALL_BITS && zeros != UUID_ALL_BITS) {
143
		/*
144
		 * 3.3.2.1 System UUID
145
		 *
146
		 * "Although RFC 4122 recommends network byte order for all
147
		 * fields, the PC industry (including the ACPI, UEFI, and
148
		 * Microsoft specifications) has consistently used
149
		 * little-endian byte encoding for the first three fields:
150
		 * time_low, time_mid, time_hi_and_version. The same encoding,
151
		 * also known as wire format, should also be used for the
152
		 * SMBIOS representation of the UUID."
153
		 *
154
		 * Note: We use network byte order for backward compatibility
155
		 * unless SMBIOS version is 2.6+ or little-endian is forced.
156
		 */
157
#ifndef SMBIOS_LITTLE_ENDIAN_UUID
158
		if (ver < 0x0206) {
159
			f1 = ntohl(SMBIOS_GET32(addr, 0));
160
			f2 = ntohs(SMBIOS_GET16(addr, 4));
161
			f3 = ntohs(SMBIOS_GET16(addr, 6));
162
		} else
163
#endif
164
		{
165
			f1 = le32toh(SMBIOS_GET32(addr, 0));
166
			f2 = le16toh(SMBIOS_GET16(addr, 4));
167
			f3 = le16toh(SMBIOS_GET16(addr, 6));
168
		}
169
		sprintf(uuid,
170
		    "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
171
		    f1, f2, f3, SMBIOS_GET8(addr, 8), SMBIOS_GET8(addr, 9),
172
		    SMBIOS_GET8(addr, 10), SMBIOS_GET8(addr, 11),
173
		    SMBIOS_GET8(addr, 12), SMBIOS_GET8(addr, 13),
174
		    SMBIOS_GET8(addr, 14), SMBIOS_GET8(addr, 15));
175
		setenv(name, uuid, 1);
176
	}
177
}
178

  
179
#undef UUID_SIZE
180
#undef UUID_TYPE
181
#undef UUID_STEP
182
#undef UUID_ALL_BITS
183
#undef UUID_GET
184

  
185
#endif
186

  
187
static caddr_t
188
smbios_parse_table(const caddr_t addr, const int ver)
189
{
190
	caddr_t		cp;
191
	int		proc, size, osize, type;
192

  
193
	type = SMBIOS_GET8(addr, 0);	/* 3.1.2 Structure Header Format */
194
	switch(type) {
195
	case 0:		/* 3.3.1 BIOS Information (Type 0) */
196
		smbios_setenv("smbios.bios.vendor", addr, 0x04);
197
		smbios_setenv("smbios.bios.version", addr, 0x05);
198
		smbios_setenv("smbios.bios.reldate", addr, 0x08);
199
		break;
200

  
201
	case 1:		/* 3.3.2 System Information (Type 1) */
202
		smbios_setenv("smbios.system.maker", addr, 0x04);
203
		smbios_setenv("smbios.system.product", addr, 0x05);
204
		smbios_setenv("smbios.system.version", addr, 0x06);
205
#ifdef SMBIOS_SERIAL_NUMBERS
206
		smbios_setenv("smbios.system.serial", addr, 0x07);
207
		smbios_setuuid("smbios.system.uuid", addr + 0x08, ver);
208
#endif
209
		break;
210

  
211
	case 2:		/* 3.3.3 Base Board (or Module) Information (Type 2) */
212
		smbios_setenv("smbios.planar.maker", addr, 0x04);
213
		smbios_setenv("smbios.planar.product", addr, 0x05);
214
		smbios_setenv("smbios.planar.version", addr, 0x06);
215
#ifdef SMBIOS_SERIAL_NUMBERS
216
		smbios_setenv("smbios.planar.serial", addr, 0x07);
217
#endif
218
		break;
219

  
220
	case 3:		/* 3.3.4 System Enclosure or Chassis (Type 3) */
221
		smbios_setenv("smbios.chassis.maker", addr, 0x04);
222
		smbios_setenv("smbios.chassis.version", addr, 0x06);
223
#ifdef SMBIOS_SERIAL_NUMBERS
224
		smbios_setenv("smbios.chassis.serial", addr, 0x07);
225
		smbios_setenv("smbios.chassis.tag", addr, 0x08);
226
#endif
227
		break;
228

  
229
	case 4:		/* 3.3.5 Processor Information (Type 4) */
230
		/*
231
		 * Offset 18h: Processor Status
232
		 *
233
		 * Bit 7	Reserved, must be 0
234
		 * Bit 6	CPU Socket Populated
235
		 *		1 - CPU Socket Populated
236
		 *		0 - CPU Socket Unpopulated
237
		 * Bit 5:3	Reserved, must be zero
238
		 * Bit 2:0	CPU Status
239
		 *		0h - Unknown
240
		 *		1h - CPU Enabled
241
		 *		2h - CPU Disabled by User via BIOS Setup
242
		 *		3h - CPU Disabled by BIOS (POST Error)
243
		 *		4h - CPU is Idle, waiting to be enabled
244
		 *		5-6h - Reserved
245
		 *		7h - Other
246
		 */
247
		proc = SMBIOS_GET8(addr, 0x18);
248
		if ((proc & 0x07) == 1)
249
			smbios_enabled_sockets++;
250
		if ((proc & 0x40) != 0)
251
			smbios_populated_sockets++;
252
		break;
253

  
254
	case 6:		/* 3.3.7 Memory Module Information (Type 6, Obsolete) */
255
		/*
256
		 * Offset 0Ah: Enabled Size
257
		 *
258
		 * Bit 7	Bank connection
259
		 *		1 - Double-bank connection
260
		 *		0 - Single-bank connection
261
		 * Bit 6:0	Size (n), where 2**n is the size in MB
262
		 *		7Dh - Not determinable (Installed Size only)
263
		 *		7Eh - Module is installed, but no memory
264
		 *		      has been enabled
265
		 *		7Fh - Not installed
266
		 */
267
		osize = SMBIOS_GET8(addr, 0x0a) & 0x7f;
268
		if (osize > 0 && osize < 22)
269
			smbios_old_enabled_memory += 1 << (osize + 10);
270
		break;
271

  
272
	case 17:	/* 3.3.18 Memory Device (Type 17) */
273
		/*
274
		 * Offset 0Ch: Size
275
		 *
276
		 * Bit 15	Granularity
277
		 *		1 - Value is in kilobytes units
278
		 *		0 - Value is in megabytes units
279
		 * Bit 14:0	Size
280
		 */
281
		size = SMBIOS_GET16(addr, 0x0c);
282
		if (size != 0 && size != 0xffff)
283
			smbios_enabled_memory += (size & 0x8000) != 0 ?
284
			    (size & 0x7fff) : (size << 10);
285
		break;
286

  
287
	default:	/* skip other types */
288
		break;
289
	}
290

  
291
	/* Find structure terminator. */
292
	cp = SMBIOS_GETSTR(addr);
293
	while (SMBIOS_GET16(cp, 0) != 0)
294
		cp++;
295

  
296
	return (cp + 2);
297
}
298

  
299
void
300
smbios_detect(void)
301
{
302
	char		buf[16];
303
	caddr_t		addr, dmi, smbios;
304
	size_t		count, length;
305
	uint32_t	paddr;
306
	int		i, major, minor, ver;
307

  
308
	/* Search signatures and validate checksums. */
309
	smbios = smbios_sigsearch(PTOV(SMBIOS_START), SMBIOS_LENGTH);
310
	if (smbios == NULL)
311
		return;
312

  
313
	length = SMBIOS_GET16(smbios, 0x16);	/* Structure Table Length */
314
	paddr = SMBIOS_GET32(smbios, 0x18);	/* Structure Table Address */
315
	count = SMBIOS_GET16(smbios, 0x1c);	/* No of SMBIOS Structures */
316
	ver = SMBIOS_GET8(smbios, 0x1e);	/* SMBIOS BCD Revision */
317

  
318
	if (ver != 0) {
319
		major = ver >> 4;
320
		minor = ver & 0x0f;
321
		if (major > 9 || minor > 9)
322
			ver = 0;
323
	}
324
	if (ver == 0) {
325
		major = SMBIOS_GET8(smbios, 0x06); /* SMBIOS Major Version */
326
		minor = SMBIOS_GET8(smbios, 0x07); /* SMBIOS Minor Version */
327
	}
328
	ver = (major << 8) | minor;
329

  
330
	addr = PTOV(paddr);
331
	for (dmi = addr, i = 0; dmi < addr + length && i < count; i++)
332
		dmi = smbios_parse_table(dmi, ver);
333

  
334
	sprintf(buf, "%d.%d", major, minor);
335
	setenv("smbios.version", buf, 1);
336
	if (smbios_enabled_memory > 0 || smbios_old_enabled_memory > 0) {
337
		sprintf(buf, "%u", smbios_enabled_memory > 0 ?
338
		    smbios_enabled_memory : smbios_old_enabled_memory);
339
		setenv("smbios.memory.enabled", buf, 1);
340
	}
341
	if (smbios_enabled_sockets > 0) {
342
		sprintf(buf, "%u", smbios_enabled_sockets);
343
		setenv("smbios.socket.enabled", buf, 1);
344
	}
345
	if (smbios_populated_sockets > 0) {
346
		sprintf(buf, "%u", smbios_populated_sockets);
347
		setenv("smbios.socket.populated", buf, 1);
348
	}
349
}
sys/boot/pc32/loader/main.c
240 240
    /* detect ACPI for future reference */
241 241
    biosacpi_detect();
242 242

  
243
    /* detect SMBIOS for future reference */
244
    smbios_detect();
245

  
243 246
    /* enable EHCI */
244 247
    setenv("ehci_load", "YES", 1);
245 248

  
sys/cpu/i386/include/cpufunc.h
113 113
	return (result);
114 114
}
115 115

  
116
static __inline void
117
clflush(u_long addr)
118
{
119

  
120
	__asm __volatile("clflush %0" : : "m" (*(char *)addr));
121
}
122

  
116 123
/*
117 124
 * Test and set the specified bit (1 << bit) in the integer.  The
118 125
 * previous value of the bit is returned (0 or 1).
sys/cpu/x86_64/include/cpufunc.h
125 125
}
126 126

  
127 127
static __inline void
128
clflush(u_long addr)
129
{
130

  
131
	__asm __volatile("clflush %0" : : "m" (*(char *)addr));
132
}
133

  
134
static __inline void
128 135
do_cpuid(u_int ax, u_int *p)
129 136
{
130 137
	__asm __volatile("cpuid"
sys/kern/subr_param.c
46 46
#include <sys/param.h>
47 47
#include <sys/systm.h>
48 48
#include <sys/kernel.h>
49
#include <sys/sysctl.h>
49 50
#include <sys/malloc.h>
50 51
#include <vm/pmap.h>
51 52
#include <machine/vmparam.h>
......
56 57

  
57 58
#ifndef HZ
58 59
#define	HZ 100
60
#  ifndef HZ_VM
61
#    define	HZ_VM 100
62
#  endif
63
#else
64
#  ifndef HZ_VM
65
#    define	HZ_VM HZ
66
#  endif
59 67
#endif
60 68
#define	NPROC (20 + 16 * maxusers)
61 69
#ifndef NBUF
......
68 76
#define MAXPOSIXLOCKSPERUID (maxusers * 64) /* Should be a safe value */
69 77
#endif
70 78

  
79
static int sysctl_kern_vm_guest(SYSCTL_HANDLER_ARGS);
80

  
71 81
int	hz;
72 82
int	stathz;
73 83
int	profhz;
......
88 98
int	nswbuf;
89 99
long	maxswzone;			/* max swmeta KVA storage */
90 100
long	maxbcache;			/* max buffer cache KVA storage */
101
int 	vm_guest;			/* Running as virtual machine guest? */
91 102
u_quad_t	maxtsiz;			/* max text size */
92 103
u_quad_t	dfldsiz;			/* initial data size limit */
93 104
u_quad_t	maxdsiz;			/* max data size */
......
95 106
u_quad_t	maxssiz;			/* max stack size */
96 107
u_quad_t	sgrowsiz;			/* amount to grow stack */
97 108

  
109
SYSCTL_PROC(_kern, OID_AUTO, vm_guest, CTLFLAG_RD | CTLTYPE_STRING,
110
    NULL, 0, sysctl_kern_vm_guest, "A",
111
    "Virtual machine guest detected? (none|generic|xen)");
112

  
98 113
/*
99 114
 * These have to be allocated somewhere; allocating
100 115
 * them here forces loader errors if this file is omitted
......
103 118
struct	buf *swbuf;
104 119

  
105 120
/*
121
 * The elements of this array are ordered based upon the values of the
122
 * corresponding enum VM_GUEST members.
123
 */
124
static const char *const vm_guest_sysctl_names[] = {
125
	"none",
126
	"generic",
127
	"xen",
128
	NULL
129
};
130

  
131
#ifndef XEN
132
static const char *const vm_bnames[] = {
133
	"QEMU",				/* QEMU */
134
	"Plex86",			/* Plex86 */
135
	"Bochs",			/* Bochs */
136
	"Xen",				/* Xen */
137
	NULL
138
};
139

  
140
static const char *const vm_pnames[] = {
141
	"VMware Virtual Platform",	/* VMWare VM */
142
	"Virtual Machine",		/* Microsoft VirtualPC */
143
	"VirtualBox",			/* Sun xVM VirtualBox */
144
	"Parallels Virtual Platform",	/* Parallels VM */
145
	NULL
146
};
147

  
148

  
149
/*
150
 * Detect known Virtual Machine hosts by inspecting the emulated BIOS.
151
 */
152
static enum VM_GUEST
153
detect_virtual(void)
154
{
155
	char *sysenv;
156
	int i;
157

  
158
	sysenv = kgetenv("smbios.bios.vendor");
159
	if (sysenv != NULL) {
160
		for (i = 0; vm_bnames[i] != NULL; i++)
161
			if (strcmp(sysenv, vm_bnames[i]) == 0) {
162
				kfreeenv(sysenv);
163
				return (VM_GUEST_VM);
164
			}
165
		kfreeenv(sysenv);
166
	}
167
	sysenv = kgetenv("smbios.system.product");
168
	if (sysenv != NULL) {
169
		for (i = 0; vm_pnames[i] != NULL; i++)
170
			if (strcmp(sysenv, vm_pnames[i]) == 0) {
171
				kfreeenv(sysenv);
172
				return (VM_GUEST_VM);
173
			}
174
		kfreeenv(sysenv);
175
	}
176
	return (VM_GUEST_NO);
177
}
178
#endif
179

  
180
/*
106 181
 * Boot time overrides that are not scaled against main memory
107 182
 */
108 183
void
109 184
init_param1(void)
110 185
{
111
	hz = HZ;
186
#ifndef XEN
187
	vm_guest = detect_virtual();
188
#else
189
	vm_guest = VM_GUEST_XEN;
190
#endif
191
	hz = -1;
112 192
	TUNABLE_INT_FETCH("kern.hz", &hz);
193
	if (hz == -1)
194
		hz = vm_guest > VM_GUEST_NO ? HZ_VM : HZ;
113 195
	stathz = hz * 128 / 100;
114 196
	profhz = stathz;
115 197
	ustick = 1000000 / hz;
......
227 309
	TUNABLE_INT_FETCH("kern.ncallout", &ncallout);
228 310
}
229 311

  
312
/*
313
 * Sysctl stringiying handler for kern.vm_guest.
314
 */
315
static int
316
sysctl_kern_vm_guest(SYSCTL_HANDLER_ARGS)
317
{
318
	return (SYSCTL_OUT(req, vm_guest_sysctl_names[vm_guest],
319
	    strlen(vm_guest_sysctl_names[vm_guest])));
320
}
sys/platform/pc32/i386/initcpu.c
41 41
#include <machine/md_var.h>
42 42
#include <machine/specialreg.h>
43 43

  
44
#include <vm/vm.h>
45
#include <vm/pmap.h>
46

  
47
#if !defined(CPU_DISABLE_SSE) && defined(I686_CPU)
48
#define CPU_ENABLE_SSE
49
#endif
50

  
44 51
void initializecpu(void);
45 52
#if defined(I586_CPU) && defined(CPU_WT_ALLOC)
46 53
void	enable_K5_wt_alloc(void);
......
68 75
static int	hw_instruction_sse;
69 76
SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD,
70 77
    &hw_instruction_sse, 0, "SIMD/MMX2 instructions available in CPU");
78
/*
79
 * -1: automatic (default)
80
 *  0: keep enable CLFLUSH
81
 *  1: force disable CLFLUSH
82
 */
83
static int	hw_clflush_disable = -1;
71 84

  
72 85
/* Must *NOT* be BSS or locore will bzero these after setting them */
73 86
int	cpu = 0;		/* Are we 386, 386sx, 486, etc? */
......
84 97
u_int	cpu_procinfo2 = 0;	/* Multicore info */
85 98
char	cpu_vendor[20] = "";	/* CPU Origin code */
86 99
u_int	cpu_vendor_id = 0;	/* CPU vendor ID */
100
u_int	cpu_clflush_line_size = 32;
87 101

  
88 102
SYSCTL_UINT(_hw, OID_AUTO, via_feature_rng, CTLFLAG_RD,
89 103
	&via_feature_rng, 0, "VIA C3/C7 RNG feature available in CPU");
90 104
SYSCTL_UINT(_hw, OID_AUTO, via_feature_xcrypt, CTLFLAG_RD,
91 105
	&via_feature_xcrypt, 0, "VIA C3/C7 xcrypt feature available in CPU");
92 106

  
107
#if 0
93 108
#ifndef CPU_DISABLE_SSE
94 109
u_int	cpu_fxsr;		/* SSE enabled */
95 110
#endif
111
#endif
112
#ifdef CPU_ENABLE_SSE
113
u_int	cpu_fxsr;		/* SSE enabled */
114
#if 0
115
u_int	cpu_mxcsr_mask;		/* valid bits in mxcsr */
116
#endif
117
#endif
96 118

  
97 119
#ifdef I486_CPU
98 120
/*
......
588 610
void
589 611
enable_sse(void)
590 612
{
613
#if 0
591 614
#ifndef CPU_DISABLE_SSE
592 615
	if ((cpu_feature & CPUID_SSE) && (cpu_feature & CPUID_FXSR)) {
593 616
		load_cr4(rcr4() | CR4_FXSR | CR4_XMM);
594 617
		cpu_fxsr = hw_instruction_sse = 1;
595 618
	}
596 619
#endif
620
#endif
621
#if defined(CPU_ENABLE_SSE)
622
	if ((cpu_feature & CPUID_XMM) && (cpu_feature & CPUID_FXSR)) {
623
		load_cr4(rcr4() | CR4_FXSR | CR4_XMM);
624
		cpu_fxsr = hw_instruction_sse = 1;
625
	}
626
#endif
597 627
}
598 628

  
599 629
#ifdef I686_CPU
......
685 715
		break;
686 716
	}
687 717
	enable_sse();
718

  
719
	/*
720
	 * CPUID with %eax = 1, %ebx returns
721
	 * Bits 15-8: CLFLUSH line size
722
	 * 	(Value * 8 = cache line size in bytes)
723
	 */
724
	if ((cpu_feature & CPUID_CLFSH) != 0)
725
		cpu_clflush_line_size = ((cpu_procinfo >> 8) & 0xff) * 8;
726
	/*
727
	 * XXXKIB: (temporary) hack to work around traps generated
728
	 * when CLFLUSHing APIC register window under virtualization
729
	 * environments.  These environments tend to disable the
730
	 * CPUID_SS feature even though the native CPU supports it.
731
	 */
732
	TUNABLE_INT_FETCH("hw.clflush_disable", &hw_clflush_disable);
733
	if (vm_guest != VM_GUEST_NO && hw_clflush_disable == -1)
734
		cpu_feature &= ~CPUID_CLFSH;
735
	/*
736
	 * Allow to disable CLFLUSH feature manually by
737
	 * hw.clflush_disable tunable.
738
	 */
739
	if (hw_clflush_disable == 1)
740
		cpu_feature &= ~CPUID_CLFSH;
688 741
}
689 742

  
690 743
#if defined(I586_CPU) && defined(CPU_WT_ALLOC)
sys/platform/pc32/include/md_var.h
61 61
extern	u_int	amd_feature2;
62 62
extern	u_int	via_feature_rng;
63 63
extern	u_int	via_feature_xcrypt;
64
extern	u_int	cpu_clflush_line_size;
64 65
extern	u_int	cpu_fxsr;
65 66
extern	u_int	cpu_high;
66 67
extern	u_int	cpu_id;
sys/platform/pc64/include/md_var.h
49 49
extern	u_int	via_feature_xcrypt;
50 50
extern	u_int	amd_feature;
51 51
extern	u_int	amd_feature2;
52
extern	u_int	cpu_clflush_line_size;
52 53
extern	u_int	cpu_fxsr;
53 54
extern	u_int	cpu_high;
54 55
extern	u_int	cpu_id;
......
101 102
void    minidumpsys(struct dumperinfo *);
102 103
void	dump_add_page(vm_paddr_t);
103 104
void	dump_drop_page(vm_paddr_t);
105
#if 0
106
void	initializecpu(void);
107
#endif
108
void	initializecpucache(void);
104 109

  
105 110
#endif /* !_MACHINE_MD_VAR_H_ */
sys/platform/pc64/x86_64/initcpu.c
46 46
static int	hw_instruction_sse;
47 47
SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD,
48 48
    &hw_instruction_sse, 0, "SIMD/MMX2 instructions available in CPU");
49
/*
50
 * -1: automatic (default)
51
 *  0: keep enable CLFLUSH
52
 *  1: force disable CLFLUSH
53
 */
54
static int	hw_clflush_disable = -1;
49 55

  
50 56
int	cpu;			/* Are we 386, 386sx, 486, etc? */
51 57
u_int	cpu_feature;		/* Feature flags */
......
63 69
u_int	cpu_vendor_id;		/* CPU vendor ID */
64 70
u_int	cpu_fxsr;		/* SSE enabled */
65 71
u_int	cpu_mxcsr_mask;		/* Valid bits in mxcsr */
72
u_int	cpu_clflush_line_size = 32;
66 73

  
67 74
SYSCTL_UINT(_hw, OID_AUTO, via_feature_rng, CTLFLAG_RD,
68 75
	&via_feature_rng, 0, "VIA C3/C7 RNG feature available in CPU");
......
180 187
	    CPUID_TO_MODEL(cpu_id) >= 0xf)
181 188
		init_via();
182 189
}
190

  
191
void
192
initializecpucache(void)
193
{
194

  
195
	/*
196
	 * CPUID with %eax = 1, %ebx returns
197
	 * Bits 15-8: CLFLUSH line size
198
	 * 	(Value * 8 = cache line size in bytes)
199
	 */
200
	if ((cpu_feature & CPUID_CLFSH) != 0)
201
		cpu_clflush_line_size = ((cpu_procinfo >> 8) & 0xff) * 8;
202
	/*
203
	 * XXXKIB: (temporary) hack to work around traps generated
204
	 * when CLFLUSHing APIC register window under virtualization
205
	 * environments.  These environments tend to disable the
206
	 * CPUID_SS feature even though the native CPU supports it.
207
	 */
208
	TUNABLE_INT_FETCH("hw.clflush_disable", &hw_clflush_disable);
209
	if (vm_guest != VM_GUEST_NO && hw_clflush_disable == -1)
210
		cpu_feature &= ~CPUID_CLFSH;
211
	/*
212
	 * Allow to disable CLFLUSH feature manually by
213
	 * hw.clflush_disable tunable.
214
	 */
215
	if (hw_clflush_disable == 1)
216
		cpu_feature &= ~CPUID_CLFSH;
217
}
sys/platform/pc64/x86_64/machdep.c
1905 1905
#endif
1906 1906
	identify_cpu();		/* Final stage of CPU initialization */
1907 1907
	initializecpu();	/* Initialize CPU registers */
1908
	initializecpucache();
1908 1909

  
1909 1910
	TUNABLE_INT_FETCH("hw.apic_io_enable", &ioapic_enable); /* for compat */
1910 1911
	TUNABLE_INT_FETCH("hw.ioapic_enable", &ioapic_enable);
sys/sys/systm.h
85 85

  
86 86
extern int maxusers;		/* system tune hint */
87 87

  
88
extern int vm_guest;		/* Running as virtual machine guest? */
89

  
90
/*
91
 * Detected virtual machine guest types. The intention is to expand
92
 * and/or add to the VM_GUEST_VM type if specific VM functionality is
93
 * ever implemented (e.g. vendor-specific paravirtualization features).
94
 */
95
enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN };
96

  
88 97
extern int ncpus;		/* total number of cpus (real, hyper, virtual)*/
89 98
extern int ncpus2;		/* ncpus rounded down to power of 2 */
90 99
extern int ncpus2_shift;	/* log base 2 of ncpus2 */