mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
Reworked and fixed most of the CPU and PnP code.
svn path=/trunk/; revision=4658
This commit is contained in:
parent
77d0973eaa
commit
d882e9a38b
6 changed files with 648 additions and 785 deletions
|
@ -209,8 +209,10 @@ ARCH_OBJS = fathelp.o \
|
|||
i386disk.o \
|
||||
portio.o \
|
||||
hardware.o \
|
||||
hwcpu.o \
|
||||
_alloca.o # For Mingw32 builds
|
||||
|
||||
|
||||
RTL_OBJS = print.o \
|
||||
stdlib.o \
|
||||
string.o \
|
||||
|
|
|
@ -89,36 +89,6 @@ typedef struct _CM_PNP_BIOS_INSTALLATION_CHECK
|
|||
} __attribute__((packed)) CM_PNP_BIOS_INSTALLATION_CHECK, *PCM_PNP_BIOS_INSTALLATION_CHECK;
|
||||
|
||||
|
||||
typedef struct _MPS_CONFIG_TABLE_HEADER
|
||||
{
|
||||
U32 Signature;
|
||||
U16 BaseTableLength;
|
||||
U8 SpecRev;
|
||||
U8 Checksum;
|
||||
CHAR OemIdString[8];
|
||||
CHAR ProductIdString[12];
|
||||
U32 OemTablePointer;
|
||||
U16 OemTableLength;
|
||||
U16 EntryCount;
|
||||
U32 AddressOfLocalAPIC;
|
||||
U16 ExtendedTableLength;
|
||||
U8 ExtendedTableChecksum;
|
||||
U8 Reserved;
|
||||
} PACKED MPS_CONFIG_TABLE_HEADER, *PMPS_CONFIG_TABLE_HEADER;
|
||||
|
||||
|
||||
typedef struct _MPS_PROCESSOR_ENTRY
|
||||
{
|
||||
U8 EntryType;
|
||||
U8 LocalApicId;
|
||||
U8 LocalApicVersion;
|
||||
U8 CpuFlags;
|
||||
U32 CpuSignature;
|
||||
U32 FeatureFlags;
|
||||
U32 Reserved1;
|
||||
U32 Reserved2;
|
||||
} PACKED MPS_PROCESSOR_ENTRY, *PMPS_PROCESSOR_ENTRY;
|
||||
|
||||
|
||||
static char Hex[] = "0123456789ABCDEF";
|
||||
static unsigned int delay_count = 1;
|
||||
|
@ -265,6 +235,7 @@ DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
|
|||
{
|
||||
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
|
||||
PCM_PNP_BIOS_DEVICE_NODE DeviceNode;
|
||||
PCM_PNP_BIOS_INSTALLATION_CHECK InstData;
|
||||
char Buffer[80];
|
||||
HKEY BusKey;
|
||||
U32 x;
|
||||
|
@ -278,43 +249,26 @@ DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
|
|||
char *Ptr;
|
||||
S32 Error;
|
||||
|
||||
x = PnpBiosSupported((PVOID)DISKREADBUFFER);
|
||||
if (!x)
|
||||
InstData = (PCM_PNP_BIOS_INSTALLATION_CHECK)PnpBiosSupported();
|
||||
if (InstData == NULL || strncmp(InstData->Signature, "$PnP", 4))
|
||||
{
|
||||
printf(" PnP-BIOS not supported\n");
|
||||
DbgPrint((DPRINT_HWDETECT, "PnP-BIOS not supported\n"));
|
||||
return;
|
||||
}
|
||||
DbgPrint((DPRINT_HWDETECT, "Signature '%c%c%c%c'\n",
|
||||
InstData->Signature[0], InstData->Signature[1],
|
||||
InstData->Signature[2], InstData->Signature[3]));
|
||||
|
||||
|
||||
x = PnpBiosGetDeviceNodeCount(&NodeSize, &NodeCount);
|
||||
if (x != 0 || NodeSize == 0 || NodeCount == 0)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "PnP-BIOS failed to enumerate device nodes\n");
|
||||
DbgPrint((DPRINT_HWDETECT, "PnP-BIOS failed to enumerate device nodes\n"));
|
||||
return;
|
||||
}
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"PnP-BIOS supported: found %u device nodes\n",
|
||||
(unsigned int)NodeCount));
|
||||
|
||||
FoundNodeCount = 0;
|
||||
|
||||
PnpBufferSize = 0;
|
||||
for (i = 0; i < 0x255; i++)
|
||||
{
|
||||
NodeNumber = (U8)i;
|
||||
|
||||
x = PnpBiosGetDeviceNode(&NodeNumber, (PVOID)DISKREADBUFFER);
|
||||
if (x == 0)
|
||||
{
|
||||
DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DISKREADBUFFER;
|
||||
PnpBufferSize += DeviceNode->Size;
|
||||
|
||||
FoundNodeCount++;
|
||||
if (FoundNodeCount >= NodeCount)
|
||||
break;
|
||||
}
|
||||
}
|
||||
PnpBufferSize += sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
|
||||
DbgPrint((DPRINT_HWDETECT, "PnpBufferSize: %u\n", PnpBufferSize));
|
||||
DbgPrint((DPRINT_HWDETECT, "PnP-BIOS supported\n"));
|
||||
DbgPrint((DPRINT_HWDETECT, "MaxNodeSize %u NodeCount %u\n", NodeSize, NodeCount));
|
||||
DbgPrint((DPRINT_HWDETECT, "Estimated buffer size %u\n", NodeSize * NodeCount));
|
||||
|
||||
/* Create new bus key */
|
||||
sprintf(Buffer,
|
||||
|
@ -344,7 +298,7 @@ DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
|
|||
}
|
||||
|
||||
/* Set 'Configuration Data' value */
|
||||
Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + PnpBufferSize;
|
||||
Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + (NodeSize * NodeCount);
|
||||
FullResourceDescriptor = MmAllocateMemory(Size);
|
||||
if (FullResourceDescriptor == NULL)
|
||||
{
|
||||
|
@ -352,9 +306,9 @@ DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
|
|||
"Failed to allocate resource descriptor\n"));
|
||||
return;
|
||||
}
|
||||
memset(FullResourceDescriptor, 0, Size);
|
||||
|
||||
/* Initialize resource descriptor */
|
||||
memset(FullResourceDescriptor, 0, Size);
|
||||
FullResourceDescriptor->InterfaceType = Internal;
|
||||
FullResourceDescriptor->BusNumber = 0;
|
||||
FullResourceDescriptor->PartialResourceList.Count = 1;
|
||||
|
@ -363,19 +317,18 @@ DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
|
|||
FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
|
||||
CmResourceShareUndetermined;
|
||||
// FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
|
||||
FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize =
|
||||
PnpBufferSize;
|
||||
|
||||
Ptr = (char *)((PVOID)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
|
||||
Ptr = (char *)(((PVOID)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[0]) +
|
||||
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
|
||||
|
||||
/* Set instalation check data */
|
||||
PnpBiosSupported((PVOID)DISKREADBUFFER);
|
||||
memcpy (Ptr, (PVOID)DISKREADBUFFER, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
|
||||
|
||||
Ptr = (char *)((PVOID)Ptr + sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
|
||||
memcpy (Ptr, InstData, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
|
||||
Ptr += sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
|
||||
|
||||
/* Copy device nodes */
|
||||
for (i = 0; i < 0x255; i++)
|
||||
FoundNodeCount = 0;
|
||||
PnpBufferSize = sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
|
||||
for (i = 0; i < 0xFF; i++)
|
||||
{
|
||||
NodeNumber = (U8)i;
|
||||
|
||||
|
@ -384,10 +337,18 @@ DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
|
|||
{
|
||||
DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DISKREADBUFFER;
|
||||
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Node: %u Size %u (0x%x)\n",
|
||||
DeviceNode->Node,
|
||||
DeviceNode->Size,
|
||||
DeviceNode->Size));
|
||||
|
||||
memcpy (Ptr,
|
||||
DeviceNode,
|
||||
DeviceNode->Size);
|
||||
Ptr = (char *)((U32)Ptr + DeviceNode->Size);
|
||||
|
||||
Ptr += DeviceNode->Size;
|
||||
PnpBufferSize += DeviceNode->Size;
|
||||
|
||||
FoundNodeCount++;
|
||||
if (FoundNodeCount >= NodeCount)
|
||||
|
@ -395,6 +356,14 @@ DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
|
|||
}
|
||||
}
|
||||
|
||||
/* Set real data size */
|
||||
FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize =
|
||||
PnpBufferSize;
|
||||
Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + PnpBufferSize;
|
||||
|
||||
DbgPrint((DPRINT_HWDETECT, "Real buffer size: %u\n", PnpBufferSize));
|
||||
DbgPrint((DPRINT_HWDETECT, "Resource size: %u\n", Size));
|
||||
|
||||
/* Set 'Configuration Data' value */
|
||||
Error = RegSetValue(BusKey,
|
||||
"Configuration Data",
|
||||
|
@ -411,398 +380,6 @@ DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
|
|||
}
|
||||
|
||||
|
||||
static VOID
|
||||
DetectCPU(HKEY CpuKey,
|
||||
HKEY FpuKey)
|
||||
{
|
||||
char VendorIdentifier[13];
|
||||
char Identifier[64];
|
||||
U32 FeatureSet;
|
||||
HKEY CpuInstKey;
|
||||
HKEY FpuInstKey;
|
||||
U32 eax = 0;
|
||||
U32 ebx = 0;
|
||||
U32 ecx = 0;
|
||||
U32 edx = 0;
|
||||
U32 *Ptr;
|
||||
S32 Error;
|
||||
|
||||
/* Create the CPU instance key */
|
||||
Error = RegCreateKey(CpuKey,
|
||||
"0",
|
||||
&CpuInstKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create the FPU instance key */
|
||||
Error = RegCreateKey(FpuKey,
|
||||
"0",
|
||||
&FpuInstKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
eax = CpuidSupported();
|
||||
if (eax & 1)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "CPUID supported\n"));
|
||||
|
||||
/* Get vendor identifier */
|
||||
GetCpuid(0, &eax, &ebx, &ecx, &edx);
|
||||
VendorIdentifier[12] = 0;
|
||||
Ptr = (U32*)&VendorIdentifier[0];
|
||||
*Ptr = ebx;
|
||||
Ptr++;
|
||||
*Ptr = edx;
|
||||
Ptr++;
|
||||
*Ptr = ecx;
|
||||
|
||||
/* Get Identifier */
|
||||
GetCpuid(1, &eax, &ebx, &ecx, &edx);
|
||||
sprintf(Identifier,
|
||||
"x86 Family %u Model %u Stepping %u",
|
||||
(unsigned int)((eax >> 8) & 0x0F),
|
||||
(unsigned int)((eax >> 4) & 0x0F),
|
||||
(unsigned int)(eax & 0x0F));
|
||||
FeatureSet = edx;
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "CPUID not supported\n"));
|
||||
|
||||
strcpy(VendorIdentifier, "Unknown");
|
||||
sprintf(Identifier,
|
||||
"x86 Family %u Model %u Stepping %u",
|
||||
(unsigned int)((eax >> 8) & 0x0F),
|
||||
(unsigned int)((eax >> 4) & 0x0F),
|
||||
(unsigned int)(eax & 0x0F));
|
||||
FeatureSet = 0;
|
||||
}
|
||||
|
||||
/* Set 'Conmponent Information' value (CPU and FPU) */
|
||||
SetComponentInformation(CpuInstKey, 0, 0, 1);
|
||||
SetComponentInformation(FpuInstKey, 0, 0, 1);
|
||||
|
||||
/* Set 'FeatureSet' value (CPU only) */
|
||||
DbgPrint((DPRINT_HWDETECT, "FeatureSet: %x\n", FeatureSet));
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
"FeatureSet",
|
||||
REG_DWORD,
|
||||
(PU8)&FeatureSet,
|
||||
sizeof(U32));
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
/* Set 'Identifier' value (CPU and FPU) */
|
||||
DbgPrint((DPRINT_HWDETECT, "Identifier: %s\n", Identifier));
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
"Identifier",
|
||||
REG_SZ,
|
||||
(PU8)Identifier,
|
||||
strlen(Identifier) + 1);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
Error = RegSetValue(FpuInstKey,
|
||||
"Identifier",
|
||||
REG_SZ,
|
||||
(PU8)Identifier,
|
||||
strlen(Identifier) + 1);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
/* Set 'VendorIdentifier' value (CPU only) */
|
||||
DbgPrint((DPRINT_HWDETECT, "Vendor Identifier: %s\n", VendorIdentifier));
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
"VendorIdentifier",
|
||||
REG_SZ,
|
||||
(PU8)VendorIdentifier,
|
||||
strlen(VendorIdentifier) + 1);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
/* FIXME: Set 'Update Signature' value (CPU only) */
|
||||
|
||||
/* FIXME: Set 'Update Status' value (CPU only) */
|
||||
|
||||
/* FIXME: Set '~MHz' value (CPU only) */
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
SetMpsProcessor(HKEY CpuKey,
|
||||
HKEY FpuKey,
|
||||
PMPS_PROCESSOR_ENTRY CpuEntry)
|
||||
{
|
||||
char VendorIdentifier[13];
|
||||
char Identifier[64];
|
||||
char Buffer[8];
|
||||
U32 FeatureSet;
|
||||
HKEY CpuInstKey;
|
||||
HKEY FpuInstKey;
|
||||
U32 eax = 0;
|
||||
U32 ebx = 0;
|
||||
U32 ecx = 0;
|
||||
U32 edx = 0;
|
||||
U32 *Ptr;
|
||||
S32 Error;
|
||||
|
||||
/* Get processor instance number */
|
||||
sprintf(Buffer, "%u", CpuEntry->LocalApicId);
|
||||
|
||||
/* Create the CPU instance key */
|
||||
Error = RegCreateKey(CpuKey,
|
||||
Buffer,
|
||||
&CpuInstKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create the FPU instance key */
|
||||
Error = RegCreateKey(FpuKey,
|
||||
Buffer,
|
||||
&FpuInstKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get 'VendorIdentifier' */
|
||||
GetCpuid(0, &eax, &ebx, &ecx, &edx);
|
||||
VendorIdentifier[12] = 0;
|
||||
Ptr = (U32*)&VendorIdentifier[0];
|
||||
*Ptr = ebx;
|
||||
Ptr++;
|
||||
*Ptr = edx;
|
||||
Ptr++;
|
||||
*Ptr = ecx;
|
||||
|
||||
/* Get 'Identifier' */
|
||||
sprintf(Identifier,
|
||||
"x86 Family %u Model %u Stepping %u",
|
||||
(U32)((CpuEntry->CpuSignature >> 8) & 0x0F),
|
||||
(U32)((CpuEntry->CpuSignature >> 4) & 0x0F),
|
||||
(U32)(CpuEntry->CpuSignature & 0x0F));
|
||||
|
||||
/* Get FeatureSet */
|
||||
FeatureSet = CpuEntry->FeatureFlags;
|
||||
|
||||
/* Set 'Configuration Data' value (CPU and FPU) */
|
||||
SetComponentInformation(CpuInstKey,
|
||||
0,
|
||||
CpuEntry->LocalApicId,
|
||||
1 << CpuEntry->LocalApicId);
|
||||
|
||||
SetComponentInformation(FpuInstKey,
|
||||
0,
|
||||
CpuEntry->LocalApicId,
|
||||
1 << CpuEntry->LocalApicId);
|
||||
|
||||
/* Set 'FeatureSet' value (CPU only) */
|
||||
DbgPrint((DPRINT_HWDETECT, "FeatureSet: %x\n", FeatureSet));
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
"FeatureSet",
|
||||
REG_DWORD,
|
||||
(PU8)&FeatureSet,
|
||||
sizeof(U32));
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
/* Set 'Identifier' value (CPU and FPU) */
|
||||
DbgPrint((DPRINT_HWDETECT, "Identifier: %s\n", Identifier));
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
"Identifier",
|
||||
REG_SZ,
|
||||
(PU8)Identifier,
|
||||
strlen(Identifier) + 1);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
Error = RegSetValue(FpuInstKey,
|
||||
"Identifier",
|
||||
REG_SZ,
|
||||
(PU8)Identifier,
|
||||
strlen(Identifier) + 1);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
/* Set 'VendorIdentifier' value (CPU only) */
|
||||
DbgPrint((DPRINT_HWDETECT, "Vendor Identifier: %s\n", VendorIdentifier));
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
"VendorIdentifier",
|
||||
REG_SZ,
|
||||
(PU8)VendorIdentifier,
|
||||
strlen(VendorIdentifier) + 1);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
/* FIXME: Set 'Update Signature' value (CPU only) */
|
||||
|
||||
/* FIXME: Set 'Update Status' value (CPU only) */
|
||||
|
||||
/* FIXME: Set '~MHz' value (CPU only) */
|
||||
}
|
||||
|
||||
|
||||
static BOOL
|
||||
DetectMps(HKEY CpuKey,
|
||||
HKEY FpuKey)
|
||||
{
|
||||
PMPS_CONFIG_TABLE_HEADER ConfigTable;
|
||||
PMPS_PROCESSOR_ENTRY CpuEntry;
|
||||
U32 DefaultConfig;
|
||||
char *Buffer;
|
||||
char *Ptr;
|
||||
U32 Offset;
|
||||
|
||||
DefaultConfig = MpsGetDefaultConfiguration();
|
||||
if (DefaultConfig == 0)
|
||||
{
|
||||
/* Read configuration table */
|
||||
MpsGetConfigurationTable((PVOID)DISKREADBUFFER);
|
||||
Buffer = (char *)DISKREADBUFFER;
|
||||
DbgPrint((DPRINT_HWDETECT, "MPS signature: %c%c%c%c\n",
|
||||
Buffer[0], Buffer[1], Buffer[2], Buffer[3]));
|
||||
|
||||
ConfigTable = (PMPS_CONFIG_TABLE_HEADER)DISKREADBUFFER;
|
||||
Offset = 0x2C;
|
||||
while (Offset < ConfigTable->BaseTableLength)
|
||||
{
|
||||
Ptr = Buffer + Offset;
|
||||
|
||||
switch (*Ptr)
|
||||
{
|
||||
case 0:
|
||||
CpuEntry = (PMPS_PROCESSOR_ENTRY)Ptr;
|
||||
|
||||
DbgPrint((DPRINT_HWDETECT, "Processor Entry\n"));
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"APIC Id %u APIC Version %u Flags %x Signature %x Feature %x\n",
|
||||
CpuEntry->LocalApicId,
|
||||
CpuEntry->LocalApicVersion,
|
||||
CpuEntry->CpuFlags,
|
||||
CpuEntry->CpuSignature,
|
||||
CpuEntry->FeatureFlags));
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Processor %u: x86 Family %u Model %u Stepping %u\n",
|
||||
CpuEntry->LocalApicId,
|
||||
(U32)((CpuEntry->CpuSignature >> 8) & 0x0F),
|
||||
(U32)((CpuEntry->CpuSignature >> 4) & 0x0F),
|
||||
(U32)(CpuEntry->CpuSignature & 0x0F)));
|
||||
|
||||
SetMpsProcessor(CpuKey, FpuKey, CpuEntry);
|
||||
Offset += 0x14;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
DbgPrint((DPRINT_HWDETECT, "Bus Entry\n"));
|
||||
Offset += 0x08;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
DbgPrint((DPRINT_HWDETECT, "I/0 APIC Entry\n"));
|
||||
Offset += 0x08;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
DbgPrint((DPRINT_HWDETECT, "I/0 Interrupt Assignment Entry\n"));
|
||||
Offset += 0x08;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
DbgPrint((DPRINT_HWDETECT, "Local Interrupt Assignment Entry\n"));
|
||||
Offset += 0x08;
|
||||
break;
|
||||
|
||||
default:
|
||||
DbgPrint((DPRINT_HWDETECT, "Unknown Entry %u\n",(U32)*Ptr));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Unsupported MPS configuration: %x\n",
|
||||
(U32)DefaultConfig));
|
||||
|
||||
/* FIXME: Identify default configurations */
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
DetectCPUs(HKEY SystemKey)
|
||||
{
|
||||
HKEY CpuKey;
|
||||
HKEY FpuKey;
|
||||
S32 Error;
|
||||
|
||||
/* Create the 'CentralProcessor' key */
|
||||
Error = RegCreateKey(SystemKey,
|
||||
"CentralProcessor",
|
||||
&CpuKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create the 'FloatingPointProcessor' key */
|
||||
Error = RegCreateKey(SystemKey,
|
||||
"FloatingPointProcessor",
|
||||
&FpuKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (MpsSupported())
|
||||
{
|
||||
DetectMps(CpuKey, FpuKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
DetectCPU(CpuKey, FpuKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
SetHarddiskConfigurationData(HKEY DiskKey,
|
||||
|
|
|
@ -150,6 +150,7 @@ VOID SetComponentInformation(HKEY ComponentKey,
|
|||
U32 Affinity);
|
||||
|
||||
/* hwcpu.c */
|
||||
VOID DetectCPUs(HKEY SystemKey);
|
||||
|
||||
/* i386cpu.S */
|
||||
U32 CpuidSupported(VOID);
|
||||
|
@ -159,13 +160,8 @@ VOID GetCpuid(U32 Level,
|
|||
U32 *ecx,
|
||||
U32 *edx);
|
||||
|
||||
U32 MpsSupported(VOID);
|
||||
U32 MpsGetDefaultConfiguration(VOID);
|
||||
U32 MpsGetConfigurationTable(PVOID ConfigTable);
|
||||
|
||||
/* i386pnp.S */
|
||||
//U32 PnpBiosSupported(VOID);
|
||||
U32 PnpBiosSupported(PVOID InstallationCheck);
|
||||
U32 PnpBiosSupported(VOID);
|
||||
U32 PnpBiosGetDeviceNodeCount(U32 *NodeSize,
|
||||
U32 *NodeCount);
|
||||
U32 PnpBiosGetDeviceNode(U8 *NodeId,
|
||||
|
|
571
freeldr/freeldr/arch/i386/hwcpu.c
Normal file
571
freeldr/freeldr/arch/i386/hwcpu.c
Normal file
|
@ -0,0 +1,571 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
*
|
||||
* Copyright (C) 2003 Eric Kohl
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <arch.h>
|
||||
#include <rtl.h>
|
||||
#include <debug.h>
|
||||
#include <mm.h>
|
||||
#include <portio.h>
|
||||
|
||||
#include "../../reactos/registry.h"
|
||||
#include "hardware.h"
|
||||
|
||||
|
||||
#define MP_FP_SIGNATURE 0x5F504D5F /* "_MP_" */
|
||||
#define MP_CT_SIGNATURE 0x504D4350 /* "_MP_" */
|
||||
|
||||
|
||||
typedef struct _MP_FLOATING_POINT_TABLE
|
||||
{
|
||||
U32 Signature; /* "_MP_" */
|
||||
U32 PhysicalAddressPointer;
|
||||
U8 Length;
|
||||
U8 SpecRev;
|
||||
U8 Checksum;
|
||||
U8 FeatureByte[5];
|
||||
} PACKED MP_FLOATING_POINT_TABLE, *PMP_FLOATING_POINT_TABLE;
|
||||
|
||||
|
||||
typedef struct _MPS_CONFIG_TABLE_HEADER
|
||||
{
|
||||
U32 Signature; /* "PCMP" */
|
||||
U16 BaseTableLength;
|
||||
U8 SpecRev;
|
||||
U8 Checksum;
|
||||
U8 OemIdString[8];
|
||||
U8 ProductIdString[12];
|
||||
U32 OemTablePointer;
|
||||
U16 OemTableLength;
|
||||
U16 EntryCount;
|
||||
U32 AddressOfLocalAPIC;
|
||||
U16 ExtendedTableLength;
|
||||
U8 ExtendedTableChecksum;
|
||||
U8 Reserved;
|
||||
} PACKED MP_CONFIGURATION_TABLE, *PMP_CONFIGURATION_TABLE;
|
||||
|
||||
|
||||
typedef struct _MP_PROCESSOR_ENTRY
|
||||
{
|
||||
U8 EntryType;
|
||||
U8 LocalApicId;
|
||||
U8 LocalApicVersion;
|
||||
U8 CpuFlags;
|
||||
U32 CpuSignature;
|
||||
U32 FeatureFlags;
|
||||
U32 Reserved1;
|
||||
U32 Reserved2;
|
||||
} PACKED MP_PROCESSOR_ENTRY, *PMP_PROCESSOR_ENTRY;
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static VOID
|
||||
DetectCPU(HKEY CpuKey,
|
||||
HKEY FpuKey)
|
||||
{
|
||||
char VendorIdentifier[13];
|
||||
char Identifier[64];
|
||||
U32 FeatureSet;
|
||||
HKEY CpuInstKey;
|
||||
HKEY FpuInstKey;
|
||||
U32 eax = 0;
|
||||
U32 ebx = 0;
|
||||
U32 ecx = 0;
|
||||
U32 edx = 0;
|
||||
U32 *Ptr;
|
||||
S32 Error;
|
||||
|
||||
/* Create the CPU instance key */
|
||||
Error = RegCreateKey(CpuKey,
|
||||
"0",
|
||||
&CpuInstKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create the FPU instance key */
|
||||
Error = RegCreateKey(FpuKey,
|
||||
"0",
|
||||
&FpuInstKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
eax = CpuidSupported();
|
||||
if (eax & 1)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "CPUID supported\n"));
|
||||
|
||||
/* Get vendor identifier */
|
||||
GetCpuid(0, &eax, &ebx, &ecx, &edx);
|
||||
VendorIdentifier[12] = 0;
|
||||
Ptr = (U32*)&VendorIdentifier[0];
|
||||
*Ptr = ebx;
|
||||
Ptr++;
|
||||
*Ptr = edx;
|
||||
Ptr++;
|
||||
*Ptr = ecx;
|
||||
|
||||
/* Get Identifier */
|
||||
GetCpuid(1, &eax, &ebx, &ecx, &edx);
|
||||
sprintf(Identifier,
|
||||
"x86 Family %u Model %u Stepping %u",
|
||||
(unsigned int)((eax >> 8) & 0x0F),
|
||||
(unsigned int)((eax >> 4) & 0x0F),
|
||||
(unsigned int)(eax & 0x0F));
|
||||
FeatureSet = edx;
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "CPUID not supported\n"));
|
||||
|
||||
strcpy(VendorIdentifier, "Unknown");
|
||||
sprintf(Identifier,
|
||||
"x86 Family %u Model %u Stepping %u",
|
||||
(unsigned int)((eax >> 8) & 0x0F),
|
||||
(unsigned int)((eax >> 4) & 0x0F),
|
||||
(unsigned int)(eax & 0x0F));
|
||||
FeatureSet = 0;
|
||||
}
|
||||
|
||||
/* Set 'Conmponent Information' value (CPU and FPU) */
|
||||
SetComponentInformation(CpuInstKey, 0, 0, 1);
|
||||
SetComponentInformation(FpuInstKey, 0, 0, 1);
|
||||
|
||||
/* Set 'FeatureSet' value (CPU only) */
|
||||
DbgPrint((DPRINT_HWDETECT, "FeatureSet: %x\n", FeatureSet));
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
"FeatureSet",
|
||||
REG_DWORD,
|
||||
(PU8)&FeatureSet,
|
||||
sizeof(U32));
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
/* Set 'Identifier' value (CPU and FPU) */
|
||||
DbgPrint((DPRINT_HWDETECT, "Identifier: %s\n", Identifier));
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
"Identifier",
|
||||
REG_SZ,
|
||||
(PU8)Identifier,
|
||||
strlen(Identifier) + 1);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
Error = RegSetValue(FpuInstKey,
|
||||
"Identifier",
|
||||
REG_SZ,
|
||||
(PU8)Identifier,
|
||||
strlen(Identifier) + 1);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
/* Set 'VendorIdentifier' value (CPU only) */
|
||||
DbgPrint((DPRINT_HWDETECT, "Vendor Identifier: %s\n", VendorIdentifier));
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
"VendorIdentifier",
|
||||
REG_SZ,
|
||||
(PU8)VendorIdentifier,
|
||||
strlen(VendorIdentifier) + 1);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
/* FIXME: Set 'Update Signature' value (CPU only) */
|
||||
|
||||
/* FIXME: Set 'Update Status' value (CPU only) */
|
||||
|
||||
/* FIXME: Set '~MHz' value (CPU only) */
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
SetMpsProcessor(HKEY CpuKey,
|
||||
HKEY FpuKey,
|
||||
PMP_PROCESSOR_ENTRY CpuEntry)
|
||||
{
|
||||
char VendorIdentifier[13];
|
||||
char Identifier[64];
|
||||
char Buffer[8];
|
||||
U32 FeatureSet;
|
||||
HKEY CpuInstKey;
|
||||
HKEY FpuInstKey;
|
||||
U32 eax = 0;
|
||||
U32 ebx = 0;
|
||||
U32 ecx = 0;
|
||||
U32 edx = 0;
|
||||
U32 *Ptr;
|
||||
S32 Error;
|
||||
|
||||
/* Get processor instance number */
|
||||
sprintf(Buffer, "%u", CpuEntry->LocalApicId);
|
||||
|
||||
/* Create the CPU instance key */
|
||||
Error = RegCreateKey(CpuKey,
|
||||
Buffer,
|
||||
&CpuInstKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create the FPU instance key */
|
||||
Error = RegCreateKey(FpuKey,
|
||||
Buffer,
|
||||
&FpuInstKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get 'VendorIdentifier' */
|
||||
GetCpuid(0, &eax, &ebx, &ecx, &edx);
|
||||
VendorIdentifier[12] = 0;
|
||||
Ptr = (U32*)&VendorIdentifier[0];
|
||||
*Ptr = ebx;
|
||||
Ptr++;
|
||||
*Ptr = edx;
|
||||
Ptr++;
|
||||
*Ptr = ecx;
|
||||
|
||||
/* Get 'Identifier' */
|
||||
sprintf(Identifier,
|
||||
"x86 Family %u Model %u Stepping %u",
|
||||
(U32)((CpuEntry->CpuSignature >> 8) & 0x0F),
|
||||
(U32)((CpuEntry->CpuSignature >> 4) & 0x0F),
|
||||
(U32)(CpuEntry->CpuSignature & 0x0F));
|
||||
|
||||
/* Get FeatureSet */
|
||||
FeatureSet = CpuEntry->FeatureFlags;
|
||||
|
||||
/* Set 'Configuration Data' value (CPU and FPU) */
|
||||
SetComponentInformation(CpuInstKey,
|
||||
0,
|
||||
CpuEntry->LocalApicId,
|
||||
1 << CpuEntry->LocalApicId);
|
||||
|
||||
SetComponentInformation(FpuInstKey,
|
||||
0,
|
||||
CpuEntry->LocalApicId,
|
||||
1 << CpuEntry->LocalApicId);
|
||||
|
||||
/* Set 'FeatureSet' value (CPU only) */
|
||||
DbgPrint((DPRINT_HWDETECT, "FeatureSet: %x\n", FeatureSet));
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
"FeatureSet",
|
||||
REG_DWORD,
|
||||
(PU8)&FeatureSet,
|
||||
sizeof(U32));
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
/* Set 'Identifier' value (CPU and FPU) */
|
||||
DbgPrint((DPRINT_HWDETECT, "Identifier: %s\n", Identifier));
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
"Identifier",
|
||||
REG_SZ,
|
||||
(PU8)Identifier,
|
||||
strlen(Identifier) + 1);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
Error = RegSetValue(FpuInstKey,
|
||||
"Identifier",
|
||||
REG_SZ,
|
||||
(PU8)Identifier,
|
||||
strlen(Identifier) + 1);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
/* Set 'VendorIdentifier' value (CPU only) */
|
||||
DbgPrint((DPRINT_HWDETECT, "Vendor Identifier: %s\n", VendorIdentifier));
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
"VendorIdentifier",
|
||||
REG_SZ,
|
||||
(PU8)VendorIdentifier,
|
||||
strlen(VendorIdentifier) + 1);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
/* FIXME: Set 'Update Signature' value (CPU only) */
|
||||
|
||||
/* FIXME: Set 'Update Status' value (CPU only) */
|
||||
|
||||
/* FIXME: Set '~MHz' value (CPU only) */
|
||||
}
|
||||
|
||||
|
||||
static PMP_FLOATING_POINT_TABLE
|
||||
GetMpFloatingPointTable(VOID)
|
||||
{
|
||||
PMP_FLOATING_POINT_TABLE FpTable;
|
||||
char *Ptr;
|
||||
U8 Sum;
|
||||
U32 Length;
|
||||
U32 i;
|
||||
|
||||
FpTable = (PMP_FLOATING_POINT_TABLE)0xF0000;
|
||||
while ((U32)FpTable < 0x100000)
|
||||
{
|
||||
if (FpTable->Signature == MP_FP_SIGNATURE)
|
||||
{
|
||||
Length = FpTable->Length * 0x10;
|
||||
Ptr = (char *)FpTable;
|
||||
Sum = 0;
|
||||
for (i = 0; i < Length; i++)
|
||||
{
|
||||
Sum += Ptr[i];
|
||||
}
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Checksum: %u\n",
|
||||
Sum));
|
||||
|
||||
if (Sum != 0)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Invalid MP floating point checksum: %u\n",
|
||||
Sum));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return FpTable;
|
||||
}
|
||||
|
||||
FpTable = (PMP_FLOATING_POINT_TABLE)((U32)FpTable + 0x10);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static PMP_CONFIGURATION_TABLE
|
||||
GetMpConfigurationTable(PMP_FLOATING_POINT_TABLE FpTable)
|
||||
{
|
||||
PMP_CONFIGURATION_TABLE ConfigTable;
|
||||
char *Ptr;
|
||||
U8 Sum;
|
||||
U32 Length;
|
||||
U32 i;
|
||||
|
||||
if (FpTable->FeatureByte[0] != 0 ||
|
||||
FpTable->PhysicalAddressPointer == 0)
|
||||
return NULL;
|
||||
|
||||
ConfigTable = (PMP_CONFIGURATION_TABLE)FpTable->PhysicalAddressPointer;
|
||||
if (ConfigTable->Signature != MP_CT_SIGNATURE)
|
||||
return NULL;
|
||||
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"MP Configuration Table at: %x\n",
|
||||
(U32)ConfigTable));
|
||||
|
||||
/* Calculate base table checksum */
|
||||
Length = ConfigTable->BaseTableLength;
|
||||
Ptr = (char *)ConfigTable;
|
||||
Sum = 0;
|
||||
for (i = 0; i < Length; i++)
|
||||
{
|
||||
Sum += Ptr[i];
|
||||
}
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"MP Configuration Table base checksum: %u\n",
|
||||
Sum));
|
||||
|
||||
if (Sum != 0)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Invalid MP Configuration Table base checksum: %u\n",
|
||||
Sum));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ConfigTable->ExtendedTableLength != 0)
|
||||
{
|
||||
/* FIXME: Check extended table */
|
||||
}
|
||||
|
||||
return ConfigTable;
|
||||
}
|
||||
|
||||
|
||||
static BOOL
|
||||
DetectMps(HKEY CpuKey,
|
||||
HKEY FpuKey)
|
||||
{
|
||||
PMP_FLOATING_POINT_TABLE FpTable;
|
||||
PMP_CONFIGURATION_TABLE ConfigTable;
|
||||
PMP_PROCESSOR_ENTRY CpuEntry;
|
||||
char *Ptr;
|
||||
U32 Offset;
|
||||
|
||||
/* Get floating point table */
|
||||
FpTable = GetMpFloatingPointTable();
|
||||
if (FpTable == NULL)
|
||||
return FALSE;
|
||||
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"MP Floating Point Table at: %x\n",
|
||||
(U32)FpTable));
|
||||
|
||||
if (FpTable->FeatureByte[0] == 0)
|
||||
{
|
||||
/* Get configuration table */
|
||||
ConfigTable = GetMpConfigurationTable(FpTable);
|
||||
if (ConfigTable == NULL)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Failed to find the MP Configuration Table\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Offset = sizeof(MP_CONFIGURATION_TABLE);
|
||||
while (Offset < ConfigTable->BaseTableLength)
|
||||
{
|
||||
Ptr = (char*)((U32)ConfigTable + Offset);
|
||||
|
||||
switch (*Ptr)
|
||||
{
|
||||
case 0:
|
||||
CpuEntry = (PMP_PROCESSOR_ENTRY)Ptr;
|
||||
|
||||
DbgPrint((DPRINT_HWDETECT, "Processor Entry\n"));
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"APIC Id %u APIC Version %u Flags %x Signature %x Feature %x\n",
|
||||
CpuEntry->LocalApicId,
|
||||
CpuEntry->LocalApicVersion,
|
||||
CpuEntry->CpuFlags,
|
||||
CpuEntry->CpuSignature,
|
||||
CpuEntry->FeatureFlags));
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Processor %u: x86 Family %u Model %u Stepping %u\n",
|
||||
CpuEntry->LocalApicId,
|
||||
(U32)((CpuEntry->CpuSignature >> 8) & 0x0F),
|
||||
(U32)((CpuEntry->CpuSignature >> 4) & 0x0F),
|
||||
(U32)(CpuEntry->CpuSignature & 0x0F)));
|
||||
|
||||
SetMpsProcessor(CpuKey, FpuKey, CpuEntry);
|
||||
Offset += 0x14;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
DbgPrint((DPRINT_HWDETECT, "Bus Entry\n"));
|
||||
Offset += 0x08;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
DbgPrint((DPRINT_HWDETECT, "I/0 APIC Entry\n"));
|
||||
Offset += 0x08;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
DbgPrint((DPRINT_HWDETECT, "I/0 Interrupt Assignment Entry\n"));
|
||||
Offset += 0x08;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
DbgPrint((DPRINT_HWDETECT, "Local Interrupt Assignment Entry\n"));
|
||||
Offset += 0x08;
|
||||
break;
|
||||
|
||||
default:
|
||||
DbgPrint((DPRINT_HWDETECT, "Unknown Entry %u\n",(U32)*Ptr));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"Unsupported MPS configuration: %x\n",
|
||||
FpTable->FeatureByte[0]));
|
||||
|
||||
/* FIXME: Identify default configurations */
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
DetectCPUs(HKEY SystemKey)
|
||||
{
|
||||
HKEY CpuKey;
|
||||
HKEY FpuKey;
|
||||
S32 Error;
|
||||
|
||||
/* Create the 'CentralProcessor' key */
|
||||
Error = RegCreateKey(SystemKey,
|
||||
"CentralProcessor",
|
||||
&CpuKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create the 'FloatingPointProcessor' key */
|
||||
Error = RegCreateKey(SystemKey,
|
||||
"FloatingPointProcessor",
|
||||
&FpuKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Detect CPUs */
|
||||
if (!DetectMps(CpuKey, FpuKey))
|
||||
{
|
||||
DetectCPU(CpuKey, FpuKey);
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -93,6 +93,7 @@ EXTERN(_GetCpuid)
|
|||
pushl %esi
|
||||
|
||||
movl 0x08(%ebp),%eax
|
||||
|
||||
cpuid
|
||||
|
||||
movl 0x0C(%ebp),%esi
|
||||
|
@ -117,227 +118,4 @@ EXTERN(_GetCpuid)
|
|||
popl %ebp
|
||||
ret
|
||||
|
||||
/*
|
||||
* U32 MpsSupported(VOID);
|
||||
*
|
||||
* RETURNS:
|
||||
*/
|
||||
|
||||
.code16
|
||||
_mps_supported:
|
||||
.long 0
|
||||
_mps_fp_table_offset:
|
||||
.word 0
|
||||
|
||||
EXTERN(_MpsSupported)
|
||||
.code32
|
||||
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushal
|
||||
push %es
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* init ES */
|
||||
pushw $0xF000
|
||||
popw %es
|
||||
|
||||
/* init SI */
|
||||
movw $0xFFF0,%si
|
||||
|
||||
mps_again:
|
||||
movw %es:(%si),%ax
|
||||
cmp $0x4D5F,%ax /* "_M" */
|
||||
jne mps_next
|
||||
|
||||
push %si
|
||||
add $2,%si
|
||||
movw %es:(%si),%ax
|
||||
cmp $0x5F50,%ax /* "P_" */
|
||||
pop %si
|
||||
je mps_found
|
||||
|
||||
mps_next:
|
||||
cmp $0,%si
|
||||
je mps_not_found
|
||||
|
||||
sub $0x10,%si
|
||||
jmp mps_again
|
||||
|
||||
mps_found:
|
||||
movw %si,_mps_fp_table_offset
|
||||
movzwl %si,%eax
|
||||
movl %eax,_mps_supported
|
||||
|
||||
mps_not_found:
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
pop %es
|
||||
popal
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
|
||||
movl _mps_supported,%eax
|
||||
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
* U32 MpsGetDefaultConfiguration(VOID);
|
||||
*
|
||||
* RETURNS:
|
||||
*/
|
||||
.code16
|
||||
_mps_default_configuration:
|
||||
.long 0
|
||||
|
||||
EXTERN(_MpsGetDefaultConfiguration)
|
||||
.code32
|
||||
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushal
|
||||
push %es
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* init ES */
|
||||
pushw $0xF000
|
||||
popw %es
|
||||
|
||||
/* init SI */
|
||||
movw _mps_fp_table_offset,%si
|
||||
|
||||
/* read default configuration (feature byte 1) */
|
||||
addw $0x0B,%si
|
||||
movb %es:(%si),%al
|
||||
|
||||
/* save configuration */
|
||||
movzbl %al,%ecx
|
||||
movl %ecx,_mps_default_configuration
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
pop %es
|
||||
popal
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
|
||||
movl _mps_default_configuration,%eax
|
||||
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
* U32 MpsGetConfigurationTable(PVOID ConfigTable);
|
||||
*
|
||||
* RETURNS:
|
||||
*/
|
||||
.code16
|
||||
_mps_buffer_segment:
|
||||
.word 0
|
||||
_mps_buffer_offset:
|
||||
.word 0
|
||||
|
||||
_mps_config_segment:
|
||||
.word 0
|
||||
_mps_config_offset:
|
||||
.word 0
|
||||
_mps_config_length:
|
||||
.word 0
|
||||
|
||||
EXTERN(_MpsGetConfigurationTable)
|
||||
.code32
|
||||
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushal
|
||||
push %es
|
||||
|
||||
/* convert pointer to node buffer to segment/offset */
|
||||
movl 0x08(%ebp),%eax
|
||||
shrl $4,%eax
|
||||
andl $0xf000,%eax
|
||||
movw %ax,_mps_buffer_segment
|
||||
movl 0x08(%ebp),%eax
|
||||
andl $0xffff,%eax
|
||||
movw %ax,_mps_buffer_offset
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* init ES */
|
||||
pushw $0xF000
|
||||
popw %es
|
||||
|
||||
/* init SI */
|
||||
movw _mps_fp_table_offset,%si
|
||||
|
||||
/* read pointer to configuration table */
|
||||
addw $0x04,%si
|
||||
movl %es:(%si),%eax
|
||||
|
||||
/* save table offset */
|
||||
movw %ax,_mps_config_offset
|
||||
|
||||
/* save table segment */
|
||||
shrl $0x4,%eax
|
||||
andw $0xf000,%ax
|
||||
movw %ax,_mps_config_segment
|
||||
|
||||
/* init ES */
|
||||
pushw _mps_config_segment
|
||||
popw %es
|
||||
|
||||
/* init CX (read table lenght) */
|
||||
movw _mps_config_offset,%si
|
||||
addw $0x04,%si
|
||||
movw %es:(%si),%cx
|
||||
|
||||
/* init ES */
|
||||
pushw _mps_buffer_segment
|
||||
popw %es
|
||||
|
||||
/* init DI */
|
||||
movw _mps_buffer_offset,%di
|
||||
|
||||
/* init SI */
|
||||
movw _mps_config_offset,%si
|
||||
|
||||
/* init DS */
|
||||
.code32
|
||||
movw _mps_config_segment,%ax
|
||||
.code16
|
||||
pushw %ds
|
||||
pushw %ax
|
||||
popw %ds
|
||||
|
||||
/* copy table */
|
||||
// cld
|
||||
rep movsb
|
||||
|
||||
/* restore DS */
|
||||
pop %ds
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
pop %es
|
||||
popal
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
|
||||
ret
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -26,101 +26,56 @@
|
|||
|
||||
|
||||
/*
|
||||
* U32 PnpBiosSupported(PVOID InstallationCheck);
|
||||
* U32 PnpBiosSupported(VOID);
|
||||
*
|
||||
* RETURNS:
|
||||
*/
|
||||
_pnp_support_result:
|
||||
_pnp_bios_entry_point:
|
||||
.long 0
|
||||
_pnp_entry_point:
|
||||
.word 0
|
||||
_pnp_code_segment:
|
||||
.word 0
|
||||
_pnp_data_segment:
|
||||
_pnp_bios_data_segment:
|
||||
.word 0
|
||||
|
||||
EXTERN(_PnpBiosSupported)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
push %es
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
|
||||
/* convert pointer to node buffer to segment/offset */
|
||||
movl 0x08(%ebp),%eax
|
||||
shrl $4,%eax
|
||||
andl $0xf000,%eax
|
||||
movw %ax,_pnp_buffer_segment
|
||||
movl 0x08(%ebp),%eax
|
||||
andl $0xffff,%eax
|
||||
movw %ax,_pnp_buffer_offset
|
||||
xorl %edi,%edi
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* init ES */
|
||||
pushw $0xF000
|
||||
popw %es
|
||||
|
||||
/* init cx */
|
||||
movw $0xFFF0,%si
|
||||
/* init esi */
|
||||
movl $0xFFFF0,%esi
|
||||
|
||||
pnp_again:
|
||||
movw %es:(%si),%ax
|
||||
cmp $0x5024,%ax /* "$P" */
|
||||
jne pnp_next
|
||||
|
||||
push %si
|
||||
add $2,%si
|
||||
movw %es:(%si),%ax
|
||||
cmp $0x506E,%ax /* "nP" */
|
||||
pop %si
|
||||
movl (%esi),%eax
|
||||
cmp $0x506E5024,%eax /* "$PnP" */
|
||||
je pnp_found
|
||||
|
||||
pnp_next:
|
||||
cmp $0,%si
|
||||
cmp $0xF0000,%esi
|
||||
je pnp_not_found
|
||||
|
||||
sub $0x10,%si
|
||||
subl $0x10,%esi
|
||||
jmp pnp_again
|
||||
|
||||
pnp_found:
|
||||
movzwl %si,%eax
|
||||
movl %eax,_pnp_support_result
|
||||
movl %esi,%edi
|
||||
|
||||
add $0x0D,%si
|
||||
movw %es:(%si),%ax
|
||||
movw %ax,_pnp_entry_point
|
||||
/* Calculate the bios entry point (far pointer) */
|
||||
xorl %eax,%eax
|
||||
movw 0x0F(%esi),%ax
|
||||
shll $16,%eax
|
||||
movw 0x0D(%esi),%ax
|
||||
movl %eax,_pnp_bios_entry_point
|
||||
|
||||
add $0x02,%si
|
||||
movw %es:(%si),%ax
|
||||
movw %ax,_pnp_code_segment
|
||||
/* Store bios data segment */
|
||||
movw 0x1B(%esi),%ax
|
||||
movw %ax,_pnp_bios_data_segment
|
||||
|
||||
add $0x0C,%si
|
||||
movw %es:(%si),%ax
|
||||
movw %ax,_pnp_data_segment
|
||||
|
||||
/* copy data to buffer */
|
||||
push %ds
|
||||
movw %es, %ax
|
||||
movw %ax, %ds
|
||||
movl _pnp_support_result, %esi
|
||||
movw _pnp_buffer_segment, %es
|
||||
movw _pnp_buffer_offset, %di
|
||||
movw $0x21, %cx
|
||||
rep movsb
|
||||
|
||||
pop %ds
|
||||
pnp_not_found:
|
||||
movl %edi,%eax
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
pop %es
|
||||
popal
|
||||
|
||||
movl _pnp_support_result,%eax
|
||||
popl %esi
|
||||
popl %edi
|
||||
|
||||
ret
|
||||
|
||||
|
@ -130,7 +85,7 @@ pnp_not_found:
|
|||
*
|
||||
* RETURNS:
|
||||
*/
|
||||
_entry_point:
|
||||
_pnp_result:
|
||||
.long 0
|
||||
_pnp_node_size:
|
||||
.word 0
|
||||
|
@ -147,10 +102,9 @@ EXTERN(_PnpBiosGetDeviceNodeCount)
|
|||
push %es
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
movw _pnp_data_segment,%ax
|
||||
movw _pnp_bios_data_segment,%ax
|
||||
pushw %ax
|
||||
|
||||
pushw %cs
|
||||
|
@ -163,23 +117,14 @@ EXTERN(_PnpBiosGetDeviceNodeCount)
|
|||
|
||||
pushw $0
|
||||
|
||||
movw _pnp_code_segment,%ax
|
||||
movzwl %ax,%ecx
|
||||
shll $16,%ecx
|
||||
movw _pnp_entry_point,%ax
|
||||
movzwl %ax,%ebx
|
||||
orl %ebx,%ecx
|
||||
movl %ecx,_entry_point
|
||||
|
||||
lcall *_entry_point
|
||||
lcall *_pnp_bios_entry_point
|
||||
addw $12,%sp
|
||||
|
||||
movzwl %ax,%ecx
|
||||
movl %ecx,_pnp_support_result
|
||||
movl %ecx,_pnp_result
|
||||
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
movl 0x08(%ebp),%esi
|
||||
|
@ -198,7 +143,7 @@ EXTERN(_PnpBiosGetDeviceNodeCount)
|
|||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
|
||||
movl _pnp_support_result,%eax
|
||||
movl _pnp_result,%eax
|
||||
|
||||
ret
|
||||
|
||||
|
@ -216,7 +161,6 @@ _pnp_buffer_offset:
|
|||
_pnp_node_number:
|
||||
.byte 0
|
||||
|
||||
|
||||
EXTERN(_PnpBiosGetDeviceNode)
|
||||
.code32
|
||||
|
||||
|
@ -241,11 +185,10 @@ EXTERN(_PnpBiosGetDeviceNode)
|
|||
movw %ax,_pnp_buffer_offset
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* push bios segment */
|
||||
movw _pnp_data_segment,%ax
|
||||
movw _pnp_bios_data_segment,%ax
|
||||
pushw %ax
|
||||
|
||||
/* push control flag */
|
||||
|
@ -266,31 +209,27 @@ EXTERN(_PnpBiosGetDeviceNode)
|
|||
pushw $1
|
||||
|
||||
/* call entry point */
|
||||
lcall *_entry_point
|
||||
lcall *_pnp_bios_entry_point
|
||||
addw $14,%sp
|
||||
|
||||
movzwl %ax,%ecx
|
||||
movl %ecx,_pnp_support_result
|
||||
|
||||
movl %ecx,_pnp_result
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
|
||||
/* update node number */
|
||||
movl 0x08(%ebp),%esi
|
||||
movb _pnp_node_number,%al
|
||||
movb %al,(%esi)
|
||||
|
||||
|
||||
pop %es
|
||||
popal
|
||||
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
|
||||
movl _pnp_support_result,%eax
|
||||
movl _pnp_result,%eax
|
||||
|
||||
ret
|
||||
|
||||
|
|
Loading…
Reference in a new issue