xref: /freebsd/sys/amd64/vmm/x86.c (revision 366f60834ff8ef709f132fe8976c96a5e2caace9)
1*366f6083SPeter Grehan /*-
2*366f6083SPeter Grehan  * Copyright (c) 2011 NetApp, Inc.
3*366f6083SPeter Grehan  * All rights reserved.
4*366f6083SPeter Grehan  *
5*366f6083SPeter Grehan  * Redistribution and use in source and binary forms, with or without
6*366f6083SPeter Grehan  * modification, are permitted provided that the following conditions
7*366f6083SPeter Grehan  * are met:
8*366f6083SPeter Grehan  * 1. Redistributions of source code must retain the above copyright
9*366f6083SPeter Grehan  *    notice, this list of conditions and the following disclaimer.
10*366f6083SPeter Grehan  * 2. Redistributions in binary form must reproduce the above copyright
11*366f6083SPeter Grehan  *    notice, this list of conditions and the following disclaimer in the
12*366f6083SPeter Grehan  *    documentation and/or other materials provided with the distribution.
13*366f6083SPeter Grehan  *
14*366f6083SPeter Grehan  * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
15*366f6083SPeter Grehan  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*366f6083SPeter Grehan  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*366f6083SPeter Grehan  * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
18*366f6083SPeter Grehan  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*366f6083SPeter Grehan  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*366f6083SPeter Grehan  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*366f6083SPeter Grehan  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*366f6083SPeter Grehan  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*366f6083SPeter Grehan  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*366f6083SPeter Grehan  * SUCH DAMAGE.
25*366f6083SPeter Grehan  *
26*366f6083SPeter Grehan  * $FreeBSD$
27*366f6083SPeter Grehan  */
28*366f6083SPeter Grehan 
29*366f6083SPeter Grehan #include <sys/cdefs.h>
30*366f6083SPeter Grehan __FBSDID("$FreeBSD$");
31*366f6083SPeter Grehan 
32*366f6083SPeter Grehan #include <sys/types.h>
33*366f6083SPeter Grehan 
34*366f6083SPeter Grehan #include <machine/cpufunc.h>
35*366f6083SPeter Grehan #include <machine/specialreg.h>
36*366f6083SPeter Grehan 
37*366f6083SPeter Grehan #include "x86.h"
38*366f6083SPeter Grehan 
39*366f6083SPeter Grehan int
40*366f6083SPeter Grehan x86_emulate_cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
41*366f6083SPeter Grehan {
42*366f6083SPeter Grehan 	unsigned int 	func, regs[4];
43*366f6083SPeter Grehan 
44*366f6083SPeter Grehan 	func = *eax;
45*366f6083SPeter Grehan 
46*366f6083SPeter Grehan 	cpuid_count(*eax, *ecx, regs);
47*366f6083SPeter Grehan 
48*366f6083SPeter Grehan 	switch(func) {
49*366f6083SPeter Grehan 		case CPUID_0000_0000:
50*366f6083SPeter Grehan 		case CPUID_0000_0002:
51*366f6083SPeter Grehan 		case CPUID_0000_0003:
52*366f6083SPeter Grehan 		case CPUID_0000_0004:
53*366f6083SPeter Grehan 		case CPUID_0000_000A:
54*366f6083SPeter Grehan 			break;
55*366f6083SPeter Grehan 
56*366f6083SPeter Grehan 		case CPUID_8000_0000:
57*366f6083SPeter Grehan 		case CPUID_8000_0001:
58*366f6083SPeter Grehan 		case CPUID_8000_0002:
59*366f6083SPeter Grehan 		case CPUID_8000_0003:
60*366f6083SPeter Grehan 		case CPUID_8000_0004:
61*366f6083SPeter Grehan 		case CPUID_8000_0006:
62*366f6083SPeter Grehan 		case CPUID_8000_0007:
63*366f6083SPeter Grehan 		case CPUID_8000_0008:
64*366f6083SPeter Grehan 
65*366f6083SPeter Grehan 			break;
66*366f6083SPeter Grehan 
67*366f6083SPeter Grehan 		case CPUID_0000_0001:
68*366f6083SPeter Grehan 			/*
69*366f6083SPeter Grehan 			 * Override the APIC ID only in ebx
70*366f6083SPeter Grehan 			 */
71*366f6083SPeter Grehan 			regs[1] &= ~(CPUID_0000_0001_APICID_MASK);
72*366f6083SPeter Grehan 			/*
73*366f6083SPeter Grehan 			 * XXX fixme for MP case, set apicid properly for cpu.
74*366f6083SPeter Grehan 			 */
75*366f6083SPeter Grehan 			regs[1] |= (0 << CPUID_0000_0001_APICID_SHIFT);
76*366f6083SPeter Grehan 
77*366f6083SPeter Grehan 			/*
78*366f6083SPeter Grehan 			 * Don't expose VMX capability.
79*366f6083SPeter Grehan 			 * Advertise x2APIC capability.
80*366f6083SPeter Grehan 			 */
81*366f6083SPeter Grehan 			regs[2] &= ~CPUID_0000_0001_FEAT0_VMX;
82*366f6083SPeter Grehan 			regs[2] |= CPUID2_X2APIC;
83*366f6083SPeter Grehan 
84*366f6083SPeter Grehan 			/*
85*366f6083SPeter Grehan 			 * Machine check handling is done in the host.
86*366f6083SPeter Grehan 			 * Hide MTRR capability.
87*366f6083SPeter Grehan 			 */
88*366f6083SPeter Grehan 			regs[3] &= ~(CPUID_MCA | CPUID_MCE | CPUID_MTRR);
89*366f6083SPeter Grehan 
90*366f6083SPeter Grehan 			break;
91*366f6083SPeter Grehan 
92*366f6083SPeter Grehan 		case CPUID_0000_000B:
93*366f6083SPeter Grehan 			/*
94*366f6083SPeter Grehan 			 * XXXSMP fixme
95*366f6083SPeter Grehan 			 * Processor topology enumeration
96*366f6083SPeter Grehan 			 */
97*366f6083SPeter Grehan 			regs[0] = 0;
98*366f6083SPeter Grehan 			regs[1] = 0;
99*366f6083SPeter Grehan 			regs[2] = *ecx & 0xff;
100*366f6083SPeter Grehan 			regs[3] = 0;
101*366f6083SPeter Grehan 			break;
102*366f6083SPeter Grehan 
103*366f6083SPeter Grehan 		default:
104*366f6083SPeter Grehan 			return (0);
105*366f6083SPeter Grehan 	}
106*366f6083SPeter Grehan 
107*366f6083SPeter Grehan 	*eax = regs[0];
108*366f6083SPeter Grehan 	*ebx = regs[1];
109*366f6083SPeter Grehan 	*ecx = regs[2];
110*366f6083SPeter Grehan 	*edx = regs[3];
111*366f6083SPeter Grehan 	return (1);
112*366f6083SPeter Grehan }
113*366f6083SPeter Grehan 
114