2 * Copyright (c) 2008 The Hewlett-Packard Development Company
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
14 * Copyright (c) 2008 The Regents of The University of Michigan
15 * All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 #include "arch/x86/bios/smbios.hh"
43 #include "arch/x86/isa_traits.hh"
44 #include "base/types.hh"
45 #include "mem/port_proxy.hh"
46 #include "params/X86SMBiosBiosInformation.hh"
47 #include "params/X86SMBiosSMBiosStructure.hh"
48 #include "params/X86SMBiosSMBiosTable.hh"
49 #include "sim/byteswap.hh"
51 const char X86ISA::SMBios::SMBiosTable::SMBiosHeader::anchorString
[] = "_SM_";
52 const uint8_t X86ISA::SMBios::SMBiosTable::
53 SMBiosHeader::formattedArea
[] = {0,0,0,0,0};
54 const uint8_t X86ISA::SMBios::SMBiosTable::
55 SMBiosHeader::entryPointLength
= 0x1F;
56 const uint8_t X86ISA::SMBios::SMBiosTable::
57 SMBiosHeader::entryPointRevision
= 0;
58 const char X86ISA::SMBios::SMBiosTable::
59 SMBiosHeader::IntermediateHeader::anchorString
[] = "_DMI_";
63 composeBitVector(T vec
)
66 typename
T::iterator vecIt
;
67 for (vecIt
= vec
.begin(); vecIt
!= vec
.end(); vecIt
++) {
68 val
|= (1 << (*vecIt
));
74 X86ISA::SMBios::SMBiosStructure::writeOut(PortProxy
& proxy
, Addr addr
)
76 proxy
.writeBlob(addr
, &type
, 1);
78 uint8_t length
= getLength();
79 proxy
.writeBlob(addr
+ 1, &length
, 1);
81 uint16_t handleGuest
= htole(handle
);
82 proxy
.writeBlob(addr
+ 2, &handleGuest
, 2);
84 return length
+ getStringLength();
87 X86ISA::SMBios::SMBiosStructure::SMBiosStructure(
88 const Params
&p
, uint8_t _type
) :
89 SimObject(p
), type(_type
), handle(0), stringFields(false)
93 X86ISA::SMBios::SMBiosStructure::writeOutStrings(
94 PortProxy
& proxy
, Addr addr
)
96 std::vector
<std::string
>::iterator it
;
99 const uint8_t nullTerminator
= 0;
101 // If there are string fields but none of them are used, that's a
102 // special case which is handled by this if.
103 if (strings
.size() == 0 && stringFields
) {
104 proxy
.writeBlob(addr
+ offset
, &nullTerminator
, 1);
107 for (it
= strings
.begin(); it
!= strings
.end(); it
++) {
108 proxy
.writeBlob(addr
+ offset
, it
->c_str(), it
->length() + 1);
109 offset
+= it
->length() + 1;
112 proxy
.writeBlob(addr
+ offset
, &nullTerminator
, 1);
116 X86ISA::SMBios::SMBiosStructure::getStringLength()
119 std::vector
<std::string
>::iterator it
;
121 for (it
= strings
.begin(); it
!= strings
.end(); it
++) {
122 size
+= it
->length() + 1;
129 X86ISA::SMBios::SMBiosStructure::addString(const std::string
&new_string
)
132 // If a string is empty, treat it as not existing. The index for empty
134 if (new_string
.length() == 0)
136 strings
.push_back(new_string
);
137 return strings
.size();
141 X86ISA::SMBios::SMBiosStructure::readString(int n
)
143 assert(n
> 0 && n
<= strings
.size());
144 return strings
[n
- 1];
148 X86ISA::SMBios::SMBiosStructure::setString(
149 int n
, const std::string
&new_string
)
151 assert(n
> 0 && n
<= strings
.size());
152 strings
[n
- 1] = new_string
;
155 X86ISA::SMBios::BiosInformation::BiosInformation(const Params
&p
) :
156 SMBiosStructure(p
, Type
),
157 startingAddrSegment(p
.starting_addr_segment
),
159 majorVer(p
.major
), minorVer(p
.minor
),
160 embContFirmwareMajor(p
.emb_cont_firmware_major
),
161 embContFirmwareMinor(p
.emb_cont_firmware_minor
)
163 vendor
= addString(p
.vendor
);
164 version
= addString(p
.version
);
165 releaseDate
= addString(p
.release_date
);
167 characteristics
= composeBitVector(p
.characteristics
);
168 characteristicExtBytes
=
169 composeBitVector(p
.characteristic_ext_bytes
);
173 X86ISA::SMBios::BiosInformation::writeOut(PortProxy
& proxy
, Addr addr
)
175 uint8_t size
= SMBiosStructure::writeOut(proxy
, addr
);
177 proxy
.writeBlob(addr
+ 0x4, &vendor
, 1);
178 proxy
.writeBlob(addr
+ 0x5, &version
, 1);
180 uint16_t startingAddrSegmentGuest
= htole(startingAddrSegment
);
181 proxy
.writeBlob(addr
+ 0x6, &startingAddrSegmentGuest
, 2);
183 proxy
.writeBlob(addr
+ 0x8, &releaseDate
, 1);
184 proxy
.writeBlob(addr
+ 0x9, &romSize
, 1);
186 uint64_t characteristicsGuest
= htole(characteristics
);
187 proxy
.writeBlob(addr
+ 0xA, &characteristicsGuest
, 8);
189 uint16_t characteristicExtBytesGuest
=
190 htole(characteristicExtBytes
);
191 proxy
.writeBlob(addr
+ 0x12, &characteristicExtBytesGuest
, 2);
193 proxy
.writeBlob(addr
+ 0x14, &majorVer
, 1);
194 proxy
.writeBlob(addr
+ 0x15, &minorVer
, 1);
195 proxy
.writeBlob(addr
+ 0x16, &embContFirmwareMajor
, 1);
196 proxy
.writeBlob(addr
+ 0x17, &embContFirmwareMinor
, 1);
198 writeOutStrings(proxy
, addr
+ getLength());
203 X86ISA::SMBios::SMBiosTable::SMBiosTable(const Params
&p
) :
204 SimObject(p
), structures(p
.structures
)
206 smbiosHeader
.majorVersion
= p
.major_version
;
207 smbiosHeader
.minorVersion
= p
.minor_version
;
208 assert(p
.major_version
<= 9);
209 assert(p
.minor_version
<= 9);
210 smbiosHeader
.intermediateHeader
.smbiosBCDRevision
=
211 (p
.major_version
<< 4) | p
.minor_version
;
215 X86ISA::SMBios::SMBiosTable::writeOut(PortProxy
& proxy
, Addr addr
,
216 Addr
&headerSize
, Addr
&structSize
)
223 uint8_t mainChecksum
= 0;
225 proxy
.writeBlob(addr
, (uint8_t *)smbiosHeader
.anchorString
, 4);
226 for (int i
= 0; i
< 4; i
++)
227 mainChecksum
+= smbiosHeader
.anchorString
[i
];
229 // The checksum goes here, but we're figuring it out as we go.
231 proxy
.writeBlob(addr
+ 0x5, &smbiosHeader
.entryPointLength
, 1);
232 mainChecksum
+= smbiosHeader
.entryPointLength
;
233 proxy
.writeBlob(addr
+ 0x6, &smbiosHeader
.majorVersion
, 1);
234 mainChecksum
+= smbiosHeader
.majorVersion
;
235 proxy
.writeBlob(addr
+ 0x7, &smbiosHeader
.minorVersion
, 1);
236 mainChecksum
+= smbiosHeader
.minorVersion
;
237 // Maximum structure size goes here, but we'll figure it out later.
238 proxy
.writeBlob(addr
+ 0xA, &smbiosHeader
.entryPointRevision
, 1);
239 mainChecksum
+= smbiosHeader
.entryPointRevision
;
240 proxy
.writeBlob(addr
+ 0xB, &smbiosHeader
.formattedArea
, 5);
241 for (int i
= 0; i
< 5; i
++)
242 mainChecksum
+= smbiosHeader
.formattedArea
[i
];
245 * The intermediate header
247 uint8_t intChecksum
= 0;
249 proxy
.writeBlob(addr
+ 0x10,
250 smbiosHeader
.intermediateHeader
.anchorString
, 5);
251 for (int i
= 0; i
< 5; i
++)
252 intChecksum
+= smbiosHeader
.intermediateHeader
.anchorString
[i
];
254 // The checksum goes here, but we're figuring it out as we go.
255 // Then the length of the structure table which we'll find later
257 uint32_t tableAddrGuest
=
258 htole(smbiosHeader
.intermediateHeader
.tableAddr
);
259 proxy
.writeBlob(addr
+ 0x18, &tableAddrGuest
, 4);
260 for (int i
= 0; i
< 4; i
++) {
261 intChecksum
+= tableAddrGuest
;
262 tableAddrGuest
>>= 8;
265 uint16_t numStructs
= letoh(structures
.size());
266 proxy
.writeBlob(addr
+ 0x1C, &numStructs
, 2);
267 for (int i
= 0; i
< 2; i
++) {
268 intChecksum
+= numStructs
;
272 proxy
.writeBlob(addr
+ 0x1E,
273 &smbiosHeader
.intermediateHeader
.smbiosBCDRevision
, 1);
274 intChecksum
+= smbiosHeader
.intermediateHeader
.smbiosBCDRevision
;
280 Addr base
= smbiosHeader
.intermediateHeader
.tableAddr
;
282 uint16_t maxSize
= 0;
283 std::vector
<SMBiosStructure
*>::iterator it
;
284 for (it
= structures
.begin(); it
!= structures
.end(); it
++) {
285 uint16_t size
= (*it
)->writeOut(proxy
, base
+ offset
);
297 maxSize
= htole(maxSize
);
298 proxy
.writeBlob(addr
+ 0x8, &maxSize
, 2);
299 for (int i
= 0; i
< 2; i
++) {
300 mainChecksum
+= maxSize
;
305 mainChecksum
= -mainChecksum
;
306 proxy
.writeBlob(addr
+ 0x4, &mainChecksum
, 1);
309 * Intermediate header
312 uint16_t tableSize
= offset
;
313 tableSize
= htole(tableSize
);
314 proxy
.writeBlob(addr
+ 0x16, &tableSize
, 2);
315 for (int i
= 0; i
< 2; i
++) {
316 intChecksum
+= tableSize
;
320 intChecksum
= -intChecksum
;
321 proxy
.writeBlob(addr
+ 0x15, &intChecksum
, 1);