smbios: add support for stringizing the structures
This was SVN commit r9162.
This commit is contained in:
parent
a2bad46f27
commit
68bc0a5651
@ -200,11 +200,30 @@ void Fixup(Structure& UNUSED(structure))
|
||||
// primary template: do nothing
|
||||
}
|
||||
|
||||
template<>
|
||||
void Fixup<Bios>(Bios& p)
|
||||
{
|
||||
p.size = u64(p.encodedSize+1) * 64*KiB;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Fixup<Processor>(Processor& p)
|
||||
{
|
||||
// clear "populated" bit that interferes with the interpretation of ProcessorStatus
|
||||
p.status = (ProcessorStatus)(p.status & ~0x40);
|
||||
p.isPopulated = (p.status & 0x40) != 0;
|
||||
p.status = (ProcessorStatus)bits((size_t)p.status, 0, 2);
|
||||
|
||||
if(p.voltage & 0x80)
|
||||
p.voltage &= ~0x80;
|
||||
else
|
||||
{
|
||||
// (arbitrarily) report the lowest supported value
|
||||
if(IsBitSet(p.voltage, 0))
|
||||
p.voltage = 50;
|
||||
if(IsBitSet(p.voltage, 1))
|
||||
p.voltage = 33;
|
||||
if(IsBitSet(p.voltage, 2))
|
||||
p.voltage = 29;
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
@ -229,7 +248,7 @@ template<>
|
||||
void Fixup<OnBoardDevices>(OnBoardDevices& p)
|
||||
{
|
||||
p.isEnabled = (p.type & 0x80) != 0;
|
||||
p.type = (OnBoardDeviceType)(p.type & 0x7F);
|
||||
p.type = (OnBoardDeviceType)(p.type & ~0x80);
|
||||
}
|
||||
|
||||
template<>
|
||||
@ -291,7 +310,7 @@ void Fixup<TemperatureProbe>(TemperatureProbe& p)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class Structure>
|
||||
void InitStructure(Structure*& listHead, const Header* header, const Strings& strings)
|
||||
void AddStructure(const Header* header, const Strings& strings, Structure*& listHead)
|
||||
{
|
||||
Structure* const p = (Structure*)calloc(1, sizeof(Structure)); // freed in Cleanup
|
||||
p->header = *header;
|
||||
@ -334,8 +353,15 @@ static LibError InitStructures()
|
||||
|
||||
const Header* header = (const Header*)&table[0];
|
||||
const Header* const end = (const Header*)(&table[0] + table.size());
|
||||
while(header+1 <= end)
|
||||
for(;;)
|
||||
{
|
||||
if(header+1 > end)
|
||||
{
|
||||
debug_printf(L"SMBIOS: table not terminated\n");
|
||||
break;
|
||||
}
|
||||
if(header->id == 127) // end
|
||||
break;
|
||||
if(header->length < sizeof(Header))
|
||||
WARN_RETURN(ERR::_3);
|
||||
|
||||
@ -344,17 +370,12 @@ static LibError InitStructures()
|
||||
|
||||
switch(header->id)
|
||||
{
|
||||
#define STRUCTURE(name, id) case id: InitStructure(structures.name##_, header, strings); break;
|
||||
#define STRUCTURE(name, id) case id: AddStructure(header, strings, structures.name##_); break;
|
||||
STRUCTURES
|
||||
#undef STRUCTURE
|
||||
|
||||
case 126: // inactive
|
||||
break;
|
||||
case 127: // end
|
||||
return INFO::OK;
|
||||
|
||||
default:
|
||||
if(32 < header->id && header->id < 128) // only mention non-proprietary structures of which we are not aware
|
||||
if(32 < header->id && header->id < 126) // only mention non-proprietary structures of which we are not aware
|
||||
debug_printf(L"SMBIOS: unknown structure type %d\n", header->id);
|
||||
break;
|
||||
}
|
||||
@ -362,7 +383,6 @@ static LibError InitStructures()
|
||||
header = next;
|
||||
}
|
||||
|
||||
debug_printf(L"SMBIOS: table not terminated\n");
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
@ -376,4 +396,85 @@ const Structures* GetStructures()
|
||||
return &structures;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class FieldStringizer
|
||||
{
|
||||
NONCOPYABLE(FieldStringizer); // reference member
|
||||
public:
|
||||
FieldStringizer(std::stringstream& ss)
|
||||
: ss(ss)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void operator()(size_t flags, T& t, const char* name, const char* units)
|
||||
{
|
||||
if(flags & F_INTERNAL)
|
||||
return;
|
||||
|
||||
ss << name << ": ";
|
||||
if(flags & (F_HEX|F_FLAGS))
|
||||
ss << std::hex << std::uppercase;
|
||||
else
|
||||
ss << std::dec;
|
||||
|
||||
if(flags & F_HANDLE)
|
||||
{
|
||||
if(u64(t) == 0xFFFE || u64(t) == 0xFFFF)
|
||||
ss << "(N/A)";
|
||||
else
|
||||
ss << t;
|
||||
}
|
||||
else if(flags & F_SIZE)
|
||||
{
|
||||
u64 value = (u64)t;
|
||||
if(value > GiB)
|
||||
ss << value/GiB << " GiB";
|
||||
else if(value > MiB)
|
||||
ss << value/MiB << " MiB";
|
||||
else if(value > KiB)
|
||||
ss << value/KiB << " KiB";
|
||||
else
|
||||
ss << value << " bytes";
|
||||
}
|
||||
else if(sizeof(t) == 1)
|
||||
ss << (unsigned)t;
|
||||
else
|
||||
ss << t;
|
||||
|
||||
ss << units << "\n";
|
||||
}
|
||||
|
||||
private:
|
||||
std::stringstream& ss;
|
||||
};
|
||||
|
||||
|
||||
template<class Structure>
|
||||
void StringizeStructure(const char* name, Structure* p, std::stringstream& ss)
|
||||
{
|
||||
for(; p; p = p->next)
|
||||
{
|
||||
ss << "\n[" << name << "]\n";
|
||||
FieldStringizer fieldStringizer(ss);
|
||||
VisitFields(*p, fieldStringizer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string StringizeStructures(const Structures* structures)
|
||||
{
|
||||
if(!structures)
|
||||
return "(null)";
|
||||
|
||||
std::stringstream ss;
|
||||
#define STRUCTURE(name, id) StringizeStructure(#name, structures->name##_, ss);
|
||||
STRUCTURES
|
||||
#undef STRUCTURE
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
} // namespace SMBIOS
|
||||
|
@ -76,11 +76,16 @@ enum FieldFlags
|
||||
// will display the enumerators)
|
||||
F_ENUM = 0x04,
|
||||
|
||||
// a collection of bit flags and should be displayed as such.
|
||||
// a collection of bit flags.
|
||||
F_FLAGS = 0x08,
|
||||
|
||||
// an SMBIOS Handle (allows nicer display of `unknown' handles).
|
||||
F_HANDLE = 0x10
|
||||
F_HANDLE = 0x10,
|
||||
|
||||
// a number that should be displayed in hexadecimal form.
|
||||
F_HEX = 0x20,
|
||||
|
||||
F_SIZE = 0x40
|
||||
};
|
||||
|
||||
#if MSC_VERSION
|
||||
@ -94,11 +99,12 @@ enum FieldFlags
|
||||
#define Bios_FIELDS\
|
||||
FIELD(0, const char*, vendor, "")\
|
||||
FIELD(0, const char*, version, "")\
|
||||
FIELD(0, u16, startSegment, "")\
|
||||
FIELD(F_HEX, 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 */
|
||||
FIELD(F_INTERNAL, u8, encodedSize, "")\
|
||||
FIELD(F_HEX, u64, characteristics, "")\
|
||||
/* omit subsequent fields because we can't handle the variable-length characteristics extension */\
|
||||
FIELD(F_DERIVED|F_SIZE, u64, size, "")
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -119,8 +125,8 @@ enum SystemWakeUpType
|
||||
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_HEX, u64, uuid0, "")\
|
||||
FIELD(F_HEX, u64, uuid1, "")\
|
||||
FIELD(F_ENUM, SystemWakeUpType, wakeUpType, "")\
|
||||
FIELD(0, const char*, skuNumber, "")\
|
||||
FIELD(0, const char*, family, "")
|
||||
@ -228,7 +234,7 @@ enum ChassisSecurityStatus
|
||||
FIELD(F_ENUM, ChassisSecurityStatus, securityStatus, "")\
|
||||
FIELD(0, u32, oemDefined, "")\
|
||||
FIELD(0, u8, height, "U")\
|
||||
FIELD(0, u8, numPowerCords, "U")\
|
||||
FIELD(0, u8, numPowerCords, "")\
|
||||
/* omit subsequent fields because we can't handle the variable-length contained objects */
|
||||
|
||||
|
||||
@ -299,13 +305,6 @@ enum ProcessorUpgrade
|
||||
PU_SOCKET_FM2
|
||||
};
|
||||
|
||||
enum ProcessorVoltage // bitfield
|
||||
{
|
||||
PV_5 = 1,
|
||||
PV_3_3 = 2,
|
||||
PV_2_9 = 4
|
||||
};
|
||||
|
||||
enum ProcessorCharacteristics // bitfield
|
||||
{
|
||||
PC_UNKNOWN = 0x2,
|
||||
@ -322,12 +321,12 @@ enum ProcessorCharacteristics // bitfield
|
||||
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(F_HEX, 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(0, u8, voltage, " dV")\
|
||||
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, "")\
|
||||
@ -340,7 +339,8 @@ enum ProcessorCharacteristics // bitfield
|
||||
FIELD(0, u8, enabledCores, "")\
|
||||
FIELD(0, u8, logicalPerPackage, "")\
|
||||
FIELD(F_FLAGS, u16, characteristics, "")\
|
||||
FIELD(0, u16, family2, "")
|
||||
FIELD(0, u16, family2, "")\
|
||||
FIELD(F_DERIVED, u8, isPopulated, "")
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -424,8 +424,8 @@ enum CacheAssociativity
|
||||
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")
|
||||
FIELD(F_DERIVED|F_SIZE, size_t, maxSize, "")\
|
||||
FIELD(F_DERIVED|F_SIZE, size_t, installedSize, "")
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -685,7 +685,7 @@ enum MemoryArrayECC
|
||||
FIELD(F_INTERNAL, u32, maxCapacity32, "")\
|
||||
FIELD(F_HANDLE, Handle, hError, "")\
|
||||
FIELD(0, u16, numDevices, "")\
|
||||
FIELD(0, u64, maxCapacity, " bytes")
|
||||
FIELD(F_SIZE, u64, maxCapacity, "")
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -770,7 +770,7 @@ enum MemoryDeviceTypeFlags
|
||||
FIELD(F_FLAGS, u8, attributes, "")\
|
||||
FIELD(F_INTERNAL, u32, size32, "")\
|
||||
FIELD(0, u16, configuredSpeed, " MHz")\
|
||||
FIELD(F_DERIVED, u64, size, " bytes")
|
||||
FIELD(F_DERIVED|F_SIZE, u64, size, "")
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -781,8 +781,8 @@ enum MemoryDeviceTypeFlags
|
||||
FIELD(F_INTERNAL, u32, endAddress32, " bits")\
|
||||
FIELD(F_HANDLE, Handle, hMemoryArray, "")\
|
||||
FIELD(0, u8, partitionWidth, "")\
|
||||
FIELD(0, u64, startAddress, "")\
|
||||
FIELD(0, u64, endAddress, "")\
|
||||
FIELD(F_HEX, u64, startAddress, "")\
|
||||
FIELD(F_HEX, u64, endAddress, "")\
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -796,8 +796,8 @@ enum MemoryDeviceTypeFlags
|
||||
FIELD(0, u8, partitionRowPosition, "")\
|
||||
FIELD(0, u8, interleavePosition, "")\
|
||||
FIELD(0, u8, interleavedDataDepth, "")\
|
||||
FIELD(0, u64, startAddress, "")\
|
||||
FIELD(0, u64, endAddress, "")\
|
||||
FIELD(F_HEX, u64, startAddress, "")\
|
||||
FIELD(F_HEX, u64, endAddress, "")\
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -864,7 +864,7 @@ enum VoltageProbeLocation
|
||||
FIELD(0, u16, tolerance, " mV")\
|
||||
FIELD(0, u16, accuracy, " x 100 ppm")\
|
||||
FIELD(0, u32, oemDefined, "")\
|
||||
FIELD(0, u16, nominalValue, " dDegC")\
|
||||
FIELD(0, u16, nominalValue, " mv")\
|
||||
FIELD(F_DERIVED, VoltageProbeLocation, location, "")\
|
||||
FIELD(F_DERIVED, Status, status, "")
|
||||
|
||||
@ -919,13 +919,13 @@ enum TemperatureProbeLocation
|
||||
#define TemperatureProbe_FIELDS\
|
||||
FIELD(0, const char*, description, "")\
|
||||
FIELD(F_INTERNAL, u8, locationAndStatus, "")\
|
||||
FIELD(0, u16, maxValue, " dDegC")\
|
||||
FIELD(0, u16, minValue, " dDegC")\
|
||||
FIELD(0, i16, maxValue, " dDegC")\
|
||||
FIELD(0, i16, minValue, " dDegC")\
|
||||
FIELD(0, u16, resolution, " mDegC")\
|
||||
FIELD(0, u16, tolerance, " dDegC")\
|
||||
FIELD(0, u16, accuracy, " x 100 ppm")\
|
||||
FIELD(0, u32, oemDefined, "")\
|
||||
FIELD(0, u16, nominalValue, " dDegC")\
|
||||
FIELD(0, i16, nominalValue, " dDegC")\
|
||||
FIELD(F_DERIVED, TemperatureProbeLocation, location, "")\
|
||||
FIELD(F_DERIVED, Status, status, "")
|
||||
|
||||
@ -989,6 +989,7 @@ STRUCTURES
|
||||
#undef FIELD
|
||||
|
||||
LIB_API const Structures* GetStructures();
|
||||
LIB_API std::string StringizeStructures(const Structures*);
|
||||
|
||||
} // namespace SMBIOS
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user