/* INCLUDE ***********************************************************************/
-#include <ddk/ntddk.h>
-#include <internal/i386/ps.h>
-
#include <hal.h>
-#include <halirq.h>
-#include <mps.h>
-#include <apic.h>
-
+#include <halfuncs.h> /* Not in PCH because only used for MP HAL */
+#include <rtlfuncs.h> /* Not in PCH because only used for MP HAL */
#define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
/* GLOBALS ***********************************************************************/
ULONG lastvalw[MAX_CPU];
#ifdef CONFIG_SMP
-typedef struct __attribute__((packed)) _COMMON_AREA_INFO
+#include <pshpack1.h>
+typedef struct _COMMON_AREA_INFO
{
ULONG Stack; /* Location of AP stack */
ULONG PageDirectory; /* Page directory for an AP */
ULONG PaeModeEnabled; /* PAE mode is enabled */
ULONG Debug[16]; /* For debugging */
} COMMON_AREA_INFO, *PCOMMON_AREA_INFO;
+#include <poppack.h>
#endif
-CHAR *APstart, *APend;
+extern CHAR *APstart, *APend;
#define BIOS_AREA 0x0
#define COMMON_AREA 0x2000
#define HZ (100)
#define APIC_DIVISOR (16)
-#define CMOS_READ(address) ({ \
+#define CMOS_READ(address) { \
WRITE_PORT_UCHAR((PUCHAR)0x70, address)); \
READ_PORT_UCHAR((PUCHAR)0x71)); \
-})
+}
-#define CMOS_WRITE(address, value) ({ \
+#define CMOS_WRITE(address, value) { \
WRITE_PORT_UCHAR((PUCHAR)0x70, address); \
WRITE_PORT_UCHAR((PUCHAR)0x71, value); \
-})
+}
-extern PVOID IMPORTED MmSystemRangeStart;
+extern ULONG_PTR KernelBase;
/* FUNCTIONS *********************************************************************/
}
/* Disable symetric I/O mode ie. go to PIC mode */
-inline VOID DisableSMPMode(VOID)
+__inline VOID DisableSMPMode(VOID)
{
/*
* Put the board back into PIC mode (has an effect
APICWrite(APIC_SIVR, tmp);
}
-
-inline ULONG _APICRead(ULONG Offset)
-{
- PULONG p;
-
- p = (PULONG)((ULONG)APICBase + Offset);
- return *p;
-}
-
-#if 0
-inline VOID APICWrite(ULONG Offset,
- ULONG Value)
-{
- PULONG p;
-
- p = (PULONG)((ULONG)APICBase + Offset);
-
- *p = Value;
-}
-#else
-inline VOID APICWrite(ULONG Offset,
- ULONG Value)
-{
- PULONG p;
- ULONG CPU = (_APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
-
- lastregw[CPU] = Offset;
- lastvalw[CPU] = Value;
-
- p = (PULONG)((ULONG)APICBase + Offset);
-
- *p = Value;
-}
-#endif
-
-
-#if 0
-inline ULONG APICRead(ULONG Offset)
-{
- PULONG p;
-
- p = (PULONG)((ULONG)APICBase + Offset);
- return *p;
-}
-#else
-inline ULONG APICRead(ULONG Offset)
-{
- PULONG p;
- ULONG CPU = (_APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
-
- lastregr[CPU] = Offset;
- lastvalr[CPU] = 0;
-
- p = (PULONG)((ULONG)APICBase + Offset);
-
- lastvalr[CPU] = *p;
- return lastvalr[CPU];
-}
-#endif
-
-inline VOID APICSendEOI(VOID)
-{
- // Send the EOI
- APICWrite(APIC_EOI, 0);
-}
-
static VOID APICDumpBit(ULONG base)
{
ULONG v, i, j;
{
ULONG v, ver, maxlvt;
ULONG r1, r2, w1, w2;
- ULONG CPU = ThisCPU();;
-
+ ULONG CPU = ThisCPU();
r1 = lastregr[CPU];
BOOLEAN VerifyLocalAPIC(VOID)
{
- UINT reg0, reg1;
+ SIZE_T reg0, reg1;
+ LARGE_INTEGER MsrValue;
+
/* The version register is read-only in a real APIC */
reg0 = APICRead(APIC_VER);
DPRINT1("Getting VERSION: %x\n", reg0);
return FALSE;
}
- ULONG l, h;
- Ki386Rdmsr(0x1b /*MSR_IA32_APICBASE*/, l, h);
+ MsrValue.QuadPart = __readmsr(0x1B /*MSR_IA32_APICBASE*/);
- if (!(l & /*MSR_IA32_APICBASE_ENABLE*/(1<<11)))
+ if (!(MsrValue.LowPart & /*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);
+ MsrValue.LowPart &= ~/*MSR_IA32_APICBASE_BASE*/(1<<11);
+ MsrValue.LowPart |= /*MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE*/(1<<11)|0xfee00000;
+ __writemsr(0x1B /*MSR_IA32_APICBASE*/, MsrValue.HighPart);
}
ULONG tmp, i, flags;
/* save flags and disable interrupts */
- Ki386SaveFlags(flags);
- Ki386DisableInterrupts();
+ flags = __readeflags();
+ _disable();
/* Wait up to 100ms for the APIC to become ready */
for (i = 0; i < 10000; i++)
{
DPRINT1("CPU(%d) Current IPI was not delivered after 100ms.\n", ThisCPU());
}
- Ki386RestoreFlags(flags);
+ __writeeflags(flags);
}
#endif
{
KIRQL oldIrql;
- HalBeginSystemInterrupt(IPI_VECTOR,
- IPI_LEVEL,
+ HalBeginSystemInterrupt(IPI_LEVEL,
+ IPI_VECTOR,
&oldIrql);
- Ki386EnableInterrupts();
+ _enable();
#if 0
DbgPrint("(%s:%d) MpsIpiHandler on CPU%d, current irql is %d\n",
__FILE__,__LINE__, KeGetCurrentProcessorNumber(), KeGetCurrentIrql());
DbgPrint("(%s:%d) MpsIpiHandler on CPU%d done\n", __FILE__,__LINE__, KeGetCurrentProcessorNumber());
#endif
- Ki386DisableInterrupts();
+ _disable();
HalEndSystemInterrupt(oldIrql, 0);
}
#endif
MpsIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
PKTRAP_FRAME TrapFrame)
{
- TrapFrame->Gs = (USHORT)IrqTrapFrame->Gs;
- TrapFrame->Fs = (USHORT)IrqTrapFrame->Fs;
- TrapFrame->Es = (USHORT)IrqTrapFrame->Es;
- TrapFrame->Ds = (USHORT)IrqTrapFrame->Ds;
+#ifdef _M_AMD64
+ UNIMPLEMENTED;
+#else
+ TrapFrame->SegGs = (USHORT)IrqTrapFrame->Gs;
+ TrapFrame->SegFs = (USHORT)IrqTrapFrame->Fs;
+ TrapFrame->SegEs = (USHORT)IrqTrapFrame->Es;
+ TrapFrame->SegDs = (USHORT)IrqTrapFrame->Ds;
TrapFrame->Eax = IrqTrapFrame->Eax;
TrapFrame->Ecx = IrqTrapFrame->Ecx;
TrapFrame->Edx = IrqTrapFrame->Edx;
TrapFrame->Ebx = IrqTrapFrame->Ebx;
- TrapFrame->Esp = IrqTrapFrame->Esp;
+ TrapFrame->HardwareEsp = IrqTrapFrame->Esp;
TrapFrame->Ebp = IrqTrapFrame->Ebp;
TrapFrame->Esi = IrqTrapFrame->Esi;
TrapFrame->Edi = IrqTrapFrame->Edi;
TrapFrame->Eip = IrqTrapFrame->Eip;
- TrapFrame->Cs = IrqTrapFrame->Cs;
- TrapFrame->Eflags = IrqTrapFrame->Eflags;
+ TrapFrame->SegCs = IrqTrapFrame->Cs;
+ TrapFrame->EFlags = IrqTrapFrame->Eflags;
+#endif
}
VOID
HalBeginSystemInterrupt(LOCAL_TIMER_VECTOR,
PROFILE_LEVEL,
&oldIrql);
- Ki386EnableInterrupts();
+ _enable();
#if 0
CPU = ThisCPU();
if ((Count[CPU] % 100) == 0)
{
- DbgPrint("(%s:%d) MpsTimerHandler on CPU%d, irql = %d, epi = %x, KPCR = %x\n", __FILE__, __LINE__, CPU, oldIrql,Trapframe->Eip, KeGetCurrentKPCR());
+ DbgPrint("(%s:%d) MpsTimerHandler on CPU%d, irql = %d, epi = %x, KPCR = %x\n", __FILE__, __LINE__, CPU, oldIrql,Trapframe->Eip, KeGetPcr());
}
Count[CPU]++;
#endif
+ /* FIXME: SMP is totally broken */
MpsIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
if (KeGetCurrentProcessorNumber() == 0)
{
- KeUpdateSystemTime(&KernelTrapFrame, oldIrql);
+ //KeUpdateSystemTime(&KernelTrapFrame, oldIrql);
}
else
{
- KeUpdateRunTime(&KernelTrapFrame, oldIrql);
+ //KeUpdateRunTime(&KernelTrapFrame, oldIrql);
}
- Ki386DisableInterrupts();
+ _disable();
HalEndSystemInterrupt (oldIrql, 0);
}
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;;
+ 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;;
+ tmp = APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;
}
APICWrite(APIC_LVTT, tmp);
APICSetupLVTT(1000000000);
- TSCPresent = KeGetCurrentKPCR()->PrcbData.FeatureBits & X86_FEATURE_TSC ? TRUE : FALSE;
+ TSCPresent = KeGetCurrentPrcb()->FeatureBits & KF_RDTSC ? 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();
+ //WaitFor8254Wraparound();
/*
* We wrapped around just now. Let's start
*/
if (TSCPresent)
{
- Ki386RdTSC(t1);
+ t1.QuadPart = (LONGLONG)__rdtsc();
}
tt1 = APICRead(APIC_CCRT);
- WaitFor8254Wraparound();
+ //WaitFor8254Wraparound();
tt2 = APICRead(APIC_CCRT);
if (TSCPresent)
{
- Ki386RdTSC(t2);
- CPUMap[CPU].CoreSpeed = (HZ * (t2.QuadPart - t1.QuadPart));
+ t2.QuadPart = (LONGLONG)__rdtsc();
+ CPUMap[CPU].CoreSpeed = (HZ * (ULONG)(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;
+ KeGetCurrentPrcb()->MHz = CPUMap[CPU].CoreSpeed/1000000;
}
CPUMap[CPU].BusSpeed = (HZ * (long)(tt1 - tt2) * APIC_DIVISOR);
}
VOID
-SetInterruptGate(ULONG index, ULONG address)
+SetInterruptGate(ULONG index, ULONG_PTR 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);
+#ifdef _M_AMD64
+ KIDTENTRY64 *idt;
+
+ idt = &KeGetPcr()->IdtBase[index];
+
+ idt->OffsetLow = address & 0xffff;
+ idt->Selector = KGDT_64_R0_CODE;
+ idt->IstIndex = 0;
+ idt->Reserved0 = 0;
+ idt->Type = 0x0e;
+ idt->Dpl = 0;
+ idt->Present = 1;
+ idt->OffsetMiddle = (address >> 16) & 0xffff;
+ idt->OffsetHigh = address >> 32;
+ idt->Reserved1 = 0;
+ idt->Alignment = 0;
+#else
+ KIDTENTRY *idt;
+ KIDT_ACCESS Access;
+
+ /* Set the IDT Access Bits */
+ Access.Reserved = 0;
+ Access.Present = 1;
+ Access.Dpl = 0; /* Kernel-Mode */
+ Access.SystemSegmentFlag = 0;
+ Access.SegmentType = I386_INTERRUPT_GATE;
+
+ idt = (KIDTENTRY*)((ULONG)KeGetPcr()->IDT + index * sizeof(KIDTENTRY));
+ idt->Offset = (USHORT)(address & 0xffff);
+ idt->Selector = KGDT_R0_CODE;
+ idt->Access = Access.Value;
+ idt->ExtendedOffset = (USHORT)(address >> 16);
+#endif
}
VOID HaliInitBSP(VOID)
/* Only initialize the BSP once */
if (BSPInitialized)
{
- KEBUGCHECK(0);
+ ASSERT(FALSE);
return;
}
BSPInitialized = TRUE;
/* Setup interrupt handlers */
- SetInterruptGate(LOCAL_TIMER_VECTOR, (ULONG)MpsTimerInterrupt);
- SetInterruptGate(ERROR_VECTOR, (ULONG)MpsErrorInterrupt);
- SetInterruptGate(SPURIOUS_VECTOR, (ULONG)MpsSpuriousInterrupt);
+ SetInterruptGate(LOCAL_TIMER_VECTOR, (ULONG_PTR)MpsTimerInterrupt);
+ SetInterruptGate(ERROR_VECTOR, (ULONG_PTR)MpsErrorInterrupt);
+ SetInterruptGate(SPURIOUS_VECTOR, (ULONG_PTR)MpsSpuriousInterrupt);
#ifdef CONFIG_SMP
- SetInterruptGate(IPI_VECTOR, (ULONG)MpsIpiInterrupt);
+ SetInterruptGate(IPI_VECTOR, (ULONG_PTR)MpsIpiInterrupt);
#endif
- DPRINT("APIC is mapped at 0x%X\n", APICBase);
+ DPRINT1("APIC is mapped at 0x%p\n", (PVOID)APICBase);
if (VerifyLocalAPIC())
{
}
else
{
- DPRINT("No APIC found\n");
- KEBUGCHECK(0);
+ DPRINT1("No APIC found\n");
+ ASSERT(FALSE);
}
if (APICMode == amPIC)
CommonBase = (PULONG)COMMON_AREA;
/* Copy bootstrap code to common area */
- memcpy((PVOID)((ULONG)CommonBase + PAGE_SIZE),
+ memcpy((PVOID)((ULONG_PTR)CommonBase + PAGE_SIZE),
&APstart,
- (ULONG)&APend - (ULONG)&APstart + 1);
+ (ULONG_PTR)&APend - (ULONG_PTR)&APstart + 1);
/* Set shutdown code */
CMOS_WRITE(0xF, 0xA);
/* Set warm reset vector */
- ps = (PUSHORT)((ULONG)BIOSBase + 0x467);
+ ps = (PUSHORT)((ULONG_PTR)BIOSBase + 0x467);
*ps = (COMMON_AREA + PAGE_SIZE) & 0xF;
- ps = (PUSHORT)((ULONG)BIOSBase + 0x469);
+ ps = (PUSHORT)((ULONG_PTR)BIOSBase + 0x469);
*ps = (COMMON_AREA + PAGE_SIZE) >> 4;
#endif
Cpu >= CPUCount ||
OnlineCPUs & (1 << Cpu))
{
- KEBUGCHECK(0);
+ ASSERT(FALSE);
}
DPRINT1("Attempting to boot CPU %d\n", Cpu);
/* Write the location of the AP stack */
Common->Stack = (ULONG)Stack;
/* Write the page directory page */
- Ke386GetPageTableDirectory(Common->PageDirectory);
+ Common->PageDirectory = __readcr3();
/* Write the kernel entry point */
- Common->NtProcessStartup = (ULONG_PTR)RtlImageNtHeader(MmSystemRangeStart)->OptionalHeader.AddressOfEntryPoint + (ULONG_PTR)MmSystemRangeStart;
+ Common->NtProcessStartup = (ULONG_PTR)RtlImageNtHeader((PVOID)KernelBase)->OptionalHeader.AddressOfEntryPoint + KernelBase;
/* Write the state of the mae mode */
- Common->PaeModeEnabled = Ke386GetCr4() & X86_CR4_PAE ? 1 : 0;
+ Common->PaeModeEnabled = __readcr4() & CR4_PAE ? 1 : 0;
DPRINT1("%x %x %x %x\n", Common->Stack, Common->PageDirectory, Common->NtProcessStartup, Common->PaeModeEnabled);