cpuid.cc revision 9473
12SN/A/* 21762SN/A * Copyright (c) 2008 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Gabe Black 292665Ssaidi@eecs.umich.edu */ 302SN/A 312SN/A#include "arch/x86/cpuid.hh" 322SN/A#include "base/bitfield.hh" 332SN/A#include "cpu/thread_context.hh" 342SN/A 352520SN/Anamespace X86ISA { 362207SN/A enum StandardCpuidFunction { 372207SN/A VendorAndLargestStdFunc, 386214Snate@binkert.org FamilyModelStepping, 392SN/A NumStandardCpuidFuncs 402519SN/A }; 412SN/A 422SN/A enum ExtendedCpuidFunctions { 432SN/A VendorAndLargestExtFunc, 442SN/A FamilyModelSteppingBrandFeatures, 45360SN/A NameString1, 46360SN/A NameString2, 47360SN/A NameString3, 48360SN/A L1CacheAndTLB, 492207SN/A L2L3CacheAndL2TLB, 504111Sgblack@eecs.umich.edu APMInfo, 514111Sgblack@eecs.umich.edu 524155Sgblack@eecs.umich.edu /* 535874Sgblack@eecs.umich.edu * The following are defined by the spec but not yet implemented 545874Sgblack@eecs.umich.edu */ 556691Stjones1@inf.ed.ac.uk/* LongModeAddressSize, 567095Sgblack@eecs.umich.edu // Function 9 is reserved 576691Stjones1@inf.ed.ac.uk SVMInfo = 10, 58360SN/A // Functions 11-24 are reserved 59360SN/A TLB1GBPageInfo = 25, 60360SN/A PerformanceInfo,*/ 61360SN/A 62360SN/A NumExtendedCpuidFuncs 632207SN/A }; 646392Ssaidi@eecs.umich.edu 656392Ssaidi@eecs.umich.edu static const int vendorStringSize = 13; 66360SN/A static const char vendorString[vendorStringSize] = "M5 Simulator"; 67360SN/A static const int nameStringSize = 48; 682SN/A static const char nameString[nameStringSize] = "Fake M5 x86_64 CPU"; 6912SN/A 702SN/A uint64_t 7112SN/A stringToRegister(const char *str) 722SN/A { 732SN/A uint64_t reg = 0; 74360SN/A for (int pos = 3; pos >=0; pos--) { 75360SN/A reg <<= 8; 76360SN/A reg |= str[pos]; 7712SN/A } 78360SN/A return reg; 79360SN/A } 8012SN/A 812SN/A bool 822SN/A doCpuid(ThreadContext * tc, uint32_t function, 832SN/A uint32_t index, CpuidResult &result) 842SN/A { 852SN/A uint16_t family = bits(function, 31, 16); 862520SN/A uint16_t funcNum = bits(function, 15, 0); 872520SN/A if (family == 0x8000) { 883812Ssaidi@eecs.umich.edu // The extended functions 893812Ssaidi@eecs.umich.edu switch (funcNum) { 903812Ssaidi@eecs.umich.edu case VendorAndLargestExtFunc: 913812Ssaidi@eecs.umich.edu assert(vendorStringSize >= 12); 922SN/A result = CpuidResult( 935070Ssaidi@eecs.umich.edu 0x80000000 + NumExtendedCpuidFuncs - 1, 945070Ssaidi@eecs.umich.edu stringToRegister(vendorString), 953917Ssaidi@eecs.umich.edu stringToRegister(vendorString + 4), 96360SN/A stringToRegister(vendorString + 8)); 97360SN/A break; 98360SN/A case FamilyModelSteppingBrandFeatures: 992SN/A result = CpuidResult(0x00020f51, 0x00000405, 1002SN/A 0xe3d3fbff, 0x00000001); 10112SN/A break; 1022420SN/A case NameString1: 1032420SN/A case NameString2: 1042420SN/A case NameString3: 10512SN/A { 10612SN/A // Zero fill anything beyond the end of the string. This 10712SN/A // should go away once the string is a vetted parameter. 10812SN/A char cleanName[nameStringSize]; 10912SN/A memset(cleanName, '\0', nameStringSize); 11012SN/A strncpy(cleanName, nameString, nameStringSize); 11112SN/A 11212SN/A int offset = (funcNum - NameString1) * 16; 1132SN/A assert(nameStringSize >= offset + 16); 1142520SN/A result = CpuidResult( 1152472SN/A stringToRegister(cleanName + offset + 0), 1162420SN/A stringToRegister(cleanName + offset + 4), 1172SN/A stringToRegister(cleanName + offset + 12), 11812SN/A stringToRegister(cleanName + offset + 8)); 1192472SN/A } 12012SN/A break; 1212SN/A case L1CacheAndTLB: 12212SN/A result = CpuidResult(0xff08ff08, 0xff20ff20, 12312SN/A 0x40020140, 0x40020140); 12412SN/A break; 12512SN/A case L2L3CacheAndL2TLB: 12612SN/A result = CpuidResult(0x00000000, 0x42004200, 12712SN/A 0x00000000, 0x04008140); 12812SN/A break; 1293584Ssaidi@eecs.umich.edu case APMInfo: 1303584Ssaidi@eecs.umich.edu result = CpuidResult(0x80000018, 0x68747541, 1312SN/A 0x69746e65, 0x444d4163); 1322SN/A break; 1333584Ssaidi@eecs.umich.edu/* case LongModeAddressSize: 1342SN/A case SVMInfo: 1352SN/A case TLB1GBPageInfo: 1362SN/A case PerformanceInfo:*/ 137 default: 138 warn("x86 cpuid: unimplemented function %u", funcNum); 139 return false; 140 } 141 } else if(family == 0x0000) { 142 // The standard functions 143 switch (funcNum) { 144 case VendorAndLargestStdFunc: 145 assert(vendorStringSize >= 12); 146 result = CpuidResult( 147 NumStandardCpuidFuncs - 1, 148 stringToRegister(vendorString), 149 stringToRegister(vendorString + 4), 150 stringToRegister(vendorString + 8)); 151 break; 152 case FamilyModelStepping: 153 result = CpuidResult(0x00020f51, 0x00000805, 154 0xe7dbfbff, 0x00000001); 155 break; 156 default: 157 warn("x86 cpuid: unimplemented function %u", funcNum); 158 return false; 159 } 160 } else { 161 warn("x86 cpuid: unknown family %#x", family); 162 return false; 163 } 164 165 return true; 166 } 167} // namespace X86ISA 168