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