(requires update-workspaces)
add initial SMBIOS implementation for retrieving system information wacpi -> wfirmware (now also used to retrieve SMBIOS table) This was SVN commit r9144.
This commit is contained in:
parent
1a072a3f37
commit
2c72e1f364
@ -23,6 +23,7 @@
|
||||
#include "precompiled.h"
|
||||
#include "lib/sysdep/acpi.h"
|
||||
|
||||
#include "lib/byte_order.h"
|
||||
#include "lib/sysdep/cpu.h"
|
||||
#include "lib/module_init.h"
|
||||
|
||||
@ -30,7 +31,7 @@
|
||||
#if ENABLE_MAHAF
|
||||
# include "lib/sysdep/os/win/mahaf.h"
|
||||
#else
|
||||
# include "lib/sysdep/os/win/wacpi.h"
|
||||
# include "lib/sysdep/os/win/wfirmware.h"
|
||||
#endif
|
||||
|
||||
#pragma pack(1)
|
||||
@ -307,14 +308,15 @@ static void AllocateAndCopyTables(const AcpiTable**& tables, size_t& numTables)
|
||||
|
||||
DeallocateTable(rsdt);
|
||||
#else
|
||||
const std::vector<u32> tableIDs = wacpi_TableIDs();
|
||||
const wfirmware::Provider provider = FOURCC_BE('A','C','P','I');
|
||||
const wfirmware::TableIds tableIDs = wfirmware::GetTableIDs(provider);
|
||||
|
||||
numTables = tableIDs.size();
|
||||
tables = new const AcpiTable*[numTables];
|
||||
|
||||
for(size_t i = 0; i < numTables; i++)
|
||||
{
|
||||
std::vector<u8> table = wacpi_GetTable(tableIDs[i]);
|
||||
wfirmware::Table table = wfirmware::GetTable(provider, tableIDs[i]);
|
||||
debug_assert(!table.empty());
|
||||
tables[i] = AllocateTable(table.size());
|
||||
memcpy((void*)tables[i], &table[0], table.size());
|
||||
|
@ -1,48 +0,0 @@
|
||||
#include "precompiled.h"
|
||||
#include "lib/sysdep/os/win/wacpi.h"
|
||||
|
||||
#include "lib/byte_order.h"
|
||||
#include "lib/sysdep/os/win/wutil.h"
|
||||
|
||||
|
||||
static const DWORD provider = FOURCC_BE('A','C','P','I');
|
||||
|
||||
std::vector<u32> wacpi_TableIDs()
|
||||
{
|
||||
std::vector<u32> tableIDs;
|
||||
|
||||
WUTIL_FUNC(pEnumSystemFirmwareTables, UINT, (DWORD, PVOID, DWORD));
|
||||
WUTIL_IMPORT_KERNEL32(EnumSystemFirmwareTables, pEnumSystemFirmwareTables);
|
||||
if(!pEnumSystemFirmwareTables)
|
||||
return tableIDs; // empty list
|
||||
|
||||
const UINT bufSize = pEnumSystemFirmwareTables(provider, 0, 0);
|
||||
debug_assert(bufSize != 0);
|
||||
debug_assert(bufSize % sizeof(DWORD) == 0);
|
||||
tableIDs.resize(DivideRoundUp((size_t)bufSize, sizeof(DWORD)));
|
||||
|
||||
const UINT ret = pEnumSystemFirmwareTables(provider, &tableIDs[0], bufSize);
|
||||
debug_assert(ret == bufSize);
|
||||
|
||||
return tableIDs;
|
||||
}
|
||||
|
||||
|
||||
std::vector<u8> wacpi_GetTable(u32 id)
|
||||
{
|
||||
std::vector<u8> table;
|
||||
|
||||
WUTIL_FUNC(pGetSystemFirmwareTable, UINT, (DWORD, DWORD, PVOID, DWORD));
|
||||
WUTIL_IMPORT_KERNEL32(GetSystemFirmwareTable, pGetSystemFirmwareTable);
|
||||
if(!pGetSystemFirmwareTable)
|
||||
return table; // empty table
|
||||
|
||||
const UINT bufSize = pGetSystemFirmwareTable(provider, id, 0, 0);
|
||||
debug_assert(bufSize != 0);
|
||||
table.resize(bufSize);
|
||||
|
||||
const UINT ret = pGetSystemFirmwareTable(provider, id, &table[0], bufSize);
|
||||
debug_assert(ret == bufSize);
|
||||
|
||||
return table;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
#ifndef INCLUDED_WACPI
|
||||
#define INCLUDED_WACPI
|
||||
|
||||
extern std::vector<u32> wacpi_TableIDs();
|
||||
|
||||
extern std::vector<u8> wacpi_GetTable(u32 id);
|
||||
|
||||
#endif // #ifndef INCLUDED_WACPI
|
48
source/lib/sysdep/os/win/wfirmware.cpp
Normal file
48
source/lib/sysdep/os/win/wfirmware.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include "precompiled.h"
|
||||
#include "lib/sysdep/os/win/wfirmware.h"
|
||||
|
||||
#include "lib/sysdep/os/win/wutil.h"
|
||||
|
||||
namespace wfirmware {
|
||||
|
||||
TableIds GetTableIDs(Provider provider)
|
||||
{
|
||||
WUTIL_FUNC(pEnumSystemFirmwareTables, UINT, (DWORD, PVOID, DWORD));
|
||||
WUTIL_IMPORT_KERNEL32(EnumSystemFirmwareTables, pEnumSystemFirmwareTables);
|
||||
if(!pEnumSystemFirmwareTables)
|
||||
return TableIds();
|
||||
|
||||
const size_t tableIdsSize = pEnumSystemFirmwareTables(provider, 0, 0);
|
||||
debug_assert(tableIdsSize != 0);
|
||||
debug_assert(tableIdsSize % sizeof(TableId) == 0);
|
||||
TableIds tableIDs(DivideRoundUp(tableIdsSize, sizeof(TableId)), 0);
|
||||
|
||||
const size_t bytesWritten = pEnumSystemFirmwareTables(provider, &tableIDs[0], tableIdsSize);
|
||||
debug_assert(bytesWritten == tableIdsSize);
|
||||
|
||||
return tableIDs;
|
||||
}
|
||||
|
||||
|
||||
Table GetTable(Provider provider, TableId tableId)
|
||||
{
|
||||
WUTIL_FUNC(pGetSystemFirmwareTable, UINT, (DWORD, DWORD, PVOID, DWORD));
|
||||
WUTIL_IMPORT_KERNEL32(GetSystemFirmwareTable, pGetSystemFirmwareTable);
|
||||
if(!pGetSystemFirmwareTable)
|
||||
return Table();
|
||||
|
||||
const size_t tableSize = pGetSystemFirmwareTable(provider, tableId, 0, 0);
|
||||
if(tableSize == 0)
|
||||
{
|
||||
debug_assert(0);
|
||||
return Table();
|
||||
}
|
||||
|
||||
Table table(tableSize, 0);
|
||||
const size_t bytesWritten = pGetSystemFirmwareTable(provider, tableId, &table[0], tableSize);
|
||||
debug_assert(bytesWritten == tableSize);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
} // namespace wfirmware
|
19
source/lib/sysdep/os/win/wfirmware.h
Normal file
19
source/lib/sysdep/os/win/wfirmware.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef INCLUDED_WFIRMWARE
|
||||
#define INCLUDED_WFIRMWARE
|
||||
|
||||
namespace wfirmware {
|
||||
|
||||
typedef u32 Provider;
|
||||
|
||||
typedef u32 TableId;
|
||||
typedef std::vector<TableId> TableIds;
|
||||
|
||||
extern TableIds GetTableIDs(Provider provider);
|
||||
|
||||
typedef std::vector<u8> Table;
|
||||
|
||||
extern Table GetTable(Provider provider, TableId tableId);
|
||||
|
||||
} // namespace wfirmware
|
||||
|
||||
#endif // #ifndef INCLUDED_WFIRMWARE
|
352
source/lib/sysdep/smbios.cpp
Normal file
352
source/lib/sysdep/smbios.cpp
Normal file
@ -0,0 +1,352 @@
|
||||
/* Copyright (c) 2011 Wildfire Games
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "smbios.h"
|
||||
|
||||
#include "lib/bits.h"
|
||||
#include "lib/byte_order.h"
|
||||
#include "lib/module_init.h"
|
||||
|
||||
#if OS_WIN
|
||||
# include "lib/sysdep/os/win/wutil.h"
|
||||
# include "lib/sysdep/os/win/wfirmware.h"
|
||||
#endif
|
||||
|
||||
namespace SMBIOS {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if OS_WIN
|
||||
|
||||
static LibError GetTable(wfirmware::Table& table)
|
||||
{
|
||||
// (MSDN mentions 'RSMB', but multi-character literals are implementation-defined.)
|
||||
const DWORD provider = FOURCC_BE('R','S','M','B');
|
||||
|
||||
// (MSDN says this will be 0, but we'll retrieve it for 100% correctness.)
|
||||
wfirmware::TableIds tableIds = wfirmware::GetTableIDs(provider);
|
||||
if(tableIds.empty())
|
||||
WARN_RETURN(ERR::_1);
|
||||
|
||||
table = wfirmware::GetTable(provider, tableIds[0]);
|
||||
if(table.empty())
|
||||
WARN_RETURN(ERR::_2);
|
||||
|
||||
// strip the WmiHeader
|
||||
struct WmiHeader
|
||||
{
|
||||
u8 used20CallingMethod;
|
||||
u8 majorVersion;
|
||||
u8 minorVersion;
|
||||
u8 dmiRevision;
|
||||
u32 length;
|
||||
};
|
||||
const WmiHeader* wmiHeader = (const WmiHeader*)&table[0];
|
||||
debug_assert(table.size() == sizeof(WmiHeader) + wmiHeader->length);
|
||||
memmove(&table[0], &table[sizeof(WmiHeader)], sizeof(WmiHeader));
|
||||
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
#endif // OS_WIN
|
||||
|
||||
|
||||
// pointers to the strings (if any) at the end of an SMBIOS structure
|
||||
typedef std::vector<const char*> Strings;
|
||||
|
||||
static Strings ExtractStrings(const Header* header, const char* end, const Header*& next)
|
||||
{
|
||||
Strings strings;
|
||||
|
||||
const char* pos = ((const char*)header) + header->length;
|
||||
while(pos <= end-2)
|
||||
{
|
||||
if(*pos == '\0')
|
||||
{
|
||||
pos++;
|
||||
if(*pos == 0)
|
||||
{
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
strings.push_back(pos);
|
||||
pos += strlen(pos);
|
||||
}
|
||||
|
||||
next = (const Header*)pos;
|
||||
return strings;
|
||||
}
|
||||
|
||||
|
||||
// storage for all structures' strings
|
||||
static char* stringStorage;
|
||||
static char* stringStoragePos;
|
||||
|
||||
// pointers to dynamically allocated structures
|
||||
static Structures structures;
|
||||
|
||||
static void Cleanup()
|
||||
{
|
||||
SAFE_FREE(stringStorage);
|
||||
stringStoragePos = 0;
|
||||
|
||||
// free each allocated structure
|
||||
#define STRUCTURE(name, id) SAFE_FREE(structures.name##_);
|
||||
STRUCTURES
|
||||
#undef STRUCTURE
|
||||
}
|
||||
|
||||
|
||||
// initialize each of a structure's fields by copying from the SMBIOS data
|
||||
class FieldInitializer
|
||||
{
|
||||
NONCOPYABLE(FieldInitializer); // reference member
|
||||
public:
|
||||
FieldInitializer(const Header* header, const Strings& strings)
|
||||
: data((const u8*)(header+1))
|
||||
, end(data + header->length)
|
||||
, strings(strings)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void operator()(size_t flags, T& t, const char* UNUSED(name), const char* UNUSED(units))
|
||||
{
|
||||
if((flags & F_DERIVED) || data >= end)
|
||||
{
|
||||
t = (T)0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(flags & F_ENUM)
|
||||
t = (T)*data++;
|
||||
else
|
||||
{
|
||||
memcpy(&t, data, sizeof(t));
|
||||
data += sizeof(t);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void operator()<const char*>(size_t flags, const char*& t, const char* UNUSED(name), const char* UNUSED(units))
|
||||
{
|
||||
u8 number;
|
||||
operator()(flags, number, 0, 0);
|
||||
if(number == 0)
|
||||
{
|
||||
t = "(unspecified)";
|
||||
return;
|
||||
}
|
||||
|
||||
if(number > strings.size())
|
||||
{
|
||||
debug_printf(L"SMBIOS: invalid string number %d (count=%d)\n", number, strings.size());
|
||||
t = "(unknown)";
|
||||
return;
|
||||
}
|
||||
|
||||
if(strings[number-1] == 0)
|
||||
{
|
||||
t = "(null)";
|
||||
return;
|
||||
}
|
||||
|
||||
// copy to stringStorage
|
||||
strcpy(stringStoragePos, strings[number-1]);
|
||||
t = stringStoragePos;
|
||||
stringStoragePos += strlen(t)+1;
|
||||
}
|
||||
|
||||
private:
|
||||
const u8* data;
|
||||
const u8* end;
|
||||
const Strings& strings;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixup (e.g. compute derived fields)
|
||||
|
||||
template<class Structure>
|
||||
void Fixup(Structure& UNUSED(structure))
|
||||
{
|
||||
// primary template: do nothing
|
||||
}
|
||||
|
||||
template<>
|
||||
void Fixup<Processor>(Processor& p)
|
||||
{
|
||||
// clear "populated" bit that interferes with the interpretation of ProcessorStatus
|
||||
p.status = (ProcessorStatus)(p.status & ~0x40);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Fixup<Cache>(Cache& p)
|
||||
{
|
||||
struct DecodeSize
|
||||
{
|
||||
size_t operator()(u16 size) const
|
||||
{
|
||||
const size_t granularity = IsBitSet(size, 15)? 64*KiB : 1*KiB;
|
||||
return size_t(bits(size, 0, 14)) * granularity;
|
||||
}
|
||||
};
|
||||
p.maxSize = DecodeSize()(p.maxSize16);
|
||||
p.installedSize = DecodeSize()(p.installedSize16);
|
||||
p.level = bits(p.configuration, 0, 2)+1;
|
||||
p.location = (CacheLocation)bits(p.configuration, 5, 6);
|
||||
p.mode = (CacheMode)bits(p.configuration, 8, 9);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Fixup<MemoryArray>(MemoryArray& p)
|
||||
{
|
||||
if(p.maxCapacity32 != (u32)INT32_MIN)
|
||||
p.maxCapacity = u64(p.maxCapacity32) * KiB;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Fixup<MemoryDevice>(MemoryDevice& p)
|
||||
{
|
||||
if(p.size16 != INT16_MAX)
|
||||
p.size = u64(bits(p.size16, 0, 14)) * (IsBitSet(p.size16, 15)? 1*KiB : 1*MiB);
|
||||
else
|
||||
p.size = u64(bits(p.size32, 0, 30)) * MiB;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Fixup<MemoryArrayMappedAddress>(MemoryArrayMappedAddress& p)
|
||||
{
|
||||
if(p.startAddress32 != UINT32_MAX)
|
||||
p.startAddress = u64(p.startAddress32) * KiB;
|
||||
if(p.endAddress32 != UINT32_MAX)
|
||||
p.endAddress = u64(p.endAddress32) * KiB;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Fixup<MemoryDeviceMappedAddress>(MemoryDeviceMappedAddress& p)
|
||||
{
|
||||
if(p.startAddress32 != UINT32_MAX)
|
||||
p.startAddress = u64(p.startAddress32) * KiB;
|
||||
if(p.endAddress32 != UINT32_MAX)
|
||||
p.endAddress = u64(p.endAddress32) * KiB;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class Structure>
|
||||
void InitStructure(Structure*& listHead, const Header* header, const Strings& strings)
|
||||
{
|
||||
Structure* const p = (Structure*)calloc(1, sizeof(Structure)); // freed in Cleanup
|
||||
p->header = *header;
|
||||
|
||||
if(listHead)
|
||||
{
|
||||
// insert at end of list to preserve order of caches/slots
|
||||
Structure* last = listHead;
|
||||
while(last->next)
|
||||
last = last->next;
|
||||
last->next = p;
|
||||
}
|
||||
else
|
||||
listHead = p;
|
||||
|
||||
FieldInitializer fieldInitializer(header, strings);
|
||||
VisitFields(*p, fieldInitializer);
|
||||
|
||||
Fixup(*p);
|
||||
}
|
||||
|
||||
|
||||
static LibError InitStructures()
|
||||
{
|
||||
#if OS_WIN
|
||||
wfirmware::Table table;
|
||||
RETURN_ERR(GetTable(table));
|
||||
#else
|
||||
std::vector<u8> table;
|
||||
return ERR::NOT_IMPLEMENTED;
|
||||
#endif
|
||||
|
||||
// workaround for stupid AMIBIOS that repeats the first 8 bytes
|
||||
if(memcmp(&table[0], &table[8], 8) == 0)
|
||||
{
|
||||
memmove(&table[8], &table[16], 8);
|
||||
table[1] += 8; // the first length field is 8 bytes short, too
|
||||
}
|
||||
|
||||
// (instead of counting the total string size, just use the
|
||||
// SMBIOS size - typically 1-2 KB - as an upper bound.)
|
||||
stringStoragePos = stringStorage = (char*)calloc(table.size(), sizeof(char)); // freed in Cleanup
|
||||
if(!stringStorage)
|
||||
WARN_RETURN(ERR::NO_MEM);
|
||||
|
||||
atexit(Cleanup);
|
||||
|
||||
const Header* header = (const Header*)&table[0];
|
||||
const Header* const end = (const Header*)(&table[0] + table.size());
|
||||
while(header+1 <= end)
|
||||
{
|
||||
if(header->length < sizeof(Header))
|
||||
WARN_RETURN(ERR::_3);
|
||||
|
||||
const Header* next;
|
||||
const Strings strings = ExtractStrings(header, (const char*)end, next);
|
||||
|
||||
switch(header->id)
|
||||
{
|
||||
#define STRUCTURE(name, id) case id: InitStructure(structures.name##_, header, strings); break;
|
||||
STRUCTURES
|
||||
#undef STRUCTURE
|
||||
|
||||
case 126: // inactive
|
||||
break;
|
||||
case 127: // end
|
||||
return INFO::OK;
|
||||
|
||||
default:
|
||||
debug_printf(L"SMBIOS: unknown structure type %d\n", header->id);
|
||||
break;
|
||||
}
|
||||
|
||||
header = next;
|
||||
}
|
||||
|
||||
debug_printf(L"SMBIOS: table not terminated\n");
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
|
||||
const Structures* GetStructures()
|
||||
{
|
||||
static ModuleInitState initState;
|
||||
LibError ret = ModuleInit(&initState, InitStructures);
|
||||
if(ret != INFO::OK)
|
||||
return 0;
|
||||
return &structures;
|
||||
}
|
||||
|
||||
} // namespace SMBIOS
|
745
source/lib/sysdep/smbios.h
Normal file
745
source/lib/sysdep/smbios.h
Normal file
@ -0,0 +1,745 @@
|
||||
/* Copyright (c) 2011 Wildfire Games
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_SMBIOS
|
||||
#define INCLUDED_SMBIOS
|
||||
|
||||
namespace SMBIOS {
|
||||
|
||||
// to introduce another structure:
|
||||
// 1) add its name and ID here
|
||||
// 2) add a <name>_FIELDS macro defining its fields
|
||||
// 3) (optional) add a specialization of Fixup
|
||||
#define STRUCTURES\
|
||||
STRUCTURE(Bios, 0)\
|
||||
STRUCTURE(System, 1)\
|
||||
STRUCTURE(Baseboard, 2)\
|
||||
STRUCTURE(Chassis, 3)\
|
||||
STRUCTURE(Processor, 4)\
|
||||
/* MemoryController (5) and MemoryModule (6) are obsolete */\
|
||||
STRUCTURE(Cache, 7)\
|
||||
/* PortConnector (8) is optional */\
|
||||
STRUCTURE(SystemSlot, 9)\
|
||||
/* OnBoardDevices (10) is obsolete */\
|
||||
/* OemStrings (11), SystemConfiguration (12), BiosLanguage (13), GroupAssociations (14), SystemEventLog (15) are optional */\
|
||||
STRUCTURE(MemoryArray, 16)\
|
||||
STRUCTURE(MemoryDevice, 17)\
|
||||
/* MemoryError32 (18) is optional */\
|
||||
STRUCTURE(MemoryArrayMappedAddress, 19)\
|
||||
STRUCTURE(MemoryDeviceMappedAddress, 20)\
|
||||
/* PointingDevice (21), PortableBattery (22), SystemReset (23), HardwareSecurity (24) are optional */\
|
||||
/* SystemPowerControls (25), VoltageProbe (26), CoolingDevice (27), TemperatureProbe (28) are optional */\
|
||||
/* ElectricalCurrentProbe (29), OutOfBandRemoteAccess (30), BootIntegrityServices (31) are optional */\
|
||||
STRUCTURE(SystemBoot, 32)
|
||||
/* MemoryError64 (33), ManagementDevice (34), ManagementDeviceComponent (35), ManagementDeviceThreshold (36) are optional */\
|
||||
/* MemoryChannel (37), IpmiDevice (38), SystemPowerSupply (39), Additional (40), OnboardDevices2 (41) are optional */\
|
||||
/* ManagementControllerHostInterface (42) is optional */
|
||||
|
||||
typedef u16 Handle;
|
||||
|
||||
// indicates a field (:= member of a structure) is:
|
||||
enum FieldFlags
|
||||
{
|
||||
// computed via other fields (i.e. should not be copied from the SMBIOS data).
|
||||
F_DERIVED = 0x01,
|
||||
|
||||
// not intended for use by applications (usually because it is
|
||||
// superseded by another - possibly derived - field).
|
||||
F_INTERNAL = 0x02,
|
||||
|
||||
// an enum type; we'll read an SMBIOS byte and cast it to this type.
|
||||
// (could also be detected via is_enum, but that requires TR1/C++0x)
|
||||
// (using enum member variables instead of the raw u8 means the debugger
|
||||
// will display the enumerators)
|
||||
F_ENUM = 0x04,
|
||||
|
||||
// a collection of bit flags and should be displayed as such.
|
||||
F_FLAGS = 0x08,
|
||||
|
||||
// an SMBIOS Handle (allows nicer display of `unknown' handles).
|
||||
F_HANDLE = 0x10
|
||||
};
|
||||
|
||||
#if MSC_VERSION
|
||||
# pragma pack(push, 1)
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Bios
|
||||
|
||||
#define Bios_FIELDS\
|
||||
FIELD(0, const char*, vendor, "")\
|
||||
FIELD(0, const char*, version, "")\
|
||||
FIELD(0, u16, startSegment, "")\
|
||||
FIELD(0, const char*, releaseDate, "")\
|
||||
FIELD(0, u8, size, " +1*64KB")\
|
||||
FIELD(0, u64, characteristics, "")\
|
||||
/* omit subsequent fields because we can't handle the variable-length characteristics extension */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// System
|
||||
|
||||
enum SystemWakeUpType
|
||||
{
|
||||
SWT_APM_TIMER = 3,
|
||||
SWT_MODEM_RING,
|
||||
SWT_LAN_REMOTE,
|
||||
SWT_POWER_SWITCH,
|
||||
SWT_PCI_PME,
|
||||
SWT_AC_POWER_RESTORED
|
||||
};
|
||||
|
||||
#define System_FIELDS\
|
||||
FIELD(0, const char*, manufacturer, "")\
|
||||
FIELD(0, const char*, productName, "")\
|
||||
FIELD(0, const char*, version, "")\
|
||||
FIELD(0, const char*, serialNumber, "")\
|
||||
FIELD(0, u64, uuid0, "")\
|
||||
FIELD(0, u64, uuid1, "")\
|
||||
FIELD(F_ENUM, SystemWakeUpType, wakeUpType, "")\
|
||||
FIELD(0, const char*, skuNumber, "")\
|
||||
FIELD(0, const char*, family, "")
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Baseboard
|
||||
|
||||
enum BaseboardFlags
|
||||
{
|
||||
BB_IS_MOTHERBOARD = 0x01,
|
||||
BB_REQUIRES_DAUGHTER = 0x02,
|
||||
BB_IS_REMOVEABLE = 0x04,
|
||||
BB_IS_REPLACEABLE = 0x08,
|
||||
BB_IS_HOT_SWAPPABLE = 0x10
|
||||
};
|
||||
|
||||
enum BaseboardType
|
||||
{
|
||||
BB_BLADE = 3,
|
||||
BB_SWITCH,
|
||||
BB_SYSTEM_MANAGEMENT,
|
||||
BB_PROCESSOR,
|
||||
BB_IO,
|
||||
BB_MEMORY,
|
||||
BB_DAUGHTER,
|
||||
BB_MOTHERBOARD,
|
||||
BB_PROCESSOR_MEMORY,
|
||||
BB_PROCESSOR_IO,
|
||||
BB_INTERCONNECT,
|
||||
};
|
||||
|
||||
#define Baseboard_FIELDS\
|
||||
FIELD(0, const char*, manufacturer, "")\
|
||||
FIELD(0, const char*, product, "")\
|
||||
FIELD(0, const char*, version, "")\
|
||||
FIELD(0, const char*, serialNumber, "")\
|
||||
FIELD(0, const char*, assetTag, "")\
|
||||
FIELD(F_FLAGS, u8, flags, "")\
|
||||
FIELD(0, const char*, location, "")\
|
||||
FIELD(F_HANDLE, Handle, hChassis, "")\
|
||||
FIELD(F_ENUM, BaseboardType, type, "")\
|
||||
/* omit subsequent fields because we can't handle the variable-length contained objects */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Chassis
|
||||
|
||||
enum ChassisType
|
||||
{
|
||||
CT_DESKTOP = 3,
|
||||
CT_LOW_PROFILE_DESKTOP,
|
||||
CT_PIZZA_BOX,
|
||||
CT_MINI_TOWER,
|
||||
CT_TOWER,
|
||||
CT_PORTABLE,
|
||||
CT_LAPTOP,
|
||||
CT_NOTEBOOK,
|
||||
CT_HANDHELD,
|
||||
CT_DOCKING_STATION,
|
||||
CT_ALL_IN_ONE,
|
||||
CT_SUBNOTEBOOK,
|
||||
CT_SPACE_SAVING,
|
||||
CT_LUNCHBOX,
|
||||
CT_MAIN_SERVER,
|
||||
CT_EXPANSION,
|
||||
CT_SUB,
|
||||
CT_BUS_EXPANSION,
|
||||
CT_PERIPHERAL,
|
||||
CT_RAID,
|
||||
CT_RACK_MOUNT,
|
||||
CT_SEALED_CASE,
|
||||
CT_MULTI_SYSTEM,
|
||||
CT_COMPACT_PCI,
|
||||
CT_ADVANCED_TCA,
|
||||
CT_BLADE,
|
||||
CT_BLADE_ENCLOSURE
|
||||
|
||||
};
|
||||
|
||||
enum ChassisState
|
||||
{
|
||||
CS_SAFE = 3,
|
||||
CS_WARNING,
|
||||
CS_CRITICAL,
|
||||
CS_NON_RECOVERABLE
|
||||
};
|
||||
|
||||
enum ChassisSecurityStatus
|
||||
{
|
||||
CSS_NONE = 3,
|
||||
CSS_EXTERNAL_INTERFACE_LOCKED,
|
||||
CSS_EXTERNAL_INTERFACE_ENABLED
|
||||
};
|
||||
|
||||
#define Chassis_FIELDS\
|
||||
FIELD(0, const char*, manufacturer, "")\
|
||||
FIELD(F_ENUM, ChassisType, type, "")\
|
||||
FIELD(0, const char*, version, "")\
|
||||
FIELD(0, const char*, serialNumber, "")\
|
||||
FIELD(0, const char*, assetTag, "")\
|
||||
FIELD(F_ENUM, ChassisState, state, "")\
|
||||
FIELD(F_ENUM, ChassisState, powerState, "")\
|
||||
FIELD(F_ENUM, ChassisState, thermalState, "")\
|
||||
FIELD(F_ENUM, ChassisSecurityStatus, securityStatus, "")\
|
||||
FIELD(0, u32, oemDefined, "")\
|
||||
FIELD(0, u8, height, "U")\
|
||||
FIELD(0, u8, numPowerCords, "U")\
|
||||
/* omit subsequent fields because we can't handle the variable-length contained objects */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Processor
|
||||
|
||||
enum ProcessorType
|
||||
{
|
||||
PT_CENTRAL = 3,
|
||||
PT_MATH,
|
||||
PT_DSP,
|
||||
PT_VIDEO
|
||||
};
|
||||
|
||||
enum ProcessorStatus
|
||||
{
|
||||
PS_UNKNOWN = 0,
|
||||
PS_ENABLED,
|
||||
PS_USER_DISABLED,
|
||||
PS_POST_DISABLED,
|
||||
PS_CPU_IDLE,
|
||||
PS_OTHER = 7,
|
||||
|
||||
// NB: we mask off 0x40 ("populated") for convenience
|
||||
};
|
||||
|
||||
enum ProcessorUpgrade
|
||||
{
|
||||
PU_DAUGHTER = 3,
|
||||
PU_ZIF,
|
||||
PU_PIGGYBACK,
|
||||
PU_NONE,
|
||||
PU_LIF,
|
||||
PU_SLOT_1,
|
||||
PU_SLOT_2,
|
||||
PU_SOCKET_370,
|
||||
PU_SLOT_A,
|
||||
PU_SLOT_M,
|
||||
PU_SOCKET_423,
|
||||
PU_SOCKET_A,
|
||||
PU_SOCKET_478,
|
||||
PU_SOCKET_754,
|
||||
PU_SOCKET_940,
|
||||
PU_SOCKET_939,
|
||||
PU_SOCKET_604,
|
||||
PU_SOCKET_771,
|
||||
PU_SOCKET_775,
|
||||
PU_SOCKET_S1,
|
||||
PU_SOCKET_AM2,
|
||||
PU_SOCKET_1207,
|
||||
PU_SOCKET_1366,
|
||||
PU_SOCKET_G34,
|
||||
PU_SOCKET_AM3,
|
||||
PU_SOCKET_C32,
|
||||
PU_SOCKET_1156,
|
||||
PU_SOCKET_1567,
|
||||
PU_SOCKET_988A,
|
||||
PU_SOCKET_1288,
|
||||
PU_SOCKET_988B,
|
||||
PU_SOCKET_1023,
|
||||
PU_SOCKET_1224,
|
||||
PU_SOCKET_1155,
|
||||
PU_SOCKET_1356,
|
||||
PU_SOCKET_2011,
|
||||
PU_SOCKET_FS1,
|
||||
PU_SOCKET_FS2,
|
||||
PU_SOCKET_FM1,
|
||||
PU_SOCKET_FM2
|
||||
};
|
||||
|
||||
enum ProcessorVoltage // bitfield
|
||||
{
|
||||
PV_5 = 1,
|
||||
PV_3_3 = 2,
|
||||
PV_2_9 = 4
|
||||
};
|
||||
|
||||
enum ProcessorCharacteristics // bitfield
|
||||
{
|
||||
PC_UNKNOWN = 0x2,
|
||||
PC_64_BIT = 0x4,
|
||||
PC_MULTI_CORE = 0x8, // (indicates cores are present; they might be disabled)
|
||||
PC_HARDWARE_THREAD = 0x10,
|
||||
PC_EXECUTE_PROTECTION = 0x20,
|
||||
PC_ENHANCED_VIRTUALIZATION = 0x40,
|
||||
PC_POWER_CONTROL = 0x80
|
||||
};
|
||||
|
||||
#define Processor_FIELDS\
|
||||
FIELD(0, const char*, socket, "")\
|
||||
FIELD(F_ENUM, ProcessorType, type, "")\
|
||||
FIELD(0, u8, family, "") /* we don't bother providing enumerators for > 200 families */\
|
||||
FIELD(0, const char*, manufacturer, "")\
|
||||
FIELD(0, u64, id, "")\
|
||||
FIELD(0, const char*, version, "")\
|
||||
FIELD(F_FLAGS, u8, voltage, "")\
|
||||
FIELD(0, u16, externalClockFrequency, " Mhz")\
|
||||
FIELD(0, u16, maxFrequency, " Mhz")\
|
||||
FIELD(0, u16, bootFrequency, " Mhz")\
|
||||
FIELD(F_ENUM, ProcessorStatus, status, "")\
|
||||
FIELD(F_ENUM, ProcessorUpgrade, upgrade, "")\
|
||||
FIELD(F_HANDLE, Handle, hL1, "")\
|
||||
FIELD(F_HANDLE, Handle, hL2, "")\
|
||||
FIELD(F_HANDLE, Handle, hL3, "")\
|
||||
FIELD(0, const char*, serialNumber, "")\
|
||||
FIELD(0, const char*, assetTag, "")\
|
||||
FIELD(0, const char*, partNumber, "")\
|
||||
FIELD(0, u8, coresPerPackage, "")\
|
||||
FIELD(0, u8, enabledCores, "")\
|
||||
FIELD(0, u8, logicalPerPackage, "")\
|
||||
FIELD(F_FLAGS, u16, characteristics, "")\
|
||||
FIELD(0, u16, family2, "")
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Cache
|
||||
|
||||
enum CacheMode
|
||||
{
|
||||
CM_WRITE_THROUGH = 0,
|
||||
CM_WRITE_BACK,
|
||||
CM_VARIES,
|
||||
CM_UNKNOWN
|
||||
};
|
||||
|
||||
enum CacheLocation
|
||||
{
|
||||
CL_INTERNAL = 0,
|
||||
CL_EXTERNAL,
|
||||
CL_RESERVED,
|
||||
CL_UNKNOWN
|
||||
};
|
||||
|
||||
enum CacheConfiguration
|
||||
{
|
||||
CC_SOCKETED = 0x08,
|
||||
CC_ENABLED = 0x80
|
||||
};
|
||||
|
||||
enum CacheFlags
|
||||
{
|
||||
CF_OTHER = 0x01,
|
||||
CF_UNKNOWN = 0x02,
|
||||
CF_NON_BURST = 0x04,
|
||||
CF_BURST = 0x08,
|
||||
CF_PIPELINE_BURST = 0x10,
|
||||
CF_SYNCHRONOUS = 0x20,
|
||||
CF_ASYNCHRONOUS = 0x40
|
||||
};
|
||||
|
||||
enum CacheECC
|
||||
{
|
||||
CE_NONE = 3,
|
||||
CE_PARITY,
|
||||
CE_SINGLE_BIT,
|
||||
CE_MULTIPLE_BIT
|
||||
};
|
||||
|
||||
enum CacheType
|
||||
{
|
||||
CT_INSTRUCTION = 3,
|
||||
CT_DATA,
|
||||
CT_UNIFIED
|
||||
};
|
||||
|
||||
enum CacheAssociativity
|
||||
{
|
||||
CA_DIRECT_MAPPED = 3,
|
||||
CA_2,
|
||||
CA_4,
|
||||
CA_FULL,
|
||||
CA_8,
|
||||
CA_16,
|
||||
CA_12,
|
||||
CA_24,
|
||||
CA_32,
|
||||
CA_48,
|
||||
CA_64,
|
||||
CA_20
|
||||
};
|
||||
|
||||
#define Cache_FIELDS\
|
||||
FIELD(0, const char*, designation, "")\
|
||||
FIELD(F_FLAGS, u16, configuration, "")\
|
||||
FIELD(F_INTERNAL, u16, maxSize16, "")\
|
||||
FIELD(F_INTERNAL, u16, installedSize16, "")\
|
||||
FIELD(F_FLAGS, u16, supportedFlags, "")\
|
||||
FIELD(F_FLAGS, u16, currentFlags, "")\
|
||||
FIELD(0, u8, speed, " ns")\
|
||||
FIELD(F_ENUM, CacheECC, ecc, "")\
|
||||
FIELD(F_ENUM, CacheType, type, "")\
|
||||
FIELD(F_ENUM, CacheAssociativity, associativity, "")\
|
||||
FIELD(F_DERIVED, size_t, level, "") /* 1..8 */\
|
||||
FIELD(F_DERIVED|F_ENUM, CacheLocation, location, "")\
|
||||
FIELD(F_DERIVED|F_ENUM, CacheMode, mode, "")\
|
||||
FIELD(F_DERIVED, size_t, maxSize, " bytes")\
|
||||
FIELD(F_DERIVED, size_t, installedSize, " bytes")
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SystemSlot
|
||||
|
||||
enum SystemSlotType
|
||||
{
|
||||
ST_ISA = 3,
|
||||
ST_MCA,
|
||||
ST_EISA,
|
||||
ST_PCI,
|
||||
ST_PCMCIA,
|
||||
ST_VESA,
|
||||
ST_PROPRIETARY,
|
||||
ST_PROCESSOR,
|
||||
ST_MEMORY_CARD,
|
||||
ST_IO_RISER,
|
||||
ST_NUBUS,
|
||||
ST_PCI_66,
|
||||
ST_AGP,
|
||||
ST_AGP_2X,
|
||||
ST_AGP_4X,
|
||||
ST_PCIX,
|
||||
ST_AGP_8X,
|
||||
// (PC98 omitted)
|
||||
ST_PCIE = 0xA5,
|
||||
ST_PCIE_X1,
|
||||
ST_PCIE_X2,
|
||||
ST_PCIE_X4,
|
||||
ST_PCIE_X8,
|
||||
ST_PCIE_X16,
|
||||
ST_PCIE2,
|
||||
ST_PCIE2_X1,
|
||||
ST_PCIE2_X2,
|
||||
ST_PCIE2_X4,
|
||||
ST_PCIE2_X8,
|
||||
ST_PCIE2_X16,
|
||||
ST_PCIE3,
|
||||
ST_PCIE3_X1,
|
||||
ST_PCIE3_X2,
|
||||
ST_PCIE3_X4,
|
||||
ST_PCIE3_X8,
|
||||
ST_PCIE3_X16
|
||||
};
|
||||
|
||||
enum SystemSlotBusWidth
|
||||
{
|
||||
SBW_8 = 3,
|
||||
SBW_16,
|
||||
SBW_32,
|
||||
SBW_64,
|
||||
SBW_128,
|
||||
SBW_1X,
|
||||
SBW_2X,
|
||||
SBW_4X,
|
||||
SBW_8X,
|
||||
SBW_12X,
|
||||
SBW_16X,
|
||||
SBW_32X,
|
||||
};
|
||||
|
||||
enum SystemSlotUsage
|
||||
{
|
||||
SU_AVAILABLE = 3,
|
||||
SU_IN_USE
|
||||
};
|
||||
|
||||
enum SystemSlotLength
|
||||
{
|
||||
SL_SHORT = 3,
|
||||
SL_LONG
|
||||
};
|
||||
|
||||
enum SystemSlotCharacteristics
|
||||
{
|
||||
SC_UNKNOWN = 1,
|
||||
SC_5_VOLT = 2,
|
||||
SC_3_3_VOLT = 4,
|
||||
SC_IS_SHARED = 8
|
||||
// unused "PC card" bits omitted
|
||||
};
|
||||
|
||||
enum SystemSlotCharacteristics2
|
||||
{
|
||||
SC2_SUPPORTS_PME = 1,
|
||||
SC2_SUPPORTS_HOT_PLUG = 2,
|
||||
SC2_SUPPORTS_SMBUS = 4
|
||||
};
|
||||
|
||||
#define SystemSlot_FIELDS\
|
||||
FIELD(0, const char*, designation, "")\
|
||||
FIELD(F_ENUM, SystemSlotType, type, "")\
|
||||
FIELD(F_ENUM, SystemSlotBusWidth, busWidth, "")\
|
||||
FIELD(F_ENUM, SystemSlotUsage, usage, "")\
|
||||
FIELD(F_ENUM, SystemSlotLength, length, "")\
|
||||
FIELD(0, u16, id, "")\
|
||||
FIELD(F_FLAGS, u8, characteristics, "")\
|
||||
FIELD(F_FLAGS, u8, characteristics2, "")\
|
||||
FIELD(0, u8, busNumber, "")\
|
||||
FIELD(0, u8, deviceAndFunctionNumbers, "")
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MemoryArray
|
||||
|
||||
enum MemoryArrayLocation
|
||||
{
|
||||
ML_MOTHERBOARD = 3,
|
||||
ML_ISA_ADDON,
|
||||
ML_EISA_ADDON,
|
||||
ML_PCI_ADDON,
|
||||
ML_MCA_ADDON,
|
||||
ML_PCMCIA_ADDON,
|
||||
ML_PROPRIETARY_ADDON,
|
||||
ML_NUBUS
|
||||
// (PC98 omitted)
|
||||
};
|
||||
|
||||
enum MemoryArrayUse
|
||||
{
|
||||
MU_SYSTEM = 3,
|
||||
MU_VIDEO,
|
||||
MU_FLASH,
|
||||
MU_NVRAM,
|
||||
MU_CACHE
|
||||
};
|
||||
|
||||
enum MemoryArrayECC
|
||||
{
|
||||
ME_NONE = 3,
|
||||
ME_PARITY,
|
||||
ME_SINGLE_BIT,
|
||||
ME_MULTIPLE_BIT,
|
||||
ME_CRC
|
||||
};
|
||||
|
||||
#define MemoryArray_FIELDS\
|
||||
FIELD(F_ENUM, MemoryArrayLocation, location, "")\
|
||||
FIELD(F_ENUM, MemoryArrayUse, use, "")\
|
||||
FIELD(F_ENUM, MemoryArrayECC, ecc, "")\
|
||||
FIELD(F_INTERNAL, u32, maxCapacity32, "")\
|
||||
FIELD(F_HANDLE, Handle, hError, "")\
|
||||
FIELD(0, u16, numDevices, "")\
|
||||
FIELD(0, u64, maxCapacity, " bytes")
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MemoryDevice
|
||||
|
||||
enum MemoryDeviceFormFactor
|
||||
{
|
||||
MF_SIMM = 3,
|
||||
MF_SIP,
|
||||
MF_CHIP,
|
||||
MF_DIP,
|
||||
MF_ZIP,
|
||||
MF_PROPRIETARY_CARD,
|
||||
MF_DIMM,
|
||||
MF_TSOP,
|
||||
MF_ROW_OF_CHIPS,
|
||||
MF_RIMM,
|
||||
MF_SODIMM,
|
||||
MF_SRIMM,
|
||||
MF_FBDIMM
|
||||
};
|
||||
|
||||
enum MemoryDeviceType
|
||||
{
|
||||
MT_DRAM = 3,
|
||||
MT_EDRAM,
|
||||
MT_VRAM,
|
||||
MT_SRAM,
|
||||
MT_RAM,
|
||||
MT_ROM,
|
||||
MT_FLASH,
|
||||
MT_EEPROM,
|
||||
MT_FEPROM,
|
||||
MT_EPROM,
|
||||
MT_CRRAM,
|
||||
MT_3DRAM,
|
||||
MT_SDRAM,
|
||||
MT_SGRAM,
|
||||
MT_RDRAM,
|
||||
MT_DDR,
|
||||
MT_DDR2,
|
||||
MT_DDR2_FBDIMM,
|
||||
MT_DDR3 = 0x18,
|
||||
MT_FBD2
|
||||
};
|
||||
|
||||
enum MemoryDeviceTypeFlags
|
||||
{
|
||||
MTF_OTHER = 0x0002,
|
||||
MTF_UNKNOWN = 0x0004,
|
||||
MTF_FAST_PAGED = 0x0008,
|
||||
MTF_STATIC_COLUMN = 0x0010,
|
||||
MTF_PSEUDO_STATIC = 0x0020,
|
||||
MTF_RAMBUS = 0x0040,
|
||||
MTF_SYNCHRONOUS = 0x0080,
|
||||
MTF_CMOS = 0x0100,
|
||||
MTF_EDO = 0x0200,
|
||||
MTF_WINDOW_DRAM = 0x0400,
|
||||
MTF_CACHE_DRAM = 0x0800,
|
||||
MTF_NON_VOLATILE = 0x1000,
|
||||
MTF_BUFFERED = 0x2000,
|
||||
MTF_UNBUFFERED = 0x4000,
|
||||
};
|
||||
|
||||
#define MemoryDevice_FIELDS\
|
||||
FIELD(F_HANDLE, Handle, hMemoryArray, "")\
|
||||
FIELD(F_HANDLE, Handle, hError, "")\
|
||||
FIELD(0, u16, totalWidth, " bits")\
|
||||
FIELD(0, u16, dataWidth, " bits")\
|
||||
FIELD(F_INTERNAL, u16, size16, "")\
|
||||
FIELD(F_ENUM, MemoryDeviceFormFactor, formFactor, "")\
|
||||
FIELD(0, u8, deviceSet, "")\
|
||||
FIELD(0, const char*, locator, "")\
|
||||
FIELD(0, const char*, bank, "")\
|
||||
FIELD(F_ENUM, MemoryDeviceType, type, "")\
|
||||
FIELD(F_FLAGS, u16, typeFlags, "")\
|
||||
FIELD(0, u16, speed, " MHz")\
|
||||
FIELD(0, const char*, manufacturer, "")\
|
||||
FIELD(0, const char*, serialNumber, "")\
|
||||
FIELD(0, const char*, assetTag, "")\
|
||||
FIELD(0, const char*, partNumber, "")\
|
||||
FIELD(F_FLAGS, u8, attributes, "")\
|
||||
FIELD(F_INTERNAL, u32, size32, "")\
|
||||
FIELD(0, u16, configuredSpeed, " MHz")\
|
||||
FIELD(F_DERIVED, u64, size, " bytes")
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MemoryArrayMappedAddress
|
||||
|
||||
#define MemoryArrayMappedAddress_FIELDS\
|
||||
FIELD(F_INTERNAL, u32, startAddress32, " bits")\
|
||||
FIELD(F_INTERNAL, u32, endAddress32, " bits")\
|
||||
FIELD(F_HANDLE, Handle, hMemoryArray, "")\
|
||||
FIELD(0, u8, partitionWidth, "")\
|
||||
FIELD(0, u64, startAddress, "")\
|
||||
FIELD(0, u64, endAddress, "")\
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MemoryDeviceMappedAddress
|
||||
|
||||
#define MemoryDeviceMappedAddress_FIELDS\
|
||||
FIELD(F_INTERNAL, u32, startAddress32, " bits")\
|
||||
FIELD(F_INTERNAL, u32, endAddress32, " bits")\
|
||||
FIELD(F_HANDLE, Handle, hMemoryDevice, "")\
|
||||
FIELD(F_HANDLE, Handle, hMemoryArrayMappedAddress, "")\
|
||||
FIELD(0, u8, partitionRowPosition, "")\
|
||||
FIELD(0, u8, interleavePosition, "")\
|
||||
FIELD(0, u8, interleavedDataDepth, "")\
|
||||
FIELD(0, u64, startAddress, "")\
|
||||
FIELD(0, u64, endAddress, "")\
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SystemBoot
|
||||
|
||||
enum SystemBootStatus
|
||||
{
|
||||
SBS_NO_ERROR = 0,
|
||||
SBS_NO_BOOTABLE_MEDIA,
|
||||
SBS_OS_LOAD_FAILED,
|
||||
SBS_HARDWARE_FAILURE_FIRMWARE,
|
||||
SBS_HARDWARE_FAILURE_OS,
|
||||
SBS_USER_REQUESTED_BOOT,
|
||||
SBS_SECURITY_VIOLATION,
|
||||
SBS_PREVIOUSLY_REQUESTED_IMAGE,
|
||||
SBS_WATCHDOG_EXPIRED
|
||||
};
|
||||
|
||||
#define SystemBoot_FIELDS\
|
||||
FIELD(F_INTERNAL, u32, reserved32, "")\
|
||||
FIELD(F_INTERNAL, u16, reserved16, "")\
|
||||
FIELD(F_HANDLE, Handle, hError, "")\
|
||||
FIELD(0, u16, totalWidth, " bits")\
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct Header
|
||||
{
|
||||
u8 id;
|
||||
u8 length;
|
||||
Handle handle;
|
||||
};
|
||||
|
||||
// declare each structure
|
||||
#define FIELD(flags, type, name, units) type name;
|
||||
#define STRUCTURE(name, id) struct name { Header header; name* next; name##_FIELDS };
|
||||
STRUCTURES
|
||||
#undef STRUCTURE
|
||||
#undef FIELD
|
||||
|
||||
// declare a UDT holding pointers (freed at exit) to each structure
|
||||
struct Structures
|
||||
{
|
||||
#define STRUCTURE(name, id) name* name##_;
|
||||
STRUCTURES
|
||||
#undef STRUCTURE
|
||||
};
|
||||
|
||||
#if MSC_VERSION
|
||||
# pragma pack(pop)
|
||||
#endif
|
||||
|
||||
// define function templates that invoke a Visitor for each of a structure's fields
|
||||
#define FIELD(flags, type, name, units) visitor(flags, p.name, #name, units);
|
||||
#define STRUCTURE(name, id) template<class Visitor> void VisitFields(name& p, Visitor& visitor) { name##_FIELDS }
|
||||
STRUCTURES
|
||||
#undef STRUCTURE
|
||||
#undef FIELD
|
||||
|
||||
LIB_API const Structures* GetStructures();
|
||||
|
||||
} // namespace SMBIOS
|
||||
|
||||
#endif // #ifndef INCLUDED_SMBIOS
|
Loading…
Reference in New Issue
Block a user