cpuid.cc revision 11217
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"
325659Sgblack@eecs.umich.edu#include "base/bitfield.hh"
335659Sgblack@eecs.umich.edu#include "cpu/thread_context.hh"
345659Sgblack@eecs.umich.edu
355659Sgblack@eecs.umich.edunamespace X86ISA {
365659Sgblack@eecs.umich.edu    enum StandardCpuidFunction {
375659Sgblack@eecs.umich.edu        VendorAndLargestStdFunc,
385659Sgblack@eecs.umich.edu        FamilyModelStepping,
395659Sgblack@eecs.umich.edu        NumStandardCpuidFuncs
405659Sgblack@eecs.umich.edu    };
415659Sgblack@eecs.umich.edu
425659Sgblack@eecs.umich.edu    enum ExtendedCpuidFunctions {
435659Sgblack@eecs.umich.edu        VendorAndLargestExtFunc,
445659Sgblack@eecs.umich.edu        FamilyModelSteppingBrandFeatures,
455659Sgblack@eecs.umich.edu        NameString1,
465659Sgblack@eecs.umich.edu        NameString2,
475659Sgblack@eecs.umich.edu        NameString3,
485659Sgblack@eecs.umich.edu        L1CacheAndTLB,
495659Sgblack@eecs.umich.edu        L2L3CacheAndL2TLB,
505659Sgblack@eecs.umich.edu        APMInfo,
5110439Smajiuyue@ncic.ac.cn        LongModeAddressSize,
525659Sgblack@eecs.umich.edu
535659Sgblack@eecs.umich.edu        /*
545659Sgblack@eecs.umich.edu         * The following are defined by the spec but not yet implemented
555659Sgblack@eecs.umich.edu         */
5610439Smajiuyue@ncic.ac.cn/*      // Function 9 is reserved
575659Sgblack@eecs.umich.edu        SVMInfo = 10,
585659Sgblack@eecs.umich.edu        // Functions 11-24 are reserved
595659Sgblack@eecs.umich.edu        TLB1GBPageInfo = 25,
605659Sgblack@eecs.umich.edu        PerformanceInfo,*/
615659Sgblack@eecs.umich.edu
625659Sgblack@eecs.umich.edu        NumExtendedCpuidFuncs
635659Sgblack@eecs.umich.edu    };
645659Sgblack@eecs.umich.edu
655659Sgblack@eecs.umich.edu    static const int vendorStringSize = 13;
666040Sgblack@eecs.umich.edu    static const char vendorString[vendorStringSize] = "M5 Simulator";
675659Sgblack@eecs.umich.edu    static const int nameStringSize = 48;
685659Sgblack@eecs.umich.edu    static const char nameString[nameStringSize] = "Fake M5 x86_64 CPU";
695659Sgblack@eecs.umich.edu
705659Sgblack@eecs.umich.edu    uint64_t
715659Sgblack@eecs.umich.edu    stringToRegister(const char *str)
725659Sgblack@eecs.umich.edu    {
735659Sgblack@eecs.umich.edu        uint64_t reg = 0;
745659Sgblack@eecs.umich.edu        for (int pos = 3; pos >=0; pos--) {
755659Sgblack@eecs.umich.edu            reg <<= 8;
765659Sgblack@eecs.umich.edu            reg |= str[pos];
775659Sgblack@eecs.umich.edu        }
785659Sgblack@eecs.umich.edu        return reg;
795659Sgblack@eecs.umich.edu    }
805659Sgblack@eecs.umich.edu
815659Sgblack@eecs.umich.edu    bool
827072Sgblack@eecs.umich.edu    doCpuid(ThreadContext * tc, uint32_t function,
837072Sgblack@eecs.umich.edu            uint32_t index, CpuidResult &result)
845659Sgblack@eecs.umich.edu    {
855659Sgblack@eecs.umich.edu        uint16_t family = bits(function, 31, 16);
865659Sgblack@eecs.umich.edu        uint16_t funcNum = bits(function, 15, 0);
875659Sgblack@eecs.umich.edu        if (family == 0x8000) {
885659Sgblack@eecs.umich.edu            // The extended functions
895659Sgblack@eecs.umich.edu            switch (funcNum) {
905659Sgblack@eecs.umich.edu              case VendorAndLargestExtFunc:
915659Sgblack@eecs.umich.edu                assert(vendorStringSize >= 12);
925659Sgblack@eecs.umich.edu                result = CpuidResult(
936052Sgblack@eecs.umich.edu                        0x80000000 + NumExtendedCpuidFuncs - 1,
945659Sgblack@eecs.umich.edu                        stringToRegister(vendorString),
955659Sgblack@eecs.umich.edu                        stringToRegister(vendorString + 4),
965659Sgblack@eecs.umich.edu                        stringToRegister(vendorString + 8));
975659Sgblack@eecs.umich.edu                break;
985659Sgblack@eecs.umich.edu              case FamilyModelSteppingBrandFeatures:
995659Sgblack@eecs.umich.edu                result = CpuidResult(0x00020f51, 0x00000405,
10010637Sgabeblack@google.com                                     0xe3d3fbff, 0x00000001);
1015659Sgblack@eecs.umich.edu                break;
1025659Sgblack@eecs.umich.edu              case NameString1:
1035659Sgblack@eecs.umich.edu              case NameString2:
1045659Sgblack@eecs.umich.edu              case NameString3:
1055659Sgblack@eecs.umich.edu                {
1065659Sgblack@eecs.umich.edu                    // Zero fill anything beyond the end of the string. This
1075659Sgblack@eecs.umich.edu                    // should go away once the string is a vetted parameter.
1085659Sgblack@eecs.umich.edu                    char cleanName[nameStringSize];
1095659Sgblack@eecs.umich.edu                    memset(cleanName, '\0', nameStringSize);
1105659Sgblack@eecs.umich.edu                    strncpy(cleanName, nameString, nameStringSize);
1115659Sgblack@eecs.umich.edu
1125659Sgblack@eecs.umich.edu                    int offset = (funcNum - NameString1) * 16;
1135659Sgblack@eecs.umich.edu                    assert(nameStringSize >= offset + 16);
1145659Sgblack@eecs.umich.edu                    result = CpuidResult(
1155659Sgblack@eecs.umich.edu                            stringToRegister(cleanName + offset + 0),
1165659Sgblack@eecs.umich.edu                            stringToRegister(cleanName + offset + 4),
1176068Sgblack@eecs.umich.edu                            stringToRegister(cleanName + offset + 12),
1186068Sgblack@eecs.umich.edu                            stringToRegister(cleanName + offset + 8));
1195659Sgblack@eecs.umich.edu                }
1205659Sgblack@eecs.umich.edu                break;
1215659Sgblack@eecs.umich.edu              case L1CacheAndTLB:
1225659Sgblack@eecs.umich.edu                result = CpuidResult(0xff08ff08, 0xff20ff20,
1235659Sgblack@eecs.umich.edu                                     0x40020140, 0x40020140);
1245659Sgblack@eecs.umich.edu                break;
1255659Sgblack@eecs.umich.edu              case L2L3CacheAndL2TLB:
1265659Sgblack@eecs.umich.edu                result = CpuidResult(0x00000000, 0x42004200,
1275659Sgblack@eecs.umich.edu                                     0x00000000, 0x04008140);
1285659Sgblack@eecs.umich.edu                break;
1295659Sgblack@eecs.umich.edu              case APMInfo:
1305659Sgblack@eecs.umich.edu                result = CpuidResult(0x80000018, 0x68747541,
1315659Sgblack@eecs.umich.edu                                     0x69746e65, 0x444d4163);
1325659Sgblack@eecs.umich.edu                break;
13310439Smajiuyue@ncic.ac.cn              case LongModeAddressSize:
13410539Sgabeblack@google.com                result = CpuidResult(0x00003030, 0x00000000,
13510439Smajiuyue@ncic.ac.cn                                     0x00000000, 0x00000000);
13610439Smajiuyue@ncic.ac.cn                break;
13710439Smajiuyue@ncic.ac.cn/*            case SVMInfo:
1385659Sgblack@eecs.umich.edu              case TLB1GBPageInfo:
1395659Sgblack@eecs.umich.edu              case PerformanceInfo:*/
1405659Sgblack@eecs.umich.edu              default:
14111217Sbaz21@cam.ac.uk                warn("x86 cpuid family 0x8000: unimplemented function %u",
14211217Sbaz21@cam.ac.uk                    funcNum);
1435659Sgblack@eecs.umich.edu                return false;
1445659Sgblack@eecs.umich.edu            }
1455659Sgblack@eecs.umich.edu        } else if(family == 0x0000) {
1465659Sgblack@eecs.umich.edu            // The standard functions
1475659Sgblack@eecs.umich.edu            switch (funcNum) {
1485659Sgblack@eecs.umich.edu              case VendorAndLargestStdFunc:
1495659Sgblack@eecs.umich.edu                assert(vendorStringSize >= 12);
1505659Sgblack@eecs.umich.edu                result = CpuidResult(
1515659Sgblack@eecs.umich.edu                        NumStandardCpuidFuncs - 1,
1525659Sgblack@eecs.umich.edu                        stringToRegister(vendorString),
1535659Sgblack@eecs.umich.edu                        stringToRegister(vendorString + 4),
1545659Sgblack@eecs.umich.edu                        stringToRegister(vendorString + 8));
1555659Sgblack@eecs.umich.edu                break;
1565659Sgblack@eecs.umich.edu              case FamilyModelStepping:
1579473Snilay@cs.wisc.edu                result = CpuidResult(0x00020f51, 0x00000805,
15810638Sgabeblack@google.com                                     0xe7dbfbff, 0x04000209);
1595659Sgblack@eecs.umich.edu                break;
1605659Sgblack@eecs.umich.edu              default:
16111217Sbaz21@cam.ac.uk                warn("x86 cpuid family 0x0000: unimplemented function %u",
16211217Sbaz21@cam.ac.uk                    funcNum);
1635659Sgblack@eecs.umich.edu                return false;
1645659Sgblack@eecs.umich.edu            }
1659124Snilay@cs.wisc.edu        } else {
1669124Snilay@cs.wisc.edu            warn("x86 cpuid: unknown family %#x", family);
1679124Snilay@cs.wisc.edu            return false;
1685659Sgblack@eecs.umich.edu        }
1699124Snilay@cs.wisc.edu
1705659Sgblack@eecs.umich.edu        return true;
1715659Sgblack@eecs.umich.edu    }
1727811Ssteve.reinhardt@amd.com} // namespace X86ISA
173