x86.c revision 222105
1221828Sgrehan/*-
2221828Sgrehan * Copyright (c) 2011 NetApp, Inc.
3221828Sgrehan * All rights reserved.
4221828Sgrehan *
5221828Sgrehan * Redistribution and use in source and binary forms, with or without
6221828Sgrehan * modification, are permitted provided that the following conditions
7221828Sgrehan * are met:
8221828Sgrehan * 1. Redistributions of source code must retain the above copyright
9221828Sgrehan *    notice, this list of conditions and the following disclaimer.
10221828Sgrehan * 2. Redistributions in binary form must reproduce the above copyright
11221828Sgrehan *    notice, this list of conditions and the following disclaimer in the
12221828Sgrehan *    documentation and/or other materials provided with the distribution.
13221828Sgrehan *
14221828Sgrehan * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
15221828Sgrehan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16221828Sgrehan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17221828Sgrehan * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
18221828Sgrehan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19221828Sgrehan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20221828Sgrehan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21221828Sgrehan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22221828Sgrehan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23221828Sgrehan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24221828Sgrehan * SUCH DAMAGE.
25221828Sgrehan *
26221828Sgrehan * $FreeBSD$
27221828Sgrehan */
28221828Sgrehan
29221828Sgrehan#include <sys/cdefs.h>
30221828Sgrehan__FBSDID("$FreeBSD$");
31221828Sgrehan
32221828Sgrehan#include <sys/types.h>
33221828Sgrehan
34221828Sgrehan#include <machine/cpufunc.h>
35221828Sgrehan#include <machine/specialreg.h>
36221828Sgrehan
37221828Sgrehan#include "x86.h"
38221828Sgrehan
39221828Sgrehanint
40221828Sgrehanx86_emulate_cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
41221828Sgrehan{
42221828Sgrehan	unsigned int 	func, regs[4];
43221828Sgrehan
44221828Sgrehan	func = *eax;
45221828Sgrehan
46221828Sgrehan	cpuid_count(*eax, *ecx, regs);
47221828Sgrehan
48221828Sgrehan	switch(func) {
49221828Sgrehan		case CPUID_0000_0000:
50221828Sgrehan		case CPUID_0000_0002:
51221828Sgrehan		case CPUID_0000_0003:
52221828Sgrehan		case CPUID_0000_0004:
53221828Sgrehan		case CPUID_0000_000A:
54221828Sgrehan			break;
55221828Sgrehan
56221828Sgrehan		case CPUID_8000_0000:
57221828Sgrehan		case CPUID_8000_0001:
58221828Sgrehan		case CPUID_8000_0002:
59221828Sgrehan		case CPUID_8000_0003:
60221828Sgrehan		case CPUID_8000_0004:
61221828Sgrehan		case CPUID_8000_0006:
62221828Sgrehan		case CPUID_8000_0007:
63221828Sgrehan		case CPUID_8000_0008:
64221828Sgrehan
65221828Sgrehan			break;
66221828Sgrehan
67221828Sgrehan		case CPUID_0000_0001:
68221828Sgrehan			/*
69221828Sgrehan			 * Override the APIC ID only in ebx
70221828Sgrehan			 */
71221828Sgrehan			regs[1] &= ~(CPUID_0000_0001_APICID_MASK);
72221828Sgrehan			/*
73221828Sgrehan			 * XXX fixme for MP case, set apicid properly for cpu.
74221828Sgrehan			 */
75221828Sgrehan			regs[1] |= (0 << CPUID_0000_0001_APICID_SHIFT);
76221828Sgrehan
77221828Sgrehan			/*
78222105Sgrehan			 * Don't expose VMX, SpeedStep or TME capability.
79221828Sgrehan			 * Advertise x2APIC capability.
80221828Sgrehan			 */
81222105Sgrehan			regs[2] &= ~(CPUID_0000_0001_FEAT0_VMX | CPUID2_EST |
82222105Sgrehan				     CPUID2_TM2);
83221828Sgrehan			regs[2] |= CPUID2_X2APIC;
84221828Sgrehan
85221828Sgrehan			/*
86222105Sgrehan			 * Hide thermal monitoring
87222105Sgrehan			 */
88222105Sgrehan			regs[3] &= ~(CPUID_ACPI | CPUID_TM);
89222105Sgrehan
90222105Sgrehan			/*
91221828Sgrehan			 * Machine check handling is done in the host.
92221828Sgrehan			 * Hide MTRR capability.
93221828Sgrehan			 */
94221828Sgrehan			regs[3] &= ~(CPUID_MCA | CPUID_MCE | CPUID_MTRR);
95221828Sgrehan
96221828Sgrehan			break;
97221828Sgrehan
98222105Sgrehan		case CPUID_0000_0006:
99222105Sgrehan			/*
100222105Sgrehan			 * Handle the access, but report 0 for
101222105Sgrehan			 * all options
102222105Sgrehan			 */
103222105Sgrehan			regs[0] = 0;
104222105Sgrehan			regs[1] = 0;
105222105Sgrehan			regs[2] = 0;
106222105Sgrehan			regs[3] = 0;
107222105Sgrehan			break;
108222105Sgrehan
109221828Sgrehan		case CPUID_0000_000B:
110221828Sgrehan			/*
111221828Sgrehan			 * XXXSMP fixme
112221828Sgrehan			 * Processor topology enumeration
113221828Sgrehan			 */
114221828Sgrehan			regs[0] = 0;
115221828Sgrehan			regs[1] = 0;
116221828Sgrehan			regs[2] = *ecx & 0xff;
117221828Sgrehan			regs[3] = 0;
118221828Sgrehan			break;
119221828Sgrehan
120221828Sgrehan		default:
121221828Sgrehan			return (0);
122221828Sgrehan	}
123221828Sgrehan
124221828Sgrehan	*eax = regs[0];
125221828Sgrehan	*ebx = regs[1];
126221828Sgrehan	*ecx = regs[2];
127221828Sgrehan	*edx = regs[3];
128221828Sgrehan	return (1);
129221828Sgrehan}
130221828Sgrehan
131