smbios.cc revision 7087
15612Sgblack@eecs.umich.edu/* 27087Snate@binkert.org * Copyright (c) 2008 The Hewlett-Packard Development Company 37087Snate@binkert.org * All rights reserved. 47087Snate@binkert.org * 57087Snate@binkert.org * The license below extends only to copyright in the software and shall 67087Snate@binkert.org * not be construed as granting a license to any other intellectual 77087Snate@binkert.org * property including but not limited to intellectual property relating 87087Snate@binkert.org * to a hardware implementation of the functionality of the software 97087Snate@binkert.org * licensed hereunder. You may use the software subject to the license 107087Snate@binkert.org * terms below provided that you ensure that this notice is replicated 117087Snate@binkert.org * unmodified and in its entirety in all distributions of the software, 127087Snate@binkert.org * modified or unmodified, in source code or in binary form. 137087Snate@binkert.org * 145612Sgblack@eecs.umich.edu * Copyright (c) 2008 The Regents of The University of Michigan 155612Sgblack@eecs.umich.edu * All rights reserved. 165612Sgblack@eecs.umich.edu * 175612Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 185612Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 195612Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 205612Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 215612Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 225612Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 235612Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 245612Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 255612Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 265612Sgblack@eecs.umich.edu * this software without specific prior written permission. 275612Sgblack@eecs.umich.edu * 285612Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 295612Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 305612Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 315612Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 325612Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 335612Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 345612Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 355612Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 365612Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 375612Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 385612Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 395612Sgblack@eecs.umich.edu * 405612Sgblack@eecs.umich.edu * Authors: Gabe Black 415612Sgblack@eecs.umich.edu */ 425612Sgblack@eecs.umich.edu 435612Sgblack@eecs.umich.edu#include "arch/x86/bios/smbios.hh" 445612Sgblack@eecs.umich.edu#include "arch/x86/isa_traits.hh" 456216Snate@binkert.org#include "base/types.hh" 465612Sgblack@eecs.umich.edu#include "mem/port.hh" 475615Sgblack@eecs.umich.edu#include "params/X86SMBiosBiosInformation.hh" 485615Sgblack@eecs.umich.edu#include "params/X86SMBiosSMBiosStructure.hh" 495615Sgblack@eecs.umich.edu#include "params/X86SMBiosSMBiosTable.hh" 505612Sgblack@eecs.umich.edu#include "sim/byteswap.hh" 515612Sgblack@eecs.umich.edu 525615Sgblack@eecs.umich.eduusing namespace std; 535615Sgblack@eecs.umich.edu 545612Sgblack@eecs.umich.educonst char X86ISA::SMBios::SMBiosTable::SMBiosHeader::anchorString[] = "_SM_"; 555612Sgblack@eecs.umich.educonst uint8_t X86ISA::SMBios::SMBiosTable:: 565612Sgblack@eecs.umich.edu SMBiosHeader::formattedArea[] = {0,0,0,0,0}; 575612Sgblack@eecs.umich.educonst uint8_t X86ISA::SMBios::SMBiosTable:: 585612Sgblack@eecs.umich.edu SMBiosHeader::entryPointLength = 0x1F; 595612Sgblack@eecs.umich.educonst uint8_t X86ISA::SMBios::SMBiosTable:: 605612Sgblack@eecs.umich.edu SMBiosHeader::entryPointRevision = 0; 615612Sgblack@eecs.umich.educonst char X86ISA::SMBios::SMBiosTable:: 625612Sgblack@eecs.umich.edu SMBiosHeader::IntermediateHeader::anchorString[] = "_DMI_"; 635612Sgblack@eecs.umich.edu 645615Sgblack@eecs.umich.edutemplate <class T> 655615Sgblack@eecs.umich.eduuint64_t 665615Sgblack@eecs.umich.educomposeBitVector(T vec) 675615Sgblack@eecs.umich.edu{ 685615Sgblack@eecs.umich.edu uint64_t val = 0; 695615Sgblack@eecs.umich.edu typename T::iterator vecIt; 705615Sgblack@eecs.umich.edu for (vecIt = vec.begin(); vecIt != vec.end(); vecIt++) { 715615Sgblack@eecs.umich.edu val |= (1 << (*vecIt)); 725615Sgblack@eecs.umich.edu } 735615Sgblack@eecs.umich.edu return val; 745615Sgblack@eecs.umich.edu} 755615Sgblack@eecs.umich.edu 765615Sgblack@eecs.umich.eduuint16_t 775615Sgblack@eecs.umich.eduX86ISA::SMBios::SMBiosStructure::writeOut(FunctionalPort * port, Addr addr) 785615Sgblack@eecs.umich.edu{ 795615Sgblack@eecs.umich.edu port->writeBlob(addr, (uint8_t *)(&type), 1); 805615Sgblack@eecs.umich.edu 815615Sgblack@eecs.umich.edu uint8_t length = getLength(); 825615Sgblack@eecs.umich.edu port->writeBlob(addr + 1, (uint8_t *)(&length), 1); 835615Sgblack@eecs.umich.edu 845615Sgblack@eecs.umich.edu uint16_t handleGuest = X86ISA::htog(handle); 855615Sgblack@eecs.umich.edu port->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2); 865615Sgblack@eecs.umich.edu 875615Sgblack@eecs.umich.edu return length + getStringLength(); 885615Sgblack@eecs.umich.edu} 895615Sgblack@eecs.umich.edu 905615Sgblack@eecs.umich.eduX86ISA::SMBios::SMBiosStructure::SMBiosStructure(Params * p, uint8_t _type) : 915615Sgblack@eecs.umich.edu SimObject(p), type(_type), handle(0), stringFields(false) 925615Sgblack@eecs.umich.edu{} 935615Sgblack@eecs.umich.edu 945615Sgblack@eecs.umich.eduvoid 955615Sgblack@eecs.umich.eduX86ISA::SMBios::SMBiosStructure::writeOutStrings( 965615Sgblack@eecs.umich.edu FunctionalPort * port, Addr addr) 975615Sgblack@eecs.umich.edu{ 985615Sgblack@eecs.umich.edu std::vector<std::string>::iterator it; 995615Sgblack@eecs.umich.edu Addr offset = 0; 1005615Sgblack@eecs.umich.edu 1015615Sgblack@eecs.umich.edu const uint8_t nullTerminator = 0; 1025615Sgblack@eecs.umich.edu 1035615Sgblack@eecs.umich.edu // If there are string fields but none of them are used, that's a 1045615Sgblack@eecs.umich.edu // special case which is handled by this if. 1055615Sgblack@eecs.umich.edu if (strings.size() == 0 && stringFields) { 1065615Sgblack@eecs.umich.edu port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); 1075615Sgblack@eecs.umich.edu offset++; 1085615Sgblack@eecs.umich.edu } else { 1095615Sgblack@eecs.umich.edu for (it = strings.begin(); it != strings.end(); it++) { 1105615Sgblack@eecs.umich.edu port->writeBlob(addr + offset, 1115615Sgblack@eecs.umich.edu (uint8_t *)it->c_str(), it->length() + 1); 1125615Sgblack@eecs.umich.edu offset += it->length() + 1; 1135615Sgblack@eecs.umich.edu } 1145615Sgblack@eecs.umich.edu } 1155615Sgblack@eecs.umich.edu port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); 1165615Sgblack@eecs.umich.edu} 1175615Sgblack@eecs.umich.edu 1185615Sgblack@eecs.umich.eduint 1195615Sgblack@eecs.umich.eduX86ISA::SMBios::SMBiosStructure::getStringLength() 1205615Sgblack@eecs.umich.edu{ 1215615Sgblack@eecs.umich.edu int size = 0; 1225615Sgblack@eecs.umich.edu std::vector<std::string>::iterator it; 1235615Sgblack@eecs.umich.edu 1245615Sgblack@eecs.umich.edu for (it = strings.begin(); it != strings.end(); it++) { 1255615Sgblack@eecs.umich.edu size += it->length() + 1; 1265615Sgblack@eecs.umich.edu } 1275615Sgblack@eecs.umich.edu 1285615Sgblack@eecs.umich.edu return size + 1; 1295615Sgblack@eecs.umich.edu} 1305615Sgblack@eecs.umich.edu 1315615Sgblack@eecs.umich.eduint 1325615Sgblack@eecs.umich.eduX86ISA::SMBios::SMBiosStructure::addString(string & newString) 1335615Sgblack@eecs.umich.edu{ 1345615Sgblack@eecs.umich.edu stringFields = true; 1355615Sgblack@eecs.umich.edu // If a string is empty, treat it as not existing. The index for empty 1365615Sgblack@eecs.umich.edu // strings is 0. 1375615Sgblack@eecs.umich.edu if (newString.length() == 0) 1385615Sgblack@eecs.umich.edu return 0; 1395615Sgblack@eecs.umich.edu strings.push_back(newString); 1405615Sgblack@eecs.umich.edu return strings.size(); 1415615Sgblack@eecs.umich.edu} 1425615Sgblack@eecs.umich.edu 1435615Sgblack@eecs.umich.edustring 1445615Sgblack@eecs.umich.eduX86ISA::SMBios::SMBiosStructure::readString(int n) 1455615Sgblack@eecs.umich.edu{ 1465615Sgblack@eecs.umich.edu assert(n > 0 && n <= strings.size()); 1475615Sgblack@eecs.umich.edu return strings[n - 1]; 1485615Sgblack@eecs.umich.edu} 1495615Sgblack@eecs.umich.edu 1505615Sgblack@eecs.umich.eduvoid 1515615Sgblack@eecs.umich.eduX86ISA::SMBios::SMBiosStructure::setString(int n, std::string & newString) 1525615Sgblack@eecs.umich.edu{ 1535615Sgblack@eecs.umich.edu assert(n > 0 && n <= strings.size()); 1545615Sgblack@eecs.umich.edu strings[n - 1] = newString; 1555615Sgblack@eecs.umich.edu} 1565615Sgblack@eecs.umich.edu 1575615Sgblack@eecs.umich.eduX86ISA::SMBios::BiosInformation::BiosInformation(Params * p) : 1585615Sgblack@eecs.umich.edu SMBiosStructure(p, Type), 1595615Sgblack@eecs.umich.edu startingAddrSegment(p->starting_addr_segment), 1605615Sgblack@eecs.umich.edu romSize(p->rom_size), 1615615Sgblack@eecs.umich.edu majorVer(p->major), minorVer(p->minor), 1625615Sgblack@eecs.umich.edu embContFirmwareMajor(p->emb_cont_firmware_major), 1635615Sgblack@eecs.umich.edu embContFirmwareMinor(p->emb_cont_firmware_minor) 1645615Sgblack@eecs.umich.edu { 1655615Sgblack@eecs.umich.edu vendor = addString(p->vendor); 1665615Sgblack@eecs.umich.edu version = addString(p->version); 1675615Sgblack@eecs.umich.edu releaseDate = addString(p->release_date); 1685615Sgblack@eecs.umich.edu 1695615Sgblack@eecs.umich.edu characteristics = composeBitVector(p->characteristics); 1705615Sgblack@eecs.umich.edu characteristicExtBytes = 1715615Sgblack@eecs.umich.edu composeBitVector(p->characteristic_ext_bytes); 1725615Sgblack@eecs.umich.edu } 1735615Sgblack@eecs.umich.edu 1745612Sgblack@eecs.umich.eduuint16_t 1755612Sgblack@eecs.umich.eduX86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr) 1765612Sgblack@eecs.umich.edu{ 1775612Sgblack@eecs.umich.edu uint8_t size = SMBiosStructure::writeOut(port, addr); 1785612Sgblack@eecs.umich.edu 1795612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1); 1805612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x5, (uint8_t *)(&version), 1); 1815612Sgblack@eecs.umich.edu 1825612Sgblack@eecs.umich.edu uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment); 1835612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2); 1845612Sgblack@eecs.umich.edu 1855612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1); 1865612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1); 1875612Sgblack@eecs.umich.edu 1885612Sgblack@eecs.umich.edu uint64_t characteristicsGuest = X86ISA::htog(characteristics); 1895612Sgblack@eecs.umich.edu port->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8); 1905612Sgblack@eecs.umich.edu 1915612Sgblack@eecs.umich.edu uint16_t characteristicExtBytesGuest = 1925612Sgblack@eecs.umich.edu X86ISA::htog(characteristicExtBytes); 1935612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2); 1945612Sgblack@eecs.umich.edu 1955615Sgblack@eecs.umich.edu port->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1); 1965615Sgblack@eecs.umich.edu port->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1); 1975612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1); 1985612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1); 1995612Sgblack@eecs.umich.edu 2005612Sgblack@eecs.umich.edu writeOutStrings(port, addr + getLength()); 2015612Sgblack@eecs.umich.edu 2025612Sgblack@eecs.umich.edu return size; 2035612Sgblack@eecs.umich.edu} 2045612Sgblack@eecs.umich.edu 2055615Sgblack@eecs.umich.eduX86ISA::SMBios::SMBiosTable::SMBiosTable(Params * p) : 2065615Sgblack@eecs.umich.edu SimObject(p), structures(p->structures) 2075615Sgblack@eecs.umich.edu{ 2085615Sgblack@eecs.umich.edu smbiosHeader.majorVersion = p->major_version; 2095615Sgblack@eecs.umich.edu smbiosHeader.minorVersion = p->minor_version; 2105615Sgblack@eecs.umich.edu assert(p->major_version <= 9); 2115615Sgblack@eecs.umich.edu assert(p->minor_version <= 9); 2125615Sgblack@eecs.umich.edu smbiosHeader.intermediateHeader.smbiosBCDRevision = 2135615Sgblack@eecs.umich.edu (p->major_version << 4) | p->minor_version; 2145615Sgblack@eecs.umich.edu} 2155615Sgblack@eecs.umich.edu 2165612Sgblack@eecs.umich.eduvoid 2175615Sgblack@eecs.umich.eduX86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr, 2185615Sgblack@eecs.umich.edu Addr &headerSize, Addr &structSize) 2195612Sgblack@eecs.umich.edu{ 2205615Sgblack@eecs.umich.edu headerSize = 0x1F; 2215612Sgblack@eecs.umich.edu 2225612Sgblack@eecs.umich.edu /* 2235612Sgblack@eecs.umich.edu * The main header 2245612Sgblack@eecs.umich.edu */ 2255612Sgblack@eecs.umich.edu uint8_t mainChecksum = 0; 2265612Sgblack@eecs.umich.edu 2275612Sgblack@eecs.umich.edu port->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4); 2285612Sgblack@eecs.umich.edu for (int i = 0; i < 4; i++) 2295612Sgblack@eecs.umich.edu mainChecksum += smbiosHeader.anchorString[i]; 2305612Sgblack@eecs.umich.edu 2315612Sgblack@eecs.umich.edu // The checksum goes here, but we're figuring it out as we go. 2325612Sgblack@eecs.umich.edu 2335612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x5, 2345612Sgblack@eecs.umich.edu (uint8_t *)(&smbiosHeader.entryPointLength), 1); 2355612Sgblack@eecs.umich.edu mainChecksum += smbiosHeader.entryPointLength; 2365612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x6, 2375612Sgblack@eecs.umich.edu (uint8_t *)(&smbiosHeader.majorVersion), 1); 2385612Sgblack@eecs.umich.edu mainChecksum += smbiosHeader.majorVersion; 2395612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x7, 2405612Sgblack@eecs.umich.edu (uint8_t *)(&smbiosHeader.minorVersion), 1); 2415612Sgblack@eecs.umich.edu mainChecksum += smbiosHeader.minorVersion; 2425612Sgblack@eecs.umich.edu // Maximum structure size goes here, but we'll figure it out later. 2435612Sgblack@eecs.umich.edu port->writeBlob(addr + 0xA, 2445612Sgblack@eecs.umich.edu (uint8_t *)(&smbiosHeader.entryPointRevision), 1); 2455612Sgblack@eecs.umich.edu mainChecksum += smbiosHeader.entryPointRevision; 2465612Sgblack@eecs.umich.edu port->writeBlob(addr + 0xB, 2475612Sgblack@eecs.umich.edu (uint8_t *)(&smbiosHeader.formattedArea), 5); 2485612Sgblack@eecs.umich.edu for (int i = 0; i < 5; i++) 2495612Sgblack@eecs.umich.edu mainChecksum += smbiosHeader.formattedArea[i]; 2505612Sgblack@eecs.umich.edu 2515612Sgblack@eecs.umich.edu /* 2525612Sgblack@eecs.umich.edu * The intermediate header 2535612Sgblack@eecs.umich.edu */ 2545612Sgblack@eecs.umich.edu uint8_t intChecksum = 0; 2555612Sgblack@eecs.umich.edu 2565612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x10, 2575612Sgblack@eecs.umich.edu (uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5); 2585612Sgblack@eecs.umich.edu for (int i = 0; i < 5; i++) 2595612Sgblack@eecs.umich.edu intChecksum += smbiosHeader.intermediateHeader.anchorString[i]; 2605612Sgblack@eecs.umich.edu 2615612Sgblack@eecs.umich.edu // The checksum goes here, but we're figuring it out as we go. 2625612Sgblack@eecs.umich.edu // Then the length of the structure table which we'll find later 2635612Sgblack@eecs.umich.edu 2645612Sgblack@eecs.umich.edu uint32_t tableAddrGuest = 2655612Sgblack@eecs.umich.edu X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr); 2665612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4); 2675612Sgblack@eecs.umich.edu for (int i = 0; i < 4; i++) { 2685612Sgblack@eecs.umich.edu intChecksum += tableAddrGuest; 2695612Sgblack@eecs.umich.edu tableAddrGuest >>= 8; 2705612Sgblack@eecs.umich.edu } 2715612Sgblack@eecs.umich.edu 2725612Sgblack@eecs.umich.edu uint16_t numStructs = X86ISA::gtoh(structures.size()); 2735612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2); 2745612Sgblack@eecs.umich.edu for (int i = 0; i < 2; i++) { 2755612Sgblack@eecs.umich.edu intChecksum += numStructs; 2765612Sgblack@eecs.umich.edu numStructs >>= 8; 2775612Sgblack@eecs.umich.edu } 2785612Sgblack@eecs.umich.edu 2795612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x1E, 2805612Sgblack@eecs.umich.edu (uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision), 2815612Sgblack@eecs.umich.edu 1); 2825612Sgblack@eecs.umich.edu intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision; 2835612Sgblack@eecs.umich.edu 2845612Sgblack@eecs.umich.edu /* 2855612Sgblack@eecs.umich.edu * Structure table 2865612Sgblack@eecs.umich.edu */ 2875612Sgblack@eecs.umich.edu 2885612Sgblack@eecs.umich.edu Addr base = smbiosHeader.intermediateHeader.tableAddr; 2895612Sgblack@eecs.umich.edu Addr offset = 0; 2905612Sgblack@eecs.umich.edu uint16_t maxSize = 0; 2915615Sgblack@eecs.umich.edu std::vector<SMBiosStructure *>::iterator it; 2925612Sgblack@eecs.umich.edu for (it = structures.begin(); it != structures.end(); it++) { 2935615Sgblack@eecs.umich.edu uint16_t size = (*it)->writeOut(port, base + offset); 2945612Sgblack@eecs.umich.edu if (size > maxSize) 2955612Sgblack@eecs.umich.edu maxSize = size; 2965612Sgblack@eecs.umich.edu offset += size; 2975612Sgblack@eecs.umich.edu } 2985612Sgblack@eecs.umich.edu 2995615Sgblack@eecs.umich.edu structSize = offset; 3005615Sgblack@eecs.umich.edu 3015612Sgblack@eecs.umich.edu /* 3025612Sgblack@eecs.umich.edu * Header 3035612Sgblack@eecs.umich.edu */ 3045612Sgblack@eecs.umich.edu 3055612Sgblack@eecs.umich.edu maxSize = X86ISA::htog(maxSize); 3065612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2); 3075612Sgblack@eecs.umich.edu for (int i = 0; i < 2; i++) { 3085612Sgblack@eecs.umich.edu mainChecksum += maxSize; 3095612Sgblack@eecs.umich.edu maxSize >>= 8; 3105612Sgblack@eecs.umich.edu } 3115612Sgblack@eecs.umich.edu 3125612Sgblack@eecs.umich.edu // Set the checksum 3135612Sgblack@eecs.umich.edu mainChecksum = -mainChecksum; 3145612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1); 3155612Sgblack@eecs.umich.edu 3165612Sgblack@eecs.umich.edu /* 3175612Sgblack@eecs.umich.edu * Intermediate header 3185612Sgblack@eecs.umich.edu */ 3195612Sgblack@eecs.umich.edu 3205612Sgblack@eecs.umich.edu uint16_t tableSize = offset; 3215612Sgblack@eecs.umich.edu tableSize = X86ISA::htog(tableSize); 3225612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2); 3235612Sgblack@eecs.umich.edu for (int i = 0; i < 2; i++) { 3245612Sgblack@eecs.umich.edu intChecksum += tableSize; 3255612Sgblack@eecs.umich.edu tableSize >>= 8; 3265612Sgblack@eecs.umich.edu } 3275612Sgblack@eecs.umich.edu 3285612Sgblack@eecs.umich.edu intChecksum = -intChecksum; 3295612Sgblack@eecs.umich.edu port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1); 3305612Sgblack@eecs.umich.edu} 3315615Sgblack@eecs.umich.edu 3325615Sgblack@eecs.umich.eduX86ISA::SMBios::BiosInformation * 3335615Sgblack@eecs.umich.eduX86SMBiosBiosInformationParams::create() 3345615Sgblack@eecs.umich.edu{ 3355615Sgblack@eecs.umich.edu return new X86ISA::SMBios::BiosInformation(this); 3365615Sgblack@eecs.umich.edu} 3375615Sgblack@eecs.umich.edu 3385615Sgblack@eecs.umich.eduX86ISA::SMBios::SMBiosTable * 3395615Sgblack@eecs.umich.eduX86SMBiosSMBiosTableParams::create() 3405615Sgblack@eecs.umich.edu{ 3415615Sgblack@eecs.umich.edu return new X86ISA::SMBios::SMBiosTable(this); 3425615Sgblack@eecs.umich.edu} 343