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