59typedef struct _COMMON_AREA_INFO
66} COMMON_AREA_INFO, *PCOMMON_AREA_INFO;
73#define COMMON_AREA 0x2000
76#define APIC_DIVISOR (16)
78#define CMOS_READ(address) { \
79 WRITE_PORT_UCHAR((PUCHAR)0x70, address)); \
80 READ_PORT_UCHAR((PUCHAR)0x71)); \
83#define CMOS_WRITE(address, value) { \
84 WRITE_PORT_UCHAR((PUCHAR)0x70, address); \
85 WRITE_PORT_UCHAR((PUCHAR)0x71, value); \
101 ULONG tmp, ver, maxlvt;
104 ver = GET_APIC_VERSION(tmp);
106 maxlvt = APIC_INTEGRATED(ver) ? GET_APIC_MAXLVT(tmp) : 2;
125 APICWrite(APIC_LVT3, tmp | APIC_LVT3_MASKED);
128 tmp = APICRead(APIC_LVTT);
129 APICWrite(APIC_LVTT, tmp | APIC_LVT_MASKED);
139 tmp = APICRead(APIC_LVTPC);
140 APICWrite(APIC_LVTPC, tmp | APIC_LVT_MASKED);
145 tmp = APICRead(APIC_LVTTHMR);
146 APICWrite(APIC_LVTTHMR, tmp | APIC_LVT_MASKED);
152 APICWrite(APIC_LVTT, APIC_LVT_MASKED);
158 APICWrite(APIC_LVT3, APIC_LVT3_MASKED);
163 APICWrite(APIC_LVTPC, APIC_LVT_MASKED);
168 APICWrite(APIC_LVTTHMR, APIC_LVT_MASKED);
221 tmp &= ~APIC_SIVR_ENABLE;
229 DbgPrint(
"0123456789abcdef0123456789abcdef\n");
230 for (
i = 0;
i < 8;
i++)
232 v = APICRead(
base +
i*0x10);
233 for (
j = 0;
j < 32;
j++)
252 ULONG CPU = ThisCPU();
260 DbgPrint(
"\nPrinting local APIC contents on CPU(%d):\n", ThisCPU());
262 DbgPrint(
"... ID : %08x (%01x) ",
v, GET_APIC_ID(
v));
265 ver = GET_APIC_VERSION(
v);
271 if (APIC_INTEGRATED(ver))
275 DbgPrint(
"... APR : %08x (%02x)\n",
v,
v & ~0);
299 if (APIC_INTEGRATED(ver))
316 v = APICRead(APIC_LVTT);
322 v = APICRead(APIC_LVTPC);
332 v = APICRead(APIC_LVT3);
336 v = APICRead(APIC_ICRT);
338 v = APICRead(APIC_CCRT);
343 DbgPrint(
"Last register read (offset): 0x%08X\n",
r1);
344 DbgPrint(
"Last register read (value): 0x%08X\n",
r2);
345 DbgPrint(
"Last register written (offset): 0x%08X\n",
w1);
346 DbgPrint(
"Last register written (value): 0x%08X\n",
w2);
357 DPRINT1(
"Getting VERSION: %x\n", reg0);
358 APICWrite(
APIC_VER, reg0 ^ APIC_VER_MASK);
360 DPRINT1(
"Getting VERSION: %x\n", reg1);
376 reg1 = GET_APIC_VERSION(reg0);
377 if (reg1 == 0x00 || reg1 == 0xff)
382 if (reg1 < 0x02 || reg1 == 0xff)
391 DPRINT1(
"Getting ID: %x\n", reg0);
392 APICWrite(
APIC_ID, reg0 ^ APIC_ID_MASK);
394 DPRINT1(
"Getting ID: %x\n", reg1);
396 if (reg1 != (reg0 ^ APIC_ID_MASK))
403 if (!(MsrValue.
LowPart & (1<<11)))
405 DPRINT1(
"Local APIC disabled by BIOS -- reenabling.\n");
407 MsrValue.
LowPart |= (1<<11)|0xfee00000;
426 for (
i = 0;
i < 10000;
i++)
430 if ((tmp & APIC_ICR0_DS) == 0)
437 DPRINT1(
"CPU(%d) Previous IPI was not delivered after 100ms.\n", ThisCPU());
444 if (
Target == APIC_TARGET_SELF)
446 Mode |= APIC_ICR0_DESTS_SELF;
448 else if (
Target == APIC_TARGET_ALL)
450 Mode |= APIC_ICR0_DESTS_ALL;
452 else if (
Target == APIC_TARGET_ALL_BUT_SELF)
454 Mode |= APIC_ICR0_DESTS_ALL_BUT_SELF;
458 Mode |= APIC_ICR0_DESTS_FIELD;
465 for (
i = 0;
i < 10000;
i++)
469 if ((tmp & APIC_ICR0_DS) == 0)
476 DPRINT1(
"CPU(%d) Current IPI was not delivered after 100ms.\n", ThisCPU());
491 DPRINT1(
" Physical APIC id: %d\n", GET_APIC_ID(APICRead(
APIC_ID)));
492 DPRINT1(
" Logical APIC id: %d\n", GET_APIC_LOGICAL_ID(APICRead(
APIC_LDR)));
511 tmp &= ~APIC_LDR_MASK;
521 DPRINT1(
" Physical APIC id: %d\n", GET_APIC_ID(APICRead(
APIC_ID)));
522 DPRINT1(
" Logical APIC id: %d\n", GET_APIC_LOGICAL_ID(APICRead(
APIC_LDR)));
532 tmp |= APIC_SIVR_ENABLE;
535 tmp &= ~APIC_SIVR_FOCUS;
537 tmp |= APIC_SIVR_FOCUS;
541 tmp |= SPURIOUS_VECTOR;
554 tmp = APIC_DM_EXTINT;
555 DPRINT1(
"enabled ExtINT on CPU#%d\n", CPU);
559 tmp = APIC_DM_EXTINT | APIC_LVT_MASKED;
560 DPRINT1(
"masked ExtINT on CPU#%d\n", CPU);
573 tmp = APIC_DM_NMI | APIC_LVT_MASKED;
575 if (!APIC_INTEGRATED(
CPUMap[CPU].APICVersion))
578 tmp |= APIC_LVT_LEVEL_TRIGGER;
582 if (APIC_INTEGRATED(
CPUMap[CPU].APICVersion))
592 DPRINT(
"ESR value before enabling vector: 0x%X\n", tmp);
596 APICWrite(APIC_LVT3, tmp);
606 DPRINT(
"ESR value after enabling vector: 0x%X\n", tmp);
615 for (
i = 0;
i < 10000;
i++)
619 if ((tmp & APIC_ICR0_DS) == 0)
626 DPRINT(
"CPU(%d) APIC busy for 100ms.\n", ThisCPU());
629 DPRINT(
"Synchronizing Arb IDs.\n");
630 APICWrite(
APIC_ICR0, APIC_ICR0_DESTS_ALL | APIC_ICR0_LEVEL | APIC_DM_INIT);
643 DPRINT1(
"APIC error on CPU(%d) ESR(%x)(%x)\n", ThisCPU(), tmp1, tmp2);
660 DPRINT1(
"APIC error on CPU(%d) ESR(%x)(%x)\n", ThisCPU(), tmp1, tmp2);
668 DPRINT(
"Spurious interrupt on CPU(%d)\n", ThisCPU());
670 tmp = APICRead(
APIC_ISR + ((SPURIOUS_VECTOR & ~0x1f) >> 1));
671 if (tmp & (1 << (SPURIOUS_VECTOR & 0x1f)))
692 DbgPrint(
"(%s:%d) MpsIpiHandler on CPU%d, current irql is %d\n",
718 TrapFrame->
Eax = IrqTrapFrame->
Eax;
719 TrapFrame->
Ecx = IrqTrapFrame->
Ecx;
720 TrapFrame->
Edx = IrqTrapFrame->
Edx;
721 TrapFrame->
Ebx = IrqTrapFrame->
Ebx;
723 TrapFrame->
Ebp = IrqTrapFrame->
Ebp;
724 TrapFrame->
Esi = IrqTrapFrame->
Esi;
725 TrapFrame->
Edi = IrqTrapFrame->
Edi;
726 TrapFrame->
Eip = IrqTrapFrame->
Eip;
727 TrapFrame->
SegCs = IrqTrapFrame->
Cs;
748 if ((
Count[CPU] % 100) == 0)
750 DbgPrint(
"(%s:%d) MpsTimerHandler on CPU%d, irql = %d, epi = %x, KPCR = %x\n", __FILE__, __LINE__, CPU, oldIrql,Trapframe->
Eip,
KeGetPcr());
774 tmp = GET_APIC_VERSION(APICRead(
APIC_VER));
775 if (!APIC_INTEGRATED(tmp))
777 tmp = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;
782 tmp = APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;
784 APICWrite(APIC_LVTT, tmp);
787 tmp &= ~(APIC_TDCR_1 | APIC_TIMER_BASE_DIV);
800 DPRINT(
"Calibrating APIC timer for CPU %d\n", CPU);
820 tt1 = APICRead(APIC_CCRT);
825 tt2 = APICRead(APIC_CCRT);
830 DPRINT(
"CPU clock speed is %ld.%04ld MHz.\n",
831 CPUMap[CPU].CoreSpeed/1000000,
832 CPUMap[CPU].CoreSpeed%1000000);
843 DPRINT(
"Host bus clock speed is %ld.%04ld MHz.\n",
844 CPUMap[CPU].BusSpeed/1000000,
845 CPUMap[CPU].BusSpeed%1000000);
881 idt->Access = Access.
Value;
901 BSPInitialized =
TRUE;
918 DPRINT(
"No APIC found\n");
961 PCOMMON_AREA_INFO Common;
964 ULONG DeliveryStatus = 0;
965 ULONG AcceptStatus = 0;
967 if (Cpu >= MAX_CPU ||
973 DPRINT1(
"Attempting to boot CPU %d\n", Cpu);
977 APICSendIPI(Cpu, APIC_DM_INIT|APIC_ICR0_LEVEL_ASSERT);
983 APICSendIPI(Cpu, APIC_DM_INIT|APIC_ICR0_LEVEL_DEASSERT);
985 if (APIC_INTEGRATED(
CPUMap[Cpu].APICVersion))
989 tmp = (APICRead(
APIC_ESR) & APIC_ESR_MASK);
992 Common = (PCOMMON_AREA_INFO)CommonBase;
1003 DPRINT1(
"%x %x %x %x\n", Common->Stack, Common->PageDirectory, Common->NtProcessStartup, Common->PaeModeEnabled);
1005 DPRINT(
"Cpu %d got stack at 0x%X\n", Cpu, Common->Stack);
1007 for (
j = 0;
j < 16;
j++)
1009 Common->Debug[
j] = 0;
1016 StartupCount = (APIC_INTEGRATED(
CPUMap[Cpu].APICVersion)) ? 2 : 0;
1018 for (
i = 1;
i <= StartupCount;
i++)
1021 DPRINT(
"Sending startup signal %d\n",
i);
1026 APICSendIPI(Cpu, APIC_DM_STARTUP | ((
COMMON_AREA +
PAGE_SIZE) >> 12)|APIC_ICR0_LEVEL_DEASSERT);
1035 DeliveryStatus = APICRead(
APIC_ICR0) & APIC_ICR0_DS;
1038 }
while ((DeliveryStatus) && (
j < 1000));
1051 AcceptStatus = APICRead(
APIC_ESR) & APIC_ESR_MASK;
1053 if (DeliveryStatus || AcceptStatus)
1061 DPRINT(
"STARTUP IPI for CPU %d was never delivered.\n", Cpu);
1066 DPRINT(
"STARTUP IPI for CPU %d was never accepted.\n", Cpu);
1069 if (!(DeliveryStatus || AcceptStatus))
1073 DPRINT(
"Waiting for 5 seconds for CPU %d to boot\n", Cpu);
1076 for (
j = 0;
j < 50000;
j++)
1088 DbgPrint(
"CPU %d is now running\n", Cpu);
1092 DbgPrint(
"Initialization of CPU %d failed\n", Cpu);
1096 DPRINT(
"Debug bytes are:\n");
1098 for (
j = 0;
j < 4;
j++)
1100 DPRINT(
"0x%08X 0x%08X 0x%08X 0x%08X.\n",
1101 Common->Debug[
j*4+0],
1102 Common->Debug[
j*4+1],
1103 Common->Debug[
j*4+2],
1104 Common->Debug[
j*4+3]);
1120 TrapFrame->Eip = TrapFrame->Eax;
VOID DECLSPEC_NORETURN FASTCALL HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
VOID NTAPI HalEndSystemInterrupt(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
#define KeGetCurrentIrql()
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
void __cdecl _disable(void)
void __cdecl _enable(void)
PPC_QUAL void __writemsr(const unsigned long Value)
PPC_QUAL unsigned long long __readmsr()
PPC_QUAL unsigned long long __rdtsc(void)
__INTRIN_INLINE unsigned long __readcr3(void)
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
__INTRIN_INLINE unsigned long __readcr4(void)
__INTRIN_INLINE uintptr_t __readeflags(void)
#define memcpy(s1, s2, n)
#define KeStallExecutionProcessor(MicroSeconds)
VOID APICSetupLVTT(ULONG ClockTicks)
VOID MpsTimerHandler(ULONG Vector, PKIRQ_TRAPFRAME Trapframe)
ULONG Read8254Timer(VOID)
VOID MpsErrorInterrupt(VOID)
#define CMOS_WRITE(address, value)
VOID MpsIpiInterrupt(VOID)
VOID MpsIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame, PKTRAP_FRAME TrapFrame)
ULONG APICGetMaxLVT(VOID)
VOID WaitFor8254Wraparound(VOID)
VOID EnableApicMode(VOID)
VOID APICCalibrateTimer(ULONG CPU)
__inline VOID DisableSMPMode(VOID)
VOID MpsSpuriousHandler(VOID)
static VOID APICDumpBit(ULONG base)
VOID SetInterruptGate(ULONG index, ULONG_PTR address)
VOID MpsSpuriousInterrupt(VOID)
VOID MpsTimerInterrupt(VOID)
VOID MpsErrorHandler(VOID)
BOOLEAN VerifyLocalAPIC(VOID)
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
#define I386_INTERRUPT_GATE
#define DECLSPEC_NORETURN
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
BOOLEAN NTAPI KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
#define WRITE_PORT_UCHAR(p, d)
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
VOID NTAPI NtProcessStartup(PPEB Peb)
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
_Must_inspect_result_ _In_ ULONG Flags