27 #include "precompiled.h"
66 u8 used20CallingMethod;
72 const WmiHeader* wmiHeader = (
const WmiHeader*)&table[0];
73 ENSURE(table.size() ==
sizeof(WmiHeader) + wmiHeader->length);
74 memmove(&table[0], &table[
sizeof(WmiHeader)], table.size()-
sizeof(WmiHeader));
92 const char* pos = ((
const char*)header) + header->
length;
105 strings.push_back(pos);
109 next = (
const Header*)pos;
129 #define STRUCTURE(name, id)\
130 while(structures.name##_)\
132 name* next = structures.name##_->next;\
133 SAFE_FREE(structures.name##_);\
134 structures.name##_ = next;\
145 #define FIELD(flags, type, name, units) visitor(flags, p.name, #name, units);
146 #define STRUCTURE(name, id) template<class Visitor> void VisitFields(name& p, Visitor& visitor) { name##_FIELDS }
158 :
data((const
u8*)(header+1))
159 ,
end((const
u8*)header + header->length)
164 template<
typename Field>
181 memcpy(&value,
data,
sizeof(value));
182 data +=
sizeof(value);
188 template<
typename Field>
191 field = Field(ReadValue<typename Field::T>());
194 template<
typename Field>
197 field = ReadValue<Field>();
211 void FieldInitializer::operator()<
bool>(
size_t flags,
bool&
UNUSED(t),
const char*
UNUSED(name),
const char*
UNUSED(units))
219 void FieldInitializer::operator()<
const char*>(
size_t flags,
const char*& t,
const char*
UNUSED(name),
const char*
UNUSED(units))
224 operator()(flags, number, 0, 0);
228 if(number > strings.size())
230 debug_printf(L
"SMBIOS: invalid string number %d (count=%d)\n", number, (
int)strings.size());
244 template<
class Structure>
253 p.size = size_t(p.encodedSize+1) * 64*
KiB;
259 p.populated = (p.status & 0x40) != 0;
260 p.status = (ProcessorStatus)
bits(p.status, 0, 2);
281 u64 operator()(
u16 size)
const
284 return u64(
bits(size, 0, 14)) * granularity;
287 p.maxSize = DecodeSize()(p.maxSize16);
288 p.installedSize = DecodeSize()(p.installedSize16);
289 p.level =
bits(p.configuration, 0, 2)+1;
290 p.location = (CacheLocation)
bits(p.configuration, 5, 6);
291 p.mode = (CacheMode)
bits(p.configuration, 8, 9);
292 p.configuration = (CacheConfigurationFlags)(p.configuration & ~0x367);
299 if(p.functionAndDeviceNumber != 0xFF)
301 p.functionNumber =
bits(p.functionAndDeviceNumber, 0, 2);
302 p.deviceNumber =
bits(p.functionAndDeviceNumber, 3, 7);
309 p.enabled = (p.type.value & 0x80) != 0;
310 p.type = (OnBoardDeviceType)(p.type & ~0x80);
317 p.maxCapacity =
u64(p.maxCapacity32) *
KiB;
327 p.rank =
bits(p.attributes, 0, 3);
334 p.startAddress =
u64(p.startAddress32) *
KiB;
336 p.endAddress =
u64(p.endAddress32) *
KiB;
343 p.startAddress =
u64(p.startAddress32) *
KiB;
345 p.endAddress =
u64(p.endAddress32) *
KiB;
351 p.location = (VoltageProbeLocation)
bits(p.locationAndStatus, 0, 4);
352 p.status = (State)
bits(p.locationAndStatus, 5, 7);
358 p.type = (CoolingDeviceType)
bits(p.typeAndStatus, 0, 4);
359 p.status = (State)
bits(p.typeAndStatus, 5, 7);
365 p.location = (TemperatureProbeLocation)
bits(p.locationAndStatus, 0, 4);
366 p.status = (State)
bits(p.locationAndStatus, 5, 7);
372 p.type = (SystemPowerSupplyType)
bits(p.characteristics, 10, 13);
373 p.status = (State)
bits(p.characteristics, 7, 9);
374 p.inputSwitching = (SystemPowerSupplyInputSwitching)
bits(p.characteristics, 3, 6);
375 p.characteristics =
bits(p.characteristics, 0, 2);
382 p.type = (OnBoardDeviceType)
bits(p.type, 0, 6);
383 p.deviceNumber =
bits(p.functionAndDeviceNumber, 3, 7);
384 p.functionNumber =
bits(p.functionAndDeviceNumber, 0, 2);
391 template<
class Structure>
394 Structure*
const p = (Structure*)calloc(1,
sizeof(Structure));
400 Structure* last = listHead;
409 VisitFields(*p, fieldInitializer);
421 std::vector<u8> table;
434 const Header*
const end = (
const Header*)(&table[0] + table.size());
442 if(header->
id == 127)
452 #define STRUCTURE(name, id) case id: AddStructure(header, strings, structures.name##_); break;
457 if(32 < header->
id && header->
id < 126)
475 return "(unknown enumeration)";
478 #define ENUM(enumerator, VALUE)\
479 if(field.value == VALUE) \
481 if(!is_pow2(VALUE)) \
486 if(allowFlags && (field.value & (VALUE)))\
490 string += #enumerator;\
492 #define ENUMERATION(name, type)\
494 std::string StringFromEnum<name>(name field)\
497 bool allowFlags = true;\
500 if(string.empty() && field != 0)\
502 std::stringstream ss;\
503 ss << "(unknown " << #name << " " << field.value << ")";\
525 template<
typename Field>
526 void operator()(
size_t flags, Field& field,
const char* name,
const char* units)
531 Write(flags, field, name, units, 0);
570 if(value % divisor == 0)
571 ss << (value/divisor);
573 ss << (double(value)/divisor);
592 template<
typename Field>
593 void Write(
size_t UNUSED(flags), Field& field,
const char* name,
const char* units,
typename Field::Enum*)
608 template<
typename Field>
609 void Write(
size_t flags, Field& field,
const char* name,
const char* units, ...)
614 if(field == std::numeric_limits<Field>::min() || field == std::numeric_limits<Field>::max())
620 ss << std::hex << std::uppercase;
622 if(
sizeof(field) == 1)
623 ss << unsigned(field);
633 std::stringstream&
ss;
637 void FieldStringizer::operator()<
bool>(
size_t flags,
bool& value,
const char* name,
const char* units)
643 ss << (value?
"true" :
"false");
648 void FieldStringizer::operator()<
Handle>(
size_t flags,
Handle&
handle,
const char* name,
const char* units)
664 void FieldStringizer::operator()<
const char*>(
size_t flags,
const char*& value,
const char* name,
const char* units)
672 std::string string(value);
673 const size_t lastChar =
string.find_last_not_of(
' ');
674 if(lastChar == std::string::npos)
676 string.resize(lastChar+1);
677 if(!strcasecmp(value,
"To Be Filled By O.E.M."))
681 ss <<
"\"" <<
string <<
"\"";
700 template<
class Structure>
703 for(; p; p = p->next)
705 ss <<
"\n[" << name <<
"]\n";
707 VisitFields(*p, fieldStringizer);
713 std::stringstream ss;
714 #define STRUCTURE(name, id) StringizeStructure(#name, structures->name##_, ss);
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
void StringizeStructure(const char *name, Structure *p, std::stringstream &ss)
void Read(Field &field,...)
void Fixup< MemoryDeviceMappedAddress >(MemoryDeviceMappedAddress &p)
std::string StringizeStructures(const Structures *structures)
void operator()(size_t flags, Size< T > &size, const char *name, const char *units)
static Status InitStructures()
void Fixup< MemoryArray >(MemoryArray &p)
void Fixup< OnBoardDevices >(OnBoardDevices &p)
void Fixup< SystemPowerSupply >(SystemPowerSupply &p)
Table GetTable(Provider provider, TableId tableId)
static ModuleInitState initState
std::vector< const char * > Strings
const Structures * GetStructures()
const Status NOT_SUPPORTED
#define SAFE_FREE(p)
free memory ensuing from malloc and set the pointer to zero (thus making double-frees safe / a no-op)...
void Write(size_t flags, Field &field, const char *name, const char *units, typename Field::Enum *)
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
#define UNUSED2(param)
mark a function local variable or parameter as unused and avoid the corresponding compiler warning...
intptr_t ModuleInitState
initialization state of a module (class, source file, etc.) must be initialized to zero (e...
static Structures structures
void Read(Field &field, typename Field::T *)
bool IsBitSet(T value, size_t index)
void Fixup< Cache >(Cache &p)
FieldStringizer(std::stringstream &ss)
void Fixup< MemoryArrayMappedAddress >(MemoryArrayMappedAddress &p)
void Fixup< Bios >(Bios &p)
void Write(size_t flags, Field &field, const char *name, const char *units,...)
i64 Status
Error handling system.
void Fixup< SystemSlot >(SystemSlot &p)
std::vector< TableId > TableIds
#define T(string_literal)
T bits(T num, size_t lo_idx, size_t hi_idx)
extract the value of bits hi_idx:lo_idx within num
void WriteUnits(const char *units)
void Fixup< OnboardDevices2 >(OnboardDevices2 &p)
void Fixup< MemoryDevice >(MemoryDevice &p)
static char * stringStoragePos
void Fixup< Processor >(Processor &p)
#define FOURCC_BE(a, b, c, d)
big-endian version of FOURCC
FieldInitializer(const Header *header, const Strings &strings)
static Strings ExtractStrings(const Header *header, const char *end, const Header *&next)
void Fixup(Structure &structure)
#define WARN_RETURN(status)
static Handle handle(size_t idx, u64 tag)
NONCOPYABLE(FieldStringizer)
void WriteName(const char *name)
TableIds GetTableIDs(Provider provider)
NONCOPYABLE(FieldInitializer)
void AddStructure(const Header *header, const Strings &strings, Structure *&listHead)
void operator()(size_t flags, Field &field, const char *name, const char *units)
void operator()(size_t flags, Field &field, const char *name, const char *units)
Status ModuleInit(volatile ModuleInitState *initState, Status(*init)())
calls a user-defined init function if initState is zero.
void Fixup< CoolingDevice >(CoolingDevice &p)
std::string StringFromEnum(Enum field)
static char * stringStorage
void Fixup< TemperatureProbe >(TemperatureProbe &p)
void debug_printf(const wchar_t *fmt,...)
write a formatted string to the debug channel, subject to filtering (see below).
void Fixup< VoltageProbe >(VoltageProbe &p)
#define RETURN_STATUS_IF_ERR(expression)