|
|
/*++
Copyright (c) 1990, 1991 Microsoft Corporation
Module Name:
init386.c
Abstract:
This module is responsible to build any x86 specific entries in the hardware tree of registry.
Author:
Ken Reneris (kenr) 04-Aug-1992
Environment:
Kernel mode.
Revision History:
shielint - add BIOS date and version detection.
--*/
#include "cmp.h"
#include "stdio.h"
#include "smbios.h"
//
// Title Index is set to 0.
// (from ..\cmconfig.c)
//
#define TITLE_INDEX_VALUE 0
extern PCHAR SearchStrings[]; extern PCHAR BiosBegin; extern PCHAR Start; extern PCHAR End; extern UCHAR CmpID[]; extern WCHAR CmpVendorID[]; extern WCHAR CmpProcessorNameString[]; extern WCHAR CmpFeatureBits[]; extern WCHAR CmpMHz[]; extern WCHAR CmpUpdateSignature[]; extern UCHAR CmpIntelID[]; extern UCHAR CmpItanium[]; extern UCHAR CmpMcKinley[]; extern UCHAR CmpIA64Proc[];
//
// Bios date and version definitions
//
#define BIOS_DATE_LENGTH 64
#define MAXIMUM_BIOS_VERSION_LENGTH 128
WCHAR SystemBIOSDateString[BIOS_DATE_LENGTH]; WCHAR SystemBIOSVersionString[MAXIMUM_BIOS_VERSION_LENGTH]; WCHAR VideoBIOSDateString[BIOS_DATE_LENGTH]; WCHAR VideoBIOSVersionString[MAXIMUM_BIOS_VERSION_LENGTH];
//
// Extended CPUID function definitions
//
#define CPUID_PROCESSOR_NAME_STRING_SZ 65
#define CPUID_EXTFN_BASE 0x80000000
#define CPUID_EXTFN_PROCESSOR_NAME 0x80000002
extern ULONG CmpConfigurationAreaSize; extern PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData;
BOOLEAN CmpGetBiosVersion ( PCHAR SearchArea, ULONG SearchLength, PCHAR VersionString );
BOOLEAN CmpGetBiosDate ( PCHAR SearchArea, ULONG SearchLength, PCHAR DateString );
ULONG Ke386CyrixId ( VOID );
VOID InitializeProcessorInformationFromSMBIOS( IN PLOADER_PARAMETER_BLOCK LoaderBlock );
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,CmpInitializeMachineDependentConfiguration)
#pragma alloc_text(INIT,InitializeProcessorInformationFromSMBIOS)
#endif
#if 0
//
// Use SMBIOS to gather this information.
//
BOOLEAN CmpGetBiosDate ( PCHAR SearchArea, ULONG SearchLength, PCHAR DateString )
/*++
Routine Description:
This routine finds the most recent date in the computer/video card's ROM. When GetRomDate encounters a datae, it checks the previously found date to see if the new date is more recent.
Arguments:
SearchArea - the area to search for a date.
SearchLength - Length of search.
DateString - Supplies a pointer to a fixed length memory to receive the date string.
Return Value:
NT_SUCCESS if a date is found.
--*/
{ BOOLEAN FoundFlag = TRUE; // Set to TRUE if the item was found
CHAR PrevDate[BIOS_DATE_LENGTH]; // Date currently being examined
CHAR CurrDate[BIOS_DATE_LENGTH]; // Date currently being examined
PCHAR String; USHORT i; // Looping variable
USHORT Length; // Number of characters to move
PCHAR Start = SearchArea + 2; PCHAR End = SearchArea + SearchLength - 5;
//
// Clear out the previous date
//
RtlZeroMemory(PrevDate, BIOS_DATE_LENGTH);
while (FoundFlag) {
String = NULL;
//
// Search for '/' with a digit on either side and another
// '/' 3 character away.
//
while (Start < End) { if (*Start == '/' && *(Start+3) == '/' && (*(Start+1) <= '9' && *(Start+1) >= '0') && (*(Start-1) <= '9' && *(Start-1) >= '0') && (*(Start+5) <= '9' && *(Start+5) >= '0') && (*(Start+4) <= '9' && *(Start+4) >= '0') && (*(Start+2) <= '9' && *(Start+2) >= '0')) {
String = Start; break; } else { Start++; } }
if (String) { Start = String + 3; String -= 2; // Move String to the beginning of
// date.
//
// Copy the year into CurrDate
//
CurrDate[0] = String[6]; CurrDate[1] = String[7]; CurrDate[2] = '/'; // The 1st "/" for YY/MM/DD
//
// Copy the month & day into CurrDate
// (Process properly if this is a one digit month)
//
if (*String > '9' || *String < '0') { CurrDate[3] = '0'; String++; i = 4; Length = 4; } else { i = 3; Length = 5; }
RtlMoveMemory(&CurrDate[i], String, Length);
//
// Compare the dates, to see which is more recent
//
if (memcmp (PrevDate, CurrDate, BIOS_DATE_LENGTH - 1) < 0) { RtlMoveMemory(PrevDate, CurrDate, BIOS_DATE_LENGTH - 1); } } else { FoundFlag = FALSE; } }
//
// If we did not find a date
//
if (PrevDate[0] == '\0') { DateString[0] = '\0'; return (FALSE); }
//
// Put the date from chPrevDate's YY/MM/DD format
// into pchDateString's MM/DD/YY format
DateString[5] = '/'; DateString[6] = PrevDate[0]; DateString[7] = PrevDate[1]; RtlMoveMemory(DateString, &PrevDate[3], 5); DateString[8] = '\0';
return (TRUE); }
BOOLEAN CmpGetBiosVersion ( PCHAR SearchArea, ULONG SearchLength, PCHAR VersionString )
/*++
Routine Description:
This routine finds the version number stored in ROM, if any.
Arguments:
SearchArea - the area to search for the version.
SearchLength - Length of search
VersionString - Supplies a pointer to a fixed length memory to receive the version string.
Return Value:
TRUE if a version number is found. Else a value of FALSE is returned.
--*/ { PCHAR String; USHORT Length; USHORT i; CHAR Buffer[MAXIMUM_BIOS_VERSION_LENGTH]; PCHAR BufferPointer;
if (SearchArea != NULL) {
//
// If caller does not specify the search area, we will search
// the area left from previous search.
//
BiosBegin = SearchArea; Start = SearchArea + 1; End = SearchArea + SearchLength - 2; }
while (1) {
//
// Search for a period with a digit on either side
//
String = NULL; while (Start <= End) { if (*Start == '.' && *(Start+1) >= '0' && *(Start+1) <= '9' && *(Start-1) >= '0' && *(Start-1) <= '9') { String = Start; break; } else { Start++; } }
if (Start > End) { return(FALSE); } else { Start += 2; }
Length = 0; Buffer[MAXIMUM_BIOS_VERSION_LENGTH - 1] = '\0'; BufferPointer = &Buffer[MAXIMUM_BIOS_VERSION_LENGTH - 1];
//
// Search for the beginning of the string
//
String--; while (Length < MAXIMUM_BIOS_VERSION_LENGTH - 8 && String >= BiosBegin && *String >= ' ' && *String <= 127 && *String != '$') { --BufferPointer; *BufferPointer = *String; --String, ++Length; } ++String;
//
// Can one of the search strings be found
//
for (i = 0; SearchStrings[i]; i++) { if (strstr(BufferPointer, SearchStrings[i])) { goto Found; } } }
Found:
//
// Skip leading white space
//
for (; *String == ' '; ++String) ;
//
// Copy the string to user supplied buffer
//
for (i = 0; i < MAXIMUM_BIOS_VERSION_LENGTH - 1 && String <= (End + 1) && *String >= ' ' && *String <= 127 && *String != '$'; ++i, ++String) { VersionString[i] = *String; } VersionString[i] = '\0'; return (TRUE); }
#endif // #if 0
NTSTATUS CmpInitializeMachineDependentConfiguration( IN PLOADER_PARAMETER_BLOCK LoaderBlock ) /*++
Routine Description:
This routine creates IA64 specific entries in the registry.
Arguments:
LoaderBlock - supplies a pointer to the LoaderBlock passed in from the OS Loader.
Returns:
NTSTATUS code for sucess or reason of failure.
--*/ { NTSTATUS Status; ULONG VideoBiosStart; UNICODE_STRING KeyName; UNICODE_STRING ValueName; UNICODE_STRING ValueData; ANSI_STRING AnsiString; OBJECT_ATTRIBUTES ObjectAttributes; ULONG Disposition; HANDLE ParentHandle; HANDLE BaseHandle, NpxHandle; HANDLE CurrentControlSet; CONFIGURATION_COMPONENT_DATA CurrentEntry; PUCHAR VendorID; UCHAR Buffer[MAXIMUM_BIOS_VERSION_LENGTH]; PKPRCB Prcb; ULONG i, Junk; ULONG VersionsLength = 0, Length; PCHAR VersionStrings, VersionPointer; UNICODE_STRING SectionName; ULONG ViewSize; LARGE_INTEGER ViewBase; PVOID BaseAddress; USHORT DeviceIndexTable[NUMBER_TYPES]; ULONG CpuIdFunction; ULONG MaxExtFn; PULONG NameString = NULL; ULONG ReturnedLength; struct { union { UCHAR Bytes[CPUID_PROCESSOR_NAME_STRING_SZ]; ULONG DWords[1]; } u; } ProcessorNameString;
for (i = 0; i < NUMBER_TYPES; i++) { DeviceIndexTable[i] = 0; }
//
// Go get a bunch of information out of SMBIOS
//
InitializeProcessorInformationFromSMBIOS(LoaderBlock);
InitializeObjectAttributes( &ObjectAttributes, &CmRegistryMachineHardwareDescriptionSystemName, OBJ_CASE_INSENSITIVE, NULL, NULL );
Status = NtOpenKey( &ParentHandle, KEY_READ, &ObjectAttributes );
if (!NT_SUCCESS(Status)) { // Something is really wrong...
return Status; }
//
// On an ARC machine the processor(s) are included in the hardware
// configuration passed in from bootup. Since there's no standard
// way to get all the ARC information for each processor in an MP
// machine via pc-ROMs the information will be added here (if it's
// not already present).
//
RtlInitUnicodeString( &KeyName, L"CentralProcessor" );
InitializeObjectAttributes( &ObjectAttributes, &KeyName, 0, ParentHandle, NULL );
ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
Status = NtCreateKey( &BaseHandle, KEY_READ | KEY_WRITE, &ObjectAttributes, TITLE_INDEX_VALUE, &CmClassName[ProcessorClass], 0, &Disposition );
NtClose (BaseHandle);
if (Disposition == REG_CREATED_NEW_KEY) {
//
// The ARC rom didn't add the processor(s) into the registry.
// Do it now.
//
CmpConfigurationData = (PCM_FULL_RESOURCE_DESCRIPTOR)ExAllocatePool( PagedPool, CmpConfigurationAreaSize );
if (CmpConfigurationData == NULL) { // bail out
NtClose (ParentHandle); return(STATUS_INSUFFICIENT_RESOURCES); }
for (i=0; i < (ULONG)KeNumberProcessors; i++) { Prcb = KiProcessorBlock[i];
RtlZeroMemory (&CurrentEntry, sizeof CurrentEntry); CurrentEntry.ComponentEntry.Class = ProcessorClass; CurrentEntry.ComponentEntry.Type = CentralProcessor; CurrentEntry.ComponentEntry.Key = i; CurrentEntry.ComponentEntry.AffinityMask = AFFINITY_MASK(i);
CurrentEntry.ComponentEntry.Identifier = Buffer;
sprintf( Buffer, CmpID, Prcb->ProcessorFamily, Prcb->ProcessorModel, Prcb->ProcessorRevision );
CurrentEntry.ComponentEntry.IdentifierLength = strlen (Buffer) + 1;
Status = CmpInitializeRegistryNode( &CurrentEntry, ParentHandle, &BaseHandle, -1, (ULONG)-1, DeviceIndexTable );
if (!NT_SUCCESS(Status)) { return(Status); }
VendorID = Prcb->ProcessorVendorString; if ( *VendorID == '\0' ) { VendorID = NULL; }
if (VendorID) {
//
// Add Vendor Indentifier to the registry
//
RtlInitUnicodeString( &ValueName, CmpVendorID );
RtlInitAnsiString( &AnsiString, VendorID );
RtlAnsiStringToUnicodeString( &ValueData, &AnsiString, TRUE );
Status = NtSetValueKey( BaseHandle, &ValueName, TITLE_INDEX_VALUE, REG_SZ, ValueData.Buffer, ValueData.Length + sizeof( UNICODE_NULL ) );
RtlFreeUnicodeString(&ValueData); }
if ( VendorID && !strcmp( VendorID, CmpIntelID ) ) {
ULONG processorModel; PUCHAR processorNameString = CmpItanium;
//
// Add Processor Name String to the registry
//
RtlInitUnicodeString( &ValueName, CmpProcessorNameString );
//
// ISSUE-2000/02/10-v-thief - Pseudo cases to be updated when known.
//
processorModel = Prcb->ProcessorModel; switch( processorModel ) { case 1: // Pseudo-Itanium:
break;
case 2: // Pseudo-McKinley:
processorNameString = CmpMcKinley; break;
default: processorNameString = CmpIA64Proc; break; }
RtlInitAnsiString( &AnsiString, processorNameString );
RtlAnsiStringToUnicodeString( &ValueData, &AnsiString, TRUE );
Status = NtSetValueKey( BaseHandle, &ValueName, TITLE_INDEX_VALUE, REG_SZ, ValueData.Buffer, ValueData.Length + sizeof( UNICODE_NULL ) );
RtlFreeUnicodeString(&ValueData);
}
//
// If more processor IDs have to be restored or initialized,
// check non-IA64 implementations of this function.
//
if ( Prcb->ProcessorFeatureBits ) {
//
// Add processor feature bits to the registry
//
RtlInitUnicodeString( &ValueName, CmpFeatureBits );
Status = NtSetValueKey( BaseHandle, &ValueName, TITLE_INDEX_VALUE, REG_QWORD, &Prcb->ProcessorFeatureBits, sizeof( Prcb->ProcessorFeatureBits ) ); }
if (Prcb->MHz) { //
// Add processor MHz to the registry
//
RtlInitUnicodeString( &ValueName, CmpMHz );
Status = NtSetValueKey( BaseHandle, &ValueName, TITLE_INDEX_VALUE, REG_DWORD, &Prcb->MHz, sizeof (Prcb->MHz) ); }
#if 0
//
// ISSUE-2000/02/01-v-thief
//
if ( Prcb->ProcessorUpdateSignature ) {
//
// Add processor Update Signature to the registry
//
RtlInitUnicodeString( &ValueName, CmpUpdateSignature );
Status = NtSetValueKey( BaseHandle, &ValueName, TITLE_INDEX_VALUE, REG_BINARY, &Prcb->ProcessorUpdateSignature, sizeof( Prcb->ProcessorUpdateSignature ) ); }
#endif // 0
//
// Add ia32 floating point enties for iVE.
//
RtlZeroMemory (&CurrentEntry, sizeof CurrentEntry); CurrentEntry.ComponentEntry.Class = ProcessorClass; CurrentEntry.ComponentEntry.Type = FloatingPointProcessor; CurrentEntry.ComponentEntry.Key = i; CurrentEntry.ComponentEntry.AffinityMask = AFFINITY_MASK(i);
CurrentEntry.ComponentEntry.Identifier = Buffer;
//
// The iVE is defined to look like the Pentium III FP
// This is the value returned by the ia32 CPUID instruction
// on Merced (Itanium)
//
strcpy (Buffer, "x86 Family 7 Model 0 Stepping 0");
CurrentEntry.ComponentEntry.IdentifierLength = strlen (Buffer) + 1;
Status = CmpInitializeRegistryNode( &CurrentEntry, ParentHandle, &NpxHandle, -1, (ULONG)-1, DeviceIndexTable );
//
// How odd. Some calls check the status return value
// and others don't. Is this based on required vs. optional
// keys? For the moment, since it was checked on the i386
// then do the check here too...
//
if (!NT_SUCCESS(Status)) { NtClose(BaseHandle); return(Status); }
//
// Only need to close the handle if we succeeded
//
NtClose(NpxHandle);
NtClose(BaseHandle); }
ExFreePool((PVOID)CmpConfigurationData); }
//
// Next we try to collect System BIOS date and version strings.
//
if( SystemBIOSDateString[0] != 0 ) {
RtlInitUnicodeString( &ValueName, L"SystemBiosDate" );
Status = NtSetValueKey( ParentHandle, &ValueName, TITLE_INDEX_VALUE, REG_SZ, SystemBIOSDateString, (wcslen(SystemBIOSDateString)+1) * sizeof( WCHAR ) );
}
if( SystemBIOSVersionString[0] != 0 ) {
RtlInitUnicodeString( &ValueName, L"SystemBiosVersion" );
Status = NtSetValueKey( ParentHandle, &ValueName, TITLE_INDEX_VALUE, REG_SZ, SystemBIOSVersionString, (wcslen(SystemBIOSVersionString)+1) * sizeof( WCHAR ) );
}
//
// Next we try to collect Video BIOS date and version strings.
//
if( VideoBIOSDateString[0] != 0 ) {
RtlInitUnicodeString( &ValueName, L"VideoBiosDate" );
Status = NtSetValueKey( ParentHandle, &ValueName, TITLE_INDEX_VALUE, REG_SZ, VideoBIOSDateString, (wcslen(VideoBIOSDateString)+1) * sizeof( WCHAR ) );
}
if( VideoBIOSVersionString[0] != 0 ) {
RtlInitUnicodeString( &ValueName, L"VideoBiosVersion" );
Status = NtSetValueKey( ParentHandle, &ValueName, TITLE_INDEX_VALUE, REG_SZ, VideoBIOSVersionString, (wcslen(VideoBIOSVersionString)+1) * sizeof( WCHAR ) );
}
NtClose (ParentHandle);
//
// Add any other x86 specific code here...
//
return STATUS_SUCCESS; }
VOID InitializeProcessorInformationFromSMBIOS( IN PLOADER_PARAMETER_BLOCK LoaderBlock ) /*++
Routine Description:
This function attempts to load processor-specific information out of the SMBIOS table. If present, that information will be used to initialize specific global variables.
Arguments:
LoaderBlock : Pointer to the loaderblock as sent in from the loader.
Return Value:
NONE.
--*/ { PLOADER_PARAMETER_EXTENSION LoaderExtension; NTSTATUS Status = STATUS_SUCCESS; PSMBIOS_EPS_HEADER SMBiosEPSHeader; PDMIBIOS_EPS_HEADER DMIBiosEPSHeader; BOOLEAN Found = FALSE; PHYSICAL_ADDRESS SMBiosTablePhysicalAddress = {0}; PUCHAR StartPtr = NULL; PUCHAR EndPtr = NULL; PUCHAR SMBiosDataVirtualAddress = NULL; PSMBIOS_STRUCT_HEADER Header = NULL; ULONG i = 0; PKPRCB Prcb; UCHAR Checksum;
PAGED_CODE();
LoaderExtension = LoaderBlock->Extension;
if (LoaderExtension->Size >= sizeof(LOADER_PARAMETER_EXTENSION)) {
if (LoaderExtension->SMBiosEPSHeader != NULL) {
//
// Load the SMBIOS table address and checksum it just to make sure.
//
SMBiosEPSHeader = (PSMBIOS_EPS_HEADER)LoaderExtension->SMBiosEPSHeader; DMIBiosEPSHeader = (PDMIBIOS_EPS_HEADER)&SMBiosEPSHeader->Signature2[0];
SMBiosTablePhysicalAddress.HighPart = 0; SMBiosTablePhysicalAddress.LowPart = DMIBiosEPSHeader->StructureTableAddress;
StartPtr = (PUCHAR)SMBiosEPSHeader; Checksum = 0; for( i = 0; i < SMBiosEPSHeader->Length; i++ ) { Checksum += StartPtr[i]; } if( Checksum != 0 ) { CmKdPrintEx((DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"InitializeProcessorInformationFromSMBIOS: _SM_ table has an incorrect checksum.\n")); return; }
//
// Map the table into a virtual address and search it.
//
SMBiosDataVirtualAddress = MmMapIoSpace( SMBiosTablePhysicalAddress, DMIBiosEPSHeader->StructureTableLength, MmCached );
if( SMBiosDataVirtualAddress != NULL ) {
//
// Search...
//
StartPtr = SMBiosDataVirtualAddress; EndPtr = StartPtr + DMIBiosEPSHeader->StructureTableLength; Found = FALSE; while( (StartPtr < EndPtr) ) {
Header = (PSMBIOS_STRUCT_HEADER)StartPtr;
if( Header->Type == SMBIOS_BIOS_INFORMATION_TYPE ) {
PSMBIOS_BIOS_INFORMATION_STRUCT InfoHeader = (PSMBIOS_BIOS_INFORMATION_STRUCT)StartPtr; PUCHAR StringPtr = NULL;
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL,"InitializeProcessorInformationFromSMBIOS: SMBIOS_BIOS_INFORMATION\n"));
//
// Load the System BIOS Version information.
//
// Now jump to the BiosInfoHeader->BIOSVersion-th string which
// is appended onto the end of the formatted section of the table.
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," I think the version string is at offset: %d\n", (ULONG)InfoHeader->Version)); if( (ULONG)InfoHeader->Version > 0 ) {
// Jump to the end of the formatted portion of the SMBIOS table.
StringPtr = StartPtr + Header->Length;
// Jump over some number of strings to get to our string.
for( i = 0; i < ((ULONG)InfoHeader->Version-1); i++ ) { while( (*StringPtr != 0) && (StringPtr < EndPtr) ) { StringPtr++; } StringPtr++; }
// StringPtr should be sitting at the BIOSVersion string. Convert him to
// Unicode and save it off.
if( StringPtr < EndPtr ) { UNICODE_STRING UnicodeString; ANSI_STRING AnsiString;
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," I'm about to load the Version string %s\n", StringPtr)); UnicodeString.Buffer = SystemBIOSVersionString; UnicodeString.MaximumLength = MAXIMUM_BIOS_VERSION_LENGTH; RtlInitAnsiString( &AnsiString, StringPtr );
RtlAnsiStringToUnicodeString( &UnicodeString, &AnsiString, FALSE );
} }
//
// Load the System BIOS Date information
//
// Now jump to the BiosInfoHeader->BIOSDate-th string which
// is appended onto the end of the formatted section of the table.
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," I think the ReleaseDate string is at offset: %d\n", (ULONG)InfoHeader->ReleaseDate)); if( (ULONG)InfoHeader->ReleaseDate > 0 ) {
// Jump to the end of the formatted portion of the SMBIOS table.
StringPtr = StartPtr + Header->Length;
// Jump over some number of strings to get to our string.
for( i = 0; i < ((ULONG)InfoHeader->ReleaseDate-1); i++ ) { while( (*StringPtr != 0) && (StringPtr < EndPtr) ) { StringPtr++; } StringPtr++; }
// StringPtr should be sitting at the BIOSDate string. Convert him to
// Unicode and save it off.
if( StringPtr < EndPtr ) { UNICODE_STRING UnicodeString; ANSI_STRING AnsiString;
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," I'm about to load the Date string %s\n", StringPtr)); UnicodeString.Buffer = SystemBIOSDateString; UnicodeString.MaximumLength = BIOS_DATE_LENGTH; RtlInitAnsiString( &AnsiString, StringPtr );
RtlAnsiStringToUnicodeString( &UnicodeString, &AnsiString, FALSE );
} }
} else if( Header->Type == SMBIOS_BASE_BOARD_INFORMATION_TYPE ) { PSMBIOS_BASE_BOARD_INFORMATION_STRUCT InfoHeader = (PSMBIOS_BASE_BOARD_INFORMATION_STRUCT)StartPtr; PUCHAR StringPtr = NULL;
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL,"InitializeProcessorInformationFromSMBIOS: SMBIOS_BASE_BOARD_INFORMATION\n"));
#if 0
//
// We aren't using any of this information right now.
// -matth 4/2001
//
// Manufacturer
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," I think the Manufacturer string is at offset: %d\n", (ULONG)InfoHeader->Manufacturer)); if( (ULONG)InfoHeader->Manufacturer > 0 ) {
// Jump to the end of the formatted portion of the SMBIOS table.
StringPtr = StartPtr + Header->Length;
// Jump over some number of strings to get to our string.
for( i = 0; i < ((ULONG)InfoHeader->Manufacturer-1); i++ ) { while( (*StringPtr != 0) && (StringPtr < EndPtr) ) { StringPtr++; } StringPtr++; } KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," Manufacturer: %s\n", StringPtr)); }
// Product
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," I think the Product string is at offset: %d\n", (ULONG)InfoHeader->Product)); if( (ULONG)InfoHeader->Product > 0 ) {
// Jump to the end of the formatted portion of the SMBIOS table.
StringPtr = StartPtr + Header->Length;
// Jump over some number of strings to get to our string.
for( i = 0; i < ((ULONG)InfoHeader->Product-1); i++ ) { while( (*StringPtr != 0) && (StringPtr < EndPtr) ) { StringPtr++; } StringPtr++; } KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," Product: %s\n", StringPtr)); }
// Version
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," I think the Version string is at offset: %d\n", (ULONG)InfoHeader->Version)); if( (ULONG)InfoHeader->Version > 0 ) {
// Jump to the end of the formatted portion of the SMBIOS table.
StringPtr = StartPtr + Header->Length;
// Jump over some number of strings to get to our string.
for( i = 0; i < ((ULONG)InfoHeader->Version-1); i++ ) { while( (*StringPtr != 0) && (StringPtr < EndPtr) ) { StringPtr++; } StringPtr++; } KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," Version: %s\n", StringPtr)); }
// SerialNumber
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," I think the SerialNumber string is at offset: %d\n", (ULONG)InfoHeader->SerialNumber)); if( (ULONG)InfoHeader->SerialNumber > 0 ) {
// Jump to the end of the formatted portion of the SMBIOS table.
StringPtr = StartPtr + Header->Length;
// Jump over some number of strings to get to our string.
for( i = 0; i < ((ULONG)InfoHeader->SerialNumber-1); i++ ) { while( (*StringPtr != 0) && (StringPtr < EndPtr) ) { StringPtr++; } StringPtr++; } KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," SerialNumber: %s\n", StringPtr)); } #endif
} else if( Header->Type == SMBIOS_SYSTEM_CHASIS_INFORMATION_TYPE ) {
PSMBIOS_SYSTEM_CHASIS_INFORMATION_STRUCT InfoHeader = (PSMBIOS_SYSTEM_CHASIS_INFORMATION_STRUCT)StartPtr; PUCHAR StringPtr = NULL;
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL,"InitializeProcessorInformationFromSMBIOS: SMBIOS_SYSTEM_CHASIS_INFORMATION\n"));
#if 0
//
// We aren't using any of this information right now.
// -matth 4/2001
//
// Manufacturer
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," I think the Manufacturer string is at offset: %d\n", (ULONG)InfoHeader->Manufacturer)); if( (ULONG)InfoHeader->Manufacturer > 0 ) {
// Jump to the end of the formatted portion of the SMBIOS table.
StringPtr = StartPtr + Header->Length;
// Jump over some number of strings to get to our string.
for( i = 0; i < ((ULONG)InfoHeader->Manufacturer-1); i++ ) { while( (*StringPtr != 0) && (StringPtr < EndPtr) ) { StringPtr++; } StringPtr++; } KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," Manufacturer: %s\n", StringPtr)); }
// Product
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," I think the Manufacturer string is at offset: %d\n", (ULONG)InfoHeader->ChasisType)); if( (ULONG)InfoHeader->ChasisType > 0 ) {
// Jump to the end of the formatted portion of the SMBIOS table.
StringPtr = StartPtr + Header->Length;
// Jump over some number of strings to get to our string.
for( i = 0; i < ((ULONG)InfoHeader->ChasisType-1); i++ ) { while( (*StringPtr != 0) && (StringPtr < EndPtr) ) { StringPtr++; } StringPtr++; } KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," ChasisType: %s\n", StringPtr)); }
// Version
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," I think the Version string is at offset: %d\n", (ULONG)InfoHeader->Version)); if( (ULONG)InfoHeader->Version > 0 ) {
// Jump to the end of the formatted portion of the SMBIOS table.
StringPtr = StartPtr + Header->Length;
// Jump over some number of strings to get to our string.
for( i = 0; i < ((ULONG)InfoHeader->Version-1); i++ ) { while( (*StringPtr != 0) && (StringPtr < EndPtr) ) { StringPtr++; } StringPtr++; } KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," Version: %s\n", StringPtr)); }
// SerialNumber
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," I think the SerialNumber string is at offset: %d\n", (ULONG)InfoHeader->SerialNumber)); if( (ULONG)InfoHeader->SerialNumber > 0 ) {
// Jump to the end of the formatted portion of the SMBIOS table.
StringPtr = StartPtr + Header->Length;
// Jump over some number of strings to get to our string.
for( i = 0; i < ((ULONG)InfoHeader->SerialNumber-1); i++ ) { while( (*StringPtr != 0) && (StringPtr < EndPtr) ) { StringPtr++; } StringPtr++; } KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL," SerialNumber: %s\n", StringPtr)); }
#endif
}
//
// Go to the next table.
//
KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL,"InitializeProcessorInformationFromSMBIOS: Haven't found the ProcessorInformation block yet. Just looked at a block of type: %d.\n", Header->Type));
StartPtr += Header->Length;
// jump over any trailing string-list too.
while ( (*((USHORT UNALIGNED *)StartPtr) != 0) && (StartPtr < EndPtr) ) { StartPtr++; } StartPtr += 2;
}
MmUnmapIoSpace(SMBiosDataVirtualAddress, DMIBiosEPSHeader->StructureTableLength);
} else { KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL,"InitializeProcessorInformationFromSMBIOS: Failed to map the SMBIOS physical address.\n")); }
} else { KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL,"InitializeProcessorInformationFromSMBIOS: The SMBiosEPSHeader is NULL in the extension block.\n")); }
} else { KdPrintEx((DPFLTR_SYSTEM_ID, DPFLTR_INFO_LEVEL,"InitializeProcessorInformationFromSMBIOS: LoaderBlock extension is out of sync with the kernel.\n"));
} }
|