1
0
forked from 0ad/0ad

smbios: add support for stringizing the structures

This was SVN commit r9162.
This commit is contained in:
janwas 2011-04-04 16:50:02 +00:00
parent a2bad46f27
commit 68bc0a5651
2 changed files with 149 additions and 47 deletions

View File

@ -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

View File

@ -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