Reworked and fixed most of the CPU and PnP code.

svn path=/trunk/; revision=4658
This commit is contained in:
Eric Kohl 2003-05-08 18:35:46 +00:00
parent 77d0973eaa
commit d882e9a38b
6 changed files with 648 additions and 785 deletions

View file

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

View file

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

View file

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

View 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 */

View file

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

View file

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