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.AddressOfEntryPoint + (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]