gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
smbios.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 The Hewlett-Packard Development Company
3  * All rights reserved.
4  *
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.
13  *
14  * Copyright (c) 2008 The Regents of The University of Michigan
15  * All rights reserved.
16  *
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.
27  *
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.
39  *
40  * Authors: Gabe Black
41  */
42 
43 #include "arch/x86/bios/smbios.hh"
44 
45 #include "arch/x86/isa_traits.hh"
46 #include "base/types.hh"
47 #include "mem/port_proxy.hh"
48 #include "params/X86SMBiosBiosInformation.hh"
49 #include "params/X86SMBiosSMBiosStructure.hh"
50 #include "params/X86SMBiosSMBiosTable.hh"
51 #include "sim/byteswap.hh"
52 
53 using namespace std;
54 
57  SMBiosHeader::formattedArea[] = {0,0,0,0,0};
64 
65 template <class T>
66 uint64_t
68 {
69  uint64_t val = 0;
70  typename T::iterator vecIt;
71  for (vecIt = vec.begin(); vecIt != vec.end(); vecIt++) {
72  val |= (1 << (*vecIt));
73  }
74  return val;
75 }
76 
77 uint16_t
79 {
80  proxy.writeBlob(addr, (uint8_t *)(&type), 1);
81 
82  uint8_t length = getLength();
83  proxy.writeBlob(addr + 1, (uint8_t *)(&length), 1);
84 
85  uint16_t handleGuest = X86ISA::htog(handle);
86  proxy.writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2);
87 
88  return length + getStringLength();
89 }
90 
92  SimObject(p), type(_type), handle(0), stringFields(false)
93 {}
94 
95 void
97  PortProxy& proxy, Addr addr)
98 {
100  Addr offset = 0;
101 
102  const uint8_t nullTerminator = 0;
103 
104  // If there are string fields but none of them are used, that's a
105  // special case which is handled by this if.
106  if (strings.size() == 0 && stringFields) {
107  proxy.writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
108  offset++;
109  } else {
110  for (it = strings.begin(); it != strings.end(); it++) {
111  proxy.writeBlob(addr + offset,
112  (uint8_t *)it->c_str(), it->length() + 1);
113  offset += it->length() + 1;
114  }
115  }
116  proxy.writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
117 }
118 
119 int
121 {
122  int size = 0;
124 
125  for (it = strings.begin(); it != strings.end(); it++) {
126  size += it->length() + 1;
127  }
128 
129  return size + 1;
130 }
131 
132 int
134 {
135  stringFields = true;
136  // If a string is empty, treat it as not existing. The index for empty
137  // strings is 0.
138  if (newString.length() == 0)
139  return 0;
140  strings.push_back(newString);
141  return strings.size();
142 }
143 
144 string
146 {
147  assert(n > 0 && n <= strings.size());
148  return strings[n - 1];
149 }
150 
151 void
152 X86ISA::SMBios::SMBiosStructure::setString(int n, std::string & newString)
153 {
154  assert(n > 0 && n <= strings.size());
155  strings[n - 1] = newString;
156 }
157 
159  SMBiosStructure(p, Type),
160  startingAddrSegment(p->starting_addr_segment),
161  romSize(p->rom_size),
162  majorVer(p->major), minorVer(p->minor),
163  embContFirmwareMajor(p->emb_cont_firmware_major),
164  embContFirmwareMinor(p->emb_cont_firmware_minor)
165  {
166  vendor = addString(p->vendor);
167  version = addString(p->version);
168  releaseDate = addString(p->release_date);
169 
170  characteristics = composeBitVector(p->characteristics);
172  composeBitVector(p->characteristic_ext_bytes);
173  }
174 
175 uint16_t
177 {
178  uint8_t size = SMBiosStructure::writeOut(proxy, addr);
179 
180  proxy.writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1);
181  proxy.writeBlob(addr + 0x5, (uint8_t *)(&version), 1);
182 
183  uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment);
184  proxy.writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2);
185 
186  proxy.writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1);
187  proxy.writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1);
188 
189  uint64_t characteristicsGuest = X86ISA::htog(characteristics);
190  proxy.writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8);
191 
192  uint16_t characteristicExtBytesGuest =
193  X86ISA::htog(characteristicExtBytes);
194  proxy.writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2);
195 
196  proxy.writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1);
197  proxy.writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1);
198  proxy.writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
199  proxy.writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
200 
201  writeOutStrings(proxy, addr + getLength());
202 
203  return size;
204 }
205 
207  SimObject(p), structures(p->structures)
208 {
209  smbiosHeader.majorVersion = p->major_version;
210  smbiosHeader.minorVersion = p->minor_version;
211  assert(p->major_version <= 9);
212  assert(p->minor_version <= 9);
214  (p->major_version << 4) | p->minor_version;
215 }
216 
217 void
219  Addr &headerSize, Addr &structSize)
220 {
221  headerSize = 0x1F;
222 
223  /*
224  * The main header
225  */
226  uint8_t mainChecksum = 0;
227 
228  proxy.writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4);
229  for (int i = 0; i < 4; i++)
230  mainChecksum += smbiosHeader.anchorString[i];
231 
232  // The checksum goes here, but we're figuring it out as we go.
233 
234  proxy.writeBlob(addr + 0x5,
235  (uint8_t *)(&smbiosHeader.entryPointLength), 1);
236  mainChecksum += smbiosHeader.entryPointLength;
237  proxy.writeBlob(addr + 0x6,
238  (uint8_t *)(&smbiosHeader.majorVersion), 1);
239  mainChecksum += smbiosHeader.majorVersion;
240  proxy.writeBlob(addr + 0x7,
241  (uint8_t *)(&smbiosHeader.minorVersion), 1);
242  mainChecksum += smbiosHeader.minorVersion;
243  // Maximum structure size goes here, but we'll figure it out later.
244  proxy.writeBlob(addr + 0xA,
245  (uint8_t *)(&smbiosHeader.entryPointRevision), 1);
246  mainChecksum += smbiosHeader.entryPointRevision;
247  proxy.writeBlob(addr + 0xB,
248  (uint8_t *)(&smbiosHeader.formattedArea), 5);
249  for (int i = 0; i < 5; i++)
250  mainChecksum += smbiosHeader.formattedArea[i];
251 
252  /*
253  * The intermediate header
254  */
255  uint8_t intChecksum = 0;
256 
257  proxy.writeBlob(addr + 0x10,
258  (uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5);
259  for (int i = 0; i < 5; i++)
260  intChecksum += smbiosHeader.intermediateHeader.anchorString[i];
261 
262  // The checksum goes here, but we're figuring it out as we go.
263  // Then the length of the structure table which we'll find later
264 
265  uint32_t tableAddrGuest =
266  X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr);
267  proxy.writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4);
268  for (int i = 0; i < 4; i++) {
269  intChecksum += tableAddrGuest;
270  tableAddrGuest >>= 8;
271  }
272 
273  uint16_t numStructs = X86ISA::gtoh(structures.size());
274  proxy.writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2);
275  for (int i = 0; i < 2; i++) {
276  intChecksum += numStructs;
277  numStructs >>= 8;
278  }
279 
280  proxy.writeBlob(addr + 0x1E,
281  (uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision),
282  1);
283  intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision;
284 
285  /*
286  * Structure table
287  */
288 
289  Addr base = smbiosHeader.intermediateHeader.tableAddr;
290  Addr offset = 0;
291  uint16_t maxSize = 0;
293  for (it = structures.begin(); it != structures.end(); it++) {
294  uint16_t size = (*it)->writeOut(proxy, base + offset);
295  if (size > maxSize)
296  maxSize = size;
297  offset += size;
298  }
299 
300  structSize = offset;
301 
302  /*
303  * Header
304  */
305 
306  maxSize = X86ISA::htog(maxSize);
307  proxy.writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2);
308  for (int i = 0; i < 2; i++) {
309  mainChecksum += maxSize;
310  maxSize >>= 8;
311  }
312 
313  // Set the checksum
314  mainChecksum = -mainChecksum;
315  proxy.writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
316 
317  /*
318  * Intermediate header
319  */
320 
321  uint16_t tableSize = offset;
322  tableSize = X86ISA::htog(tableSize);
323  proxy.writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2);
324  for (int i = 0; i < 2; i++) {
325  intChecksum += tableSize;
326  tableSize >>= 8;
327  }
328 
329  intChecksum = -intChecksum;
330  proxy.writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
331 }
332 
334 X86SMBiosBiosInformationParams::create()
335 {
336  return new X86ISA::SMBios::BiosInformation(this);
337 }
338 
340 X86SMBiosSMBiosTableParams::create()
341 {
342  return new X86ISA::SMBios::SMBiosTable(this);
343 }
offset
Definition: misc.hh:977
T htog(T value)
Definition: byteswap.hh:177
Bitfield< 7 > i
Definition: miscregs.hh:1378
void writeOutStrings(PortProxy &proxy, Addr addr)
Definition: smbios.cc:96
void writeOut(PortProxy &proxy, Addr addr, Addr &headerSize, Addr &structSize)
Definition: smbios.cc:218
std::string readString(int n)
Definition: smbios.cc:145
SMBiosStructure(Params *p, uint8_t _type)
Definition: smbios.cc:91
ip6_addr_t addr
Definition: inet.hh:335
virtual uint16_t writeOut(PortProxy &proxy, Addr addr)
Definition: smbios.cc:78
static const uint8_t entryPointLength
Definition: smbios.hh:168
static const uint8_t entryPointRevision
Definition: smbios.hh:180
STL vector class.
Definition: stl.hh:40
T gtoh(T value)
Definition: byteswap.hh:179
Bitfield< 63 > val
Definition: misc.hh:770
Bitfield< 31 > n
Definition: miscregs.hh:1636
X86SMBiosSMBiosStructureParams Params
Definition: smbios.hh:68
PortProxy Object Declaration.
struct X86ISA::SMBios::SMBiosTable::SMBiosHeader::IntermediateHeader intermediateHeader
int addString(std::string &newString)
Definition: smbios.cc:133
Bitfield< 51, 12 > base
Definition: pagetable.hh:85
static const uint8_t formattedArea[5]
Definition: smbios.hh:183
struct X86ISA::SMBios::SMBiosTable::SMBiosHeader smbiosHeader
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
void setString(int n, std::string &newString)
Definition: smbios.cc:152
This object is a proxy for a structural port, to be used for debug accesses.
Definition: port_proxy.hh:84
type
Definition: misc.hh:728
int size()
Definition: pagetable.hh:146
uint64_t composeBitVector(T vec)
Definition: smbios.cc:67
virtual void writeBlob(Addr addr, const uint8_t *p, int size) const
Write size bytes from p to address.
Definition: port_proxy.cc:58
X86SMBiosSMBiosTableParams Params
Definition: smbios.hh:154
uint8_t length
Definition: inet.hh:334
Bitfield< 0 > p
Definition: pagetable.hh:95
uint16_t writeOut(PortProxy &proxy, Addr addr)
Definition: smbios.cc:176
Bitfield< 0 > p
Bitfield< 3 > addr
Definition: types.hh:81
Abstract superclass for simulation objects.
Definition: sim_object.hh:94

Generated on Fri Jun 9 2017 13:03:40 for gem5 by doxygen 1.8.6