smbios.cc revision 5612
1/*
2 * Copyright (c) 2008 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Gabe Black
29 */
30
31/*
32 * Copyright (c) 2008 The Hewlett-Packard Development Company
33 * All rights reserved.
34 *
35 * Redistribution and use of this software in source and binary forms,
36 * with or without modification, are permitted provided that the
37 * following conditions are met:
38 *
39 * The software must be used only for Non-Commercial Use which means any
40 * use which is NOT directed to receiving any direct monetary
41 * compensation for, or commercial advantage from such use.  Illustrative
42 * examples of non-commercial use are academic research, personal study,
43 * teaching, education and corporate research & development.
44 * Illustrative examples of commercial use are distributing products for
45 * commercial advantage and providing services using the software for
46 * commercial advantage.
47 *
48 * If you wish to use this software or functionality therein that may be
49 * covered by patents for commercial use, please contact:
50 *     Director of Intellectual Property Licensing
51 *     Office of Strategy and Technology
52 *     Hewlett-Packard Company
53 *     1501 Page Mill Road
54 *     Palo Alto, California  94304
55 *
56 * Redistributions of source code must retain the above copyright notice,
57 * this list of conditions and the following disclaimer.  Redistributions
58 * in binary form must reproduce the above copyright notice, this list of
59 * conditions and the following disclaimer in the documentation and/or
60 * other materials provided with the distribution.  Neither the name of
61 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
62 * contributors may be used to endorse or promote products derived from
63 * this software without specific prior written permission.  No right of
64 * sublicense is granted herewith.  Derivatives of the software and
65 * output created using the software may be prepared, but only for
66 * Non-Commercial Uses.  Derivatives of the software may be shared with
67 * others provided: (i) the others agree to abide by the list of
68 * conditions herein which includes the Non-Commercial Use restrictions;
69 * and (ii) such Derivatives of the software include the above copyright
70 * notice to acknowledge the contribution from this software where
71 * applicable, this list of conditions and the disclaimer below.
72 *
73 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
74 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
75 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
76 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
77 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
78 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
79 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
80 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
81 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
82 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
83 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
84 *
85 * Authors: Gabe Black
86 */
87
88#include "arch/x86/bios/smbios.hh"
89#include "arch/x86/isa_traits.hh"
90#include "mem/port.hh"
91#include "sim/byteswap.hh"
92#include "sim/host.hh"
93
94const char X86ISA::SMBios::SMBiosTable::SMBiosHeader::anchorString[] = "_SM_";
95const uint8_t X86ISA::SMBios::SMBiosTable::
96        SMBiosHeader::formattedArea[] = {0,0,0,0,0};
97const uint8_t X86ISA::SMBios::SMBiosTable::
98        SMBiosHeader::entryPointLength = 0x1F;
99const uint8_t X86ISA::SMBios::SMBiosTable::
100        SMBiosHeader::entryPointRevision = 0;
101const char X86ISA::SMBios::SMBiosTable::
102        SMBiosHeader::IntermediateHeader::anchorString[] = "_DMI_";
103
104uint16_t
105X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr)
106{
107    uint8_t size = SMBiosStructure::writeOut(port, addr);
108
109    port->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1);
110    port->writeBlob(addr + 0x5, (uint8_t *)(&version), 1);
111
112    uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment);
113    port->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2);
114
115    port->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1);
116    port->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1);
117
118    uint64_t characteristicsGuest = X86ISA::htog(characteristics);
119    port->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8);
120
121    uint16_t characteristicExtBytesGuest =
122        X86ISA::htog(characteristicExtBytes);
123    port->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2);
124
125    port->writeBlob(addr + 0x14, (uint8_t *)(&major), 1);
126    port->writeBlob(addr + 0x15, (uint8_t *)(&minor), 1);
127    port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
128    port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
129
130    writeOutStrings(port, addr + getLength());
131
132    return size;
133}
134
135void
136X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr)
137{
138
139    /*
140     * The main header
141     */
142    uint8_t mainChecksum = 0;
143
144    port->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4);
145    for (int i = 0; i < 4; i++)
146        mainChecksum += smbiosHeader.anchorString[i];
147
148    // The checksum goes here, but we're figuring it out as we go.
149
150    port->writeBlob(addr + 0x5,
151            (uint8_t *)(&smbiosHeader.entryPointLength), 1);
152    mainChecksum += smbiosHeader.entryPointLength;
153    port->writeBlob(addr + 0x6,
154            (uint8_t *)(&smbiosHeader.majorVersion), 1);
155    mainChecksum += smbiosHeader.majorVersion;
156    port->writeBlob(addr + 0x7,
157            (uint8_t *)(&smbiosHeader.minorVersion), 1);
158    mainChecksum += smbiosHeader.minorVersion;
159    // Maximum structure size goes here, but we'll figure it out later.
160    port->writeBlob(addr + 0xA,
161            (uint8_t *)(&smbiosHeader.entryPointRevision), 1);
162    mainChecksum += smbiosHeader.entryPointRevision;
163    port->writeBlob(addr + 0xB,
164            (uint8_t *)(&smbiosHeader.formattedArea), 5);
165    for (int i = 0; i < 5; i++)
166        mainChecksum += smbiosHeader.formattedArea[i];
167
168    /*
169     * The intermediate header
170     */
171    uint8_t intChecksum = 0;
172
173    port->writeBlob(addr + 0x10,
174            (uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5);
175    for (int i = 0; i < 5; i++)
176        intChecksum += smbiosHeader.intermediateHeader.anchorString[i];
177
178    // The checksum goes here, but we're figuring it out as we go.
179    // Then the length of the structure table which we'll find later
180
181    uint32_t tableAddrGuest =
182        X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr);
183    port->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4);
184    for (int i = 0; i < 4; i++) {
185        intChecksum += tableAddrGuest;
186        tableAddrGuest >>= 8;
187    }
188
189    uint16_t numStructs = X86ISA::gtoh(structures.size());
190    port->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2);
191    for (int i = 0; i < 2; i++) {
192        intChecksum += numStructs;
193        numStructs >>= 8;
194    }
195
196    port->writeBlob(addr + 0x1E,
197            (uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision),
198            1);
199    intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision;
200
201    /*
202     * Structure table
203     */
204
205    Addr base = smbiosHeader.intermediateHeader.tableAddr;
206    Addr offset = 0;
207    uint16_t maxSize = 0;
208    std::vector<SMBiosStructure>::iterator it;
209    for (it = structures.begin(); it != structures.end(); it++) {
210        uint16_t size = it->writeOut(port, base + offset);
211        if (size > maxSize)
212            maxSize = size;
213        offset += size;
214    }
215
216    /*
217     * Header
218     */
219
220    maxSize = X86ISA::htog(maxSize);
221    port->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2);
222    for (int i = 0; i < 2; i++) {
223        mainChecksum += maxSize;
224        maxSize >>= 8;
225    }
226
227    // Set the checksum
228    mainChecksum = -mainChecksum;
229    port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
230
231    /*
232     * Intermediate header
233     */
234
235    uint16_t tableSize = offset;
236    tableSize = X86ISA::htog(tableSize);
237    port->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2);
238    for (int i = 0; i < 2; i++) {
239        intChecksum += tableSize;
240        tableSize >>= 8;
241    }
242
243    intChecksum = -intChecksum;
244    port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
245}
246