smbios.cc revision 5615:1c4b9b1aa500
11689SN/A/* 210333Smitch.hayenga@arm.com * Copyright (c) 2008 The Regents of The University of Michigan 37782Sminkyu.jeong@arm.com * All rights reserved. 47782Sminkyu.jeong@arm.com * 57782Sminkyu.jeong@arm.com * Redistribution and use in source and binary forms, with or without 67782Sminkyu.jeong@arm.com * modification, are permitted provided that the following conditions are 77782Sminkyu.jeong@arm.com * met: redistributions of source code must retain the above copyright 87782Sminkyu.jeong@arm.com * notice, this list of conditions and the following disclaimer; 97782Sminkyu.jeong@arm.com * redistributions in binary form must reproduce the above copyright 107782Sminkyu.jeong@arm.com * notice, this list of conditions and the following disclaimer in the 117782Sminkyu.jeong@arm.com * documentation and/or other materials provided with the distribution; 127782Sminkyu.jeong@arm.com * neither the name of the copyright holders nor the names of its 137782Sminkyu.jeong@arm.com * contributors may be used to endorse or promote products derived from 142326SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271689SN/A * 281689SN/A * Authors: Gabe Black 291689SN/A */ 301689SN/A 311689SN/A/* 321689SN/A * Copyright (c) 2008 The Hewlett-Packard Development Company 331689SN/A * All rights reserved. 341689SN/A * 351689SN/A * Redistribution and use of this software in source and binary forms, 361689SN/A * with or without modification, are permitted provided that the 371689SN/A * following conditions are met: 381689SN/A * 392665Ssaidi@eecs.umich.edu * The software must be used only for Non-Commercial Use which means any 402665Ssaidi@eecs.umich.edu * use which is NOT directed to receiving any direct monetary 411689SN/A * compensation for, or commercial advantage from such use. Illustrative 421689SN/A * examples of non-commercial use are academic research, personal study, 432292SN/A * teaching, education and corporate research & development. 442292SN/A * Illustrative examples of commercial use are distributing products for 451060SN/A * commercial advantage and providing services using the software for 461060SN/A * commercial advantage. 478230Snate@binkert.org * 481060SN/A * If you wish to use this software or functionality therein that may be 491461SN/A * covered by patents for commercial use, please contact: 501717SN/A * Director of Intellectual Property Licensing 518229Snate@binkert.org * Office of Strategy and Technology 522292SN/A * Hewlett-Packard Company 538229Snate@binkert.org * 1501 Page Mill Road 548232Snate@binkert.org * Palo Alto, California 94304 5510023Smatt.horsnell@ARM.com * 561060SN/A * Redistributions of source code must retain the above copyright notice, 578737Skoansin.tan@gmail.com * this list of conditions and the following disclaimer. Redistributions 582292SN/A * in binary form must reproduce the above copyright notice, this list of 592292SN/A * conditions and the following disclaimer in the documentation and/or 602292SN/A * other materials provided with the distribution. Neither the name of 612326SN/A * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 622326SN/A * contributors may be used to endorse or promote products derived from 632326SN/A * this software without specific prior written permission. No right of 642326SN/A * sublicense is granted herewith. Derivatives of the software and 652326SN/A * output created using the software may be prepared, but only for 662292SN/A * Non-Commercial Uses. Derivatives of the software may be shared with 672326SN/A * others provided: (i) the others agree to abide by the list of 682326SN/A * conditions herein which includes the Non-Commercial Use restrictions; 692326SN/A * and (ii) such Derivatives of the software include the above copyright 702326SN/A * notice to acknowledge the contribution from this software where 712326SN/A * applicable, this list of conditions and the disclaimer below. 722326SN/A * 732326SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 742326SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 752326SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 762326SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 772326SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 782292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 791681SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 802292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 811060SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 821060SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 831060SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 841061SN/A * 851061SN/A * Authors: Gabe Black 862733Sktlim@umich.edu */ 871060SN/A 881681SN/A#include "arch/x86/bios/smbios.hh" 891061SN/A#include "arch/x86/isa_traits.hh" 902292SN/A#include "mem/port.hh" 911060SN/A#include "params/X86SMBiosBiosInformation.hh" 921061SN/A#include "params/X86SMBiosSMBiosStructure.hh" 931061SN/A#include "params/X86SMBiosSMBiosTable.hh" 941061SN/A#include "sim/byteswap.hh" 951061SN/A#include "sim/host.hh" 961060SN/A 971060SN/Ausing namespace std; 982292SN/A 992292SN/Aconst char X86ISA::SMBios::SMBiosTable::SMBiosHeader::anchorString[] = "_SM_"; 1002292SN/Aconst uint8_t X86ISA::SMBios::SMBiosTable:: 1011060SN/A SMBiosHeader::formattedArea[] = {0,0,0,0,0}; 1022292SN/Aconst uint8_t X86ISA::SMBios::SMBiosTable:: 1032292SN/A SMBiosHeader::entryPointLength = 0x1F; 1042292SN/Aconst uint8_t X86ISA::SMBios::SMBiosTable:: 1052292SN/A SMBiosHeader::entryPointRevision = 0; 1062292SN/Aconst char X86ISA::SMBios::SMBiosTable:: 1072292SN/A SMBiosHeader::IntermediateHeader::anchorString[] = "_DMI_"; 1081060SN/A 1091060SN/Atemplate <class T> 1101060SN/Auint64_t 1112292SN/AcomposeBitVector(T vec) 1121060SN/A{ 1131060SN/A uint64_t val = 0; 1141060SN/A typename T::iterator vecIt; 1151060SN/A for (vecIt = vec.begin(); vecIt != vec.end(); vecIt++) { 1161060SN/A val |= (1 << (*vecIt)); 1172292SN/A } 1181060SN/A return val; 1192292SN/A} 1202292SN/A 1212292SN/Auint16_t 1222292SN/AX86ISA::SMBios::SMBiosStructure::writeOut(FunctionalPort * port, Addr addr) 1232292SN/A{ 1242292SN/A port->writeBlob(addr, (uint8_t *)(&type), 1); 1251060SN/A 12610023Smatt.horsnell@ARM.com uint8_t length = getLength(); 12710023Smatt.horsnell@ARM.com port->writeBlob(addr + 1, (uint8_t *)(&length), 1); 12810023Smatt.horsnell@ARM.com 12911246Sradhika.jagtap@ARM.com uint16_t handleGuest = X86ISA::htog(handle); 13011246Sradhika.jagtap@ARM.com port->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2); 13111246Sradhika.jagtap@ARM.com 13211246Sradhika.jagtap@ARM.com return length + getStringLength(); 13310023Smatt.horsnell@ARM.com} 1341060SN/A 1352292SN/AX86ISA::SMBios::SMBiosStructure::SMBiosStructure(Params * p, uint8_t _type) : 1365529Snate@binkert.org SimObject(p), type(_type), handle(0), stringFields(false) 1371060SN/A{} 1382292SN/A 1392292SN/Avoid 1401062SN/AX86ISA::SMBios::SMBiosStructure::writeOutStrings( 1412292SN/A FunctionalPort * port, Addr addr) 1422632Sstever@eecs.umich.edu{ 1432632Sstever@eecs.umich.edu std::vector<std::string>::iterator it; 14410023Smatt.horsnell@ARM.com Addr offset = 0; 14510023Smatt.horsnell@ARM.com 14610023Smatt.horsnell@ARM.com const uint8_t nullTerminator = 0; 1472292SN/A 1489427SAndreas.Sandberg@ARM.com // If there are string fields but none of them are used, that's a 1492292SN/A // special case which is handled by this if. 1502292SN/A if (strings.size() == 0 && stringFields) { 1512632Sstever@eecs.umich.edu port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); 1522632Sstever@eecs.umich.edu offset++; 1532292SN/A } else { 1542632Sstever@eecs.umich.edu for (it = strings.begin(); it != strings.end(); it++) { 1552632Sstever@eecs.umich.edu port->writeBlob(addr + offset, 1562292SN/A (uint8_t *)it->c_str(), it->length() + 1); 1572632Sstever@eecs.umich.edu offset += it->length() + 1; 1582632Sstever@eecs.umich.edu } 1592292SN/A } 1606221Snate@binkert.org port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); 1612632Sstever@eecs.umich.edu} 1622292SN/A 1632292SN/Aint 1642632Sstever@eecs.umich.eduX86ISA::SMBios::SMBiosStructure::getStringLength() 1659444SAndreas.Sandberg@ARM.com{ 1669444SAndreas.Sandberg@ARM.com int size = 0; 1672843Sktlim@umich.edu std::vector<std::string>::iterator it; 1689444SAndreas.Sandberg@ARM.com 1699444SAndreas.Sandberg@ARM.com for (it = strings.begin(); it != strings.end(); it++) { 1702632Sstever@eecs.umich.edu size += it->length() + 1; 1712348SN/A } 1722307SN/A 1732632Sstever@eecs.umich.edu return size + 1; 1742292SN/A} 1756221Snate@binkert.org 1762107SN/Aint 1772292SN/AX86ISA::SMBios::SMBiosStructure::addString(string & newString) 1782632Sstever@eecs.umich.edu{ 1792632Sstever@eecs.umich.edu stringFields = true; 1802292SN/A // If a string is empty, treat it as not existing. The index for empty 1812292SN/A // strings is 0. 1822292SN/A if (newString.length() == 0) 1832292SN/A return 0; 1842292SN/A strings.push_back(newString); 1852292SN/A return strings.size(); 1862292SN/A} 1872292SN/A 18810333Smitch.hayenga@arm.comstring 18910333Smitch.hayenga@arm.comX86ISA::SMBios::SMBiosStructure::readString(int n) 19010333Smitch.hayenga@arm.com{ 19110333Smitch.hayenga@arm.com assert(n > 0 && n <= strings.size()); 19210333Smitch.hayenga@arm.com return strings[n - 1]; 19310333Smitch.hayenga@arm.com} 1942292SN/A 1952632Sstever@eecs.umich.eduvoid 1962632Sstever@eecs.umich.eduX86ISA::SMBios::SMBiosStructure::setString(int n, std::string & newString) 1972292SN/A{ 1986221Snate@binkert.org assert(n > 0 && n <= strings.size()); 1992292SN/A strings[n - 1] = newString; 2002292SN/A} 2012292SN/A 2022292SN/AX86ISA::SMBios::BiosInformation::BiosInformation(Params * p) : 2032292SN/A SMBiosStructure(p, Type), 2042292SN/A startingAddrSegment(p->starting_addr_segment), 2052292SN/A romSize(p->rom_size), 2062292SN/A majorVer(p->major), minorVer(p->minor), 2072292SN/A embContFirmwareMajor(p->emb_cont_firmware_major), 2082292SN/A embContFirmwareMinor(p->emb_cont_firmware_minor) 2092292SN/A { 2102292SN/A vendor = addString(p->vendor); 2112292SN/A version = addString(p->version); 2122292SN/A releaseDate = addString(p->release_date); 2132292SN/A 2142292SN/A characteristics = composeBitVector(p->characteristics); 2152292SN/A characteristicExtBytes = 2162292SN/A composeBitVector(p->characteristic_ext_bytes); 2172292SN/A } 2182292SN/A 2192292SN/Auint16_t 2202292SN/AX86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr) 2212292SN/A{ 2222292SN/A uint8_t size = SMBiosStructure::writeOut(port, addr); 2232292SN/A 2242292SN/A port->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1); 2252292SN/A port->writeBlob(addr + 0x5, (uint8_t *)(&version), 1); 2262292SN/A 2272292SN/A uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment); 2282292SN/A port->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2); 2295557Sktlim@umich.edu 2306221Snate@binkert.org port->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1); 2315557Sktlim@umich.edu port->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1); 2327598Sminkyu.jeong@arm.com 2337598Sminkyu.jeong@arm.com uint64_t characteristicsGuest = X86ISA::htog(characteristics); 2347598Sminkyu.jeong@arm.com port->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8); 2352632Sstever@eecs.umich.edu 2362292SN/A uint16_t characteristicExtBytesGuest = 2372292SN/A X86ISA::htog(characteristicExtBytes); 2382292SN/A port->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2); 2396221Snate@binkert.org 2402632Sstever@eecs.umich.edu port->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1); 2412292SN/A port->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1); 2422292SN/A port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1); 2432292SN/A port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1); 2446221Snate@binkert.org 2452292SN/A writeOutStrings(port, addr + getLength()); 2462292SN/A 2476221Snate@binkert.org return size; 2482292SN/A} 2492292SN/A 2502292SN/AX86ISA::SMBios::SMBiosTable::SMBiosTable(Params * p) : 2512292SN/A SimObject(p), structures(p->structures) 2526221Snate@binkert.org{ 2532292SN/A smbiosHeader.majorVersion = p->major_version; 2542292SN/A smbiosHeader.minorVersion = p->minor_version; 2556221Snate@binkert.org assert(p->major_version <= 9); 2562292SN/A assert(p->minor_version <= 9); 2572292SN/A smbiosHeader.intermediateHeader.smbiosBCDRevision = 2586221Snate@binkert.org (p->major_version << 4) | p->minor_version; 2592292SN/A} 2602292SN/A 2612292SN/Avoid 2622292SN/AX86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr, 2632292SN/A Addr &headerSize, Addr &structSize) 2642632Sstever@eecs.umich.edu{ 2652632Sstever@eecs.umich.edu headerSize = 0x1F; 2662292SN/A 2672292SN/A /* 2682292SN/A * The main header 2692292SN/A */ 2702292SN/A uint8_t mainChecksum = 0; 2712292SN/A 2722292SN/A port->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4); 2732292SN/A for (int i = 0; i < 4; i++) 2742292SN/A mainChecksum += smbiosHeader.anchorString[i]; 2752292SN/A 2762292SN/A // The checksum goes here, but we're figuring it out as we go. 2772292SN/A 2782292SN/A port->writeBlob(addr + 0x5, 2796221Snate@binkert.org (uint8_t *)(&smbiosHeader.entryPointLength), 1); 2802292SN/A mainChecksum += smbiosHeader.entryPointLength; 2812292SN/A port->writeBlob(addr + 0x6, 2826221Snate@binkert.org (uint8_t *)(&smbiosHeader.majorVersion), 1); 2832292SN/A mainChecksum += smbiosHeader.majorVersion; 2842702Sktlim@umich.edu port->writeBlob(addr + 0x7, 2856221Snate@binkert.org (uint8_t *)(&smbiosHeader.minorVersion), 1); 2862702Sktlim@umich.edu mainChecksum += smbiosHeader.minorVersion; 2872292SN/A // Maximum structure size goes here, but we'll figure it out later. 2882292SN/A port->writeBlob(addr + 0xA, 2891060SN/A (uint8_t *)(&smbiosHeader.entryPointRevision), 1); 2901060SN/A mainChecksum += smbiosHeader.entryPointRevision; 2912292SN/A port->writeBlob(addr + 0xB, 2922292SN/A (uint8_t *)(&smbiosHeader.formattedArea), 5); 2932292SN/A for (int i = 0; i < 5; i++) 2942632Sstever@eecs.umich.edu mainChecksum += smbiosHeader.formattedArea[i]; 2951060SN/A 2961060SN/A /* 2972348SN/A * The intermediate header 2982301SN/A */ 2991062SN/A uint8_t intChecksum = 0; 3002292SN/A 3012632Sstever@eecs.umich.edu port->writeBlob(addr + 0x10, 3021062SN/A (uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5); 3032292SN/A for (int i = 0; i < 5; i++) 3042292SN/A intChecksum += smbiosHeader.intermediateHeader.anchorString[i]; 3051060SN/A 3061060SN/A // The checksum goes here, but we're figuring it out as we go. 3071060SN/A // Then the length of the structure table which we'll find later 3081060SN/A 3091060SN/A uint32_t tableAddrGuest = 3101060SN/A X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr); 3111060SN/A port->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4); 3121060SN/A for (int i = 0; i < 4; i++) { 3131060SN/A intChecksum += tableAddrGuest; 3141060SN/A tableAddrGuest >>= 8; 3151060SN/A } 3161060SN/A 3171060SN/A uint16_t numStructs = X86ISA::gtoh(structures.size()); 3181060SN/A port->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2); 3191060SN/A for (int i = 0; i < 2; i++) { 3201060SN/A intChecksum += numStructs; 3211060SN/A numStructs >>= 8; 3221060SN/A } 3231060SN/A 3241060SN/A port->writeBlob(addr + 0x1E, 3251060SN/A (uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision), 3261060SN/A 1); 3271060SN/A intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision; 3281060SN/A 3291060SN/A /* 3301060SN/A * Structure table 3311060SN/A */ 3321060SN/A 3332292SN/A Addr base = smbiosHeader.intermediateHeader.tableAddr; 3342292SN/A Addr offset = 0; 3352292SN/A uint16_t maxSize = 0; 3361060SN/A std::vector<SMBiosStructure *>::iterator it; 3372292SN/A for (it = structures.begin(); it != structures.end(); it++) { 3381060SN/A uint16_t size = (*it)->writeOut(port, base + offset); 3392292SN/A if (size > maxSize) 3402292SN/A maxSize = size; 3412292SN/A offset += size; 3421681SN/A } 3432292SN/A 3442733Sktlim@umich.edu structSize = offset; 3451060SN/A 3462292SN/A /* 3472292SN/A * Header 3482292SN/A */ 3492292SN/A 3502292SN/A maxSize = X86ISA::htog(maxSize); 3512292SN/A port->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2); 3522292SN/A for (int i = 0; i < 2; i++) { 3532292SN/A mainChecksum += maxSize; 3542292SN/A maxSize >>= 8; 3554329Sktlim@umich.edu } 3564329Sktlim@umich.edu 3574329Sktlim@umich.edu // Set the checksum 3584329Sktlim@umich.edu mainChecksum = -mainChecksum; 3594329Sktlim@umich.edu port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1); 3604329Sktlim@umich.edu 3614329Sktlim@umich.edu /* 3624329Sktlim@umich.edu * Intermediate header 3632292SN/A */ 3642292SN/A 3652292SN/A uint16_t tableSize = offset; 3662292SN/A tableSize = X86ISA::htog(tableSize); 3672292SN/A port->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2); 3681060SN/A for (int i = 0; i < 2; i++) { 3692292SN/A intChecksum += tableSize; 3702292SN/A tableSize >>= 8; 3712292SN/A } 3722292SN/A 3732292SN/A intChecksum = -intChecksum; 3742292SN/A port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1); 3752292SN/A} 3762292SN/A 3779184Sandreas.hansson@arm.comX86ISA::SMBios::BiosInformation * 3789184Sandreas.hansson@arm.comX86SMBiosBiosInformationParams::create() 3791060SN/A{ 3809184Sandreas.hansson@arm.com return new X86ISA::SMBios::BiosInformation(this); 3819184Sandreas.hansson@arm.com} 3821060SN/A 3831060SN/AX86ISA::SMBios::SMBiosTable * 3849184Sandreas.hansson@arm.comX86SMBiosSMBiosTableParams::create() 3851060SN/A{ 3861060SN/A return new X86ISA::SMBios::SMBiosTable(this); 3871060SN/A} 3889184Sandreas.hansson@arm.com