mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +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 \
|
i386disk.o \
|
||||||
portio.o \
|
portio.o \
|
||||||
hardware.o \
|
hardware.o \
|
||||||
|
hwcpu.o \
|
||||||
_alloca.o # For Mingw32 builds
|
_alloca.o # For Mingw32 builds
|
||||||
|
|
||||||
|
|
||||||
RTL_OBJS = print.o \
|
RTL_OBJS = print.o \
|
||||||
stdlib.o \
|
stdlib.o \
|
||||||
string.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;
|
} __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 char Hex[] = "0123456789ABCDEF";
|
||||||
static unsigned int delay_count = 1;
|
static unsigned int delay_count = 1;
|
||||||
|
@ -265,6 +235,7 @@ DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
|
||||||
{
|
{
|
||||||
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
|
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
|
||||||
PCM_PNP_BIOS_DEVICE_NODE DeviceNode;
|
PCM_PNP_BIOS_DEVICE_NODE DeviceNode;
|
||||||
|
PCM_PNP_BIOS_INSTALLATION_CHECK InstData;
|
||||||
char Buffer[80];
|
char Buffer[80];
|
||||||
HKEY BusKey;
|
HKEY BusKey;
|
||||||
U32 x;
|
U32 x;
|
||||||
|
@ -278,43 +249,26 @@ DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
|
||||||
char *Ptr;
|
char *Ptr;
|
||||||
S32 Error;
|
S32 Error;
|
||||||
|
|
||||||
x = PnpBiosSupported((PVOID)DISKREADBUFFER);
|
InstData = (PCM_PNP_BIOS_INSTALLATION_CHECK)PnpBiosSupported();
|
||||||
if (!x)
|
if (InstData == NULL || strncmp(InstData->Signature, "$PnP", 4))
|
||||||
{
|
{
|
||||||
printf(" PnP-BIOS not supported\n");
|
DbgPrint((DPRINT_HWDETECT, "PnP-BIOS not supported\n"));
|
||||||
return;
|
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);
|
x = PnpBiosGetDeviceNodeCount(&NodeSize, &NodeCount);
|
||||||
if (x != 0 || NodeSize == 0 || NodeCount == 0)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
DbgPrint((DPRINT_HWDETECT,
|
DbgPrint((DPRINT_HWDETECT, "PnP-BIOS supported\n"));
|
||||||
"PnP-BIOS supported: found %u device nodes\n",
|
DbgPrint((DPRINT_HWDETECT, "MaxNodeSize %u NodeCount %u\n", NodeSize, NodeCount));
|
||||||
(unsigned int)NodeCount));
|
DbgPrint((DPRINT_HWDETECT, "Estimated buffer size %u\n", NodeSize * 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));
|
|
||||||
|
|
||||||
/* Create new bus key */
|
/* Create new bus key */
|
||||||
sprintf(Buffer,
|
sprintf(Buffer,
|
||||||
|
@ -344,7 +298,7 @@ DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set 'Configuration Data' value */
|
/* Set 'Configuration Data' value */
|
||||||
Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + PnpBufferSize;
|
Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + (NodeSize * NodeCount);
|
||||||
FullResourceDescriptor = MmAllocateMemory(Size);
|
FullResourceDescriptor = MmAllocateMemory(Size);
|
||||||
if (FullResourceDescriptor == NULL)
|
if (FullResourceDescriptor == NULL)
|
||||||
{
|
{
|
||||||
|
@ -352,9 +306,9 @@ DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
|
||||||
"Failed to allocate resource descriptor\n"));
|
"Failed to allocate resource descriptor\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
memset(FullResourceDescriptor, 0, Size);
|
||||||
|
|
||||||
/* Initialize resource descriptor */
|
/* Initialize resource descriptor */
|
||||||
memset(FullResourceDescriptor, 0, Size);
|
|
||||||
FullResourceDescriptor->InterfaceType = Internal;
|
FullResourceDescriptor->InterfaceType = Internal;
|
||||||
FullResourceDescriptor->BusNumber = 0;
|
FullResourceDescriptor->BusNumber = 0;
|
||||||
FullResourceDescriptor->PartialResourceList.Count = 1;
|
FullResourceDescriptor->PartialResourceList.Count = 1;
|
||||||
|
@ -363,19 +317,18 @@ DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
|
||||||
FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
|
FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
|
||||||
CmResourceShareUndetermined;
|
CmResourceShareUndetermined;
|
||||||
// FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
|
// 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 */
|
/* Set instalation check data */
|
||||||
PnpBiosSupported((PVOID)DISKREADBUFFER);
|
memcpy (Ptr, InstData, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
|
||||||
memcpy (Ptr, (PVOID)DISKREADBUFFER, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
|
Ptr += sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
|
||||||
|
|
||||||
Ptr = (char *)((PVOID)Ptr + sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
|
|
||||||
|
|
||||||
/* Copy device nodes */
|
/* 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;
|
NodeNumber = (U8)i;
|
||||||
|
|
||||||
|
@ -384,10 +337,18 @@ DetectPnpBios(HKEY SystemKey, U32 *BusNumber)
|
||||||
{
|
{
|
||||||
DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DISKREADBUFFER;
|
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,
|
memcpy (Ptr,
|
||||||
DeviceNode,
|
DeviceNode,
|
||||||
DeviceNode->Size);
|
DeviceNode->Size);
|
||||||
Ptr = (char *)((U32)Ptr + DeviceNode->Size);
|
|
||||||
|
Ptr += DeviceNode->Size;
|
||||||
|
PnpBufferSize += DeviceNode->Size;
|
||||||
|
|
||||||
FoundNodeCount++;
|
FoundNodeCount++;
|
||||||
if (FoundNodeCount >= NodeCount)
|
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 */
|
/* Set 'Configuration Data' value */
|
||||||
Error = RegSetValue(BusKey,
|
Error = RegSetValue(BusKey,
|
||||||
"Configuration Data",
|
"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
|
static VOID
|
||||||
SetHarddiskConfigurationData(HKEY DiskKey,
|
SetHarddiskConfigurationData(HKEY DiskKey,
|
||||||
|
|
|
@ -150,6 +150,7 @@ VOID SetComponentInformation(HKEY ComponentKey,
|
||||||
U32 Affinity);
|
U32 Affinity);
|
||||||
|
|
||||||
/* hwcpu.c */
|
/* hwcpu.c */
|
||||||
|
VOID DetectCPUs(HKEY SystemKey);
|
||||||
|
|
||||||
/* i386cpu.S */
|
/* i386cpu.S */
|
||||||
U32 CpuidSupported(VOID);
|
U32 CpuidSupported(VOID);
|
||||||
|
@ -159,13 +160,8 @@ VOID GetCpuid(U32 Level,
|
||||||
U32 *ecx,
|
U32 *ecx,
|
||||||
U32 *edx);
|
U32 *edx);
|
||||||
|
|
||||||
U32 MpsSupported(VOID);
|
|
||||||
U32 MpsGetDefaultConfiguration(VOID);
|
|
||||||
U32 MpsGetConfigurationTable(PVOID ConfigTable);
|
|
||||||
|
|
||||||
/* i386pnp.S */
|
/* i386pnp.S */
|
||||||
//U32 PnpBiosSupported(VOID);
|
U32 PnpBiosSupported(VOID);
|
||||||
U32 PnpBiosSupported(PVOID InstallationCheck);
|
|
||||||
U32 PnpBiosGetDeviceNodeCount(U32 *NodeSize,
|
U32 PnpBiosGetDeviceNodeCount(U32 *NodeSize,
|
||||||
U32 *NodeCount);
|
U32 *NodeCount);
|
||||||
U32 PnpBiosGetDeviceNode(U8 *NodeId,
|
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
|
pushl %esi
|
||||||
|
|
||||||
movl 0x08(%ebp),%eax
|
movl 0x08(%ebp),%eax
|
||||||
|
|
||||||
cpuid
|
cpuid
|
||||||
|
|
||||||
movl 0x0C(%ebp),%esi
|
movl 0x0C(%ebp),%esi
|
||||||
|
@ -117,227 +118,4 @@ EXTERN(_GetCpuid)
|
||||||
popl %ebp
|
popl %ebp
|
||||||
ret
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -26,101 +26,56 @@
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* U32 PnpBiosSupported(PVOID InstallationCheck);
|
* U32 PnpBiosSupported(VOID);
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
*/
|
*/
|
||||||
_pnp_support_result:
|
_pnp_bios_entry_point:
|
||||||
.long 0
|
.long 0
|
||||||
_pnp_entry_point:
|
_pnp_bios_data_segment:
|
||||||
.word 0
|
|
||||||
_pnp_code_segment:
|
|
||||||
.word 0
|
|
||||||
_pnp_data_segment:
|
|
||||||
.word 0
|
.word 0
|
||||||
|
|
||||||
EXTERN(_PnpBiosSupported)
|
EXTERN(_PnpBiosSupported)
|
||||||
.code32
|
.code32
|
||||||
|
|
||||||
pushal
|
pushl %edi
|
||||||
push %es
|
pushl %esi
|
||||||
|
|
||||||
/* convert pointer to node buffer to segment/offset */
|
xorl %edi,%edi
|
||||||
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
|
|
||||||
|
|
||||||
call switch_to_real
|
/* init esi */
|
||||||
|
movl $0xFFFF0,%esi
|
||||||
.code16
|
|
||||||
|
|
||||||
/* init ES */
|
|
||||||
pushw $0xF000
|
|
||||||
popw %es
|
|
||||||
|
|
||||||
/* init cx */
|
|
||||||
movw $0xFFF0,%si
|
|
||||||
|
|
||||||
pnp_again:
|
pnp_again:
|
||||||
movw %es:(%si),%ax
|
movl (%esi),%eax
|
||||||
cmp $0x5024,%ax /* "$P" */
|
cmp $0x506E5024,%eax /* "$PnP" */
|
||||||
jne pnp_next
|
|
||||||
|
|
||||||
push %si
|
|
||||||
add $2,%si
|
|
||||||
movw %es:(%si),%ax
|
|
||||||
cmp $0x506E,%ax /* "nP" */
|
|
||||||
pop %si
|
|
||||||
je pnp_found
|
je pnp_found
|
||||||
|
|
||||||
pnp_next:
|
cmp $0xF0000,%esi
|
||||||
cmp $0,%si
|
|
||||||
je pnp_not_found
|
je pnp_not_found
|
||||||
|
|
||||||
sub $0x10,%si
|
subl $0x10,%esi
|
||||||
jmp pnp_again
|
jmp pnp_again
|
||||||
|
|
||||||
pnp_found:
|
pnp_found:
|
||||||
movzwl %si,%eax
|
movl %esi,%edi
|
||||||
movl %eax,_pnp_support_result
|
|
||||||
|
|
||||||
add $0x0D,%si
|
/* Calculate the bios entry point (far pointer) */
|
||||||
movw %es:(%si),%ax
|
xorl %eax,%eax
|
||||||
movw %ax,_pnp_entry_point
|
movw 0x0F(%esi),%ax
|
||||||
|
shll $16,%eax
|
||||||
|
movw 0x0D(%esi),%ax
|
||||||
|
movl %eax,_pnp_bios_entry_point
|
||||||
|
|
||||||
add $0x02,%si
|
/* Store bios data segment */
|
||||||
movw %es:(%si),%ax
|
movw 0x1B(%esi),%ax
|
||||||
movw %ax,_pnp_code_segment
|
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:
|
pnp_not_found:
|
||||||
|
movl %edi,%eax
|
||||||
|
|
||||||
call switch_to_prot
|
popl %esi
|
||||||
|
popl %edi
|
||||||
.code32
|
|
||||||
|
|
||||||
pop %es
|
|
||||||
popal
|
|
||||||
|
|
||||||
movl _pnp_support_result,%eax
|
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -130,7 +85,7 @@ pnp_not_found:
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
*/
|
*/
|
||||||
_entry_point:
|
_pnp_result:
|
||||||
.long 0
|
.long 0
|
||||||
_pnp_node_size:
|
_pnp_node_size:
|
||||||
.word 0
|
.word 0
|
||||||
|
@ -147,10 +102,9 @@ EXTERN(_PnpBiosGetDeviceNodeCount)
|
||||||
push %es
|
push %es
|
||||||
|
|
||||||
call switch_to_real
|
call switch_to_real
|
||||||
|
|
||||||
.code16
|
.code16
|
||||||
|
|
||||||
movw _pnp_data_segment,%ax
|
movw _pnp_bios_data_segment,%ax
|
||||||
pushw %ax
|
pushw %ax
|
||||||
|
|
||||||
pushw %cs
|
pushw %cs
|
||||||
|
@ -163,23 +117,14 @@ EXTERN(_PnpBiosGetDeviceNodeCount)
|
||||||
|
|
||||||
pushw $0
|
pushw $0
|
||||||
|
|
||||||
movw _pnp_code_segment,%ax
|
lcall *_pnp_bios_entry_point
|
||||||
movzwl %ax,%ecx
|
|
||||||
shll $16,%ecx
|
|
||||||
movw _pnp_entry_point,%ax
|
|
||||||
movzwl %ax,%ebx
|
|
||||||
orl %ebx,%ecx
|
|
||||||
movl %ecx,_entry_point
|
|
||||||
|
|
||||||
lcall *_entry_point
|
|
||||||
addw $12,%sp
|
addw $12,%sp
|
||||||
|
|
||||||
movzwl %ax,%ecx
|
movzwl %ax,%ecx
|
||||||
movl %ecx,_pnp_support_result
|
movl %ecx,_pnp_result
|
||||||
|
|
||||||
|
|
||||||
call switch_to_prot
|
call switch_to_prot
|
||||||
|
|
||||||
.code32
|
.code32
|
||||||
|
|
||||||
movl 0x08(%ebp),%esi
|
movl 0x08(%ebp),%esi
|
||||||
|
@ -198,7 +143,7 @@ EXTERN(_PnpBiosGetDeviceNodeCount)
|
||||||
movl %ebp,%esp
|
movl %ebp,%esp
|
||||||
popl %ebp
|
popl %ebp
|
||||||
|
|
||||||
movl _pnp_support_result,%eax
|
movl _pnp_result,%eax
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -216,7 +161,6 @@ _pnp_buffer_offset:
|
||||||
_pnp_node_number:
|
_pnp_node_number:
|
||||||
.byte 0
|
.byte 0
|
||||||
|
|
||||||
|
|
||||||
EXTERN(_PnpBiosGetDeviceNode)
|
EXTERN(_PnpBiosGetDeviceNode)
|
||||||
.code32
|
.code32
|
||||||
|
|
||||||
|
@ -241,11 +185,10 @@ EXTERN(_PnpBiosGetDeviceNode)
|
||||||
movw %ax,_pnp_buffer_offset
|
movw %ax,_pnp_buffer_offset
|
||||||
|
|
||||||
call switch_to_real
|
call switch_to_real
|
||||||
|
|
||||||
.code16
|
.code16
|
||||||
|
|
||||||
/* push bios segment */
|
/* push bios segment */
|
||||||
movw _pnp_data_segment,%ax
|
movw _pnp_bios_data_segment,%ax
|
||||||
pushw %ax
|
pushw %ax
|
||||||
|
|
||||||
/* push control flag */
|
/* push control flag */
|
||||||
|
@ -266,31 +209,27 @@ EXTERN(_PnpBiosGetDeviceNode)
|
||||||
pushw $1
|
pushw $1
|
||||||
|
|
||||||
/* call entry point */
|
/* call entry point */
|
||||||
lcall *_entry_point
|
lcall *_pnp_bios_entry_point
|
||||||
addw $14,%sp
|
addw $14,%sp
|
||||||
|
|
||||||
movzwl %ax,%ecx
|
movzwl %ax,%ecx
|
||||||
movl %ecx,_pnp_support_result
|
movl %ecx,_pnp_result
|
||||||
|
|
||||||
|
|
||||||
call switch_to_prot
|
call switch_to_prot
|
||||||
|
|
||||||
.code32
|
.code32
|
||||||
|
|
||||||
|
|
||||||
/* update node number */
|
/* update node number */
|
||||||
movl 0x08(%ebp),%esi
|
movl 0x08(%ebp),%esi
|
||||||
movb _pnp_node_number,%al
|
movb _pnp_node_number,%al
|
||||||
movb %al,(%esi)
|
movb %al,(%esi)
|
||||||
|
|
||||||
|
|
||||||
pop %es
|
pop %es
|
||||||
popal
|
popal
|
||||||
|
|
||||||
movl %ebp,%esp
|
movl %ebp,%esp
|
||||||
popl %ebp
|
popl %ebp
|
||||||
|
|
||||||
movl _pnp_support_result,%eax
|
movl _pnp_result,%eax
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue