ReactOS  0.4.13-dev-249-gcba1a2f
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 
37 ULONG CPUCount; /* Total number of CPUs */
38 ULONG BootCPU; /* Bootstrap processor */
39 ULONG OnlineCPUs; /* Bitmask of online CPUs */
40 CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in the system */
41 
42 #ifdef CONFIG_SMP
43 PULONG BIOSBase; /* Virtual address of BIOS data segment */
44 PULONG CommonBase; /* Virtual address of common area */
45 #endif
46 
47 PULONG APICBase = (PULONG)APIC_DEFAULT_BASE; /* Virtual address of local APIC */
48 
49 ULONG APICMode; /* APIC mode at startup */
50 
51 /* For debugging */
56 
57 #ifdef CONFIG_SMP
58 #include <pshpack1.h>
59 typedef 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 
70 extern 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 
88 extern ULONG_PTR KernelBase;
89 
90 /* FUNCTIONS *********************************************************************/
91 
92 extern ULONG Read8254Timer(VOID);
97 extern VOID MpsIpiInterrupt(VOID);
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;
126  }
127 
128  tmp = APICRead(APIC_LVTT);
130 
131  tmp = APICRead(APIC_LINT0);
133 
134  tmp = APICRead(APIC_LINT1);
136 
137  if (maxlvt >= 4)
138  {
139  tmp = APICRead(APIC_LVTPC);
141  }
142 #if 0
143  if (maxlvt >= 5)
144  {
145  tmp = APICRead(APIC_LVTTHMR);
147  }
148 #endif
149  /*
150  * Clean APIC state for other OSs:
151  */
155 
156  if (maxlvt >= 3)
157  {
159  }
160 
161  if (maxlvt >= 4)
162  {
164  }
165 #if 0
166  if (maxlvt >= 5)
167  {
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);
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
418 {
419  ULONG tmp, i, flags;
420 
421  /* save flags and disable interrupts */
422  flags = __readeflags();
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);
443 
444  if (Target == APIC_TARGET_SELF)
445  {
447  }
448  else if (Target == APIC_TARGET_ALL)
449  {
451  }
452  else if (Target == APIC_TARGET_ALL_BUT_SELF)
453  {
455  }
456  else
457  {
459  }
460 
461  /* Now, fire off the IPI */
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  */
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  {
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  {
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
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");
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
683 VOID 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 
707 VOID
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 
732 VOID
734 {
735  KIRQL oldIrql;
736  KTRAP_FRAME KernelTrapFrame;
737 #if 0
738  ULONG CPU;
739  static ULONG Count[MAX_CPU] = {0,};
740 #endif
742  PROFILE_LEVEL,
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);
757  if (KeGetCurrentProcessorNumber() == 0)
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 
775  if (!APIC_INTEGRATED(tmp))
776  {
778  }
779  else
780  {
781  /* Periodic timer */
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 
793 VOID
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 
848 VOID
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 */
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  {
924  EnableApicMode();
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
957 VOID
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 
978 
980 
981  /* Deassert INIT */
982 
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 
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  {
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 
1112 VOID
1113 FASTCALL
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 */
1126  UNIMPLEMENTED;
1127 
1128  /* Exit the interrupt */
1129  KiEoiHelper(TrapFrame);
1130 
1131 }
1132 
1133 /* EOF */
ULONG Ecx
Definition: mps.h:19
ULONG lastregr[MAX_CPU]
Definition: apic.c:52
VOID MpsIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame, PKTRAP_FRAME TrapFrame)
Definition: apic.c:708
ULONG Gs
Definition: mps.h:14
#define APIC_LDR_MASK
Definition: apic.h:48
#define APIC_LDR
Definition: apic.h:16
ULONG Eflags
Definition: mps.h:28
#define APIC_DEFAULT_BASE
Definition: apic.h:7
__inline VOID APICSendEOI(VOID)
#define ERROR_VECTOR
Definition: apic.h:166
#define APIC_ICR0_DESTS_SELF
Definition: apic.h:77
#define IN
Definition: typedefs.h:38
ULONG Eip
Definition: mps.h:26
VOID HaliInitBSP(VOID)
Definition: apic.c:886
ULONG_PTR KernelBase
Definition: mboot.c:69
#define TRUE
Definition: types.h:120
ULONG CoreSpeed
Definition: apic.h:182
#define APIC_IRR
Definition: apic.h:21
#define GET_APIC_LOGICAL_ID(x)
Definition: apic.h:37
ULONG Read8254Timer(VOID)
_In_ ULONG Mode
Definition: hubbusif.h:303
#define DbgPrint
Definition: loader.c:25
#define APIC_ID
Definition: apic.h:10
#define APIC_DM_EXTINT
Definition: apic.h:71
#define APIC_TARGET_ALL_BUT_SELF
Definition: apic.h:143
#define IPI_VECTOR
Definition: apic.h:165
VOID MpsSpuriousInterrupt(VOID)
Definition: apic.h:148
unsigned char * PUCHAR
Definition: retypes.h:3
char CHAR
Definition: xmlstorage.h:175
void __cdecl _enable(void)
Definition: intrin_arm.h:373
USHORT Value
Definition: ketypes.h:455
#define KF_RDTSC
Definition: ketypes.h:144
#define MAX_CPU
Definition: apic.h:155
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
USHORT SegFs
Definition: ketypes.h:366
static DNS_RECORDW r1
Definition: record.c:37
ULONG Es
Definition: mps.h:16
#define KGDT_R0_CODE
Definition: ketypes.h:74
#define CPU_ENABLED
Definition: apic.h:171
PPC_QUAL unsigned long long __rdtsc(void)
Definition: intrin_ppc.h:688
ULONG Esi
Definition: mps.h:24
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define APIC_ID_MASK
Definition: apic.h:35
ULONG OnlineCPUs
Definition: apic.c:39
UCHAR SystemSegmentFlag
Definition: ketypes.h:451
__INTRIN_INLINE unsigned long __readcr3(void)
Definition: intrin_x86.h:1706
USHORT Access
Definition: ketypes.h:386
ULONG Esi
Definition: ketypes.h:261
__inline VOID APICWrite(ULONG Offset, ULONG Value)
VOID MpsTimerInterrupt(VOID)
#define APIC_DM_NMI
Definition: apic.h:68
#define FASTCALL
Definition: nt_native.h:50
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
VOID APICSendIPI(ULONG Target, ULONG Mode)
VOID APICSyncArbIDs(VOID)
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
ULONG APICGetMaxLVT(VOID)
Definition: apic.c:99
#define KeGetPcr()
Definition: ke.h:25
BOOLEAN PaeModeEnabled
Definition: mboot.c:72
ULONG Edi
Definition: ketypes.h:260
VOID APICDump(VOID)
Definition: apic.c:245
USHORT Selector
Definition: ketypes.h:467
#define APIC_LVT_MASKED
Definition: apic.h:121
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define APIC_TPR
Definition: apic.h:12
VOID EnableApicMode(VOID)
Definition: apic.c:174
UCHAR Present
Definition: ketypes.h:453
__inline VOID DisableSMPMode(VOID)
Definition: apic.c:186
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:325
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define APIC_TARGET_SELF
Definition: apic.h:141
#define APIC_LVT_LEVEL_TRIGGER
Definition: apic.h:120
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
VOID HaliStartApplicationProcessor(ULONG Cpu, ULONG Stack)
#define APIC_ICR0
Definition: apic.h:23
#define APIC_ICR0_LEVEL
Definition: apic.h:59
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1555
ULONG Eax
Definition: ketypes.h:256
#define APIC_ICR0_DS
Definition: apic.h:58
#define APIC_TIMER_BASE_DIV
Definition: apic.h:91
#define APIC_LVTTHMR
Definition: apic.h:26
USHORT SegGs
Definition: ketypes.h:367
#define LOCAL_TIMER_VECTOR
Definition: apic.h:163
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define APIC_TDCR
Definition: apic.h:33
long LONG
Definition: pedump.c:60
#define APIC_LVTT
Definition: apic.h:25
#define APIC_LVT_PERIODIC
Definition: apic.h:122
#define APIC_ICR1
Definition: apic.h:24
#define BIOS_AREA
Definition: apic.c:72
USHORT SegEs
Definition: ketypes.h:365
#define APIC_TDCR_16
Definition: apic.h:135
UCHAR Reserved
Definition: ketypes.h:449
UCHAR Dpl
Definition: ketypes.h:452
unsigned char BOOLEAN
VOID APICClear(VOID)
Definition: apic.c:111
BOOLEAN VerifyLocalAPIC(VOID)
Definition: apic.c:350
smooth NULL
Definition: ftsmooth.c:416
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
#define CMOS_WRITE(address, value)
Definition: apic.c:83
ULONG Eax
Definition: mps.h:18
USHORT SegCs
Definition: ketypes.h:380
USHORT OffsetLow
Definition: ketypes.h:466
USHORT Reserved0
Definition: ketypes.h:469
void DPRINT(...)
Definition: polytest.cpp:61
VOID APICSetupLVTT(ULONG ClockTicks)
Definition: apic.c:770
GLuint index
Definition: glext.h:6031
VOID SetInterruptGate(ULONG index, ULONG_PTR address)
Definition: apic.c:849
KIRQL NTAPI KeGetCurrentIrql(VOID)
Definition: apic.c:757
USHORT Type
Definition: ketypes.h:470
ULONG Ebx
Definition: mps.h:21
#define GET_APIC_VERSION(x)
Definition: apic.h:39
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 APIC_DFR
Definition: apic.h:17
#define APIC_ESR_MASK
Definition: apic.h:53
int64_t LONGLONG
Definition: typedefs.h:66
UCHAR SegmentType
Definition: ketypes.h:450
#define IPI_LEVEL
Definition: env_spec_w32.h:701
#define APIC_INTEGRATED(version)
Definition: apic.h:145
static VOID APICDumpBit(ULONG base)
Definition: apic.c:225
#define APIC_ISR
Definition: apic.h:19
ULONG lastvalr[MAX_CPU]
Definition: apic.c:53
static DNS_RECORDW r2
Definition: record.c:38
ULONG HardwareEsp
Definition: ketypes.h:268
GLuint address
Definition: glext.h:9393
#define APIC_ICR0_DESTS_FIELD
Definition: apic.h:76
#define APIC_VER_MASK
Definition: apic.h:38
#define APIC_LINT1
Definition: apic.h:29
#define APIC_EOI
Definition: apic.h:15
USHORT Present
Definition: ketypes.h:472
CHAR * APstart
USHORT Offset
Definition: ketypes.h:384
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1067
#define SET_APIC_TIMER_BASE(x)
Definition: apic.h:88
#define APIC_ICRT
Definition: apic.h:31
ULONG BootCPU
Definition: apic.c:38
GLbitfield flags
Definition: glext.h:7161
USHORT OffsetMiddle
Definition: ketypes.h:473
USHORT IstIndex
Definition: ketypes.h:468
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
USHORT ExtendedOffset
Definition: ketypes.h:387
#define GET_APIC_MAXLVT(x)
Definition: apic.h:40
VOID MpsTimerHandler(ULONG Vector, PKIRQ_TRAPFRAME Trapframe)
Definition: apic.c:733
#define APIC_DIVISOR
Definition: apic.c:76
VOID NTAPI NtProcessStartup(PPEB Peb)
Definition: usetup.c:4979
#define APIC_ESR
Definition: apic.h:22
#define index(s, c)
Definition: various.h:29
USHORT Dpl
Definition: ketypes.h:471
ULONG Edx
Definition: mps.h:20
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1550
ULONG BusSpeed
Definition: apic.h:181
VOID WaitFor8254Wraparound(VOID)
ULONG Reserved1
Definition: ketypes.h:475
ULONG lastvalw[MAX_CPU]
Definition: apic.c:55
ULONG LowPart
Definition: typedefs.h:104
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define APIC_CCRT
Definition: apic.h:32
#define PAGE_SIZE
Definition: env_spec_w32.h:49
USHORT SegDs
Definition: ketypes.h:364
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
Definition: glext.h:8308
ULONG Ecx
Definition: ketypes.h:255
VOID DECLSPEC_NORETURN FASTCALL HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:487
#define APIC_ICR0_LEVEL_ASSERT
Definition: apic.h:82
ULONG Edi
Definition: mps.h:25
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1713
#define APIC_LVT3
Definition: apic.h:30
ULONG Cs
Definition: mps.h:27
ULONG Eip
Definition: ketypes.h:265
#define APIC_DM_STARTUP
Definition: apic.h:70
VOID APICCalibrateTimer(ULONG CPU)
Definition: apic.c:794
__inline ULONG APICRead(ULONG Offset)
VOID MpsIpiInterrupt(VOID)
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
VOID DumpESR(VOID)
Definition: apic.c:198
BOOLEAN NTAPI KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
Definition: ipi.c:148
#define APIC_TARGET_ALL
Definition: apic.h:142
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define APIC_PPR
Definition: apic.h:14
#define APIC_SIVR_FOCUS
Definition: apic.h:51
#define APIC_VER
Definition: apic.h:11
#define APIC_LVT3_MASKED
Definition: apic.h:127
ULONG Ebx
Definition: ketypes.h:262
VOID MpsErrorHandler(VOID)
Definition: apic.c:634
const GLdouble * v
Definition: gl.h:2040
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:369
ULONG Esp
Definition: mps.h:22
CHAR * APend
#define I386_INTERRUPT_GATE
Definition: ketypes.h:63
CPU_INFO CPUMap[MAX_CPU]
Definition: apic.c:40
PULONG APICBase
Definition: apic.c:47
#define APIC_LVTPC
Definition: apic.h:27
unsigned short USHORT
Definition: pedump.c:61
#define KIDTENTRY
Definition: ketypes.h:479
#define PROFILE_LEVEL
Definition: env_spec_w32.h:698
VOID MpsSpuriousHandler(VOID)
Definition: apic.c:664
#define CR4_PAE
Definition: ketypes.h:89
#define long
Definition: qsort.c:33
#define APIC_APR
Definition: apic.h:13
#define SPURIOUS_VECTOR
Definition: apic.h:167
static __inline ULONG ThisCPU(VOID)
Definition: apic.h:203
unsigned int * PULONG
Definition: retypes.h:1
ULONG Fs
Definition: mps.h:15
#define SET_APIC_DEST_FIELD(x)
Definition: apic.h:85
#define DPRINT1
Definition: precomp.h:8
#define RtlImageNtHeader
Definition: compat.h:457
UINT64 Alignment
Definition: ketypes.h:477
#define APIC_TDCR_1
Definition: apic.h:139
#define APIC_DM_INIT
Definition: apic.h:69
#define COMMON_AREA
Definition: apic.c:73
#define APIC_SIVR
Definition: apic.h:18
ULONG Ebp
Definition: mps.h:23
void __cdecl _disable(void)
Definition: intrin_arm.h:365
#define APIC_ICR0_DESTS_ALL
Definition: apic.h:78
ULONG APICMode
Definition: apic.c:49
#define HZ
Definition: apic.c:75
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:114
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:539
#define ULONG_PTR
Definition: config.h:101
#define APIC_ICR0_LEVEL_DEASSERT
Definition: apic.h:81
ULONG Ds
Definition: mps.h:17
#define APIC_SIVR_ENABLE
Definition: apic.h:50
#define APIC_LINT0
Definition: apic.h:28
#define APIC_ICR0_DESTS_ALL_BUT_SELF
Definition: apic.h:79
#define GET_APIC_ID(x)
Definition: apic.h:36
ULONG lastregw[MAX_CPU]
Definition: apic.c:54
ULONG CPUCount
Definition: apic.c:37
USHORT Selector
Definition: ketypes.h:385
ULONG EFlags
Definition: ketypes.h:384
unsigned short * PUSHORT
Definition: retypes.h:2
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:99
VOID MpsErrorInterrupt(VOID)
VOID APICSetup(VOID)
Definition: apic.c:482
ULONG Edx
Definition: ketypes.h:254
ULONG Ebp
Definition: ketypes.h:263
ULONG OffsetHigh
Definition: ketypes.h:474
LONGLONG QuadPart
Definition: typedefs.h:112
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
Definition: apic.c:678
VOID APICDisable(VOID)
Definition: apic.c:211
VOID NTAPI HalEndSystemInterrupt(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:741
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
Definition: glext.h:8308
#define APIC_TMR
Definition: apic.h:20