smbios.cc revision 5612
15612Sgblack@eecs.umich.edu/*
25612Sgblack@eecs.umich.edu * Copyright (c) 2008 The Regents of The University of Michigan
35612Sgblack@eecs.umich.edu * All rights reserved.
45612Sgblack@eecs.umich.edu *
55612Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
65612Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
75612Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
85612Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
95612Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
105612Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
115612Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
125612Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
135612Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
145612Sgblack@eecs.umich.edu * this software without specific prior written permission.
155612Sgblack@eecs.umich.edu *
165612Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175612Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185612Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195612Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205612Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215612Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225612Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235612Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245612Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255612Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265612Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275612Sgblack@eecs.umich.edu *
285612Sgblack@eecs.umich.edu * Authors: Gabe Black
295612Sgblack@eecs.umich.edu */
305612Sgblack@eecs.umich.edu
315612Sgblack@eecs.umich.edu/*
325612Sgblack@eecs.umich.edu * Copyright (c) 2008 The Hewlett-Packard Development Company
335612Sgblack@eecs.umich.edu * All rights reserved.
345612Sgblack@eecs.umich.edu *
355612Sgblack@eecs.umich.edu * Redistribution and use of this software in source and binary forms,
365612Sgblack@eecs.umich.edu * with or without modification, are permitted provided that the
375612Sgblack@eecs.umich.edu * following conditions are met:
385612Sgblack@eecs.umich.edu *
395612Sgblack@eecs.umich.edu * The software must be used only for Non-Commercial Use which means any
405612Sgblack@eecs.umich.edu * use which is NOT directed to receiving any direct monetary
415612Sgblack@eecs.umich.edu * compensation for, or commercial advantage from such use.  Illustrative
425612Sgblack@eecs.umich.edu * examples of non-commercial use are academic research, personal study,
435612Sgblack@eecs.umich.edu * teaching, education and corporate research & development.
445612Sgblack@eecs.umich.edu * Illustrative examples of commercial use are distributing products for
455612Sgblack@eecs.umich.edu * commercial advantage and providing services using the software for
465612Sgblack@eecs.umich.edu * commercial advantage.
475612Sgblack@eecs.umich.edu *
485612Sgblack@eecs.umich.edu * If you wish to use this software or functionality therein that may be
495612Sgblack@eecs.umich.edu * covered by patents for commercial use, please contact:
505612Sgblack@eecs.umich.edu *     Director of Intellectual Property Licensing
515612Sgblack@eecs.umich.edu *     Office of Strategy and Technology
525612Sgblack@eecs.umich.edu *     Hewlett-Packard Company
535612Sgblack@eecs.umich.edu *     1501 Page Mill Road
545612Sgblack@eecs.umich.edu *     Palo Alto, California  94304
555612Sgblack@eecs.umich.edu *
565612Sgblack@eecs.umich.edu * Redistributions of source code must retain the above copyright notice,
575612Sgblack@eecs.umich.edu * this list of conditions and the following disclaimer.  Redistributions
585612Sgblack@eecs.umich.edu * in binary form must reproduce the above copyright notice, this list of
595612Sgblack@eecs.umich.edu * conditions and the following disclaimer in the documentation and/or
605612Sgblack@eecs.umich.edu * other materials provided with the distribution.  Neither the name of
615612Sgblack@eecs.umich.edu * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
625612Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
635612Sgblack@eecs.umich.edu * this software without specific prior written permission.  No right of
645612Sgblack@eecs.umich.edu * sublicense is granted herewith.  Derivatives of the software and
655612Sgblack@eecs.umich.edu * output created using the software may be prepared, but only for
665612Sgblack@eecs.umich.edu * Non-Commercial Uses.  Derivatives of the software may be shared with
675612Sgblack@eecs.umich.edu * others provided: (i) the others agree to abide by the list of
685612Sgblack@eecs.umich.edu * conditions herein which includes the Non-Commercial Use restrictions;
695612Sgblack@eecs.umich.edu * and (ii) such Derivatives of the software include the above copyright
705612Sgblack@eecs.umich.edu * notice to acknowledge the contribution from this software where
715612Sgblack@eecs.umich.edu * applicable, this list of conditions and the disclaimer below.
725612Sgblack@eecs.umich.edu *
735612Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
745612Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
755612Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
765612Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
775612Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
785612Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
795612Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
805612Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
815612Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
825612Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
835612Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
845612Sgblack@eecs.umich.edu *
855612Sgblack@eecs.umich.edu * Authors: Gabe Black
865612Sgblack@eecs.umich.edu */
875612Sgblack@eecs.umich.edu
885612Sgblack@eecs.umich.edu#include "arch/x86/bios/smbios.hh"
895612Sgblack@eecs.umich.edu#include "arch/x86/isa_traits.hh"
905612Sgblack@eecs.umich.edu#include "mem/port.hh"
915612Sgblack@eecs.umich.edu#include "sim/byteswap.hh"
925612Sgblack@eecs.umich.edu#include "sim/host.hh"
935612Sgblack@eecs.umich.edu
945612Sgblack@eecs.umich.educonst char X86ISA::SMBios::SMBiosTable::SMBiosHeader::anchorString[] = "_SM_";
955612Sgblack@eecs.umich.educonst uint8_t X86ISA::SMBios::SMBiosTable::
965612Sgblack@eecs.umich.edu        SMBiosHeader::formattedArea[] = {0,0,0,0,0};
975612Sgblack@eecs.umich.educonst uint8_t X86ISA::SMBios::SMBiosTable::
985612Sgblack@eecs.umich.edu        SMBiosHeader::entryPointLength = 0x1F;
995612Sgblack@eecs.umich.educonst uint8_t X86ISA::SMBios::SMBiosTable::
1005612Sgblack@eecs.umich.edu        SMBiosHeader::entryPointRevision = 0;
1015612Sgblack@eecs.umich.educonst char X86ISA::SMBios::SMBiosTable::
1025612Sgblack@eecs.umich.edu        SMBiosHeader::IntermediateHeader::anchorString[] = "_DMI_";
1035612Sgblack@eecs.umich.edu
1045612Sgblack@eecs.umich.eduuint16_t
1055612Sgblack@eecs.umich.eduX86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr)
1065612Sgblack@eecs.umich.edu{
1075612Sgblack@eecs.umich.edu    uint8_t size = SMBiosStructure::writeOut(port, addr);
1085612Sgblack@eecs.umich.edu
1095612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1);
1105612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x5, (uint8_t *)(&version), 1);
1115612Sgblack@eecs.umich.edu
1125612Sgblack@eecs.umich.edu    uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment);
1135612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2);
1145612Sgblack@eecs.umich.edu
1155612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1);
1165612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1);
1175612Sgblack@eecs.umich.edu
1185612Sgblack@eecs.umich.edu    uint64_t characteristicsGuest = X86ISA::htog(characteristics);
1195612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8);
1205612Sgblack@eecs.umich.edu
1215612Sgblack@eecs.umich.edu    uint16_t characteristicExtBytesGuest =
1225612Sgblack@eecs.umich.edu        X86ISA::htog(characteristicExtBytes);
1235612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2);
1245612Sgblack@eecs.umich.edu
1255612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x14, (uint8_t *)(&major), 1);
1265612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x15, (uint8_t *)(&minor), 1);
1275612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
1285612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
1295612Sgblack@eecs.umich.edu
1305612Sgblack@eecs.umich.edu    writeOutStrings(port, addr + getLength());
1315612Sgblack@eecs.umich.edu
1325612Sgblack@eecs.umich.edu    return size;
1335612Sgblack@eecs.umich.edu}
1345612Sgblack@eecs.umich.edu
1355612Sgblack@eecs.umich.eduvoid
1365612Sgblack@eecs.umich.eduX86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr)
1375612Sgblack@eecs.umich.edu{
1385612Sgblack@eecs.umich.edu
1395612Sgblack@eecs.umich.edu    /*
1405612Sgblack@eecs.umich.edu     * The main header
1415612Sgblack@eecs.umich.edu     */
1425612Sgblack@eecs.umich.edu    uint8_t mainChecksum = 0;
1435612Sgblack@eecs.umich.edu
1445612Sgblack@eecs.umich.edu    port->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4);
1455612Sgblack@eecs.umich.edu    for (int i = 0; i < 4; i++)
1465612Sgblack@eecs.umich.edu        mainChecksum += smbiosHeader.anchorString[i];
1475612Sgblack@eecs.umich.edu
1485612Sgblack@eecs.umich.edu    // The checksum goes here, but we're figuring it out as we go.
1495612Sgblack@eecs.umich.edu
1505612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x5,
1515612Sgblack@eecs.umich.edu            (uint8_t *)(&smbiosHeader.entryPointLength), 1);
1525612Sgblack@eecs.umich.edu    mainChecksum += smbiosHeader.entryPointLength;
1535612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x6,
1545612Sgblack@eecs.umich.edu            (uint8_t *)(&smbiosHeader.majorVersion), 1);
1555612Sgblack@eecs.umich.edu    mainChecksum += smbiosHeader.majorVersion;
1565612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x7,
1575612Sgblack@eecs.umich.edu            (uint8_t *)(&smbiosHeader.minorVersion), 1);
1585612Sgblack@eecs.umich.edu    mainChecksum += smbiosHeader.minorVersion;
1595612Sgblack@eecs.umich.edu    // Maximum structure size goes here, but we'll figure it out later.
1605612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0xA,
1615612Sgblack@eecs.umich.edu            (uint8_t *)(&smbiosHeader.entryPointRevision), 1);
1625612Sgblack@eecs.umich.edu    mainChecksum += smbiosHeader.entryPointRevision;
1635612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0xB,
1645612Sgblack@eecs.umich.edu            (uint8_t *)(&smbiosHeader.formattedArea), 5);
1655612Sgblack@eecs.umich.edu    for (int i = 0; i < 5; i++)
1665612Sgblack@eecs.umich.edu        mainChecksum += smbiosHeader.formattedArea[i];
1675612Sgblack@eecs.umich.edu
1685612Sgblack@eecs.umich.edu    /*
1695612Sgblack@eecs.umich.edu     * The intermediate header
1705612Sgblack@eecs.umich.edu     */
1715612Sgblack@eecs.umich.edu    uint8_t intChecksum = 0;
1725612Sgblack@eecs.umich.edu
1735612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x10,
1745612Sgblack@eecs.umich.edu            (uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5);
1755612Sgblack@eecs.umich.edu    for (int i = 0; i < 5; i++)
1765612Sgblack@eecs.umich.edu        intChecksum += smbiosHeader.intermediateHeader.anchorString[i];
1775612Sgblack@eecs.umich.edu
1785612Sgblack@eecs.umich.edu    // The checksum goes here, but we're figuring it out as we go.
1795612Sgblack@eecs.umich.edu    // Then the length of the structure table which we'll find later
1805612Sgblack@eecs.umich.edu
1815612Sgblack@eecs.umich.edu    uint32_t tableAddrGuest =
1825612Sgblack@eecs.umich.edu        X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr);
1835612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4);
1845612Sgblack@eecs.umich.edu    for (int i = 0; i < 4; i++) {
1855612Sgblack@eecs.umich.edu        intChecksum += tableAddrGuest;
1865612Sgblack@eecs.umich.edu        tableAddrGuest >>= 8;
1875612Sgblack@eecs.umich.edu    }
1885612Sgblack@eecs.umich.edu
1895612Sgblack@eecs.umich.edu    uint16_t numStructs = X86ISA::gtoh(structures.size());
1905612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2);
1915612Sgblack@eecs.umich.edu    for (int i = 0; i < 2; i++) {
1925612Sgblack@eecs.umich.edu        intChecksum += numStructs;
1935612Sgblack@eecs.umich.edu        numStructs >>= 8;
1945612Sgblack@eecs.umich.edu    }
1955612Sgblack@eecs.umich.edu
1965612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x1E,
1975612Sgblack@eecs.umich.edu            (uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision),
1985612Sgblack@eecs.umich.edu            1);
1995612Sgblack@eecs.umich.edu    intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision;
2005612Sgblack@eecs.umich.edu
2015612Sgblack@eecs.umich.edu    /*
2025612Sgblack@eecs.umich.edu     * Structure table
2035612Sgblack@eecs.umich.edu     */
2045612Sgblack@eecs.umich.edu
2055612Sgblack@eecs.umich.edu    Addr base = smbiosHeader.intermediateHeader.tableAddr;
2065612Sgblack@eecs.umich.edu    Addr offset = 0;
2075612Sgblack@eecs.umich.edu    uint16_t maxSize = 0;
2085612Sgblack@eecs.umich.edu    std::vector<SMBiosStructure>::iterator it;
2095612Sgblack@eecs.umich.edu    for (it = structures.begin(); it != structures.end(); it++) {
2105612Sgblack@eecs.umich.edu        uint16_t size = it->writeOut(port, base + offset);
2115612Sgblack@eecs.umich.edu        if (size > maxSize)
2125612Sgblack@eecs.umich.edu            maxSize = size;
2135612Sgblack@eecs.umich.edu        offset += size;
2145612Sgblack@eecs.umich.edu    }
2155612Sgblack@eecs.umich.edu
2165612Sgblack@eecs.umich.edu    /*
2175612Sgblack@eecs.umich.edu     * Header
2185612Sgblack@eecs.umich.edu     */
2195612Sgblack@eecs.umich.edu
2205612Sgblack@eecs.umich.edu    maxSize = X86ISA::htog(maxSize);
2215612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2);
2225612Sgblack@eecs.umich.edu    for (int i = 0; i < 2; i++) {
2235612Sgblack@eecs.umich.edu        mainChecksum += maxSize;
2245612Sgblack@eecs.umich.edu        maxSize >>= 8;
2255612Sgblack@eecs.umich.edu    }
2265612Sgblack@eecs.umich.edu
2275612Sgblack@eecs.umich.edu    // Set the checksum
2285612Sgblack@eecs.umich.edu    mainChecksum = -mainChecksum;
2295612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
2305612Sgblack@eecs.umich.edu
2315612Sgblack@eecs.umich.edu    /*
2325612Sgblack@eecs.umich.edu     * Intermediate header
2335612Sgblack@eecs.umich.edu     */
2345612Sgblack@eecs.umich.edu
2355612Sgblack@eecs.umich.edu    uint16_t tableSize = offset;
2365612Sgblack@eecs.umich.edu    tableSize = X86ISA::htog(tableSize);
2375612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2);
2385612Sgblack@eecs.umich.edu    for (int i = 0; i < 2; i++) {
2395612Sgblack@eecs.umich.edu        intChecksum += tableSize;
2405612Sgblack@eecs.umich.edu        tableSize >>= 8;
2415612Sgblack@eecs.umich.edu    }
2425612Sgblack@eecs.umich.edu
2435612Sgblack@eecs.umich.edu    intChecksum = -intChecksum;
2445612Sgblack@eecs.umich.edu    port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
2455612Sgblack@eecs.umich.edu}
246