cpuid.cc revision 11793
15659Sgblack@eecs.umich.edu/*
25659Sgblack@eecs.umich.edu * Copyright (c) 2008 The Regents of The University of Michigan
35659Sgblack@eecs.umich.edu * All rights reserved.
45659Sgblack@eecs.umich.edu *
55659Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
65659Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
75659Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
85659Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
95659Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
105659Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
115659Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
125659Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
135659Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
145659Sgblack@eecs.umich.edu * this software without specific prior written permission.
155659Sgblack@eecs.umich.edu *
165659Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175659Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185659Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195659Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205659Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215659Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225659Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235659Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245659Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255659Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265659Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275659Sgblack@eecs.umich.edu *
285659Sgblack@eecs.umich.edu * Authors: Gabe Black
295659Sgblack@eecs.umich.edu */
305659Sgblack@eecs.umich.edu
315659Sgblack@eecs.umich.edu#include "arch/x86/cpuid.hh"
3211793Sbrandon.potter@amd.com
335659Sgblack@eecs.umich.edu#include "base/bitfield.hh"
345659Sgblack@eecs.umich.edu#include "cpu/thread_context.hh"
355659Sgblack@eecs.umich.edu
365659Sgblack@eecs.umich.edunamespace X86ISA {
375659Sgblack@eecs.umich.edu    enum StandardCpuidFunction {
385659Sgblack@eecs.umich.edu        VendorAndLargestStdFunc,
395659Sgblack@eecs.umich.edu        FamilyModelStepping,
405659Sgblack@eecs.umich.edu        NumStandardCpuidFuncs
415659Sgblack@eecs.umich.edu    };
425659Sgblack@eecs.umich.edu
435659Sgblack@eecs.umich.edu    enum ExtendedCpuidFunctions {
445659Sgblack@eecs.umich.edu        VendorAndLargestExtFunc,
455659Sgblack@eecs.umich.edu        FamilyModelSteppingBrandFeatures,
465659Sgblack@eecs.umich.edu        NameString1,
475659Sgblack@eecs.umich.edu        NameString2,
485659Sgblack@eecs.umich.edu        NameString3,
495659Sgblack@eecs.umich.edu        L1CacheAndTLB,
505659Sgblack@eecs.umich.edu        L2L3CacheAndL2TLB,
515659Sgblack@eecs.umich.edu        APMInfo,
5210439Smajiuyue@ncic.ac.cn        LongModeAddressSize,
5311320Ssteve.reinhardt@amd.com
545659Sgblack@eecs.umich.edu        /*
555659Sgblack@eecs.umich.edu         * The following are defined by the spec but not yet implemented
565659Sgblack@eecs.umich.edu         */
5710439Smajiuyue@ncic.ac.cn/*      // Function 9 is reserved
585659Sgblack@eecs.umich.edu        SVMInfo = 10,
595659Sgblack@eecs.umich.edu        // Functions 11-24 are reserved
605659Sgblack@eecs.umich.edu        TLB1GBPageInfo = 25,
615659Sgblack@eecs.umich.edu        PerformanceInfo,*/
625659Sgblack@eecs.umich.edu
635659Sgblack@eecs.umich.edu        NumExtendedCpuidFuncs
645659Sgblack@eecs.umich.edu    };
655659Sgblack@eecs.umich.edu
665659Sgblack@eecs.umich.edu    static const int vendorStringSize = 13;
676040Sgblack@eecs.umich.edu    static const char vendorString[vendorStringSize] = "M5 Simulator";
685659Sgblack@eecs.umich.edu    static const int nameStringSize = 48;
695659Sgblack@eecs.umich.edu    static const char nameString[nameStringSize] = "Fake M5 x86_64 CPU";
705659Sgblack@eecs.umich.edu
715659Sgblack@eecs.umich.edu    uint64_t
725659Sgblack@eecs.umich.edu    stringToRegister(const char *str)
735659Sgblack@eecs.umich.edu    {
745659Sgblack@eecs.umich.edu        uint64_t reg = 0;
755659Sgblack@eecs.umich.edu        for (int pos = 3; pos >=0; pos--) {
765659Sgblack@eecs.umich.edu            reg <<= 8;
775659Sgblack@eecs.umich.edu            reg |= str[pos];
785659Sgblack@eecs.umich.edu        }
795659Sgblack@eecs.umich.edu        return reg;
805659Sgblack@eecs.umich.edu    }
815659Sgblack@eecs.umich.edu
825659Sgblack@eecs.umich.edu    bool
837072Sgblack@eecs.umich.edu    doCpuid(ThreadContext * tc, uint32_t function,
847072Sgblack@eecs.umich.edu            uint32_t index, CpuidResult &result)
855659Sgblack@eecs.umich.edu    {
865659Sgblack@eecs.umich.edu        uint16_t family = bits(function, 31, 16);
875659Sgblack@eecs.umich.edu        uint16_t funcNum = bits(function, 15, 0);
885659Sgblack@eecs.umich.edu        if (family == 0x8000) {
895659Sgblack@eecs.umich.edu            // The extended functions
905659Sgblack@eecs.umich.edu            switch (funcNum) {
915659Sgblack@eecs.umich.edu              case VendorAndLargestExtFunc:
925659Sgblack@eecs.umich.edu                assert(vendorStringSize >= 12);
935659Sgblack@eecs.umich.edu                result = CpuidResult(
946052Sgblack@eecs.umich.edu                        0x80000000 + NumExtendedCpuidFuncs - 1,
955659Sgblack@eecs.umich.edu                        stringToRegister(vendorString),
965659Sgblack@eecs.umich.edu                        stringToRegister(vendorString + 4),
975659Sgblack@eecs.umich.edu                        stringToRegister(vendorString + 8));
985659Sgblack@eecs.umich.edu                break;
995659Sgblack@eecs.umich.edu              case FamilyModelSteppingBrandFeatures:
1005659Sgblack@eecs.umich.edu                result = CpuidResult(0x00020f51, 0x00000405,
10110637Sgabeblack@google.com                                     0xe3d3fbff, 0x00000001);
1025659Sgblack@eecs.umich.edu                break;
1035659Sgblack@eecs.umich.edu              case NameString1:
1045659Sgblack@eecs.umich.edu              case NameString2:
1055659Sgblack@eecs.umich.edu              case NameString3:
1065659Sgblack@eecs.umich.edu                {
1075659Sgblack@eecs.umich.edu                    // Zero fill anything beyond the end of the string. This
1085659Sgblack@eecs.umich.edu                    // should go away once the string is a vetted parameter.
1095659Sgblack@eecs.umich.edu                    char cleanName[nameStringSize];
1105659Sgblack@eecs.umich.edu                    memset(cleanName, '\0', nameStringSize);
1115659Sgblack@eecs.umich.edu                    strncpy(cleanName, nameString, nameStringSize);
1125659Sgblack@eecs.umich.edu
1135659Sgblack@eecs.umich.edu                    int offset = (funcNum - NameString1) * 16;
1145659Sgblack@eecs.umich.edu                    assert(nameStringSize >= offset + 16);
1155659Sgblack@eecs.umich.edu                    result = CpuidResult(
1165659Sgblack@eecs.umich.edu                            stringToRegister(cleanName + offset + 0),
1175659Sgblack@eecs.umich.edu                            stringToRegister(cleanName + offset + 4),
1186068Sgblack@eecs.umich.edu                            stringToRegister(cleanName + offset + 12),
1196068Sgblack@eecs.umich.edu                            stringToRegister(cleanName + offset + 8));
1205659Sgblack@eecs.umich.edu                }
1215659Sgblack@eecs.umich.edu                break;
1225659Sgblack@eecs.umich.edu              case L1CacheAndTLB:
1235659Sgblack@eecs.umich.edu                result = CpuidResult(0xff08ff08, 0xff20ff20,
1245659Sgblack@eecs.umich.edu                                     0x40020140, 0x40020140);
1255659Sgblack@eecs.umich.edu                break;
1265659Sgblack@eecs.umich.edu              case L2L3CacheAndL2TLB:
1275659Sgblack@eecs.umich.edu                result = CpuidResult(0x00000000, 0x42004200,
1285659Sgblack@eecs.umich.edu                                     0x00000000, 0x04008140);
1295659Sgblack@eecs.umich.edu                break;
1305659Sgblack@eecs.umich.edu              case APMInfo:
1315659Sgblack@eecs.umich.edu                result = CpuidResult(0x80000018, 0x68747541,
1325659Sgblack@eecs.umich.edu                                     0x69746e65, 0x444d4163);
1335659Sgblack@eecs.umich.edu                break;
13410439Smajiuyue@ncic.ac.cn              case LongModeAddressSize:
13510539Sgabeblack@google.com                result = CpuidResult(0x00003030, 0x00000000,
13610439Smajiuyue@ncic.ac.cn                                     0x00000000, 0x00000000);
13710439Smajiuyue@ncic.ac.cn                break;
13810439Smajiuyue@ncic.ac.cn/*            case SVMInfo:
1395659Sgblack@eecs.umich.edu              case TLB1GBPageInfo:
1405659Sgblack@eecs.umich.edu              case PerformanceInfo:*/
1415659Sgblack@eecs.umich.edu              default:
14211217Sbaz21@cam.ac.uk                warn("x86 cpuid family 0x8000: unimplemented function %u",
14311217Sbaz21@cam.ac.uk                    funcNum);
1445659Sgblack@eecs.umich.edu                return false;
1455659Sgblack@eecs.umich.edu            }
14611321Ssteve.reinhardt@amd.com        } else if (family == 0x0000) {
1475659Sgblack@eecs.umich.edu            // The standard functions
1485659Sgblack@eecs.umich.edu            switch (funcNum) {
1495659Sgblack@eecs.umich.edu              case VendorAndLargestStdFunc:
1505659Sgblack@eecs.umich.edu                assert(vendorStringSize >= 12);
1515659Sgblack@eecs.umich.edu                result = CpuidResult(
1525659Sgblack@eecs.umich.edu                        NumStandardCpuidFuncs - 1,
1535659Sgblack@eecs.umich.edu                        stringToRegister(vendorString),
1545659Sgblack@eecs.umich.edu                        stringToRegister(vendorString + 4),
1555659Sgblack@eecs.umich.edu                        stringToRegister(vendorString + 8));
1565659Sgblack@eecs.umich.edu                break;
1575659Sgblack@eecs.umich.edu              case FamilyModelStepping:
1589473Snilay@cs.wisc.edu                result = CpuidResult(0x00020f51, 0x00000805,
15910638Sgabeblack@google.com                                     0xe7dbfbff, 0x04000209);
1605659Sgblack@eecs.umich.edu                break;
1615659Sgblack@eecs.umich.edu              default:
16211217Sbaz21@cam.ac.uk                warn("x86 cpuid family 0x0000: unimplemented function %u",
16311217Sbaz21@cam.ac.uk                    funcNum);
1645659Sgblack@eecs.umich.edu                return false;
1655659Sgblack@eecs.umich.edu            }
1669124Snilay@cs.wisc.edu        } else {
1679124Snilay@cs.wisc.edu            warn("x86 cpuid: unknown family %#x", family);
1689124Snilay@cs.wisc.edu            return false;
1695659Sgblack@eecs.umich.edu        }
1709124Snilay@cs.wisc.edu
1715659Sgblack@eecs.umich.edu        return true;
1725659Sgblack@eecs.umich.edu    }
1737811Ssteve.reinhardt@amd.com} // namespace X86ISA
174