📄 mpconfig.c
字号:
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: hal/halx86/generic/mpconfig.c
* PURPOSE:
* PROGRAMMER:
*/
/* INCLUDES *****************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS ******************************************************************/
MP_FLOATING_POINTER* Mpf = NULL;
/* FUNCTIONS ****************************************************************/
static UCHAR
MPChecksum(PUCHAR Base,
ULONG Size)
/*
* Checksum an MP configuration block
*/
{
UCHAR Sum = 0;
while (Size--)
Sum += *Base++;
return Sum;
}
static VOID
HaliMPIntSrcInfo(PMP_CONFIGURATION_INTSRC m)
{
DPRINT("Int: type %d, pol %d, trig %d, bus %d,"
" IRQ %02x, APIC ID %x, APIC INT %02x\n",
m->IrqType, m->IrqFlag & 3,
(m->IrqFlag >> 2) & 3, m->SrcBusId,
m->SrcBusIrq, m->DstApicId, m->DstApicInt);
if (IRQCount > MAX_IRQ_SOURCE)
{
DPRINT1("Max # of irq sources exceeded!!\n");
KEBUGCHECK(0);
}
IRQMap[IRQCount] = *m;
IRQCount++;
}
PCHAR
HaliMPFamily(ULONG Family,
ULONG Model)
{
static CHAR str[64];
static PCHAR CPUs[] =
{
"80486DX", "80486DX",
"80486SX", "80486DX/2 or 80487",
"80486SL", "Intel5X2(tm)",
"Unknown", "Unknown",
"80486DX/4"
};
if (Family == 0x6)
return ("Pentium(tm) Pro");
if (Family == 0x5)
return ("Pentium(tm)");
if (Family == 0x0F && Model == 0x0F)
return("Special controller");
if (Family == 0x0F && Model == 0x00)
return("Pentium 4(tm)");
if (Family == 0x04 && Model < 9)
return CPUs[Model];
sprintf(str, "Unknown CPU with family ID %ld and model ID %ld", Family, Model);
return str;
}
static VOID
HaliMPProcessorInfo(PMP_CONFIGURATION_PROCESSOR m)
{
ULONG ver;
if (!(m->CpuFlags & CPU_FLAG_ENABLED))
return;
DPRINT("Processor #%d %s APIC version %d\n",
m->ApicId,
HaliMPFamily((m->FeatureFlags & CPU_FAMILY_MASK) >> 8,
(m->FeatureFlags & CPU_MODEL_MASK) >> 4),
m->ApicVersion);
if (m->FeatureFlags & (1 << 0))
DPRINT(" Floating point unit present.\n");
if (m->FeatureFlags & (1 << 7))
DPRINT(" Machine Exception supported.\n");
if (m->FeatureFlags & (1 << 8))
DPRINT(" 64 bit compare & exchange supported.\n");
if (m->FeatureFlags & (1 << 9))
DPRINT(" Internal APIC present.\n");
if (m->FeatureFlags & (1 << 11))
DPRINT(" SEP present.\n");
if (m->FeatureFlags & (1 << 12))
DPRINT(" MTRR present.\n");
if (m->FeatureFlags & (1 << 13))
DPRINT(" PGE present.\n");
if (m->FeatureFlags & (1 << 14))
DPRINT(" MCA present.\n");
if (m->FeatureFlags & (1 << 15))
DPRINT(" CMOV present.\n");
if (m->FeatureFlags & (1 << 16))
DPRINT(" PAT present.\n");
if (m->FeatureFlags & (1 << 17))
DPRINT(" PSE present.\n");
if (m->FeatureFlags & (1 << 18))
DPRINT(" PSN present.\n");
if (m->FeatureFlags & (1 << 19))
DPRINT(" Cache Line Flush Instruction present.\n");
/* 20 Reserved */
if (m->FeatureFlags & (1 << 21))
DPRINT(" Debug Trace and EMON Store present.\n");
if (m->FeatureFlags & (1 << 22))
DPRINT(" ACPI Thermal Throttle Registers present.\n");
if (m->FeatureFlags & (1 << 23))
DPRINT(" MMX present.\n");
if (m->FeatureFlags & (1 << 24))
DPRINT(" FXSR present.\n");
if (m->FeatureFlags & (1 << 25))
DPRINT(" XMM present.\n");
if (m->FeatureFlags & (1 << 26))
DPRINT(" Willamette New Instructions present.\n");
if (m->FeatureFlags & (1 << 27))
DPRINT(" Self Snoop present.\n");
/* 28 Reserved */
if (m->FeatureFlags & (1 << 29))
DPRINT(" Thermal Monitor present.\n");
/* 30, 31 Reserved */
CPUMap[CPUCount].APICId = m->ApicId;
CPUMap[CPUCount].Flags = CPU_USABLE;
if (m->CpuFlags & CPU_FLAG_BSP)
{
DPRINT(" Bootup CPU\n");
CPUMap[CPUCount].Flags |= CPU_BSP;
BootCPU = m->ApicId;
}
if (m->ApicId > MAX_CPU)
{
DPRINT("Processor #%d INVALID. (Max ID: %d).\n", m->ApicId, MAX_CPU);
return;
}
ver = m->ApicVersion;
/*
* Validate version
*/
if (ver == 0x0)
{
DPRINT("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->ApicId);
ver = 0x10;
}
// ApicVersion[m->ApicId] = Ver;
// BiosCpuApicId[CPUCount] = m->ApicId;
CPUMap[CPUCount].APICVersion = ver;
CPUCount++;
}
static VOID
HaliMPBusInfo(PMP_CONFIGURATION_BUS m)
{
static ULONG CurrentPCIBusId = 0;
DPRINT("Bus #%d is %.*s\n", m->BusId, 6, m->BusType);
if (strncmp(m->BusType, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0)
{
BUSMap[m->BusId] = MP_BUS_ISA;
}
else if (strncmp(m->BusType, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0)
{
BUSMap[m->BusId] = MP_BUS_EISA;
}
else if (strncmp(m->BusType, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0)
{
BUSMap[m->BusId] = MP_BUS_PCI;
PCIBUSMap[m->BusId] = CurrentPCIBusId;
CurrentPCIBusId++;
}
else if (strncmp(m->BusType, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0)
{
BUSMap[m->BusId] = MP_BUS_MCA;
}
else
{
DPRINT("Unknown bustype %.*s - ignoring\n", 6, m->BusType);
}
}
static VOID
HaliMPIOApicInfo(PMP_CONFIGURATION_IOAPIC m)
{
if (!(m->ApicFlags & CPU_FLAG_ENABLED))
return;
DPRINT("I/O APIC #%d Version %d at 0x%lX.\n",
m->ApicId, m->ApicVersion, m->ApicAddress);
if (IOAPICCount > MAX_IOAPIC)
{
DPRINT("Max # of I/O APICs (%d) exceeded (found %d).\n",
MAX_IOAPIC, IOAPICCount);
DPRINT1("Recompile with bigger MAX_IOAPIC!.\n");
KEBUGCHECK(0);
}
IOAPICMap[IOAPICCount].ApicId = m->ApicId;
IOAPICMap[IOAPICCount].ApicVersion = m->ApicVersion;
IOAPICMap[IOAPICCount].ApicAddress = m->ApicAddress;
IOAPICCount++;
}
static VOID
HaliMPIntLocalInfo(PMP_CONFIGURATION_INTLOCAL m)
{
DPRINT("Lint: type %d, pol %d, trig %d, bus %d,"
" IRQ %02x, APIC ID %x, APIC LINT %02x\n",
m->IrqType, m->SrcBusIrq & 3,
(m->SrcBusIrq >> 2) & 3, m->SrcBusId,
m->SrcBusIrq, m->DstApicId, m->DstApicLInt);
/*
* Well it seems all SMP boards in existence
* use ExtINT/LVT1 == LINT0 and
* NMI/LVT2 == LINT1 - the following check
* will show us if this assumptions is false.
* Until then we do not have to add baggage.
*/
if ((m->IrqType == INT_EXTINT) && (m->DstApicLInt != 0))
{
DPRINT1("Invalid MP table!\n");
KEBUGCHECK(0);
}
if ((m->IrqType == INT_NMI) && (m->DstApicLInt != 1))
{
DPRINT1("Invalid MP table!\n");
KEBUGCHECK(0);
}
}
static BOOLEAN
HaliReadMPConfigTable(PMP_CONFIGURATION_TABLE Table)
/*
PARAMETERS:
Table = Pointer to MP configuration table
*/
{
PUCHAR Entry;
ULONG Count;
if (Table->Signature != MPC_SIGNATURE)
{
PUCHAR pc = (PUCHAR)&Table->Signature;
DPRINT1("Bad MP configuration block signature: %c%c%c%c\n",
pc[0], pc[1], pc[2], pc[3]);
KEBUGCHECKEX(0, pc[0], pc[1], pc[2], pc[3]);
return FALSE;
}
if (MPChecksum((PUCHAR)Table, Table->Length))
{
DPRINT1("Bad MP configuration block checksum\n");
KEBUGCHECK(0);
return FALSE;
}
if (Table->Specification != 0x01 && Table->Specification != 0x04)
{
DPRINT1("Bad MP configuration table version (%d)\n",
Table->Specification);
KEBUGCHECK(0);
return FALSE;
}
if (Table->LocalAPICAddress != APIC_DEFAULT_BASE)
{
DPRINT1("APIC base address is at 0x%X. I cannot handle non-standard adresses\n",
Table->LocalAPICAddress);
KEBUGCHECK(0);
return FALSE;
}
DPRINT("Oem: %.*s, ProductId: %.*s\n", 8, Table->Oem, 12, Table->ProductId);
DPRINT("APIC at: %08x\n", Table->LocalAPICAddress);
Entry = (PUCHAR)((ULONG_PTR)Table + sizeof(MP_CONFIGURATION_TABLE));
Count = 0;
while (Count < (Table->Length - sizeof(MP_CONFIGURATION_TABLE)))
{
/* Switch on type */
switch (*Entry)
{
case MPCTE_PROCESSOR:
{
HaliMPProcessorInfo((PMP_CONFIGURATION_PROCESSOR)Entry);
Entry += sizeof(MP_CONFIGURATION_PROCESSOR);
Count += sizeof(MP_CONFIGURATION_PROCESSOR);
break;
}
case MPCTE_BUS:
{
HaliMPBusInfo((PMP_CONFIGURATION_BUS)Entry);
Entry += sizeof(MP_CONFIGURATION_BUS);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -