ReactOS 0.4.15-dev-7788-g1ad9096
apic.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2004, 2005 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19/*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * FILE: hal/halx86/mp/apic.c
23 * PURPOSE:
24 * PROGRAMMER:
25 */
26
27/* INCLUDE ***********************************************************************/
28
29#include <hal.h>
30#include <halfuncs.h> /* Not in PCH because only used for MP HAL */
31#include <rtlfuncs.h> /* Not in PCH because only used for MP HAL */
32#define NDEBUG
33#include <debug.h>
34
35/* GLOBALS ***********************************************************************/
36
37ULONG CPUCount; /* Total number of CPUs */
38ULONG BootCPU; /* Bootstrap processor */
39ULONG OnlineCPUs; /* Bitmask of online CPUs */
40CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in the system */
41
42#ifdef CONFIG_SMP
43PULONG BIOSBase; /* Virtual address of BIOS data segment */
44PULONG CommonBase; /* Virtual address of common area */
45#endif
46
47PULONG APICBase = (PULONG)APIC_DEFAULT_BASE; /* Virtual address of local APIC */
48
49ULONG APICMode; /* APIC mode at startup */
50
51/* For debugging */
52ULONG lastregr[MAX_CPU];
53ULONG lastvalr[MAX_CPU];
54ULONG lastregw[MAX_CPU];
55ULONG lastvalw[MAX_CPU];
56
57#ifdef CONFIG_SMP
58#include <pshpack1.h>
59typedef struct _COMMON_AREA_INFO
60{
61 ULONG Stack; /* Location of AP stack */
62 ULONG PageDirectory; /* Page directory for an AP */
63 ULONG NtProcessStartup; /* Kernel entry point for an AP */
64 ULONG PaeModeEnabled; /* PAE mode is enabled */
65 ULONG Debug[16]; /* For debugging */
66} COMMON_AREA_INFO, *PCOMMON_AREA_INFO;
67#include <poppack.h>
68#endif
69
70extern CHAR *APstart, *APend;
71
72#define BIOS_AREA 0x0
73#define COMMON_AREA 0x2000
74
75#define HZ (100)
76#define APIC_DIVISOR (16)
77
78#define CMOS_READ(address) { \
79 WRITE_PORT_UCHAR((PUCHAR)0x70, address)); \
80 READ_PORT_UCHAR((PUCHAR)0x71)); \
81}
82
83#define CMOS_WRITE(address, value) { \
84 WRITE_PORT_UCHAR((PUCHAR)0x70, address); \
85 WRITE_PORT_UCHAR((PUCHAR)0x71, value); \
86}
87
89
90/* FUNCTIONS *********************************************************************/
91
98
100{
101 ULONG tmp, ver, maxlvt;
102
103 tmp = APICRead(APIC_VER);
104 ver = GET_APIC_VERSION(tmp);
105 /* 82489DXs do not report # of LVT entries. */
106 maxlvt = APIC_INTEGRATED(ver) ? GET_APIC_MAXLVT(tmp) : 2;
107
108 return maxlvt;
109}
110
112{
113 ULONG tmp, maxlvt;
114
115 maxlvt = APICGetMaxLVT();
116
117 /*
118 * Careful: we have to set masks only first to deassert
119 * any level-triggered sources.
120 */
121
122 if (maxlvt >= 3)
123 {
124 tmp = ERROR_VECTOR;
125 APICWrite(APIC_LVT3, tmp | APIC_LVT3_MASKED);
126 }
127
128 tmp = APICRead(APIC_LVTT);
129 APICWrite(APIC_LVTT, tmp | APIC_LVT_MASKED);
130
131 tmp = APICRead(APIC_LINT0);
132 APICWrite(APIC_LINT0, tmp | APIC_LVT_MASKED);
133
134 tmp = APICRead(APIC_LINT1);
135 APICWrite(APIC_LINT1, tmp | APIC_LVT_MASKED);
136
137 if (maxlvt >= 4)
138 {
139 tmp = APICRead(APIC_LVTPC);
140 APICWrite(APIC_LVTPC, tmp | APIC_LVT_MASKED);
141 }
142#if 0
143 if (maxlvt >= 5)
144 {
145 tmp = APICRead(APIC_LVTTHMR);
146 APICWrite(APIC_LVTTHMR, tmp | APIC_LVT_MASKED);
147 }
148#endif
149 /*
150 * Clean APIC state for other OSs:
151 */
152 APICWrite(APIC_LVTT, APIC_LVT_MASKED);
153 APICWrite(APIC_LINT0, APIC_LVT_MASKED);
154 APICWrite(APIC_LINT1, APIC_LVT_MASKED);
155
156 if (maxlvt >= 3)
157 {
158 APICWrite(APIC_LVT3, APIC_LVT3_MASKED);
159 }
160
161 if (maxlvt >= 4)
162 {
163 APICWrite(APIC_LVTPC, APIC_LVT_MASKED);
164 }
165#if 0
166 if (maxlvt >= 5)
167 {
168 APICWrite(APIC_LVTTHMR, APIC_LVT_MASKED);
169 }
170#endif
171}
172
173/* Enable symetric I/O mode ie. connect the BSP's local APIC to INT and NMI lines */
175{
176 /*
177 * Do not trust the local APIC being empty at bootup.
178 */
179 APICClear();
180
181 WRITE_PORT_UCHAR((PUCHAR)0x22, 0x70);
182 WRITE_PORT_UCHAR((PUCHAR)0x23, 0x01);
183}
184
185/* Disable symetric I/O mode ie. go to PIC mode */
187{
188 /*
189 * Put the board back into PIC mode (has an effect
190 * only on certain older boards). Note that APIC
191 * interrupts, including IPIs, won't work beyond
192 * this point! The only exception are INIT IPIs.
193 */
194 WRITE_PORT_UCHAR((PUCHAR)0x22, 0x70);
195 WRITE_PORT_UCHAR((PUCHAR)0x23, 0x00);
196}
197
199{
200 ULONG tmp;
201
202 if (APICGetMaxLVT() > 3)
203 {
204 APICWrite(APIC_ESR, 0);
205 }
206 tmp = APICRead(APIC_ESR);
207 DbgPrint("ESR %08x\n", tmp);
208}
209
210
212{
213 ULONG tmp;
214
215 APICClear();
216
217 /*
218 * Disable APIC (implies clearing of registers for 82489DX!).
219 */
220 tmp = APICRead(APIC_SIVR);
221 tmp &= ~APIC_SIVR_ENABLE;
222 APICWrite(APIC_SIVR, tmp);
223}
224
226{
227 ULONG v, i, j;
228
229 DbgPrint("0123456789abcdef0123456789abcdef\n");
230 for (i = 0; i < 8; i++)
231 {
232 v = APICRead(base + i*0x10);
233 for (j = 0; j < 32; j++)
234 {
235 if (v & (1<<j))
236 DbgPrint("1");
237 else
238 DbgPrint("0");
239 }
240 DbgPrint("\n");
241 }
242}
243
244
246/*
247 * Dump the contents of the local APIC registers
248 */
249{
250 ULONG v, ver, maxlvt;
251 ULONG r1, r2, w1, w2;
252 ULONG CPU = ThisCPU();
253
254
255 r1 = lastregr[CPU];
256 r2 = lastvalr[CPU];
257 w1 = lastregw[CPU];
258 w2 = lastvalw[CPU];
259
260 DbgPrint("\nPrinting local APIC contents on CPU(%d):\n", ThisCPU());
261 v = APICRead(APIC_ID);
262 DbgPrint("... ID : %08x (%01x) ", v, GET_APIC_ID(v));
263 v = APICRead(APIC_VER);
264 DbgPrint("... VERSION: %08x\n", v);
265 ver = GET_APIC_VERSION(v);
266 maxlvt = APICGetMaxLVT();
267
268 v = APICRead(APIC_TPR);
269 DbgPrint("... TPR : %08x (%02x)", v, v & ~0);
270
271 if (APIC_INTEGRATED(ver))
272 {
273 /* !82489DX */
274 v = APICRead(APIC_APR);
275 DbgPrint("... APR : %08x (%02x)\n", v, v & ~0);
276 v = APICRead(APIC_PPR);
277 DbgPrint("... PPR : %08x\n", v);
278 }
279
280 v = APICRead(APIC_EOI);
281 DbgPrint("... EOI : %08x ! ", v);
282 v = APICRead(APIC_LDR);
283 DbgPrint("... LDR : %08x\n", v);
284 v = APICRead(APIC_DFR);
285 DbgPrint("... DFR : %08x ! ", v);
286 v = APICRead(APIC_SIVR);
287 DbgPrint("... SIVR : %08x\n", v);
288
289 if (0)
290 {
291 DbgPrint("... ISR field:\n");
293 DbgPrint("... TMR field:\n");
295 DbgPrint("... IRR field:\n");
297 }
298
299 if (APIC_INTEGRATED(ver))
300 {
301 /* !82489DX */
302 if (maxlvt > 3)
303 {
304 /* Due to the Pentium erratum 3AP. */
305 APICWrite(APIC_ESR, 0);
306 }
307 v = APICRead(APIC_ESR);
308 DbgPrint("... ESR : %08x\n", v);
309 }
310
311 v = APICRead(APIC_ICR0);
312 DbgPrint("... ICR0 : %08x ! ", v);
313 v = APICRead(APIC_ICR1);
314 DbgPrint("... ICR1 : %08x ! ", v);
315
316 v = APICRead(APIC_LVTT);
317 DbgPrint("... LVTT : %08x\n", v);
318
319 if (maxlvt > 3)
320 {
321 /* PC is LVT#4. */
322 v = APICRead(APIC_LVTPC);
323 DbgPrint("... LVTPC : %08x ! ", v);
324 }
325 v = APICRead(APIC_LINT0);
326 DbgPrint("... LINT0 : %08x ! ", v);
327 v = APICRead(APIC_LINT1);
328 DbgPrint("... LINT1 : %08x\n", v);
329
330 if (maxlvt > 2)
331 {
332 v = APICRead(APIC_LVT3);
333 DbgPrint("... LVT3 : %08x\n", v);
334 }
335
336 v = APICRead(APIC_ICRT);
337 DbgPrint("... ICRT : %08x ! ", v);
338 v = APICRead(APIC_CCRT);
339 DbgPrint("... CCCT : %08x ! ", v);
340 v = APICRead(APIC_TDCR);
341 DbgPrint("... TDCR : %08x\n", v);
342 DbgPrint("\n");
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);
347 DbgPrint("\n");
348}
349
351{
352 SIZE_T reg0, reg1;
353 LARGE_INTEGER MsrValue;
354
355 /* The version register is read-only in a real APIC */
356 reg0 = APICRead(APIC_VER);
357 DPRINT1("Getting VERSION: %x\n", reg0);
358 APICWrite(APIC_VER, reg0 ^ APIC_VER_MASK);
359 reg1 = APICRead(APIC_VER);
360 DPRINT1("Getting VERSION: %x\n", reg1);
361
362 /*
363 * The two version reads above should print the same
364 * numbers. If the second one is different, then we
365 * poke at a non-APIC.
366 */
367
368 if (reg1 != reg0)
369 {
370 return FALSE;
371 }
372
373 /*
374 * Check if the version looks reasonably.
375 */
376 reg1 = GET_APIC_VERSION(reg0);
377 if (reg1 == 0x00 || reg1 == 0xff)
378 {
379 return FALSE;
380 }
381 reg1 = APICGetMaxLVT();
382 if (reg1 < 0x02 || reg1 == 0xff)
383 {
384 return FALSE;
385 }
386
387 /*
388 * The ID register is read/write in a real APIC.
389 */
390 reg0 = APICRead(APIC_ID);
391 DPRINT1("Getting ID: %x\n", reg0);
392 APICWrite(APIC_ID, reg0 ^ APIC_ID_MASK);
393 reg1 = APICRead(APIC_ID);
394 DPRINT1("Getting ID: %x\n", reg1);
395 APICWrite(APIC_ID, reg0);
396 if (reg1 != (reg0 ^ APIC_ID_MASK))
397 {
398 return FALSE;
399 }
400
401 MsrValue.QuadPart = __readmsr(0x1B /*MSR_IA32_APICBASE*/);
402
403 if (!(MsrValue.LowPart & /*MSR_IA32_APICBASE_ENABLE*/(1<<11)))
404 {
405 DPRINT1("Local APIC disabled by BIOS -- reenabling.\n");
406 MsrValue.LowPart &= ~/*MSR_IA32_APICBASE_BASE*/(1<<11);
407 MsrValue.LowPart |= /*MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE*/(1<<11)|0xfee00000;
408 __writemsr(0x1B /*MSR_IA32_APICBASE*/, MsrValue.HighPart);
409 }
410
411
412
413 return TRUE;
414}
415
416#ifdef CONFIG_SMP
417VOID APICSendIPI(ULONG Target, ULONG Mode)
418{
419 ULONG tmp, i, flags;
420
421 /* save flags and disable interrupts */
423 _disable();
424
425 /* Wait up to 100ms for the APIC to become ready */
426 for (i = 0; i < 10000; i++)
427 {
428 tmp = APICRead(APIC_ICR0);
429 /* Check Delivery Status */
430 if ((tmp & APIC_ICR0_DS) == 0)
431 break;
433 }
434
435 if (i == 10000)
436 {
437 DPRINT1("CPU(%d) Previous IPI was not delivered after 100ms.\n", ThisCPU());
438 }
439
440 /* Setup the APIC to deliver the IPI */
441 DPRINT("%08x %x\n", SET_APIC_DEST_FIELD(Target), Target);
442 APICWrite(APIC_ICR1, SET_APIC_DEST_FIELD(Target));
443
444 if (Target == APIC_TARGET_SELF)
445 {
446 Mode |= APIC_ICR0_DESTS_SELF;
447 }
448 else if (Target == APIC_TARGET_ALL)
449 {
450 Mode |= APIC_ICR0_DESTS_ALL;
451 }
452 else if (Target == APIC_TARGET_ALL_BUT_SELF)
453 {
454 Mode |= APIC_ICR0_DESTS_ALL_BUT_SELF;
455 }
456 else
457 {
458 Mode |= APIC_ICR0_DESTS_FIELD;
459 }
460
461 /* Now, fire off the IPI */
462 APICWrite(APIC_ICR0, Mode);
463
464 /* Wait up to 100ms for the APIC to become ready */
465 for (i = 0; i < 10000; i++)
466 {
467 tmp = APICRead(APIC_ICR0);
468 /* Check Delivery Status */
469 if ((tmp & APIC_ICR0_DS) == 0)
470 break;
472 }
473
474 if (i == 10000)
475 {
476 DPRINT1("CPU(%d) Current IPI was not delivered after 100ms.\n", ThisCPU());
477 }
479}
480#endif
481
483{
484 ULONG CPU, tmp;
485
486 CPU = ThisCPU();
487
488// APICDump();
489
490 DPRINT1("CPU%d:\n", CPU);
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)));
493 DPRINT1("%08x %08x %08x\n", APICRead(APIC_ID), APICRead(APIC_LDR), APICRead(APIC_DFR));
494
495 /*
496 * Intel recommends to set DFR, LDR and TPR before enabling
497 * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
498 * document number 292116). So here it goes...
499 */
500
501 /*
502 * Put the APIC into flat delivery mode.
503 * Must be "all ones" explicitly for 82489DX.
504 */
505 APICWrite(APIC_DFR, 0xFFFFFFFF);
506
507 /*
508 * Set up the logical destination ID.
509 */
510 tmp = APICRead(APIC_LDR);
511 tmp &= ~APIC_LDR_MASK;
512 /*
513 * FIXME:
514 * This works only up to 8 CPU's
515 */
516 tmp |= (1 << (KeGetCurrentProcessorNumber() + 24));
517 APICWrite(APIC_LDR, tmp);
518
519
520 DPRINT1("CPU%d:\n", CPU);
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)));
523 DPRINT1("%08x %08x %08x\n", APICRead(APIC_ID), APICRead(APIC_LDR), APICRead(APIC_DFR));
524 DPRINT1("%d\n", CPUMap[CPU].APICId);
525
526 /* Accept only higher interrupts */
527 APICWrite(APIC_TPR, 0xef);
528
529 /* Enable local APIC */
530 tmp = APICRead(APIC_SIVR);
531 tmp &= ~0xff;
532 tmp |= APIC_SIVR_ENABLE;
533
534#if 0
535 tmp &= ~APIC_SIVR_FOCUS;
536#else
537 tmp |= APIC_SIVR_FOCUS;
538#endif
539
540 /* Set spurious interrupt vector */
541 tmp |= SPURIOUS_VECTOR;
542 APICWrite(APIC_SIVR, tmp);
543
544 /*
545 * Set up LVT0, LVT1:
546 *
547 * set up through-local-APIC on the BP's LINT0. This is not
548 * strictly necessery in pure symmetric-IO mode, but sometimes
549 * we delegate interrupts to the 8259A.
550 */
551 tmp = APICRead(APIC_LINT0) & APIC_LVT_MASKED;
552 if (CPU == BootCPU && (APICMode == amPIC || !tmp))
553 {
554 tmp = APIC_DM_EXTINT;
555 DPRINT1("enabled ExtINT on CPU#%d\n", CPU);
556 }
557 else
558 {
559 tmp = APIC_DM_EXTINT | APIC_LVT_MASKED;
560 DPRINT1("masked ExtINT on CPU#%d\n", CPU);
561 }
562 APICWrite(APIC_LINT0, tmp);
563
564 /*
565 * Only the BSP should see the LINT1 NMI signal, obviously.
566 */
567 if (CPU == BootCPU)
568 {
569 tmp = APIC_DM_NMI;
570 }
571 else
572 {
573 tmp = APIC_DM_NMI | APIC_LVT_MASKED;
574 }
575 if (!APIC_INTEGRATED(CPUMap[CPU].APICVersion))
576 {
577 /* 82489DX */
578 tmp |= APIC_LVT_LEVEL_TRIGGER;
579 }
580 APICWrite(APIC_LINT1, tmp);
581
582 if (APIC_INTEGRATED(CPUMap[CPU].APICVersion))
583 {
584 /* !82489DX */
585 if (APICGetMaxLVT() > 3)
586 {
587 /* Due to the Pentium erratum 3AP */
588 APICWrite(APIC_ESR, 0);
589 }
590
591 tmp = APICRead(APIC_ESR);
592 DPRINT("ESR value before enabling vector: 0x%X\n", tmp);
593
594 /* Enable sending errors */
595 tmp = ERROR_VECTOR;
596 APICWrite(APIC_LVT3, tmp);
597
598 /*
599 * Spec says clear errors after enabling vector
600 */
601 if (APICGetMaxLVT() > 3)
602 {
603 APICWrite(APIC_ESR, 0);
604 }
605 tmp = APICRead(APIC_ESR);
606 DPRINT("ESR value after enabling vector: 0x%X\n", tmp);
607 }
608}
609#ifdef CONFIG_SMP
610VOID APICSyncArbIDs(VOID)
611{
612 ULONG i, tmp;
613
614 /* Wait up to 100ms for the APIC to become ready */
615 for (i = 0; i < 10000; i++)
616 {
617 tmp = APICRead(APIC_ICR0);
618 /* Check Delivery Status */
619 if ((tmp & APIC_ICR0_DS) == 0)
620 break;
622 }
623
624 if (i == 10000)
625 {
626 DPRINT("CPU(%d) APIC busy for 100ms.\n", ThisCPU());
627 }
628
629 DPRINT("Synchronizing Arb IDs.\n");
630 APICWrite(APIC_ICR0, APIC_ICR0_DESTS_ALL | APIC_ICR0_LEVEL | APIC_DM_INIT);
631}
632#endif
633
635{
636 ULONG tmp1, tmp2;
637
638 APICDump();
639
640 tmp1 = APICRead(APIC_ESR);
641 APICWrite(APIC_ESR, 0);
642 tmp2 = APICRead(APIC_ESR);
643 DPRINT1("APIC error on CPU(%d) ESR(%x)(%x)\n", ThisCPU(), tmp1, tmp2);
644
645 /*
646 * Acknowledge the interrupt
647 */
648 APICSendEOI();
649
650 /* Here is what the APIC error bits mean:
651 * 0: Send CS error
652 * 1: Receive CS error
653 * 2: Send accept error
654 * 3: Receive accept error
655 * 4: Reserved
656 * 5: Send illegal vector
657 * 6: Received illegal vector
658 * 7: Illegal register address
659 */
660 DPRINT1("APIC error on CPU(%d) ESR(%x)(%x)\n", ThisCPU(), tmp1, tmp2);
661 for (;;);
662}
663
665{
666 ULONG tmp;
667
668 DPRINT("Spurious interrupt on CPU(%d)\n", ThisCPU());
669
670 tmp = APICRead(APIC_ISR + ((SPURIOUS_VECTOR & ~0x1f) >> 1));
671 if (tmp & (1 << (SPURIOUS_VECTOR & 0x1f)))
672 {
673 APICSendEOI();
674 return;
675 }
676#if 0
677 /* No need to send EOI here */
678 APICDump();
679#endif
680}
681
682#ifdef CONFIG_SMP
683VOID MpsIpiHandler(VOID)
684{
685 KIRQL oldIrql;
686
688 IPI_VECTOR,
689 &oldIrql);
690 _enable();
691#if 0
692 DbgPrint("(%s:%d) MpsIpiHandler on CPU%d, current irql is %d\n",
693 __FILE__,__LINE__, KeGetCurrentProcessorNumber(), KeGetCurrentIrql());
694#endif
695
697
698#if 0
699 DbgPrint("(%s:%d) MpsIpiHandler on CPU%d done\n", __FILE__,__LINE__, KeGetCurrentProcessorNumber());
700#endif
701
702 _disable();
703 HalEndSystemInterrupt(oldIrql, 0);
704}
705#endif
706
707VOID
709 PKTRAP_FRAME TrapFrame)
710{
711#ifdef _M_AMD64
713#else
714 TrapFrame->SegGs = (USHORT)IrqTrapFrame->Gs;
715 TrapFrame->SegFs = (USHORT)IrqTrapFrame->Fs;
716 TrapFrame->SegEs = (USHORT)IrqTrapFrame->Es;
717 TrapFrame->SegDs = (USHORT)IrqTrapFrame->Ds;
718 TrapFrame->Eax = IrqTrapFrame->Eax;
719 TrapFrame->Ecx = IrqTrapFrame->Ecx;
720 TrapFrame->Edx = IrqTrapFrame->Edx;
721 TrapFrame->Ebx = IrqTrapFrame->Ebx;
722 TrapFrame->HardwareEsp = IrqTrapFrame->Esp;
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;
728 TrapFrame->EFlags = IrqTrapFrame->Eflags;
729#endif
730}
731
732VOID
734{
735 KIRQL oldIrql;
736 KTRAP_FRAME KernelTrapFrame;
737#if 0
738 ULONG CPU;
739 static ULONG Count[MAX_CPU] = {0,};
740#endif
741 HalBeginSystemInterrupt(LOCAL_TIMER_VECTOR,
743 &oldIrql);
744 _enable();
745
746#if 0
747 CPU = ThisCPU();
748 if ((Count[CPU] % 100) == 0)
749 {
750 DbgPrint("(%s:%d) MpsTimerHandler on CPU%d, irql = %d, epi = %x, KPCR = %x\n", __FILE__, __LINE__, CPU, oldIrql,Trapframe->Eip, KeGetPcr());
751 }
752 Count[CPU]++;
753#endif
754
755 /* FIXME: SMP is totally broken */
756 MpsIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
758 {
759 //KeUpdateSystemTime(&KernelTrapFrame, oldIrql);
760 }
761 else
762 {
763 //KeUpdateRunTime(&KernelTrapFrame, oldIrql);
764 }
765
766 _disable();
767 HalEndSystemInterrupt (oldIrql, 0);
768}
769
771{
772 ULONG tmp;
773
774 tmp = GET_APIC_VERSION(APICRead(APIC_VER));
775 if (!APIC_INTEGRATED(tmp))
776 {
777 tmp = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;
778 }
779 else
780 {
781 /* Periodic timer */
782 tmp = APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;
783 }
784 APICWrite(APIC_LVTT, tmp);
785
786 tmp = APICRead(APIC_TDCR);
787 tmp &= ~(APIC_TDCR_1 | APIC_TIMER_BASE_DIV);
788 tmp |= APIC_TDCR_16;
789 APICWrite(APIC_TDCR, tmp);
790 APICWrite(APIC_ICRT, ClockTicks / APIC_DIVISOR);
791}
792
793VOID
795{
796 ULARGE_INTEGER t1, t2;
797 LONG tt1, tt2;
798 BOOLEAN TSCPresent;
799
800 DPRINT("Calibrating APIC timer for CPU %d\n", CPU);
801
802 APICSetupLVTT(1000000000);
803
804 TSCPresent = KeGetCurrentPrcb()->FeatureBits & KF_RDTSC ? TRUE : FALSE;
805
806 /*
807 * The timer chip counts down to zero. Let's wait
808 * for a wraparound to start exact measurement:
809 * (the current tick might have been already half done)
810 */
811 //WaitFor8254Wraparound();
812
813 /*
814 * We wrapped around just now. Let's start
815 */
816 if (TSCPresent)
817 {
818 t1.QuadPart = (LONGLONG)__rdtsc();
819 }
820 tt1 = APICRead(APIC_CCRT);
821
822 //WaitFor8254Wraparound();
823
824
825 tt2 = APICRead(APIC_CCRT);
826 if (TSCPresent)
827 {
828 t2.QuadPart = (LONGLONG)__rdtsc();
829 CPUMap[CPU].CoreSpeed = (HZ * (ULONG)(t2.QuadPart - t1.QuadPart));
830 DPRINT("CPU clock speed is %ld.%04ld MHz.\n",
831 CPUMap[CPU].CoreSpeed/1000000,
832 CPUMap[CPU].CoreSpeed%1000000);
833 KeGetCurrentPrcb()->MHz = CPUMap[CPU].CoreSpeed/1000000;
834 }
835
836 CPUMap[CPU].BusSpeed = (HZ * (long)(tt1 - tt2) * APIC_DIVISOR);
837
838 /* Setup timer for normal operation */
839// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100); // 100ns
840 APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 10000); // 10ms
841// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100000); // 100ms
842
843 DPRINT("Host bus clock speed is %ld.%04ld MHz.\n",
844 CPUMap[CPU].BusSpeed/1000000,
845 CPUMap[CPU].BusSpeed%1000000);
846}
847
848VOID
850{
851#ifdef _M_AMD64
852 KIDTENTRY64 *idt;
853
854 idt = &KeGetPcr()->IdtBase[index];
855
856 idt->OffsetLow = address & 0xffff;
857 idt->Selector = KGDT_64_R0_CODE;
858 idt->IstIndex = 0;
859 idt->Reserved0 = 0;
860 idt->Type = 0x0e;
861 idt->Dpl = 0;
862 idt->Present = 1;
863 idt->OffsetMiddle = (address >> 16) & 0xffff;
864 idt->OffsetHigh = address >> 32;
865 idt->Reserved1 = 0;
866 idt->Alignment = 0;
867#else
868 KIDTENTRY *idt;
869 KIDT_ACCESS Access;
870
871 /* Set the IDT Access Bits */
872 Access.Reserved = 0;
873 Access.Present = 1;
874 Access.Dpl = 0; /* Kernel-Mode */
875 Access.SystemSegmentFlag = 0;
877
878 idt = (KIDTENTRY*)((ULONG)KeGetPcr()->IDT + index * sizeof(KIDTENTRY));
879 idt->Offset = (USHORT)(address & 0xffff);
880 idt->Selector = KGDT_R0_CODE;
881 idt->Access = Access.Value;
882 idt->ExtendedOffset = (USHORT)(address >> 16);
883#endif
884}
885
887{
888#ifdef CONFIG_SMP
889 PUSHORT ps;
890#endif
891
892 static BOOLEAN BSPInitialized = FALSE;
893
894 /* Only initialize the BSP once */
895 if (BSPInitialized)
896 {
897 ASSERT(FALSE);
898 return;
899 }
900
901 BSPInitialized = TRUE;
902
903 /* Setup interrupt handlers */
904 SetInterruptGate(LOCAL_TIMER_VECTOR, (ULONG_PTR)MpsTimerInterrupt);
907#ifdef CONFIG_SMP
909#endif
910 DPRINT("APIC is mapped at 0x%X\n", APICBase);
911
912 if (VerifyLocalAPIC())
913 {
914 DPRINT("APIC found\n");
915 }
916 else
917 {
918 DPRINT("No APIC found\n");
919 ASSERT(FALSE);
920 }
921
922 if (APICMode == amPIC)
923 {
925 }
926
927 APICSetup();
928
929#ifdef CONFIG_SMP
930 /* BIOS data segment */
931 BIOSBase = (PULONG)BIOS_AREA;
932
933 /* Area for communicating with the APs */
934 CommonBase = (PULONG)COMMON_AREA;
935
936 /* Copy bootstrap code to common area */
937 memcpy((PVOID)((ULONG_PTR)CommonBase + PAGE_SIZE),
938 &APstart,
939 (ULONG_PTR)&APend - (ULONG_PTR)&APstart + 1);
940
941 /* Set shutdown code */
942 CMOS_WRITE(0xF, 0xA);
943
944 /* Set warm reset vector */
945 ps = (PUSHORT)((ULONG_PTR)BIOSBase + 0x467);
946 *ps = (COMMON_AREA + PAGE_SIZE) & 0xF;
947
948 ps = (PUSHORT)((ULONG_PTR)BIOSBase + 0x469);
949 *ps = (COMMON_AREA + PAGE_SIZE) >> 4;
950#endif
951
952 /* Calibrate APIC timer */
954}
955
956#ifdef CONFIG_SMP
957VOID
958HaliStartApplicationProcessor(ULONG Cpu, ULONG Stack)
959{
960 ULONG tmp, maxlvt;
961 PCOMMON_AREA_INFO Common;
962 ULONG StartupCount;
963 ULONG i, j;
964 ULONG DeliveryStatus = 0;
965 ULONG AcceptStatus = 0;
966
967 if (Cpu >= MAX_CPU ||
968 Cpu >= CPUCount ||
969 OnlineCPUs & (1 << Cpu))
970 {
971 ASSERT(FALSE);
972 }
973 DPRINT1("Attempting to boot CPU %d\n", Cpu);
974
975 /* Send INIT IPI */
976
977 APICSendIPI(Cpu, APIC_DM_INIT|APIC_ICR0_LEVEL_ASSERT);
978
980
981 /* Deassert INIT */
982
983 APICSendIPI(Cpu, APIC_DM_INIT|APIC_ICR0_LEVEL_DEASSERT);
984
985 if (APIC_INTEGRATED(CPUMap[Cpu].APICVersion))
986 {
987 /* Clear APIC errors */
988 APICWrite(APIC_ESR, 0);
989 tmp = (APICRead(APIC_ESR) & APIC_ESR_MASK);
990 }
991
992 Common = (PCOMMON_AREA_INFO)CommonBase;
993
994 /* Write the location of the AP stack */
995 Common->Stack = (ULONG)Stack;
996 /* Write the page directory page */
997 Common->PageDirectory = __readcr3();
998 /* Write the kernel entry point */
999 Common->NtProcessStartup = (ULONG_PTR)RtlImageNtHeader((PVOID)KernelBase)->OptionalHeader.AddressOfEntryPoint + KernelBase;
1000 /* Write the state of the mae mode */
1001 Common->PaeModeEnabled = __readcr4() & CR4_PAE ? 1 : 0;
1002
1003 DPRINT1("%x %x %x %x\n", Common->Stack, Common->PageDirectory, Common->NtProcessStartup, Common->PaeModeEnabled);
1004
1005 DPRINT("Cpu %d got stack at 0x%X\n", Cpu, Common->Stack);
1006#if 0
1007 for (j = 0; j < 16; j++)
1008 {
1009 Common->Debug[j] = 0;
1010 }
1011#endif
1012
1013 maxlvt = APICGetMaxLVT();
1014
1015 /* Is this a local APIC or an 82489DX? */
1016 StartupCount = (APIC_INTEGRATED(CPUMap[Cpu].APICVersion)) ? 2 : 0;
1017
1018 for (i = 1; i <= StartupCount; i++)
1019 {
1020 /* It's a local APIC, so send STARTUP IPI */
1021 DPRINT("Sending startup signal %d\n", i);
1022 /* Clear errors */
1023 APICWrite(APIC_ESR, 0);
1024 APICRead(APIC_ESR);
1025
1026 APICSendIPI(Cpu, APIC_DM_STARTUP | ((COMMON_AREA + PAGE_SIZE) >> 12)|APIC_ICR0_LEVEL_DEASSERT);
1027
1028 /* Wait up to 10ms for IPI to be delivered */
1029 j = 0;
1030 do
1031 {
1033
1034 /* Check Delivery Status */
1035 DeliveryStatus = APICRead(APIC_ICR0) & APIC_ICR0_DS;
1036
1037 j++;
1038 } while ((DeliveryStatus) && (j < 1000));
1039
1041
1042 /*
1043 * Due to the Pentium erratum 3AP.
1044 */
1045 if (maxlvt > 3)
1046 {
1047 APICRead(APIC_SIVR);
1048 APICWrite(APIC_ESR, 0);
1049 }
1050
1051 AcceptStatus = APICRead(APIC_ESR) & APIC_ESR_MASK;
1052
1053 if (DeliveryStatus || AcceptStatus)
1054 {
1055 break;
1056 }
1057 }
1058
1059 if (DeliveryStatus)
1060 {
1061 DPRINT("STARTUP IPI for CPU %d was never delivered.\n", Cpu);
1062 }
1063
1064 if (AcceptStatus)
1065 {
1066 DPRINT("STARTUP IPI for CPU %d was never accepted.\n", Cpu);
1067 }
1068
1069 if (!(DeliveryStatus || AcceptStatus))
1070 {
1071
1072 /* Wait no more than 5 seconds for processor to boot */
1073 DPRINT("Waiting for 5 seconds for CPU %d to boot\n", Cpu);
1074
1075 /* Wait no more than 5 seconds */
1076 for (j = 0; j < 50000; j++)
1077 {
1078 if (CPUMap[Cpu].Flags & CPU_ENABLED)
1079 {
1080 break;
1081 }
1083 }
1084 }
1085
1086 if (CPUMap[Cpu].Flags & CPU_ENABLED)
1087 {
1088 DbgPrint("CPU %d is now running\n", Cpu);
1089 }
1090 else
1091 {
1092 DbgPrint("Initialization of CPU %d failed\n", Cpu);
1093 }
1094
1095#if 0
1096 DPRINT("Debug bytes are:\n");
1097
1098 for (j = 0; j < 4; j++)
1099 {
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]);
1105 }
1106
1107#endif
1108}
1109
1110#endif
1111
1112VOID
1116{
1117 /* Set up a fake INT Stack */
1118 TrapFrame->EFlags = __readeflags();
1119 TrapFrame->SegCs = KGDT_R0_CODE;
1120 TrapFrame->Eip = TrapFrame->Eax;
1121
1122 /* Build the trap frame */
1123 KiEnterInterruptTrap(TrapFrame);
1124
1125 /* unimplemented */
1127
1128 /* Exit the interrupt */
1129 KiEoiHelper(TrapFrame);
1130
1131}
1132
1133/* EOF */
unsigned char BOOLEAN
VOID DECLSPEC_NORETURN FASTCALL HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:558
VOID NTAPI HalEndSystemInterrupt(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:815
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
Definition: apic.c:749
@ APIC_LINT1
Definition: apicp.h:100
@ APIC_PPR
Definition: apicp.h:84
@ APIC_ICR0
Definition: apicp.h:94
@ APIC_TPR
Definition: apicp.h:82
@ APIC_VER
Definition: apicp.h:81
@ APIC_LDR
Definition: apicp.h:87
@ APIC_ESR
Definition: apicp.h:93
@ APIC_IRR
Definition: apicp.h:92
@ APIC_ICR1
Definition: apicp.h:95
@ APIC_ISR
Definition: apicp.h:90
@ APIC_TDCR
Definition: apicp.h:104
@ APIC_EOI
Definition: apicp.h:85
@ APIC_ID
Definition: apicp.h:80
@ APIC_DFR
Definition: apicp.h:88
@ APIC_LINT0
Definition: apicp.h:99
@ APIC_TMR
Definition: apicp.h:91
@ APIC_SIVR
Definition: apicp.h:89
@ APIC_APR
Definition: apicp.h:83
#define index(s, c)
Definition: various.h:29
#define DPRINT1
Definition: precomp.h:8
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:81
#define UNIMPLEMENTED
Definition: debug.h:115
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define RtlImageNtHeader
Definition: compat.h:806
#define ULONG_PTR
Definition: config.h:101
#define IPI_LEVEL
Definition: env_spec_w32.h:701
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PROFILE_LEVEL
Definition: env_spec_w32.h:698
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
const GLdouble * v
Definition: gl.h:2040
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
Definition: glext.h:8308
GLuint address
Definition: glext.h:9393
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
Definition: glext.h:8308
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
Definition: glfuncs.h:248
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
Definition: glfuncs.h:250
#define DbgPrint
Definition: hal.h:12
_In_ ULONG Mode
Definition: hubbusif.h:303
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
PPC_QUAL unsigned long long __rdtsc(void)
Definition: intrin_ppc.h:688
__INTRIN_INLINE unsigned long __readcr3(void)
Definition: intrin_x86.h:1818
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1669
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1825
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1674
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ASSERT(a)
Definition: mode.c:44
static DNS_RECORDW r1
Definition: record.c:37
static DNS_RECORDW r2
Definition: record.c:38
CHAR * APend
Definition: apic.c:70
VOID APICSetupLVTT(ULONG ClockTicks)
Definition: apic.c:770
VOID APICDisable(VOID)
Definition: apic.c:211
VOID MpsTimerHandler(ULONG Vector, PKIRQ_TRAPFRAME Trapframe)
Definition: apic.c:733
ULONG Read8254Timer(VOID)
VOID APICSetup(VOID)
Definition: apic.c:482
VOID DumpESR(VOID)
Definition: apic.c:198
PULONG APICBase
Definition: apic.c:47
VOID MpsErrorInterrupt(VOID)
#define CMOS_WRITE(address, value)
Definition: apic.c:83
VOID MpsIpiInterrupt(VOID)
VOID MpsIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame, PKTRAP_FRAME TrapFrame)
Definition: apic.c:708
ULONG APICGetMaxLVT(VOID)
Definition: apic.c:99
ULONG APICMode
Definition: apic.c:49
VOID WaitFor8254Wraparound(VOID)
VOID EnableApicMode(VOID)
Definition: apic.c:174
VOID APICCalibrateTimer(ULONG CPU)
Definition: apic.c:794
ULONG lastregr[MAX_CPU]
Definition: apic.c:52
#define BIOS_AREA
Definition: apic.c:72
__inline VOID DisableSMPMode(VOID)
Definition: apic.c:186
VOID MpsSpuriousHandler(VOID)
Definition: apic.c:664
static VOID APICDumpBit(ULONG base)
Definition: apic.c:225
#define HZ
Definition: apic.c:75
VOID SetInterruptGate(ULONG index, ULONG_PTR address)
Definition: apic.c:849
CPU_INFO CPUMap[MAX_CPU]
Definition: apic.c:40
ULONG lastvalr[MAX_CPU]
Definition: apic.c:53
ULONG lastregw[MAX_CPU]
Definition: apic.c:54
ULONG_PTR KernelBase
Definition: halinit_mp.c:20
VOID MpsSpuriousInterrupt(VOID)
VOID MpsTimerInterrupt(VOID)
ULONG BootCPU
Definition: apic.c:38
VOID HaliInitBSP(VOID)
Definition: apic.c:886
CHAR * APstart
#define APIC_DIVISOR
Definition: apic.c:76
ULONG lastvalw[MAX_CPU]
Definition: apic.c:55
ULONG OnlineCPUs
Definition: apic.c:39
VOID MpsErrorHandler(VOID)
Definition: apic.c:634
#define COMMON_AREA
Definition: apic.c:73
BOOLEAN VerifyLocalAPIC(VOID)
Definition: apic.c:350
VOID APICClear(VOID)
Definition: apic.c:111
VOID APICDump(VOID)
Definition: apic.c:245
ULONG CPUCount
Definition: apic.c:37
#define KIDTENTRY
Definition: ketypes.h:549
#define CR4_PAE
Definition: ketypes.h:150
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1148
#define KF_RDTSC
Definition: ketypes.h:32
#define I386_INTERRUPT_GATE
Definition: ketypes.h:124
#define KeGetPcr()
Definition: ketypes.h:81
#define KGDT_R0_CODE
Definition: ketypes.h:123
int Count
Definition: noreturn.cpp:7
#define FASTCALL
Definition: nt_native.h:50
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
BOOLEAN NTAPI KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
Definition: ipi.c:150
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define long
Definition: qsort.c:33
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:341
#define DPRINT
Definition: sndvol32.h:71
UCHAR SystemSegmentFlag
Definition: ketypes.h:521
UCHAR Dpl
Definition: ketypes.h:522
UCHAR Reserved
Definition: ketypes.h:519
USHORT Value
Definition: ketypes.h:525
UCHAR SegmentType
Definition: ketypes.h:520
UCHAR Present
Definition: ketypes.h:523
ULONG Eip
Definition: mps.h:26
ULONG Es
Definition: mps.h:16
ULONG Ds
Definition: mps.h:17
ULONG Fs
Definition: mps.h:15
ULONG Ecx
Definition: mps.h:19
ULONG Cs
Definition: mps.h:27
ULONG Ebp
Definition: mps.h:23
ULONG Eax
Definition: mps.h:18
ULONG Esi
Definition: mps.h:24
ULONG Eflags
Definition: mps.h:28
ULONG Esp
Definition: mps.h:22
ULONG Ebx
Definition: mps.h:21
ULONG Edi
Definition: mps.h:25
ULONG Gs
Definition: mps.h:14
ULONG Edx
Definition: mps.h:20
ULONG Edi
Definition: ketypes.h:316
ULONG EFlags
Definition: ketypes.h:454
ULONG Ebp
Definition: ketypes.h:319
ULONG Ebx
Definition: ketypes.h:318
ULONG HardwareEsp
Definition: ketypes.h:324
ULONG Ecx
Definition: ketypes.h:311
ULONG Eip
Definition: ketypes.h:321
USHORT SegCs
Definition: ketypes.h:450
USHORT SegEs
Definition: ketypes.h:435
USHORT SegFs
Definition: ketypes.h:436
USHORT SegGs
Definition: ketypes.h:437
ULONG Eax
Definition: ketypes.h:312
USHORT SegDs
Definition: ketypes.h:434
ULONG Esi
Definition: ketypes.h:317
ULONG Edx
Definition: ketypes.h:310
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:368
uint32_t * PULONG
Definition: typedefs.h:59
int64_t LONGLONG
Definition: typedefs.h:68
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint16_t * PUSHORT
Definition: typedefs.h:56
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
ULONG OffsetHigh
Definition: ketypes.h:544
USHORT Reserved0
Definition: ketypes.h:539
USHORT IstIndex
Definition: ketypes.h:538
USHORT OffsetMiddle
Definition: ketypes.h:543
USHORT OffsetLow
Definition: ketypes.h:536
UINT64 Alignment
Definition: ketypes.h:547
ULONG Reserved1
Definition: ketypes.h:545
USHORT Dpl
Definition: ketypes.h:541
USHORT Present
Definition: ketypes.h:542
USHORT Selector
Definition: ketypes.h:537
USHORT Type
Definition: ketypes.h:540
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
VOID NTAPI NtProcessStartup(PPEB Peb)
Definition: usetup.c:4409
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
char CHAR
Definition: xmlstorage.h:175