xref: /freebsd/sys/amd64/vmm/x86.c (revision 1f3025e13378bfb7be746e15743c2050fae45a93)
1366f6083SPeter Grehan /*-
2366f6083SPeter Grehan  * Copyright (c) 2011 NetApp, Inc.
3366f6083SPeter Grehan  * All rights reserved.
4366f6083SPeter Grehan  *
5366f6083SPeter Grehan  * Redistribution and use in source and binary forms, with or without
6366f6083SPeter Grehan  * modification, are permitted provided that the following conditions
7366f6083SPeter Grehan  * are met:
8366f6083SPeter Grehan  * 1. Redistributions of source code must retain the above copyright
9366f6083SPeter Grehan  *    notice, this list of conditions and the following disclaimer.
10366f6083SPeter Grehan  * 2. Redistributions in binary form must reproduce the above copyright
11366f6083SPeter Grehan  *    notice, this list of conditions and the following disclaimer in the
12366f6083SPeter Grehan  *    documentation and/or other materials provided with the distribution.
13366f6083SPeter Grehan  *
14366f6083SPeter Grehan  * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
15366f6083SPeter Grehan  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16366f6083SPeter Grehan  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17366f6083SPeter Grehan  * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
18366f6083SPeter Grehan  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19366f6083SPeter Grehan  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20366f6083SPeter Grehan  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21366f6083SPeter Grehan  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22366f6083SPeter Grehan  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23366f6083SPeter Grehan  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24366f6083SPeter Grehan  * SUCH DAMAGE.
25366f6083SPeter Grehan  *
26366f6083SPeter Grehan  * $FreeBSD$
27366f6083SPeter Grehan  */
28366f6083SPeter Grehan 
29366f6083SPeter Grehan #include <sys/cdefs.h>
30366f6083SPeter Grehan __FBSDID("$FreeBSD$");
31366f6083SPeter Grehan 
32366f6083SPeter Grehan #include <sys/types.h>
33366f6083SPeter Grehan 
34366f6083SPeter Grehan #include <machine/cpufunc.h>
35366f6083SPeter Grehan #include <machine/specialreg.h>
36366f6083SPeter Grehan 
37366f6083SPeter Grehan #include "x86.h"
38366f6083SPeter Grehan 
39366f6083SPeter Grehan int
40366f6083SPeter Grehan x86_emulate_cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
41366f6083SPeter Grehan {
42366f6083SPeter Grehan 	unsigned int 	func, regs[4];
43366f6083SPeter Grehan 
44366f6083SPeter Grehan 	func = *eax;
45366f6083SPeter Grehan 
46366f6083SPeter Grehan 	cpuid_count(*eax, *ecx, regs);
47366f6083SPeter Grehan 
48366f6083SPeter Grehan 	switch(func) {
49366f6083SPeter Grehan 		case CPUID_0000_0000:
50366f6083SPeter Grehan 		case CPUID_0000_0002:
51366f6083SPeter Grehan 		case CPUID_0000_0003:
52366f6083SPeter Grehan 		case CPUID_0000_0004:
53366f6083SPeter Grehan 		case CPUID_0000_000A:
54366f6083SPeter Grehan 			break;
55366f6083SPeter Grehan 
56366f6083SPeter Grehan 		case CPUID_8000_0000:
57366f6083SPeter Grehan 		case CPUID_8000_0001:
58366f6083SPeter Grehan 		case CPUID_8000_0002:
59366f6083SPeter Grehan 		case CPUID_8000_0003:
60366f6083SPeter Grehan 		case CPUID_8000_0004:
61366f6083SPeter Grehan 		case CPUID_8000_0006:
62366f6083SPeter Grehan 		case CPUID_8000_0007:
63366f6083SPeter Grehan 		case CPUID_8000_0008:
64366f6083SPeter Grehan 
65366f6083SPeter Grehan 			break;
66366f6083SPeter Grehan 
67366f6083SPeter Grehan 		case CPUID_0000_0001:
68366f6083SPeter Grehan 			/*
69366f6083SPeter Grehan 			 * Override the APIC ID only in ebx
70366f6083SPeter Grehan 			 */
71366f6083SPeter Grehan 			regs[1] &= ~(CPUID_0000_0001_APICID_MASK);
72366f6083SPeter Grehan 			/*
73366f6083SPeter Grehan 			 * XXX fixme for MP case, set apicid properly for cpu.
74366f6083SPeter Grehan 			 */
75366f6083SPeter Grehan 			regs[1] |= (0 << CPUID_0000_0001_APICID_SHIFT);
76366f6083SPeter Grehan 
77366f6083SPeter Grehan 			/*
78*1f3025e1SPeter Grehan 			 * Don't expose VMX, SpeedStep or TME capability.
79366f6083SPeter Grehan 			 * Advertise x2APIC capability.
80366f6083SPeter Grehan 			 */
81*1f3025e1SPeter Grehan 			regs[2] &= ~(CPUID_0000_0001_FEAT0_VMX | CPUID2_EST |
82*1f3025e1SPeter Grehan 				     CPUID2_TM2);
83366f6083SPeter Grehan 			regs[2] |= CPUID2_X2APIC;
84366f6083SPeter Grehan 
85366f6083SPeter Grehan 			/*
86*1f3025e1SPeter Grehan 			 * Hide thermal monitoring
87*1f3025e1SPeter Grehan 			 */
88*1f3025e1SPeter Grehan 			regs[3] &= ~(CPUID_ACPI | CPUID_TM);
89*1f3025e1SPeter Grehan 
90*1f3025e1SPeter Grehan 			/*
91366f6083SPeter Grehan 			 * Machine check handling is done in the host.
92366f6083SPeter Grehan 			 * Hide MTRR capability.
93366f6083SPeter Grehan 			 */
94366f6083SPeter Grehan 			regs[3] &= ~(CPUID_MCA | CPUID_MCE | CPUID_MTRR);
95366f6083SPeter Grehan 
96366f6083SPeter Grehan 			break;
97366f6083SPeter Grehan 
98*1f3025e1SPeter Grehan 		case CPUID_0000_0006:
99*1f3025e1SPeter Grehan 			/*
100*1f3025e1SPeter Grehan 			 * Handle the access, but report 0 for
101*1f3025e1SPeter Grehan 			 * all options
102*1f3025e1SPeter Grehan 			 */
103*1f3025e1SPeter Grehan 			regs[0] = 0;
104*1f3025e1SPeter Grehan 			regs[1] = 0;
105*1f3025e1SPeter Grehan 			regs[2] = 0;
106*1f3025e1SPeter Grehan 			regs[3] = 0;
107*1f3025e1SPeter Grehan 			break;
108*1f3025e1SPeter Grehan 
109366f6083SPeter Grehan 		case CPUID_0000_000B:
110366f6083SPeter Grehan 			/*
111366f6083SPeter Grehan 			 * XXXSMP fixme
112366f6083SPeter Grehan 			 * Processor topology enumeration
113366f6083SPeter Grehan 			 */
114366f6083SPeter Grehan 			regs[0] = 0;
115366f6083SPeter Grehan 			regs[1] = 0;
116366f6083SPeter Grehan 			regs[2] = *ecx & 0xff;
117366f6083SPeter Grehan 			regs[3] = 0;
118366f6083SPeter Grehan 			break;
119366f6083SPeter Grehan 
120366f6083SPeter Grehan 		default:
121366f6083SPeter Grehan 			return (0);
122366f6083SPeter Grehan 	}
123366f6083SPeter Grehan 
124366f6083SPeter Grehan 	*eax = regs[0];
125366f6083SPeter Grehan 	*ebx = regs[1];
126366f6083SPeter Grehan 	*ecx = regs[2];
127366f6083SPeter Grehan 	*edx = regs[3];
128366f6083SPeter Grehan 	return (1);
129366f6083SPeter Grehan }
130366f6083SPeter Grehan 
131