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
| 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
|
88#include "arch/x86/bios/smbios.hh" 89#include "arch/x86/isa_traits.hh" 90#include "base/types.hh" 91#include "mem/port.hh" 92#include "params/X86SMBiosBiosInformation.hh" 93#include "params/X86SMBiosSMBiosStructure.hh" 94#include "params/X86SMBiosSMBiosTable.hh" 95#include "sim/byteswap.hh" 96 97using namespace std; 98 99const char X86ISA::SMBios::SMBiosTable::SMBiosHeader::anchorString[] = "_SM_"; 100const uint8_t X86ISA::SMBios::SMBiosTable:: 101 SMBiosHeader::formattedArea[] = {0,0,0,0,0}; 102const uint8_t X86ISA::SMBios::SMBiosTable:: 103 SMBiosHeader::entryPointLength = 0x1F; 104const uint8_t X86ISA::SMBios::SMBiosTable:: 105 SMBiosHeader::entryPointRevision = 0; 106const char X86ISA::SMBios::SMBiosTable:: 107 SMBiosHeader::IntermediateHeader::anchorString[] = "_DMI_"; 108 109template <class T> 110uint64_t 111composeBitVector(T vec) 112{ 113 uint64_t val = 0; 114 typename T::iterator vecIt; 115 for (vecIt = vec.begin(); vecIt != vec.end(); vecIt++) { 116 val |= (1 << (*vecIt)); 117 } 118 return val; 119} 120 121uint16_t 122X86ISA::SMBios::SMBiosStructure::writeOut(FunctionalPort * port, Addr addr) 123{ 124 port->writeBlob(addr, (uint8_t *)(&type), 1); 125 126 uint8_t length = getLength(); 127 port->writeBlob(addr + 1, (uint8_t *)(&length), 1); 128 129 uint16_t handleGuest = X86ISA::htog(handle); 130 port->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2); 131 132 return length + getStringLength(); 133} 134 135X86ISA::SMBios::SMBiosStructure::SMBiosStructure(Params * p, uint8_t _type) : 136 SimObject(p), type(_type), handle(0), stringFields(false) 137{} 138 139void 140X86ISA::SMBios::SMBiosStructure::writeOutStrings( 141 FunctionalPort * port, Addr addr) 142{ 143 std::vector<std::string>::iterator it; 144 Addr offset = 0; 145 146 const uint8_t nullTerminator = 0; 147 148 // If there are string fields but none of them are used, that's a 149 // special case which is handled by this if. 150 if (strings.size() == 0 && stringFields) { 151 port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); 152 offset++; 153 } else { 154 for (it = strings.begin(); it != strings.end(); it++) { 155 port->writeBlob(addr + offset, 156 (uint8_t *)it->c_str(), it->length() + 1); 157 offset += it->length() + 1; 158 } 159 } 160 port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); 161} 162 163int 164X86ISA::SMBios::SMBiosStructure::getStringLength() 165{ 166 int size = 0; 167 std::vector<std::string>::iterator it; 168 169 for (it = strings.begin(); it != strings.end(); it++) { 170 size += it->length() + 1; 171 } 172 173 return size + 1; 174} 175 176int 177X86ISA::SMBios::SMBiosStructure::addString(string & newString) 178{ 179 stringFields = true; 180 // If a string is empty, treat it as not existing. The index for empty 181 // strings is 0. 182 if (newString.length() == 0) 183 return 0; 184 strings.push_back(newString); 185 return strings.size(); 186} 187 188string 189X86ISA::SMBios::SMBiosStructure::readString(int n) 190{ 191 assert(n > 0 && n <= strings.size()); 192 return strings[n - 1]; 193} 194 195void 196X86ISA::SMBios::SMBiosStructure::setString(int n, std::string & newString) 197{ 198 assert(n > 0 && n <= strings.size()); 199 strings[n - 1] = newString; 200} 201 202X86ISA::SMBios::BiosInformation::BiosInformation(Params * p) : 203 SMBiosStructure(p, Type), 204 startingAddrSegment(p->starting_addr_segment), 205 romSize(p->rom_size), 206 majorVer(p->major), minorVer(p->minor), 207 embContFirmwareMajor(p->emb_cont_firmware_major), 208 embContFirmwareMinor(p->emb_cont_firmware_minor) 209 { 210 vendor = addString(p->vendor); 211 version = addString(p->version); 212 releaseDate = addString(p->release_date); 213 214 characteristics = composeBitVector(p->characteristics); 215 characteristicExtBytes = 216 composeBitVector(p->characteristic_ext_bytes); 217 } 218 219uint16_t 220X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr) 221{ 222 uint8_t size = SMBiosStructure::writeOut(port, addr); 223 224 port->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1); 225 port->writeBlob(addr + 0x5, (uint8_t *)(&version), 1); 226 227 uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment); 228 port->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2); 229 230 port->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1); 231 port->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1); 232 233 uint64_t characteristicsGuest = X86ISA::htog(characteristics); 234 port->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8); 235 236 uint16_t characteristicExtBytesGuest = 237 X86ISA::htog(characteristicExtBytes); 238 port->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2); 239 240 port->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1); 241 port->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1); 242 port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1); 243 port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1); 244 245 writeOutStrings(port, addr + getLength()); 246 247 return size; 248} 249 250X86ISA::SMBios::SMBiosTable::SMBiosTable(Params * p) : 251 SimObject(p), structures(p->structures) 252{ 253 smbiosHeader.majorVersion = p->major_version; 254 smbiosHeader.minorVersion = p->minor_version; 255 assert(p->major_version <= 9); 256 assert(p->minor_version <= 9); 257 smbiosHeader.intermediateHeader.smbiosBCDRevision = 258 (p->major_version << 4) | p->minor_version; 259} 260 261void 262X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr, 263 Addr &headerSize, Addr &structSize) 264{ 265 headerSize = 0x1F; 266 267 /* 268 * The main header 269 */ 270 uint8_t mainChecksum = 0; 271 272 port->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4); 273 for (int i = 0; i < 4; i++) 274 mainChecksum += smbiosHeader.anchorString[i]; 275 276 // The checksum goes here, but we're figuring it out as we go. 277 278 port->writeBlob(addr + 0x5, 279 (uint8_t *)(&smbiosHeader.entryPointLength), 1); 280 mainChecksum += smbiosHeader.entryPointLength; 281 port->writeBlob(addr + 0x6, 282 (uint8_t *)(&smbiosHeader.majorVersion), 1); 283 mainChecksum += smbiosHeader.majorVersion; 284 port->writeBlob(addr + 0x7, 285 (uint8_t *)(&smbiosHeader.minorVersion), 1); 286 mainChecksum += smbiosHeader.minorVersion; 287 // Maximum structure size goes here, but we'll figure it out later. 288 port->writeBlob(addr + 0xA, 289 (uint8_t *)(&smbiosHeader.entryPointRevision), 1); 290 mainChecksum += smbiosHeader.entryPointRevision; 291 port->writeBlob(addr + 0xB, 292 (uint8_t *)(&smbiosHeader.formattedArea), 5); 293 for (int i = 0; i < 5; i++) 294 mainChecksum += smbiosHeader.formattedArea[i]; 295 296 /* 297 * The intermediate header 298 */ 299 uint8_t intChecksum = 0; 300 301 port->writeBlob(addr + 0x10, 302 (uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5); 303 for (int i = 0; i < 5; i++) 304 intChecksum += smbiosHeader.intermediateHeader.anchorString[i]; 305 306 // The checksum goes here, but we're figuring it out as we go. 307 // Then the length of the structure table which we'll find later 308 309 uint32_t tableAddrGuest = 310 X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr); 311 port->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4); 312 for (int i = 0; i < 4; i++) { 313 intChecksum += tableAddrGuest; 314 tableAddrGuest >>= 8; 315 } 316 317 uint16_t numStructs = X86ISA::gtoh(structures.size()); 318 port->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2); 319 for (int i = 0; i < 2; i++) { 320 intChecksum += numStructs; 321 numStructs >>= 8; 322 } 323 324 port->writeBlob(addr + 0x1E, 325 (uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision), 326 1); 327 intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision; 328 329 /* 330 * Structure table 331 */ 332 333 Addr base = smbiosHeader.intermediateHeader.tableAddr; 334 Addr offset = 0; 335 uint16_t maxSize = 0; 336 std::vector<SMBiosStructure *>::iterator it; 337 for (it = structures.begin(); it != structures.end(); it++) { 338 uint16_t size = (*it)->writeOut(port, base + offset); 339 if (size > maxSize) 340 maxSize = size; 341 offset += size; 342 } 343 344 structSize = offset; 345 346 /* 347 * Header 348 */ 349 350 maxSize = X86ISA::htog(maxSize); 351 port->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2); 352 for (int i = 0; i < 2; i++) { 353 mainChecksum += maxSize; 354 maxSize >>= 8; 355 } 356 357 // Set the checksum 358 mainChecksum = -mainChecksum; 359 port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1); 360 361 /* 362 * Intermediate header 363 */ 364 365 uint16_t tableSize = offset; 366 tableSize = X86ISA::htog(tableSize); 367 port->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2); 368 for (int i = 0; i < 2; i++) { 369 intChecksum += tableSize; 370 tableSize >>= 8; 371 } 372 373 intChecksum = -intChecksum; 374 port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1); 375} 376 377X86ISA::SMBios::BiosInformation * 378X86SMBiosBiosInformationParams::create() 379{ 380 return new X86ISA::SMBios::BiosInformation(this); 381} 382 383X86ISA::SMBios::SMBiosTable * 384X86SMBiosSMBiosTableParams::create() 385{ 386 return new X86ISA::SMBios::SMBiosTable(this); 387}
| 43#include "arch/x86/bios/smbios.hh" 44#include "arch/x86/isa_traits.hh" 45#include "base/types.hh" 46#include "mem/port.hh" 47#include "params/X86SMBiosBiosInformation.hh" 48#include "params/X86SMBiosSMBiosStructure.hh" 49#include "params/X86SMBiosSMBiosTable.hh" 50#include "sim/byteswap.hh" 51 52using namespace std; 53 54const char X86ISA::SMBios::SMBiosTable::SMBiosHeader::anchorString[] = "_SM_"; 55const uint8_t X86ISA::SMBios::SMBiosTable:: 56 SMBiosHeader::formattedArea[] = {0,0,0,0,0}; 57const uint8_t X86ISA::SMBios::SMBiosTable:: 58 SMBiosHeader::entryPointLength = 0x1F; 59const uint8_t X86ISA::SMBios::SMBiosTable:: 60 SMBiosHeader::entryPointRevision = 0; 61const char X86ISA::SMBios::SMBiosTable:: 62 SMBiosHeader::IntermediateHeader::anchorString[] = "_DMI_"; 63 64template <class T> 65uint64_t 66composeBitVector(T vec) 67{ 68 uint64_t val = 0; 69 typename T::iterator vecIt; 70 for (vecIt = vec.begin(); vecIt != vec.end(); vecIt++) { 71 val |= (1 << (*vecIt)); 72 } 73 return val; 74} 75 76uint16_t 77X86ISA::SMBios::SMBiosStructure::writeOut(FunctionalPort * port, Addr addr) 78{ 79 port->writeBlob(addr, (uint8_t *)(&type), 1); 80 81 uint8_t length = getLength(); 82 port->writeBlob(addr + 1, (uint8_t *)(&length), 1); 83 84 uint16_t handleGuest = X86ISA::htog(handle); 85 port->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2); 86 87 return length + getStringLength(); 88} 89 90X86ISA::SMBios::SMBiosStructure::SMBiosStructure(Params * p, uint8_t _type) : 91 SimObject(p), type(_type), handle(0), stringFields(false) 92{} 93 94void 95X86ISA::SMBios::SMBiosStructure::writeOutStrings( 96 FunctionalPort * port, Addr addr) 97{ 98 std::vector<std::string>::iterator it; 99 Addr offset = 0; 100 101 const uint8_t nullTerminator = 0; 102 103 // If there are string fields but none of them are used, that's a 104 // special case which is handled by this if. 105 if (strings.size() == 0 && stringFields) { 106 port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); 107 offset++; 108 } else { 109 for (it = strings.begin(); it != strings.end(); it++) { 110 port->writeBlob(addr + offset, 111 (uint8_t *)it->c_str(), it->length() + 1); 112 offset += it->length() + 1; 113 } 114 } 115 port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); 116} 117 118int 119X86ISA::SMBios::SMBiosStructure::getStringLength() 120{ 121 int size = 0; 122 std::vector<std::string>::iterator it; 123 124 for (it = strings.begin(); it != strings.end(); it++) { 125 size += it->length() + 1; 126 } 127 128 return size + 1; 129} 130 131int 132X86ISA::SMBios::SMBiosStructure::addString(string & newString) 133{ 134 stringFields = true; 135 // If a string is empty, treat it as not existing. The index for empty 136 // strings is 0. 137 if (newString.length() == 0) 138 return 0; 139 strings.push_back(newString); 140 return strings.size(); 141} 142 143string 144X86ISA::SMBios::SMBiosStructure::readString(int n) 145{ 146 assert(n > 0 && n <= strings.size()); 147 return strings[n - 1]; 148} 149 150void 151X86ISA::SMBios::SMBiosStructure::setString(int n, std::string & newString) 152{ 153 assert(n > 0 && n <= strings.size()); 154 strings[n - 1] = newString; 155} 156 157X86ISA::SMBios::BiosInformation::BiosInformation(Params * p) : 158 SMBiosStructure(p, Type), 159 startingAddrSegment(p->starting_addr_segment), 160 romSize(p->rom_size), 161 majorVer(p->major), minorVer(p->minor), 162 embContFirmwareMajor(p->emb_cont_firmware_major), 163 embContFirmwareMinor(p->emb_cont_firmware_minor) 164 { 165 vendor = addString(p->vendor); 166 version = addString(p->version); 167 releaseDate = addString(p->release_date); 168 169 characteristics = composeBitVector(p->characteristics); 170 characteristicExtBytes = 171 composeBitVector(p->characteristic_ext_bytes); 172 } 173 174uint16_t 175X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr) 176{ 177 uint8_t size = SMBiosStructure::writeOut(port, addr); 178 179 port->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1); 180 port->writeBlob(addr + 0x5, (uint8_t *)(&version), 1); 181 182 uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment); 183 port->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2); 184 185 port->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1); 186 port->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1); 187 188 uint64_t characteristicsGuest = X86ISA::htog(characteristics); 189 port->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8); 190 191 uint16_t characteristicExtBytesGuest = 192 X86ISA::htog(characteristicExtBytes); 193 port->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2); 194 195 port->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1); 196 port->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1); 197 port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1); 198 port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1); 199 200 writeOutStrings(port, addr + getLength()); 201 202 return size; 203} 204 205X86ISA::SMBios::SMBiosTable::SMBiosTable(Params * p) : 206 SimObject(p), structures(p->structures) 207{ 208 smbiosHeader.majorVersion = p->major_version; 209 smbiosHeader.minorVersion = p->minor_version; 210 assert(p->major_version <= 9); 211 assert(p->minor_version <= 9); 212 smbiosHeader.intermediateHeader.smbiosBCDRevision = 213 (p->major_version << 4) | p->minor_version; 214} 215 216void 217X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr, 218 Addr &headerSize, Addr &structSize) 219{ 220 headerSize = 0x1F; 221 222 /* 223 * The main header 224 */ 225 uint8_t mainChecksum = 0; 226 227 port->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4); 228 for (int i = 0; i < 4; i++) 229 mainChecksum += smbiosHeader.anchorString[i]; 230 231 // The checksum goes here, but we're figuring it out as we go. 232 233 port->writeBlob(addr + 0x5, 234 (uint8_t *)(&smbiosHeader.entryPointLength), 1); 235 mainChecksum += smbiosHeader.entryPointLength; 236 port->writeBlob(addr + 0x6, 237 (uint8_t *)(&smbiosHeader.majorVersion), 1); 238 mainChecksum += smbiosHeader.majorVersion; 239 port->writeBlob(addr + 0x7, 240 (uint8_t *)(&smbiosHeader.minorVersion), 1); 241 mainChecksum += smbiosHeader.minorVersion; 242 // Maximum structure size goes here, but we'll figure it out later. 243 port->writeBlob(addr + 0xA, 244 (uint8_t *)(&smbiosHeader.entryPointRevision), 1); 245 mainChecksum += smbiosHeader.entryPointRevision; 246 port->writeBlob(addr + 0xB, 247 (uint8_t *)(&smbiosHeader.formattedArea), 5); 248 for (int i = 0; i < 5; i++) 249 mainChecksum += smbiosHeader.formattedArea[i]; 250 251 /* 252 * The intermediate header 253 */ 254 uint8_t intChecksum = 0; 255 256 port->writeBlob(addr + 0x10, 257 (uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5); 258 for (int i = 0; i < 5; i++) 259 intChecksum += smbiosHeader.intermediateHeader.anchorString[i]; 260 261 // The checksum goes here, but we're figuring it out as we go. 262 // Then the length of the structure table which we'll find later 263 264 uint32_t tableAddrGuest = 265 X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr); 266 port->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4); 267 for (int i = 0; i < 4; i++) { 268 intChecksum += tableAddrGuest; 269 tableAddrGuest >>= 8; 270 } 271 272 uint16_t numStructs = X86ISA::gtoh(structures.size()); 273 port->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2); 274 for (int i = 0; i < 2; i++) { 275 intChecksum += numStructs; 276 numStructs >>= 8; 277 } 278 279 port->writeBlob(addr + 0x1E, 280 (uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision), 281 1); 282 intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision; 283 284 /* 285 * Structure table 286 */ 287 288 Addr base = smbiosHeader.intermediateHeader.tableAddr; 289 Addr offset = 0; 290 uint16_t maxSize = 0; 291 std::vector<SMBiosStructure *>::iterator it; 292 for (it = structures.begin(); it != structures.end(); it++) { 293 uint16_t size = (*it)->writeOut(port, base + offset); 294 if (size > maxSize) 295 maxSize = size; 296 offset += size; 297 } 298 299 structSize = offset; 300 301 /* 302 * Header 303 */ 304 305 maxSize = X86ISA::htog(maxSize); 306 port->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2); 307 for (int i = 0; i < 2; i++) { 308 mainChecksum += maxSize; 309 maxSize >>= 8; 310 } 311 312 // Set the checksum 313 mainChecksum = -mainChecksum; 314 port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1); 315 316 /* 317 * Intermediate header 318 */ 319 320 uint16_t tableSize = offset; 321 tableSize = X86ISA::htog(tableSize); 322 port->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2); 323 for (int i = 0; i < 2; i++) { 324 intChecksum += tableSize; 325 tableSize >>= 8; 326 } 327 328 intChecksum = -intChecksum; 329 port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1); 330} 331 332X86ISA::SMBios::BiosInformation * 333X86SMBiosBiosInformationParams::create() 334{ 335 return new X86ISA::SMBios::BiosInformation(this); 336} 337 338X86ISA::SMBios::SMBiosTable * 339X86SMBiosSMBiosTableParams::create() 340{ 341 return new X86ISA::SMBios::SMBiosTable(this); 342}
|