mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
- Remove CPU Detection code from FreeLDR (hwcpu.c) since our kernel properly does the same job now (and better).
- Remove ReactOS hacks from recent code due to FreeLDR, since it doesn't conflict with us anymore. svn path=/trunk/; revision=26684
This commit is contained in:
parent
3fcfcbce89
commit
0efeac48a8
5 changed files with 3 additions and 774 deletions
|
@ -2284,11 +2284,6 @@ PcHwDetect(VOID)
|
|||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
DetectSystemData();
|
||||
#endif
|
||||
DetectCPUs(SystemKey);
|
||||
|
||||
/* Detect buses */
|
||||
DetectPciBios(SystemKey, &BusNumber);
|
||||
DetectApmBios(SystemKey, &BusNumber);
|
||||
|
|
|
@ -1,763 +0,0 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
*
|
||||
* Copyright (C) 2003 Eric Kohl
|
||||
* Copyright (C) 2006 Colin Finck <mail@colinfinck.de>
|
||||
*
|
||||
* 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>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define HZ (100)
|
||||
#define CLOCK_TICK_RATE (1193182)
|
||||
#define LATCH (CLOCK_TICK_RATE / HZ)
|
||||
#define CALIBRATE_LATCH (5 * LATCH)
|
||||
#define CALIBRATE_TIME (5 * 1000020/HZ)
|
||||
|
||||
#define MP_FP_SIGNATURE 0x5F504D5F /* "_MP_" */
|
||||
#define MP_CT_SIGNATURE 0x504D4350 /* "PCMP" */
|
||||
|
||||
|
||||
typedef struct _MP_FLOATING_POINT_TABLE
|
||||
{
|
||||
ULONG Signature; /* "_MP_" */
|
||||
ULONG PhysicalAddressPointer;
|
||||
UCHAR Length;
|
||||
UCHAR SpecRev;
|
||||
UCHAR Checksum;
|
||||
UCHAR FeatureByte[5];
|
||||
} PACKED MP_FLOATING_POINT_TABLE, *PMP_FLOATING_POINT_TABLE;
|
||||
|
||||
|
||||
typedef struct _MPS_CONFIG_TABLE_HEADER
|
||||
{
|
||||
ULONG Signature; /* "PCMP" */
|
||||
USHORT BaseTableLength;
|
||||
UCHAR SpecRev;
|
||||
UCHAR Checksum;
|
||||
UCHAR OemIdString[8];
|
||||
UCHAR ProductIdString[12];
|
||||
ULONG OemTablePointer;
|
||||
USHORT OemTableLength;
|
||||
USHORT EntryCount;
|
||||
ULONG AddressOfLocalAPIC;
|
||||
USHORT ExtendedTableLength;
|
||||
UCHAR ExtendedTableChecksum;
|
||||
UCHAR Reserved;
|
||||
} PACKED MP_CONFIGURATION_TABLE, *PMP_CONFIGURATION_TABLE;
|
||||
|
||||
|
||||
typedef struct _MP_PROCESSOR_ENTRY
|
||||
{
|
||||
UCHAR EntryType;
|
||||
UCHAR LocalApicId;
|
||||
UCHAR LocalApicVersion;
|
||||
UCHAR CpuFlags;
|
||||
ULONG CpuSignature;
|
||||
ULONG FeatureFlags;
|
||||
ULONG Reserved1;
|
||||
ULONG Reserved2;
|
||||
} PACKED MP_PROCESSOR_ENTRY, *PMP_PROCESSOR_ENTRY;
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static ULONG
|
||||
GetCpuSpeed(BOOLEAN DualCoreSpeedMesure)
|
||||
{
|
||||
ULONGLONG Timestamp1;
|
||||
ULONGLONG Timestamp2;
|
||||
ULONGLONG Diff;
|
||||
ULONG Count = 0;
|
||||
|
||||
/*
|
||||
FIXME
|
||||
if the DualCoreSpeedMesure is true we need
|
||||
use the wrmsr and rdmsr to mesure the speed
|
||||
|
||||
The rdtc are outdate to use if cpu support
|
||||
the wrmsr and rdmsr, see intel doc AP-485
|
||||
for more informations and how to use it.
|
||||
|
||||
Follow code is good on cpu that does not
|
||||
support dual core or have a mmx unit or
|
||||
more.
|
||||
*/
|
||||
|
||||
|
||||
/* Initialise timer channel 2 */
|
||||
/* Set the Gate high, disable speaker */
|
||||
WRITE_PORT_UCHAR((PUCHAR)0x61, (READ_PORT_UCHAR((PUCHAR)0x61) & ~0x02) | 0x01);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0x43, 0xB0); /* binary, mode 0, LSB/MSB, ch 2 */
|
||||
WRITE_PORT_UCHAR((PUCHAR)0x42, CALIBRATE_LATCH & 0xff); /* LSB */
|
||||
WRITE_PORT_UCHAR((PUCHAR)0x42, CALIBRATE_LATCH >> 8); /* MSB */
|
||||
|
||||
/* Read TSC (Time Stamp Counter) */
|
||||
Timestamp1 = RDTSC();
|
||||
|
||||
/* Wait */
|
||||
do
|
||||
{
|
||||
Count++;
|
||||
}
|
||||
while ((READ_PORT_UCHAR((PUCHAR)0x61) & 0x20) == 0);
|
||||
|
||||
/* Read TSC (Time Stamp Counter) again */
|
||||
Timestamp2 = RDTSC();
|
||||
|
||||
/* Calculate elapsed time (check for counter overrun) */
|
||||
if (Timestamp2 > Timestamp1)
|
||||
{
|
||||
Diff = Timestamp2 - Timestamp1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Diff = Timestamp2 + (((ULONGLONG)-1) - Timestamp1);
|
||||
}
|
||||
|
||||
return (ULONG)(Diff / CALIBRATE_TIME);
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
DetectCPU(FRLDRHKEY CpuKey,
|
||||
FRLDRHKEY FpuKey)
|
||||
{
|
||||
WCHAR VendorIdentifier[13];
|
||||
WCHAR ProcessorNameString[49];
|
||||
CHAR tmpVendorIdentifier[13];
|
||||
CHAR tmpProcessorNameString[49];
|
||||
WCHAR Identifier[64];
|
||||
ULONG FeatureSet;
|
||||
FRLDRHKEY CpuInstKey;
|
||||
FRLDRHKEY FpuInstKey;
|
||||
ULONG eax = 0;
|
||||
ULONG ebx = 0;
|
||||
ULONG ecx = 0;
|
||||
ULONG edx = 0;
|
||||
ULONG i;
|
||||
ULONG *Ptr;
|
||||
LONG Error;
|
||||
BOOLEAN SupportTSC = FALSE;
|
||||
ULONG CpuSpeed;
|
||||
BOOLEAN DualCoreSpeedMesure = FALSE;
|
||||
|
||||
/* Create the CPU instance key */
|
||||
Error = RegCreateKey(CpuKey,
|
||||
L"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,
|
||||
L"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);
|
||||
tmpVendorIdentifier[12] = 0;
|
||||
Ptr = (ULONG*)&tmpVendorIdentifier[0];
|
||||
*Ptr = ebx;
|
||||
Ptr++;
|
||||
*Ptr = edx;
|
||||
Ptr++;
|
||||
*Ptr = ecx;
|
||||
swprintf(VendorIdentifier, L"%S", tmpVendorIdentifier);
|
||||
|
||||
/* Get Identifier */
|
||||
GetCpuid(1, &eax, &ebx, &ecx, &edx);
|
||||
swprintf(Identifier,
|
||||
L"x86 Family %u Model %u Stepping %u",
|
||||
(unsigned int)((eax >> 8) & 0x0F),
|
||||
(unsigned int)((eax >> 4) & 0x0F),
|
||||
(unsigned int)(eax & 0x0F));
|
||||
FeatureSet = edx;
|
||||
|
||||
if ((FeatureSet & 0x10) == 0x10)
|
||||
SupportTSC = TRUE;
|
||||
|
||||
if ((FeatureSet & 0x20) == 0x20)
|
||||
DualCoreSpeedMesure = TRUE;
|
||||
|
||||
/* Check if Extended CPUID information is supported */
|
||||
GetCpuid(0x80000000, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
if(eax >= 0x80000004)
|
||||
{
|
||||
/* Get Processor Name String */
|
||||
tmpProcessorNameString[48] = 0;
|
||||
Ptr = (ULONG*)&tmpProcessorNameString[0];
|
||||
|
||||
for (i = 0x80000002; i <= 0x80000004; i++)
|
||||
{
|
||||
GetCpuid(i, &eax, &ebx, &ecx, &edx);
|
||||
*Ptr = eax;
|
||||
Ptr++;
|
||||
*Ptr = ebx;
|
||||
Ptr++;
|
||||
*Ptr = ecx;
|
||||
Ptr++;
|
||||
*Ptr = edx;
|
||||
Ptr++;
|
||||
}
|
||||
|
||||
swprintf(ProcessorNameString, L"%S", tmpProcessorNameString);
|
||||
|
||||
|
||||
/* Set 'ProcessorNameString' value (CPU only) */
|
||||
DbgPrint((DPRINT_HWDETECT, "Processor Name String: %S\n", ProcessorNameString));
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
L"ProcessorNameString",
|
||||
REG_SZ,
|
||||
(PCHAR)ProcessorNameString,
|
||||
(wcslen(ProcessorNameString) + 1) * sizeof(WCHAR));
|
||||
|
||||
if (Error != ERROR_SUCCESS)
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "CPUID not supported\n"));
|
||||
|
||||
wcscpy(VendorIdentifier, L"Unknown");
|
||||
swprintf(Identifier,
|
||||
L"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,
|
||||
L"FeatureSet",
|
||||
REG_DWORD,
|
||||
(PCHAR)&FeatureSet,
|
||||
sizeof(ULONG));
|
||||
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,
|
||||
L"Identifier",
|
||||
REG_SZ,
|
||||
(PCHAR)Identifier,
|
||||
(wcslen(Identifier) + 1) * sizeof(WCHAR));
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
Error = RegSetValue(FpuInstKey,
|
||||
L"Identifier",
|
||||
REG_SZ,
|
||||
(PCHAR)Identifier,
|
||||
(wcslen(Identifier) + 1) * sizeof(WCHAR));
|
||||
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,
|
||||
L"VendorIdentifier",
|
||||
REG_SZ,
|
||||
(PCHAR)VendorIdentifier,
|
||||
(wcslen(VendorIdentifier) + 1) * sizeof(WCHAR));
|
||||
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) */
|
||||
|
||||
/* Set '~MHz' value (CPU only) */
|
||||
if (SupportTSC)
|
||||
{
|
||||
CpuSpeed = GetCpuSpeed(DualCoreSpeedMesure);
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
L"~MHz",
|
||||
REG_DWORD,
|
||||
(PCHAR)&CpuSpeed,
|
||||
sizeof(ULONG));
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
SetMpsProcessor(FRLDRHKEY CpuKey,
|
||||
FRLDRHKEY FpuKey,
|
||||
PMP_PROCESSOR_ENTRY CpuEntry)
|
||||
{
|
||||
WCHAR ProcessorNameString[49];
|
||||
WCHAR VendorIdentifier[13];
|
||||
CHAR tmpProcessorNameString[49];
|
||||
CHAR tmpVendorIdentifier[13];
|
||||
WCHAR Identifier[64];
|
||||
WCHAR Buffer[8];
|
||||
ULONG FeatureSet;
|
||||
FRLDRHKEY CpuInstKey;
|
||||
FRLDRHKEY FpuInstKey;
|
||||
ULONG eax = 0;
|
||||
ULONG ebx = 0;
|
||||
ULONG ecx = 0;
|
||||
ULONG edx = 0;
|
||||
ULONG i;
|
||||
ULONG *Ptr;
|
||||
LONG Error;
|
||||
ULONG CpuSpeed;
|
||||
|
||||
/* Get processor instance number */
|
||||
swprintf(Buffer, L"%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);
|
||||
tmpVendorIdentifier[12] = 0;
|
||||
Ptr = (ULONG*)&tmpVendorIdentifier[0];
|
||||
*Ptr = ebx;
|
||||
Ptr++;
|
||||
*Ptr = edx;
|
||||
Ptr++;
|
||||
*Ptr = ecx;
|
||||
swprintf(VendorIdentifier, L"%S", tmpVendorIdentifier);
|
||||
|
||||
/* Get 'Identifier' */
|
||||
swprintf(Identifier,
|
||||
L"x86 Family %u Model %u Stepping %u",
|
||||
(ULONG)((CpuEntry->CpuSignature >> 8) & 0x0F),
|
||||
(ULONG)((CpuEntry->CpuSignature >> 4) & 0x0F),
|
||||
(ULONG)(CpuEntry->CpuSignature & 0x0F));
|
||||
|
||||
/* Get FeatureSet */
|
||||
FeatureSet = CpuEntry->FeatureFlags;
|
||||
|
||||
/* Check if Extended CPUID information is supported */
|
||||
GetCpuid(0x80000000, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
if(eax >= 0x80000004)
|
||||
{
|
||||
/* Get 'ProcessorNameString' */
|
||||
tmpProcessorNameString[48] = 0;
|
||||
Ptr = (ULONG*)&tmpProcessorNameString[0];
|
||||
|
||||
for (i = 0x80000002; i <= 0x80000004; i++)
|
||||
{
|
||||
GetCpuid(i, &eax, &ebx, &ecx, &edx);
|
||||
*Ptr = eax;
|
||||
Ptr++;
|
||||
*Ptr = ebx;
|
||||
Ptr++;
|
||||
*Ptr = ecx;
|
||||
Ptr++;
|
||||
*Ptr = edx;
|
||||
Ptr++;
|
||||
}
|
||||
|
||||
swprintf(ProcessorNameString, L"%S", tmpProcessorNameString);
|
||||
|
||||
|
||||
/* Set 'ProcessorNameString' value (CPU only) */
|
||||
DbgPrint((DPRINT_HWDETECT, "Processor Name String: %S\n", ProcessorNameString));
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
L"ProcessorNameString",
|
||||
REG_SZ,
|
||||
(PCHAR)ProcessorNameString,
|
||||
(wcslen(ProcessorNameString) + 1) * sizeof(WCHAR));
|
||||
if (Error != ERROR_SUCCESS)
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
/* 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,
|
||||
L"FeatureSet",
|
||||
REG_DWORD,
|
||||
(PCHAR)&FeatureSet,
|
||||
sizeof(ULONG));
|
||||
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,
|
||||
L"Identifier",
|
||||
REG_SZ,
|
||||
(PCHAR)Identifier,
|
||||
(wcslen(Identifier) + 1) * sizeof(WCHAR));
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
|
||||
Error = RegSetValue(FpuInstKey,
|
||||
L"Identifier",
|
||||
REG_SZ,
|
||||
(PCHAR)Identifier,
|
||||
(wcslen(Identifier) + 1) * sizeof(WCHAR));
|
||||
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,
|
||||
L"VendorIdentifier",
|
||||
REG_SZ,
|
||||
(PCHAR)VendorIdentifier,
|
||||
(wcslen(VendorIdentifier) + 1) * sizeof(WCHAR));
|
||||
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) */
|
||||
|
||||
/* Set '~MHz' value (CPU only) */
|
||||
|
||||
|
||||
if ((CpuEntry->FeatureFlags & 0x10) == 0x10)
|
||||
{
|
||||
if ((CpuEntry->FeatureFlags & 0x20) == 0x20)
|
||||
{
|
||||
CpuSpeed = GetCpuSpeed(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "Does not support MSR that are need for mesure the speed correct\n", (int)Error));
|
||||
CpuSpeed = GetCpuSpeed(FALSE);
|
||||
}
|
||||
|
||||
Error = RegSetValue(CpuInstKey,
|
||||
L"~MHz",
|
||||
REG_DWORD,
|
||||
(PCHAR)&CpuSpeed,
|
||||
sizeof(ULONG));
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
|
||||
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static PMP_FLOATING_POINT_TABLE
|
||||
GetMpFloatingPointTable(VOID)
|
||||
{
|
||||
PMP_FLOATING_POINT_TABLE FpTable;
|
||||
char *Ptr;
|
||||
UCHAR Sum;
|
||||
ULONG Length;
|
||||
ULONG i;
|
||||
|
||||
FpTable = (PMP_FLOATING_POINT_TABLE)0xF0000;
|
||||
while ((ULONG)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)((ULONG)FpTable + 0x10);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static PMP_CONFIGURATION_TABLE
|
||||
GetMpConfigurationTable(PMP_FLOATING_POINT_TABLE FpTable)
|
||||
{
|
||||
PMP_CONFIGURATION_TABLE ConfigTable;
|
||||
char *Ptr;
|
||||
UCHAR Sum;
|
||||
ULONG Length;
|
||||
ULONG 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",
|
||||
(ULONG)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 BOOLEAN
|
||||
DetectMps(FRLDRHKEY CpuKey,
|
||||
FRLDRHKEY FpuKey)
|
||||
{
|
||||
PMP_FLOATING_POINT_TABLE FpTable;
|
||||
PMP_CONFIGURATION_TABLE ConfigTable;
|
||||
PMP_PROCESSOR_ENTRY CpuEntry;
|
||||
char *Ptr;
|
||||
ULONG Offset;
|
||||
|
||||
/* Get floating point table */
|
||||
FpTable = GetMpFloatingPointTable();
|
||||
if (FpTable == NULL)
|
||||
return FALSE;
|
||||
|
||||
DbgPrint((DPRINT_HWDETECT,
|
||||
"MP Floating Point Table at: %x\n",
|
||||
(ULONG)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*)((ULONG)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,
|
||||
(ULONG)((CpuEntry->CpuSignature >> 8) & 0x0F),
|
||||
(ULONG)((CpuEntry->CpuSignature >> 4) & 0x0F),
|
||||
(ULONG)(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",(ULONG)*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(FRLDRHKEY SystemKey)
|
||||
{
|
||||
FRLDRHKEY CpuKey;
|
||||
FRLDRHKEY FpuKey;
|
||||
LONG Error;
|
||||
|
||||
/* Create the 'CentralProcessor' key */
|
||||
Error = RegCreateKey(SystemKey,
|
||||
L"CentralProcessor",
|
||||
&CpuKey);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create the 'FloatingPointProcessor' key */
|
||||
Error = RegCreateKey(SystemKey,
|
||||
L"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 */
|
|
@ -17,7 +17,6 @@
|
|||
<file>hardware.c</file>
|
||||
<file>hwacpi.c</file>
|
||||
<file>hwapm.c</file>
|
||||
<file>hwcpu.c</file>
|
||||
<file>hwpci.c</file>
|
||||
<file>i386disk.c</file>
|
||||
<file>i386rtl.c</file>
|
||||
|
|
|
@ -87,9 +87,7 @@ CmpInitializeRegistryNode(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
|
|||
|
||||
/* Fail if the key couldn't be created, and make sure it's a new key */
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* These keys should -not- exist, but FreeLDR creates them :( */
|
||||
//ASSERT(Disposition == REG_CREATED_NEW_KEY);
|
||||
ASSERT(Disposition == REG_CREATED_NEW_KEY);
|
||||
}
|
||||
|
||||
/* Sstup the compnent information key */
|
||||
|
|
|
@ -215,8 +215,8 @@ CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBloc
|
|||
&Disposition);
|
||||
NtClose(KeyHandle);
|
||||
|
||||
/* This key -never- exists on x86 machines, except in ReactOS! */
|
||||
//if (Disposition == REG_CREATED_NEW_KEY)
|
||||
/* The key shouldn't already exist */
|
||||
if (Disposition == REG_CREATED_NEW_KEY)
|
||||
{
|
||||
/* Allocate the configuration data for cmconfig.c */
|
||||
CmpConfigurationData = ExAllocatePoolWithTag(PagedPool,
|
||||
|
|
Loading…
Reference in a new issue