Split some of the halmp files according its functions.
Modified: trunk/reactos/hal/halx86/generic/timer.c
Modified: trunk/reactos/hal/halx86/include/apic.h
Modified: trunk/reactos/hal/halx86/include/hal.h
Added: trunk/reactos/hal/halx86/include/ioapic.h
Modified: trunk/reactos/hal/halx86/include/mps.h
Modified: trunk/reactos/hal/halx86/mp/Makefile
Modified: trunk/reactos/hal/halx86/mp/apic.c
Modified: trunk/reactos/hal/halx86/mp/halinit_mp.c
Added: trunk/reactos/hal/halx86/mp/ioapic.c
Added: trunk/reactos/hal/halx86/mp/mpconfig.c
Modified: trunk/reactos/hal/halx86/mp/mpsirql.c
Modified: trunk/reactos/hal/halx86/mp/processor_mp.c
_____
Modified: trunk/reactos/hal/halx86/generic/timer.c
--- trunk/reactos/hal/halx86/generic/timer.c 2005-03-07 16:37:49 UTC
(rev 13867)
+++ trunk/reactos/hal/halx86/generic/timer.c 2005-03-07 16:40:32 UTC
(rev 13868)
@@ -165,7 +165,7 @@
}
-static VOID WaitFor8254Wraparound(VOID)
+VOID WaitFor8254Wraparound(VOID)
{
ULONG CurCount, PrevCount = ~0;
LONG Delta;
_____
Modified: trunk/reactos/hal/halx86/include/apic.h
--- trunk/reactos/hal/halx86/include/apic.h 2005-03-07 16:37:49 UTC
(rev 13867)
+++ trunk/reactos/hal/halx86/include/apic.h 2005-03-07 16:40:32 UTC
(rev 13868)
@@ -145,7 +145,16 @@
#define APIC_INTEGRATED(version) (version & 0xF0)
+typedef enum {
+ amPIC = 0, /* IMCR and PIC compatibility mode */
+ amVWIRE /* Virtual Wire compatibility mode */
+} APIC_MODE;
+
+#ifdef CONFIG_SMP
#define MAX_CPU 32
+#else
+#define MAX_CPU 1
+#endif
/*
* Local APIC timer IRQ vector is on a different priority level,
@@ -158,6 +167,11 @@
#define ERROR_VECTOR 0xFE
#define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */
+/* CPU flags */
+#define CPU_USABLE 0x01 /* 1 if the CPU is usable (ie. can be used)
*/
+#define CPU_ENABLED 0x02 /* 1 if the CPU is enabled */
+#define CPU_BSP 0x04 /* 1 if the CPU is the bootstrap processor
*/
+#define CPU_TSC 0x08 /* 1 if the CPU has a time stamp counter */
typedef struct _CPU_INFO
{
@@ -170,23 +184,26 @@
UCHAR Padding[16-12]; /* Padding to 16-byte */
} CPU_INFO, *PCPU_INFO;
+extern ULONG CPUCount; /* Total number of CPUs */
+extern ULONG BootCPU; /* Bootstrap
processor */
+extern ULONG OnlineCPUs; /* Bitmask of online CPUs */
+extern CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in the system
*/
/* Prototypes */
-
+inline VOID APICWrite(ULONG Offset, ULONG Value);
inline ULONG APICRead(ULONG Offset);
-inline VOID APICWrite(ULONG Offset, ULONG Value);
VOID APICSendIPI(ULONG Target, ULONG Mode);
-
-ULONG APICGetMaxLVT(VOID);
VOID APICSetup(VOID);
VOID HaliInitBSP(VOID);
VOID APICSyncArbIDs(VOID);
inline VOID APICSendEOI(VOID);
+VOID APICCalibrateTimer(ULONG CPU);
+VOID HaliStartApplicationProcessor(ULONG Cpu, ULONG Stack);
static inline ULONG ThisCPU(VOID)
{
- return (APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
+ return (APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
}
_____
Modified: trunk/reactos/hal/halx86/include/hal.h
--- trunk/reactos/hal/halx86/include/hal.h 2005-03-07 16:37:49 UTC
(rev 13867)
+++ trunk/reactos/hal/halx86/include/hal.h 2005-03-07 16:40:32 UTC
(rev 13868)
@@ -413,6 +413,8 @@
#define Ki386EnableInterrupts() __asm__
__volatile__("sti\n\t")
#define Ki386HaltProcessor() __asm__ __volatile__("hlt\n\t")
#define Ki386RdTSC(x) __asm__ __volatile__("rdtsc\n\t" :
"=A" (x.u.LowPart), "=d" (x.u.HighPart));
+#define Ki386Rdmsr(msr,val1,val2) __asm__ __volatile__("rdmsr" :
"=a"
(val1), "=d" (val2) : "c" (msr))
+#define Ki386Wrmsr(msr,val1,val2) __asm__ __volatile__("wrmsr" : /*
no outputs */ : "c" (msr), "a" (val1), "d" (val2))
static inline BYTE Ki386ReadFsByte(ULONG offset)
{
_____
Added: trunk/reactos/hal/halx86/include/ioapic.h
--- trunk/reactos/hal/halx86/include/ioapic.h 2005-03-07 16:37:49 UTC
(rev 13867)
+++ trunk/reactos/hal/halx86/include/ioapic.h 2005-03-07 16:40:32 UTC
(rev 13868)
@@ -0,0 +1,101 @@
+/*
+ *
+ */
+
+#ifndef __INTERNAL_HAL_IOAPIC_H
+#define __INTERNAL_HAL_IOAPIC_H
+
+/* I/O APIC Register Address Map */
+#define IOAPIC_IOREGSEL 0x0000 /* I/O Register Select (index) (R/W) */
+#define IOAPIC_IOWIN 0x0010 /* I/O window (data) (R/W) */
+
+#define IOAPIC_ID 0x0000 /* IO APIC ID (R/W) */
+#define IOAPIC_VER 0x0001 /* IO APIC Version (R) */
+#define IOAPIC_ARB 0x0002 /* IO APIC Arbitration ID (R) */
+#define IOAPIC_REDTBL 0x0010 /* Redirection Table (0-23 64-bit
registers) (R/W) */
+
+#define IOAPIC_ID_MASK (0xF << 24)
+#define GET_IOAPIC_ID(x) (((x) & IOAPIC_ID_MASK) >> 24)
+#define SET_IOAPIC_ID(x) ((x) << 24)
+
+#define IOAPIC_VER_MASK (0xFF)
+#define GET_IOAPIC_VERSION(x) (((x) & IOAPIC_VER_MASK))
+#define IOAPIC_MRE_MASK (0xFF << 16) /* Maximum Redirection
Entry */
+#define GET_IOAPIC_MRE(x) (((x) & IOAPIC_MRE_MASK) >> 16)
+
+#define IOAPIC_ARB_MASK (0xF << 24)
+#define GET_IOAPIC_ARB(x) (((x) & IOAPIC_ARB_MASK) >> 24)
+
+#define IOAPIC_TBL_DELMOD (0x7 << 10) /* Delivery Mode (see
APIC_DM_*) */
+#define IOAPIC_TBL_DM (0x1 << 11) /* Destination Mode */
+#define IOAPIC_TBL_DS (0x1 << 12) /* Delivery Status */
+#define IOAPIC_TBL_INTPOL (0x1 << 13) /* Interrupt Input Pin Polarity
*/
+#define IOAPIC_TBL_RIRR (0x1 << 14) /* Remote IRR */
+#define IOAPIC_TBL_TM (0x1 << 15) /* Trigger Mode */
+#define IOAPIC_TBL_IM (0x1 << 16) /* Interrupt Mask */
+#define IOAPIC_TBL_DF0 (0xF << 56) /* Destination Field (physical
mode) */
+#define IOAPIC_TBL_DF1 (0xFF<< 56) /* Destination Field (logical
mode) */
+#define IOAPIC_TBL_VECTOR (0xFF << 0) /* Vector (10h - FEh) */
+
+typedef struct _IOAPIC_ROUTE_ENTRY {
+ ULONG vector : 8,
+ delivery_mode : 3, /* 000: FIXED
+ * 001: lowest priority
+ * 111: ExtINT
+ */
+ dest_mode : 1, /* 0: physical, 1: logical */
+ delivery_status : 1,
+ polarity : 1,
+ irr : 1,
+ trigger : 1, /* 0: edge, 1: level */
+ mask : 1, /* 0: enabled, 1: disabled */
+ __reserved_2 : 15;
+
+ union {
+ struct {
+ ULONG __reserved_1 : 24,
+ physical_dest : 4,
+ __reserved_2 : 4;
+ } physical;
+ struct {
+ ULONG __reserved_1 : 24,
+ logical_dest : 8;
+ } logical;
+ } dest;
+} __attribute__ ((packed)) IOAPIC_ROUTE_ENTRY, *PIOAPIC_ROUTE_ENTRY;
+
+typedef struct _IOAPIC_INFO
+{
+ ULONG ApicId; /* APIC ID */
+ ULONG ApicVersion; /* APIC version */
+ ULONG ApicAddress; /* APIC address */
+ ULONG EntryCount; /* Number of redirection entries */
+} IOAPIC_INFO, *PIOAPIC_INFO;
+
+#define IOAPIC_DEFAULT_BASE 0xFEC00000 /* Default I/O APIC Base
Register Address */
+
+extern ULONG IRQCount; /* Number of
IRQs */
+extern UCHAR BUSMap[MAX_BUS]; /* Map of all
buses in the system */
+extern UCHAR PCIBUSMap[MAX_BUS]; /* Map of all
PCI buses in the system */
+extern IOAPIC_INFO IOAPICMap[MAX_IOAPIC]; /* Map of all
I/O APICs in the system */
+extern ULONG IOAPICCount; /* Number of I/O
APICs in the system */
+extern ULONG APICMode; /* APIC mode at
startup */
+extern MP_CONFIGURATION_INTSRC IRQMap[MAX_IRQ_SOURCE]; /* Map of all
IRQs */
+
+VOID IOAPICSetupIrqs(VOID);
+VOID IOAPICEnable(VOID);
+VOID IOAPICSetupIds(VOID);
+VOID IOAPICMaskIrq(ULONG Irq);
+VOID IOAPICUnmaskIrq(ULONG Irq);
+
+VOID HaliReconfigurePciInterrupts(VOID);
+
+/* For debugging */
+VOID IOAPICDump(VOID);
+
+#endif
+
+
+
+/* EOF */
+
_____
Modified: trunk/reactos/hal/halx86/include/mps.h
--- trunk/reactos/hal/halx86/include/mps.h 2005-03-07 16:37:49 UTC
(rev 13867)
+++ trunk/reactos/hal/halx86/include/mps.h 2005-03-07 16:40:32 UTC
(rev 13868)
@@ -9,77 +9,7 @@
#define IRQL2TPR(irql) ((irql) >= IPI_LEVEL ? IPI_VECTOR : ((irql)
= PROFILE_LEVEL ? LOCAL_TIMER_VECTOR : ((irql) >
DISPATCH_LEVEL ?
IRQL2VECTOR(irql) : 0)))
-#define IOAPIC_DEFAULT_BASE 0xFEC00000 /* Default I/O APIC Base
Register Address */
-/* I/O APIC Register Address Map */
-#define IOAPIC_IOREGSEL 0x0000 /* I/O Register Select (index) (R/W) */
-#define IOAPIC_IOWIN 0x0010 /* I/O window (data) (R/W) */
-
-#define IOAPIC_ID 0x0000 /* IO APIC ID (R/W) */
-#define IOAPIC_VER 0x0001 /* IO APIC Version (R) */
-#define IOAPIC_ARB 0x0002 /* IO APIC Arbitration ID (R) */
-#define IOAPIC_REDTBL 0x0010 /* Redirection Table (0-23 64-bit
registers) (R/W) */
-
-#define IOAPIC_ID_MASK (0xF << 24)
-#define GET_IOAPIC_ID(x) (((x) & IOAPIC_ID_MASK) >> 24)
-#define SET_IOAPIC_ID(x) ((x) << 24)
-
-#define IOAPIC_VER_MASK (0xFF)
-#define GET_IOAPIC_VERSION(x) (((x) & IOAPIC_VER_MASK))
-#define IOAPIC_MRE_MASK (0xFF << 16) /* Maximum Redirection
Entry */
-#define GET_IOAPIC_MRE(x) (((x) & IOAPIC_MRE_MASK) >> 16)
-
-#define IOAPIC_ARB_MASK (0xF << 24)
-#define GET_IOAPIC_ARB(x) (((x) & IOAPIC_ARB_MASK) >> 24)
-
-#define IOAPIC_TBL_DELMOD (0x7 << 10) /* Delivery Mode (see
APIC_DM_*) */
-#define IOAPIC_TBL_DM (0x1 << 11) /* Destination Mode */
-#define IOAPIC_TBL_DS (0x1 << 12) /* Delivery Status */
-#define IOAPIC_TBL_INTPOL (0x1 << 13) /* Interrupt Input Pin Polarity
*/
-#define IOAPIC_TBL_RIRR (0x1 << 14) /* Remote IRR */
-#define IOAPIC_TBL_TM (0x1 << 15) /* Trigger Mode */
-#define IOAPIC_TBL_IM (0x1 << 16) /* Interrupt Mask */
-#define IOAPIC_TBL_DF0 (0xF << 56) /* Destination Field (physical
mode) */
-#define IOAPIC_TBL_DF1 (0xFF<< 56) /* Destination Field (logical
mode) */
-#define IOAPIC_TBL_VECTOR (0xFF << 0) /* Vector (10h - FEh) */
-
-typedef struct _IOAPIC_ROUTE_ENTRY {
- ULONG vector : 8,
- delivery_mode : 3, /* 000: FIXED
- * 001: lowest
priority
- * 111: ExtINT
- */
- dest_mode : 1, /* 0: physical, 1: logical
*/
- delivery_status : 1,
- polarity : 1,
- irr : 1,
- trigger : 1, /* 0: edge, 1: level */
- mask : 1, /* 0: enabled, 1: disabled
*/
- __reserved_2 : 15;
-
- union { struct { ULONG
- __reserved_1 : 24,
- physical_dest : 4,
- __reserved_2 : 4;
- } physical;
-
- struct { ULONG
- __reserved_1 : 24,
- logical_dest : 8;
- } logical;
- } dest;
-} __attribute__ ((packed)) IOAPIC_ROUTE_ENTRY, *PIOAPIC_ROUTE_ENTRY;
-
-typedef struct _IOAPIC_INFO
-{
- ULONG ApicId; /* APIC ID */
- ULONG ApicVersion; /* APIC version */
- ULONG ApicAddress; /* APIC address */
- ULONG EntryCount; /* Number of redirection entries */
-} IOAPIC_INFO, *PIOAPIC_INFO;
-
-
-
#if 0
/* This values are defined in halirql.h */
#define FIRST_DEVICE_VECTOR 0x30
@@ -148,14 +78,8 @@
} __attribute__((packed)) MP_CONFIGURATION_PROCESSOR,
*PMP_CONFIGURATION_PROCESSOR;
-#define CPU_FLAG_ENABLED 1 /* Processor is available */
-#define CPU_FLAG_BSP 2 /* Processor is the bootstrap
processor */
-#define CPU_STEPPING_MASK 0x0F
-#define CPU_MODEL_MASK 0xF0
-#define CPU_FAMILY_MASK 0xF00
-
typedef struct __attribute__((packed)) _MP_CONFIGURATION_BUS
{
UCHAR Type; /* 1 */
@@ -239,54 +163,20 @@
} MP_CONFIGURATION_INTLOCAL, *PMP_CONFIGURATION_INTLOCAL;
#define MP_APIC_ALL 0xFF
-
-
-static inline VOID ReadPentiumClock(PULARGE_INTEGER Count)
-{
- register ULONG nLow;
- register ULONG nHigh;
-#if defined(__GNUC__)
- __asm__ __volatile__ ("rdtsc" : "=a" (nLow), "=d"
(nHigh));
-#elif defined(_MSC_VER)
- __asm rdtsc
- __asm mov nLow, eax
- __asm mov nHigh, edx
-#else
-#error Unknown compiler for inline assembler
-#endif
+#define CPU_FLAG_ENABLED 1 /* Processor is available */
+#define CPU_FLAG_BSP 2 /* Processor is the bootstrap
processor */
- Count->u.LowPart = nLow;
- Count->u.HighPart = nHigh;
-}
+#define CPU_STEPPING_MASK 0x0F
+#define CPU_MODEL_MASK 0xF0
+#define CPU_FAMILY_MASK 0xF00
-
-
-
-/* CPU flags */
-#define CPU_USABLE 0x01 /* 1 if the CPU is usable (ie. can be used)
*/
-#define CPU_ENABLED 0x02 /* 1 if the CPU is enabled */
-#define CPU_BSP 0x04 /* 1 if the CPU is the bootstrap processor
*/
-
-
-typedef enum {
- amPIC = 0, /* IMCR and PIC compatibility mode */
- amVWIRE /* Virtual Wire compatibility mode */
-} APIC_MODE;
-
-
#define PIC_IRQS 16
/* Prototypes */
VOID HalpInitMPS(VOID);
-ULONG IOAPICRead(ULONG Apic, ULONG Offset);
-VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value);
-VOID IOAPICMaskIrq(ULONG Irq);
-VOID IOAPICUnmaskIrq(ULONG Irq);
-/* For debugging */
-VOID IOAPICDump(VOID);
#endif /* __INCLUDE_HAL_MPS */
_____
Modified: trunk/reactos/hal/halx86/mp/Makefile
--- trunk/reactos/hal/halx86/mp/Makefile 2005-03-07 16:37:49 UTC
(rev 13867)
+++ trunk/reactos/hal/halx86/mp/Makefile 2005-03-07 16:40:32 UTC
(rev 13868)
@@ -61,7 +61,9 @@
MP_OBJECTS = \
apic.o \
halinit_mp.o \
+ ioapic.o \
ipi_mp.o \
+ mpconfig.o \
mpsirql.o \
mpsboot.o \
mps.o \
_____
Modified: trunk/reactos/hal/halx86/mp/apic.c
--- trunk/reactos/hal/halx86/mp/apic.c 2005-03-07 16:37:49 UTC (rev
13867)
+++ trunk/reactos/hal/halx86/mp/apic.c 2005-03-07 16:40:32 UTC (rev
13868)
@@ -1,6 +1,6 @@
/*
* ReactOS kernel
- * Copyright (C) 2004 ReactOS Team
+ * Copyright (C) 2004, 2005 ReactOS Team
*
* 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
@@ -25,6 +25,8 @@
* PROGRAMMER:
*/
+/* INCLUDE
***********************************************************************/
+
#include <ddk/ntddk.h>
#include <internal/i386/ps.h>
@@ -36,23 +38,47 @@
#define NDEBUG
#include <internal/debug.h>
-BOOLEAN VerifyLocalAPIC(VOID);
-VOID APICCalibrateTimer(ULONG CPU);
+/* GLOBALS
***********************************************************************/
-extern VOID MpsTimerInterrupt(VOID);
-extern VOID MpsErrorInterrupt(VOID);
-extern VOID MpsSpuriousInterrupt(VOID);
-extern VOID MpsIpiInterrupt(VOID);
+ULONG CPUCount; /* Total number
of CPUs */
+ULONG BootCPU; /* Bootstrap processor
*/
+ULONG OnlineCPUs; /* Bitmask of online
CPUs */
+CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in
the system */
-extern ULONG APICMode; /* APIC mode at startup */
-extern PULONG BIOSBase; /* Virtual address of BIOS data segment
*/
-extern PULONG CommonBase; /* Virtual address of common area */
-extern ULONG BootCPU; /* Bootstrap processor */
-extern ULONG OnlineCPUs; /* Bitmask of online CPUs */
+#ifdef CONFIG_SMP
+PULONG BIOSBase; /* Virtual address of
BIOS data segment */
+PULONG CommonBase; /* Virtual address of
common area */
+#endif
-extern CHAR *APstart, *APend;
-extern VOID (*APflush)(VOID);
+PULONG APICBase = (PULONG)APIC_DEFAULT_BASE; /* Virtual address of
local APIC */
+ULONG APICMode; /* APIC mode at
startup */
+
+/* For debugging */
+ULONG lastregr[MAX_CPU];
+ULONG lastvalr[MAX_CPU];
+ULONG lastregw[MAX_CPU];
+ULONG lastvalw[MAX_CPU];
+
+#ifdef CONFIG_SMP
+typedef struct __attribute__((packed)) _COMMON_AREA_INFO
+{
+ ULONG Stack; /* Location of AP stack */
+ ULONG PageDirectory; /* Page directory for an AP */
+ ULONG NtProcessStartup; /* Kernel entry point for an AP */
+ ULONG PaeModeEnabled; /* PAE mode is enabled */
+ ULONG Debug[16]; /* For debugging */
+} COMMON_AREA_INFO, *PCOMMON_AREA_INFO;
+#endif
+
+CHAR *APstart, *APend;
+
+#define BIOS_AREA 0x0
+#define COMMON_AREA 0x2000
+
+#define HZ (100)
+#define APIC_DIVISOR (16)
+
#define CMOS_READ(address) ({ \
WRITE_PORT_UCHAR((PUCHAR)0x70, address)); \
READ_PORT_UCHAR((PUCHAR)0x71)); \
@@ -63,20 +89,17 @@
WRITE_PORT_UCHAR((PUCHAR)0x71, value); \
})
-#define BIOS_AREA 0x0
-#define COMMON_AREA 0x2000
+extern PVOID IMPORTED MmSystemRangeStart;
+/* FUNCTIONS
*********************************************************************/
-extern CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in
the system */
+extern ULONG Read8254Timer(VOID);
+extern VOID WaitFor8254Wraparound(VOID);
+extern VOID MpsTimerInterrupt(VOID);
+extern VOID MpsErrorInterrupt(VOID);
+extern VOID MpsSpuriousInterrupt(VOID);
+extern VOID MpsIpiInterrupt(VOID);
-PULONG APICBase = (PULONG)APIC_DEFAULT_BASE; /* Virtual address of
local APIC */
-
-/* For debugging */
-ULONG lastregr[MAX_CPU];
-ULONG lastvalr[MAX_CPU];
-ULONG lastregw[MAX_CPU];
-ULONG lastvalw[MAX_CPU];
-
ULONG APICGetMaxLVT(VOID)
{
ULONG tmp, ver, maxlvt;
@@ -152,7 +175,7 @@
}
/* Enable symetric I/O mode ie. connect the BSP's local APIC to INT and
NMI lines */
-VOID EnableSMPMode(VOID)
+VOID EnableApicMode(VOID)
{
/*
* Do not trust the local APIC being empty at bootup.
@@ -203,64 +226,7 @@
APICWrite(APIC_SIVR, tmp);
}
-VOID HaliInitBSP(VOID)
-{
- PUSHORT ps;
- static BOOLEAN BSPInitialized = FALSE;
- /* Only initialize the BSP once */
- if (BSPInitialized)
- {
- KEBUGCHECK(0);
- return;
- }
-
- BSPInitialized = TRUE;
-
- DPRINT("APIC is mapped at 0x%X\n", APICBase);
-
- if (VerifyLocalAPIC())
- {
- DPRINT("APIC found\n");
- }
- else
- {
- DPRINT("No APIC found\n");
- KEBUGCHECK(0);
- }
-
- if (APICMode == amPIC)
- {
- EnableSMPMode();
- }
-
- APICSetup();
-
- /* BIOS data segment */
- BIOSBase = (PULONG)BIOS_AREA;
-
- /* Area for communicating with the APs */
- CommonBase = (PULONG)COMMON_AREA;
-
- /* Copy bootstrap code to common area */
- memcpy((PVOID)((ULONG)CommonBase + PAGE_SIZE),
- &APstart,
- (ULONG)&APend - (ULONG)&APstart + 1);
-
- /* Set shutdown code */
- CMOS_WRITE(0xF, 0xA);
-
- /* Set warm reset vector */
- ps = (PUSHORT)((ULONG)BIOSBase + 0x467);
- *ps = (COMMON_AREA + PAGE_SIZE) & 0xF;
-
- ps = (PUSHORT)((ULONG)BIOSBase + 0x469);
- *ps = (COMMON_AREA + PAGE_SIZE) >> 4;
-
- /* Calibrate APIC timer */
- APICCalibrateTimer(BootCPU);
-}
-
inline ULONG _APICRead(ULONG Offset)
{
PULONG p;
@@ -455,7 +421,6 @@
BOOLEAN VerifyLocalAPIC(VOID)
{
UINT reg0, reg1;
- CHECKPOINT1;
/* The version register is read-only in a real APIC */
reg0 = APICRead(APIC_VER);
DPRINT1("Getting VERSION: %x\n", reg0);
@@ -502,9 +467,23 @@
return FALSE;
}
+ ULONG l, h;
+ Ki386Rdmsr(0x1b /*MSR_IA32_APICBASE*/, l, h);
+
+ if (!(l & /*MSR_IA32_APICBASE_ENABLE*/(1<<11)))
+ {
+ DPRINT1("Local APIC disabled by BIOS -- reenabling.\n");
+ l &= ~/*MSR_IA32_APICBASE_BASE*/(1<<11);
+ l |= /*MSR_IA32_APICBASE_ENABLE |
APIC_DEFAULT_PHYS_BASE*/(1<<11)|0xfee00000;
+ Ki386Wrmsr(0x1b/*MSR_IA32_APICBASE*/, l, h);
+ }
+
+
+
return TRUE;
}
+#ifdef CONFIG_SMP
VOID APICSendIPI(ULONG Target, ULONG Mode)
{
ULONG tmp, i, flags;
@@ -568,6 +547,7 @@
}
Ki386RestoreFlags(flags);
}
+#endif
VOID APICSetup(VOID)
{
@@ -651,7 +631,6 @@
}
APICWrite(APIC_LINT0, tmp);
-
/*
* Only the BSP should see the LINT1 NMI signal, obviously.
*/
@@ -697,7 +676,7 @@
DPRINT("ESR value after enabling vector: 0x%X\n", tmp);
}
}
-
+#ifdef CONFIG_SMP
VOID APICSyncArbIDs(VOID)
{
ULONG i, tmp;
@@ -720,6 +699,7 @@
DPRINT("Synchronizing Arb IDs.\n");
APICWrite(APIC_ICR0, APIC_ICR0_DESTS_ALL | APIC_ICR0_LEVEL |
APIC_DM_INIT);
}
+#endif
VOID MpsErrorHandler(VOID)
{
@@ -769,12 +749,13 @@
#endif
}
+#ifdef CONFIG_SMP
VOID MpsIpiHandler(VOID)
{
KIRQL oldIrql;
HalBeginSystemInterrupt(IPI_VECTOR,
- VECTOR2IRQL(IPI_VECTOR),
+ IPI_LEVEL,
&oldIrql);
Ki386EnableInterrupts();
#if 0
@@ -791,6 +772,7 @@
Ki386DisableInterrupts();
HalEndSystemInterrupt(oldIrql, 0);
}
+#endif
VOID
MpsIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
@@ -823,7 +805,7 @@
static ULONG Count[MAX_CPU] = {0,};
#endif
HalBeginSystemInterrupt(LOCAL_TIMER_VECTOR,
- VECTOR2IRQL(LOCAL_TIMER_VECTOR),
+ PROFILE_LEVEL,
&oldIrql);
Ki386EnableInterrupts();
@@ -850,4 +832,318 @@
HalEndSystemInterrupt (oldIrql, 0);
}
+VOID APICSetupLVTT(ULONG ClockTicks)
+{
+ ULONG tmp;
+
+ tmp = GET_APIC_VERSION(APICRead(APIC_VER));
+ if (!APIC_INTEGRATED(tmp))
+ {
+ tmp = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) |
APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
+ }
+ else
+ {
+ /* Periodic timer */
+ tmp = APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
+ }
+ APICWrite(APIC_LVTT, tmp);
+
+ tmp = APICRead(APIC_TDCR);
+ tmp &= ~(APIC_TDCR_1 | APIC_TIMER_BASE_DIV);
+ tmp |= APIC_TDCR_16;
+ APICWrite(APIC_TDCR, tmp);
+ APICWrite(APIC_ICRT, ClockTicks / APIC_DIVISOR);
+}
+
+VOID
+APICCalibrateTimer(ULONG CPU)
+{
+ ULARGE_INTEGER t1, t2;
+ LONG tt1, tt2;
+ BOOLEAN TSCPresent;
+
+ DPRINT("Calibrating APIC timer for CPU %d\n", CPU);
+
+ APICSetupLVTT(1000000000);
+
+ TSCPresent = KeGetCurrentKPCR()->PrcbData.FeatureBits &
X86_FEATURE_TSC ? TRUE : FALSE;
+
+ /*
+ * The timer chip counts down to zero. Let's wait
+ * for a wraparound to start exact measurement:
+ * (the current tick might have been already half done)
+ */
+ WaitFor8254Wraparound();
+
+ /*
+ * We wrapped around just now. Let's start
+ */
+ if (TSCPresent)
+ {
+ Ki386RdTSC(t1);
+ }
+ tt1 = APICRead(APIC_CCRT);
+
+ WaitFor8254Wraparound();
+
+
+ tt2 = APICRead(APIC_CCRT);
+ if (TSCPresent)
+ {
+ Ki386RdTSC(t2);
+ CPUMap[CPU].CoreSpeed = (HZ * (t2.QuadPart - t1.QuadPart));
+ DPRINT("CPU clock speed is %ld.%04ld MHz.\n",
+ CPUMap[CPU].CoreSpeed/1000000,
+ CPUMap[CPU].CoreSpeed%1000000);
+ KeGetCurrentKPCR()->PrcbData.MHz = CPUMap[CPU].CoreSpeed/1000000;
+ }
+
+ CPUMap[CPU].BusSpeed = (HZ * (long)(tt1 - tt2) * APIC_DIVISOR);
+
+ /* Setup timer for normal operation */
+// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100); // 100ns
+ APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 10000); // 10ms
+// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100000); // 100ms
+
+ DPRINT("Host bus clock speed is %ld.%04ld MHz.\n",
+ CPUMap[CPU].BusSpeed/1000000,
+ CPUMap[CPU].BusSpeed%1000000);
+}
+
+VOID
+SetInterruptGate(ULONG index, ULONG address)
+{
+ IDT_DESCRIPTOR *idt;
+
+ idt = (IDT_DESCRIPTOR*)((ULONG)KeGetCurrentKPCR()->IDT + index *
sizeof(IDT_DESCRIPTOR));
+ idt->a = (((ULONG)address)&0xffff) + (KERNEL_CS << 16);
+ idt->b = 0x8e00 + (((ULONG)address)&0xffff0000);
+}
+
+VOID HaliInitBSP(VOID)
+{
+#ifdef CONFIG_SMP
+ PUSHORT ps;
+#endif
+
+ static BOOLEAN BSPInitialized = FALSE;
+
+ /* Only initialize the BSP once */
+ if (BSPInitialized)
+ {
+ KEBUGCHECK(0);
+ return;
+ }
+
+ BSPInitialized = TRUE;
+
+ /* Setup interrupt handlers */
+ SetInterruptGate(LOCAL_TIMER_VECTOR, (ULONG)MpsTimerInterrupt);
+ SetInterruptGate(ERROR_VECTOR, (ULONG)MpsErrorInterrupt);
+ SetInterruptGate(SPURIOUS_VECTOR, (ULONG)MpsSpuriousInterrupt);
+#ifdef CONFIG_SMP
+ SetInterruptGate(IPI_VECTOR, (ULONG)MpsIpiInterrupt);
+#endif
+ DPRINT("APIC is mapped at 0x%X\n", APICBase);
+
+ if (VerifyLocalAPIC())
+ {
+ DPRINT("APIC found\n");
+ }
+ else
+ {
+ DPRINT("No APIC found\n");
+ KEBUGCHECK(0);
+ }
+
+ if (APICMode == amPIC)
+ {
+ EnableApicMode();
+ }
+
+ APICSetup();
+
+#ifdef CONFIG_SMP
+ /* BIOS data segment */
+ BIOSBase = (PULONG)BIOS_AREA;
+
+ /* Area for communicating with the APs */
+ CommonBase = (PULONG)COMMON_AREA;
+
+ /* Copy bootstrap code to common area */
+ memcpy((PVOID)((ULONG)CommonBase + PAGE_SIZE),
+ &APstart,
+ (ULONG)&APend - (ULONG)&APstart + 1);
+
+ /* Set shutdown code */
+ CMOS_WRITE(0xF, 0xA);
+
+ /* Set warm reset vector */
+ ps = (PUSHORT)((ULONG)BIOSBase + 0x467);
+ *ps = (COMMON_AREA + PAGE_SIZE) & 0xF;
+
+ ps = (PUSHORT)((ULONG)BIOSBase + 0x469);
+ *ps = (COMMON_AREA + PAGE_SIZE) >> 4;
+#endif
+
+ /* Calibrate APIC timer */
+ APICCalibrateTimer(BootCPU);
+}
+
+#ifdef CONFIG_SMP
+VOID
+HaliStartApplicationProcessor(ULONG Cpu, ULONG Stack)
+{
+ ULONG tmp, maxlvt;
+ PCOMMON_AREA_INFO Common;
+ ULONG StartupCount;
+ ULONG i, j;
+ ULONG DeliveryStatus = 0;
+ ULONG AcceptStatus = 0;
+
+ if (Cpu >= MAX_CPU ||
+ Cpu >= CPUCount ||
+ OnlineCPUs & (1 << Cpu))
+ {
+ KEBUGCHECK(0);
+ }
+ DPRINT1("Attempting to boot CPU %d\n", Cpu);
+
+ /* Send INIT IPI */
+
+ APICSendIPI(Cpu, APIC_DM_INIT|APIC_ICR0_LEVEL_ASSERT);
+
+ KeStallExecutionProcessor(200);
+
+ /* Deassert INIT */
+
+ APICSendIPI(Cpu, APIC_DM_INIT|APIC_ICR0_LEVEL_DEASSERT);
+
+ if (APIC_INTEGRATED(CPUMap[Cpu].APICVersion))
+ {
+ /* Clear APIC errors */
+ APICWrite(APIC_ESR, 0);
+ tmp = (APICRead(APIC_ESR) & APIC_ESR_MASK);
+ }
+
+ Common = (PCOMMON_AREA_INFO)CommonBase;
+
+ /* Write the location of the AP stack */
+ Common->Stack = (ULONG)Stack;
+ /* Write the page directory page */
+ Ke386GetPageTableDirectory(Common->PageDirectory);
+ /* Write the kernel entry point */
+ Common->NtProcessStartup =
(ULONG_PTR)RtlImageNtHeader(MmSystemRangeStart)->OptionalHeader.AddressO
fEntryPoint + (ULONG_PTR)MmSystemRangeStart;
+ /* Write the state of the mae mode */
+ Common->PaeModeEnabled = Ke386GetCr4() & X86_CR4_PAE ? 1 : 0;
+
+ DPRINT1("%x %x %x %x\n", Common->Stack, Common->PageDirectory,
Common->NtProcessStartup, Common->PaeModeEnabled);
+
+ DPRINT("Cpu %d got stack at 0x%X\n", Cpu, Common->Stack);
+#if 0
+ for (j = 0; j < 16; j++)
+ {
+ Common->Debug[j] = 0;
+ }
+#endif
+
+ maxlvt = APICGetMaxLVT();
+
+ /* Is this a local APIC or an 82489DX? */
+ StartupCount = (APIC_INTEGRATED(CPUMap[Cpu].APICVersion)) ? 2 : 0;
+
+ for (i = 1; i <= StartupCount; i++)
+ {
+ /* It's a local APIC, so send STARTUP IPI */
+ DPRINT("Sending startup signal %d\n", i);
+ /* Clear errors */
+ APICWrite(APIC_ESR, 0);
+ APICRead(APIC_ESR);
+
+ APICSendIPI(Cpu, APIC_DM_STARTUP | ((COMMON_AREA + PAGE_SIZE) >>
12)|APIC_ICR0_LEVEL_DEASSERT);
+
+ /* Wait up to 10ms for IPI to be delivered */
+ j = 0;
+ do
+ {
+ KeStallExecutionProcessor(10);
+
+ /* Check Delivery Status */
+ DeliveryStatus = APICRead(APIC_ICR0) & APIC_ICR0_DS;
+
+ j++;
+ } while ((DeliveryStatus) && (j < 1000));
+
+ KeStallExecutionProcessor(200);
+
+ /*
+ * Due to the Pentium erratum 3AP.
+ */
+ if (maxlvt > 3)
+ {
+ APICRead(APIC_SIVR);
+ APICWrite(APIC_ESR, 0);
+ }
+
+ AcceptStatus = APICRead(APIC_ESR) & APIC_ESR_MASK;
+
+ if (DeliveryStatus || AcceptStatus)
+ {
+ break;
+ }
+ }
+
+ if (DeliveryStatus)
+ {
+ DPRINT("STARTUP IPI for CPU %d was never delivered.\n", Cpu);
+ }
+
+ if (AcceptStatus)
+ {
+ DPRINT("STARTUP IPI for CPU %d was never accepted.\n", Cpu);
+ }
+
+ if (!(DeliveryStatus || AcceptStatus))
+ {
+
+ /* Wait no more than 5 seconds for processor to boot */
+ DPRINT("Waiting for 5 seconds for CPU %d to boot\n", Cpu);
+
+ /* Wait no more than 5 seconds */
+ for (j = 0; j < 50000; j++)
+ {
+ if (CPUMap[Cpu].Flags & CPU_ENABLED)
+ {
+ break;
+ }
+ KeStallExecutionProcessor(100);
+ }
+ }
+
+ if (CPUMap[Cpu].Flags & CPU_ENABLED)
+ {
+ DbgPrint("CPU %d is now running\n", Cpu);
+ }
+ else
+ {
+ DbgPrint("Initialization of CPU %d failed\n", Cpu);
+ }
+
+#if 0
+ DPRINT("Debug bytes are:\n");
+
+ for (j = 0; j < 4; j++)
+ {
+ DPRINT("0x%08X 0x%08X 0x%08X 0x%08X.\n",
+ Common->Debug[j*4+0],
+ Common->Debug[j*4+1],
+ Common->Debug[j*4+2],
+ Common->Debug[j*4+3]);
+ }
+
+#endif
+}
+
+#endif
+
/* EOF */
_____
Modified: trunk/reactos/hal/halx86/mp/halinit_mp.c
--- trunk/reactos/hal/halx86/mp/halinit_mp.c 2005-03-07 16:37:49 UTC
(rev 13867)
+++ trunk/reactos/hal/halx86/mp/halinit_mp.c 2005-03-07 16:40:32 UTC
(rev 13868)
@@ -20,10 +20,34 @@
/* FUNCTIONS
***************************************************************/
+extern BOOLEAN HaliFindSmpConfig(VOID);
+
+/**********************************************************************
*****/
VOID
HalpInitPhase0(VOID)
+
{
- HalpInitMPS();
+ static BOOLEAN MPSInitialized = FALSE;
+
+
+ /* Only initialize MP system once. Once called the first time,
+ each subsequent call is part of the initialization sequence
+ for an application processor. */
+
+ DPRINT("HalpInitPhase0()\n");
+
+
+ if (MPSInitialized)
+ {
+ KEBUGCHECK(0);
+ }
+
[truncated at 1000 lines; 3147 more skipped]