ReactOS  0.4.14-dev-49-gfb4591c
apic.c File Reference
#include <hal.h>
#include <halfuncs.h>
#include <rtlfuncs.h>
#include <debug.h>
Include dependency graph for apic.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define BIOS_AREA   0x0
 
#define COMMON_AREA   0x2000
 
#define HZ   (100)
 
#define APIC_DIVISOR   (16)
 
#define CMOS_READ(address)
 
#define CMOS_WRITE(address, value)
 

Functions

ULONG Read8254Timer (VOID)
 
VOID WaitFor8254Wraparound (VOID)
 
VOID MpsTimerInterrupt (VOID)
 
VOID MpsErrorInterrupt (VOID)
 
VOID MpsSpuriousInterrupt (VOID)
 
VOID MpsIpiInterrupt (VOID)
 
ULONG APICGetMaxLVT (VOID)
 
VOID APICClear (VOID)
 
VOID EnableApicMode (VOID)
 
__inline VOID DisableSMPMode (VOID)
 
VOID DumpESR (VOID)
 
VOID APICDisable (VOID)
 
static VOID APICDumpBit (ULONG base)
 
VOID APICDump (VOID)
 
BOOLEAN VerifyLocalAPIC (VOID)
 
VOID APICSetup (VOID)
 
VOID MpsErrorHandler (VOID)
 
VOID MpsSpuriousHandler (VOID)
 
VOID MpsIRQTrapFrameToTrapFrame (PKIRQ_TRAPFRAME IrqTrapFrame, PKTRAP_FRAME TrapFrame)
 
VOID MpsTimerHandler (ULONG Vector, PKIRQ_TRAPFRAME Trapframe)
 
VOID APICSetupLVTT (ULONG ClockTicks)
 
VOID APICCalibrateTimer (ULONG CPU)
 
VOID SetInterruptGate (ULONG index, ULONG_PTR address)
 
VOID HaliInitBSP (VOID)
 
VOID FASTCALL DECLSPEC_NORETURN HalpApcInterruptHandler (IN PKTRAP_FRAME TrapFrame)
 

Variables

ULONG CPUCount
 
ULONG BootCPU
 
ULONG OnlineCPUs
 
CPU_INFO CPUMap [MAX_CPU]
 
PULONG APICBase = (PULONG)APIC_DEFAULT_BASE
 
ULONG APICMode
 
ULONG lastregr [MAX_CPU]
 
ULONG lastvalr [MAX_CPU]
 
ULONG lastregw [MAX_CPU]
 
ULONG lastvalw [MAX_CPU]
 
CHARAPstart
 
CHARAPend
 
ULONG_PTR KernelBase
 

Macro Definition Documentation

◆ APIC_DIVISOR

#define APIC_DIVISOR   (16)

Definition at line 76 of file apic.c.

◆ BIOS_AREA

#define BIOS_AREA   0x0

Definition at line 72 of file apic.c.

◆ CMOS_READ

#define CMOS_READ (   address)
Value:
{ \
WRITE_PORT_UCHAR((PUCHAR)0x70, address)); \
READ_PORT_UCHAR((PUCHAR)0x71)); \
}
unsigned char * PUCHAR
Definition: retypes.h:3
GLuint address
Definition: glext.h:9393

Definition at line 78 of file apic.c.

◆ CMOS_WRITE

#define CMOS_WRITE (   address,
  value 
)
Value:
{ \
WRITE_PORT_UCHAR((PUCHAR)0x70, address); \
WRITE_PORT_UCHAR((PUCHAR)0x71, value); \
}
unsigned char * PUCHAR
Definition: retypes.h:3
GLuint address
Definition: glext.h:9393

Definition at line 83 of file apic.c.

◆ COMMON_AREA

#define COMMON_AREA   0x2000

Definition at line 73 of file apic.c.

◆ HZ

#define HZ   (100)

Definition at line 75 of file apic.c.

◆ NDEBUG

#define NDEBUG

Definition at line 32 of file apic.c.

Function Documentation

◆ APICCalibrateTimer()

VOID APICCalibrateTimer ( ULONG  CPU)

Definition at line 794 of file apic.c.

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 }
#define TRUE
Definition: types.h:120
ULONG CoreSpeed
Definition: apic.h:182
#define KF_RDTSC
Definition: ketypes.h:144
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
PPC_QUAL unsigned long long __rdtsc(void)
Definition: intrin_ppc.h:688
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
long LONG
Definition: pedump.c:60
unsigned char BOOLEAN
void DPRINT(...)
Definition: polytest.cpp:61
VOID APICSetupLVTT(ULONG ClockTicks)
Definition: apic.c:770
int64_t LONGLONG
Definition: typedefs.h:66
#define APIC_DIVISOR
Definition: apic.c:76
ULONG BusSpeed
Definition: apic.h:181
#define APIC_CCRT
Definition: apic.h:32
__inline ULONG APICRead(ULONG Offset)
CPU_INFO CPUMap[MAX_CPU]
Definition: apic.c:40
#define long
Definition: qsort.c:33
#define HZ
Definition: apic.c:75
unsigned int ULONG
Definition: retypes.h:1

Referenced by HaliInitBSP(), and HalInitializeProcessor().

◆ APICClear()

VOID APICClear ( VOID  )

Definition at line 111 of file apic.c.

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 }
#define ERROR_VECTOR
Definition: apic.h:166
__inline VOID APICWrite(ULONG Offset, ULONG Value)
ULONG APICGetMaxLVT(VOID)
Definition: apic.c:99
#define APIC_LVT_MASKED
Definition: apic.h:121
#define APIC_LVTTHMR
Definition: apic.h:26
#define APIC_LVTT
Definition: apic.h:25
#define APIC_LINT1
Definition: apic.h:29
#define APIC_LVT3
Definition: apic.h:30
__inline ULONG APICRead(ULONG Offset)
#define APIC_LVT3_MASKED
Definition: apic.h:127
#define APIC_LVTPC
Definition: apic.h:27
unsigned int ULONG
Definition: retypes.h:1
#define APIC_LINT0
Definition: apic.h:28

Referenced by APICDisable(), and EnableApicMode().

◆ APICDisable()

VOID APICDisable ( VOID  )

Definition at line 211 of file apic.c.

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 }
__inline VOID APICWrite(ULONG Offset, ULONG Value)
VOID APICClear(VOID)
Definition: apic.c:111
__inline ULONG APICRead(ULONG Offset)
#define APIC_SIVR
Definition: apic.h:18
unsigned int ULONG
Definition: retypes.h:1
#define APIC_SIVR_ENABLE
Definition: apic.h:50

◆ APICDump()

VOID APICDump ( VOID  )

Definition at line 245 of file apic.c.

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 }
ULONG lastregr[MAX_CPU]
Definition: apic.c:52
#define APIC_LDR
Definition: apic.h:16
#define APIC_IRR
Definition: apic.h:21
#define DbgPrint
Definition: loader.c:25
#define APIC_ID
Definition: apic.h:10
static DNS_RECORDW r1
Definition: record.c:37
__inline VOID APICWrite(ULONG Offset, ULONG Value)
ULONG APICGetMaxLVT(VOID)
Definition: apic.c:99
#define APIC_TPR
Definition: apic.h:12
#define APIC_ICR0
Definition: apic.h:23
#define APIC_TDCR
Definition: apic.h:33
#define APIC_LVTT
Definition: apic.h:25
#define APIC_ICR1
Definition: apic.h:24
#define GET_APIC_VERSION(x)
Definition: apic.h:39
#define APIC_DFR
Definition: apic.h:17
#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
#define APIC_LINT1
Definition: apic.h:29
#define APIC_EOI
Definition: apic.h:15
#define APIC_ICRT
Definition: apic.h:31
#define APIC_ESR
Definition: apic.h:22
ULONG lastvalw[MAX_CPU]
Definition: apic.c:55
#define APIC_CCRT
Definition: apic.h:32
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
Definition: glext.h:8308
#define APIC_LVT3
Definition: apic.h:30
__inline ULONG APICRead(ULONG Offset)
#define APIC_PPR
Definition: apic.h:14
#define APIC_VER
Definition: apic.h:11
const GLdouble * v
Definition: gl.h:2040
#define APIC_LVTPC
Definition: apic.h:27
#define APIC_APR
Definition: apic.h:13
static __inline ULONG ThisCPU(VOID)
Definition: apic.h:203
#define APIC_SIVR
Definition: apic.h:18
unsigned int ULONG
Definition: retypes.h:1
#define APIC_LINT0
Definition: apic.h:28
#define GET_APIC_ID(x)
Definition: apic.h:36
ULONG lastregw[MAX_CPU]
Definition: apic.c:54
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
Definition: glext.h:8308
#define APIC_TMR
Definition: apic.h:20

Referenced by MpsErrorHandler(), and MpsSpuriousHandler().

◆ APICDumpBit()

static VOID APICDumpBit ( ULONG  base)
static

Definition at line 225 of file apic.c.

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 }
#define DbgPrint
Definition: loader.c:25
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
__inline ULONG APICRead(ULONG Offset)
const GLdouble * v
Definition: gl.h:2040
unsigned int ULONG
Definition: retypes.h:1

Referenced by APICDump().

◆ APICGetMaxLVT()

ULONG APICGetMaxLVT ( VOID  )

Definition at line 99 of file apic.c.

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 }
#define GET_APIC_VERSION(x)
Definition: apic.h:39
#define APIC_INTEGRATED(version)
Definition: apic.h:145
#define GET_APIC_MAXLVT(x)
Definition: apic.h:40
__inline ULONG APICRead(ULONG Offset)
#define APIC_VER
Definition: apic.h:11
unsigned int ULONG
Definition: retypes.h:1

Referenced by APICClear(), APICDump(), APICSetup(), DumpESR(), and VerifyLocalAPIC().

◆ APICSetup()

VOID APICSetup ( VOID  )

Definition at line 482 of file apic.c.

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 }
#define APIC_LDR_MASK
Definition: apic.h:48
#define APIC_LDR
Definition: apic.h:16
#define ERROR_VECTOR
Definition: apic.h:166
#define GET_APIC_LOGICAL_ID(x)
Definition: apic.h:37
#define APIC_ID
Definition: apic.h:10
#define APIC_DM_EXTINT
Definition: apic.h:71
Definition: apic.h:148
__inline VOID APICWrite(ULONG Offset, ULONG Value)
#define APIC_DM_NMI
Definition: apic.h:68
ULONG APICGetMaxLVT(VOID)
Definition: apic.c:99
#define APIC_LVT_MASKED
Definition: apic.h:121
#define APIC_TPR
Definition: apic.h:12
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:325
#define APIC_LVT_LEVEL_TRIGGER
Definition: apic.h:120
void DPRINT(...)
Definition: polytest.cpp:61
#define APIC_DFR
Definition: apic.h:17
#define APIC_INTEGRATED(version)
Definition: apic.h:145
#define APIC_LINT1
Definition: apic.h:29
ULONG BootCPU
Definition: apic.c:38
#define APIC_ESR
Definition: apic.h:22
#define APIC_LVT3
Definition: apic.h:30
__inline ULONG APICRead(ULONG Offset)
#define APIC_SIVR_FOCUS
Definition: apic.h:51
CPU_INFO CPUMap[MAX_CPU]
Definition: apic.c:40
#define SPURIOUS_VECTOR
Definition: apic.h:167
static __inline ULONG ThisCPU(VOID)
Definition: apic.h:203
#define DPRINT1
Definition: precomp.h:8
#define APIC_SIVR
Definition: apic.h:18
ULONG APICMode
Definition: apic.c:49
unsigned int ULONG
Definition: retypes.h:1
#define APIC_SIVR_ENABLE
Definition: apic.h:50
#define APIC_LINT0
Definition: apic.h:28
#define GET_APIC_ID(x)
Definition: apic.h:36

Referenced by HaliInitBSP(), and HalInitializeProcessor().

◆ APICSetupLVTT()

VOID APICSetupLVTT ( ULONG  ClockTicks)

Definition at line 770 of file apic.c.

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 }
__inline VOID APICWrite(ULONG Offset, ULONG Value)
#define APIC_TIMER_BASE_DIV
Definition: apic.h:91
#define LOCAL_TIMER_VECTOR
Definition: apic.h:163
#define APIC_TDCR
Definition: apic.h:33
#define APIC_LVTT
Definition: apic.h:25
#define APIC_LVT_PERIODIC
Definition: apic.h:122
#define APIC_TDCR_16
Definition: apic.h:135
#define GET_APIC_VERSION(x)
Definition: apic.h:39
#define APIC_INTEGRATED(version)
Definition: apic.h:145
#define SET_APIC_TIMER_BASE(x)
Definition: apic.h:88
#define APIC_ICRT
Definition: apic.h:31
#define APIC_DIVISOR
Definition: apic.c:76
__inline ULONG APICRead(ULONG Offset)
#define APIC_VER
Definition: apic.h:11
#define APIC_TDCR_1
Definition: apic.h:139
unsigned int ULONG
Definition: retypes.h:1

Referenced by APICCalibrateTimer().

◆ DisableSMPMode()

__inline VOID DisableSMPMode ( VOID  )

Definition at line 186 of file apic.c.

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 }
unsigned char * PUCHAR
Definition: retypes.h:3
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532

◆ DumpESR()

VOID DumpESR ( VOID  )

Definition at line 198 of file apic.c.

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 }
#define DbgPrint
Definition: loader.c:25
__inline VOID APICWrite(ULONG Offset, ULONG Value)
ULONG APICGetMaxLVT(VOID)
Definition: apic.c:99
#define APIC_ESR
Definition: apic.h:22
__inline ULONG APICRead(ULONG Offset)
unsigned int ULONG
Definition: retypes.h:1

◆ EnableApicMode()

VOID EnableApicMode ( VOID  )

Definition at line 174 of file apic.c.

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 }
unsigned char * PUCHAR
Definition: retypes.h:3
VOID APICClear(VOID)
Definition: apic.c:111
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532

Referenced by HaliInitBSP().

◆ HaliInitBSP()

VOID HaliInitBSP ( VOID  )

Definition at line 886 of file apic.c.

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 }
#define ERROR_VECTOR
Definition: apic.h:166
#define TRUE
Definition: types.h:120
#define IPI_VECTOR
Definition: apic.h:165
VOID MpsSpuriousInterrupt(VOID)
Definition: apic.h:148
VOID MpsTimerInterrupt(VOID)
uint32_t ULONG_PTR
Definition: typedefs.h:63
VOID EnableApicMode(VOID)
Definition: apic.c:174
#define LOCAL_TIMER_VECTOR
Definition: apic.h:163
#define BIOS_AREA
Definition: apic.c:72
unsigned char BOOLEAN
BOOLEAN VerifyLocalAPIC(VOID)
Definition: apic.c:350
#define CMOS_WRITE(address, value)
Definition: apic.c:83
void DPRINT(...)
Definition: polytest.cpp:61
VOID SetInterruptGate(ULONG index, ULONG_PTR address)
Definition: apic.c:849
CHAR * APstart
ULONG BootCPU
Definition: apic.c:38
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define PAGE_SIZE
Definition: env_spec_w32.h:49
VOID APICCalibrateTimer(ULONG CPU)
Definition: apic.c:794
VOID MpsIpiInterrupt(VOID)
CHAR * APend
PULONG APICBase
Definition: apic.c:47
#define SPURIOUS_VECTOR
Definition: apic.h:167
unsigned int * PULONG
Definition: retypes.h:1
#define COMMON_AREA
Definition: apic.c:73
ULONG APICMode
Definition: apic.c:49
unsigned short * PUSHORT
Definition: retypes.h:2
VOID MpsErrorInterrupt(VOID)
VOID APICSetup(VOID)
Definition: apic.c:482

Referenced by HalInitializeProcessor().

◆ HalpApcInterruptHandler()

VOID FASTCALL DECLSPEC_NORETURN HalpApcInterruptHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 1115 of file apic.c.

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 }
#define KGDT_R0_CODE
Definition: ketypes.h:75
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1555
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:369
#define UNIMPLEMENTED
Definition: debug.h:114

◆ MpsErrorHandler()

VOID MpsErrorHandler ( VOID  )

Definition at line 634 of file apic.c.

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 }
__inline VOID APICSendEOI(VOID)
__inline VOID APICWrite(ULONG Offset, ULONG Value)
VOID APICDump(VOID)
Definition: apic.c:245
#define APIC_ESR
Definition: apic.h:22
__inline ULONG APICRead(ULONG Offset)
static __inline ULONG ThisCPU(VOID)
Definition: apic.h:203
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1

◆ MpsErrorInterrupt()

VOID MpsErrorInterrupt ( VOID  )

Referenced by HaliInitBSP().

◆ MpsIpiInterrupt()

VOID MpsIpiInterrupt ( VOID  )

Referenced by HaliInitBSP().

◆ MpsIRQTrapFrameToTrapFrame()

VOID MpsIRQTrapFrameToTrapFrame ( PKIRQ_TRAPFRAME  IrqTrapFrame,
PKTRAP_FRAME  TrapFrame 
)

Definition at line 708 of file apic.c.

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 }
ULONG Ecx
Definition: mps.h:19
ULONG Gs
Definition: mps.h:14
ULONG Eflags
Definition: mps.h:28
ULONG Eip
Definition: mps.h:26
USHORT SegFs
Definition: ketypes.h:366
ULONG Es
Definition: mps.h:16
ULONG Esi
Definition: mps.h:24
ULONG Esi
Definition: ketypes.h:263
ULONG Edi
Definition: ketypes.h:262
ULONG Eax
Definition: ketypes.h:258
USHORT SegGs
Definition: ketypes.h:367
USHORT SegEs
Definition: ketypes.h:365
ULONG Eax
Definition: mps.h:18
USHORT SegCs
Definition: ketypes.h:380
ULONG Ebx
Definition: mps.h:21
ULONG HardwareEsp
Definition: ketypes.h:270
ULONG Edx
Definition: mps.h:20
USHORT SegDs
Definition: ketypes.h:364
ULONG Ecx
Definition: ketypes.h:257
ULONG Edi
Definition: mps.h:25
ULONG Cs
Definition: mps.h:27
ULONG Eip
Definition: ketypes.h:267
ULONG Ebx
Definition: ketypes.h:264
ULONG Esp
Definition: mps.h:22
unsigned short USHORT
Definition: pedump.c:61
ULONG Fs
Definition: mps.h:15
ULONG Ebp
Definition: mps.h:23
#define UNIMPLEMENTED
Definition: debug.h:114
ULONG Ds
Definition: mps.h:17
ULONG EFlags
Definition: ketypes.h:384
ULONG Edx
Definition: ketypes.h:256
ULONG Ebp
Definition: ketypes.h:265

Referenced by MpsTimerHandler().

◆ MpsSpuriousHandler()

VOID MpsSpuriousHandler ( VOID  )

Definition at line 664 of file apic.c.

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 }
__inline VOID APICSendEOI(VOID)
VOID APICDump(VOID)
Definition: apic.c:245
void DPRINT(...)
Definition: polytest.cpp:61
#define APIC_ISR
Definition: apic.h:19
__inline ULONG APICRead(ULONG Offset)
#define SPURIOUS_VECTOR
Definition: apic.h:167
static __inline ULONG ThisCPU(VOID)
Definition: apic.h:203
unsigned int ULONG
Definition: retypes.h:1

◆ MpsSpuriousInterrupt()

VOID MpsSpuriousInterrupt ( VOID  )

Referenced by HaliInitBSP().

◆ MpsTimerHandler()

VOID MpsTimerHandler ( ULONG  Vector,
PKIRQ_TRAPFRAME  Trapframe 
)

Definition at line 733 of file apic.c.

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 }
VOID MpsIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame, PKTRAP_FRAME TrapFrame)
Definition: apic.c:708
ULONG Eip
Definition: mps.h:26
#define DbgPrint
Definition: loader.c:25
void __cdecl _enable(void)
Definition: intrin_arm.h:373
#define MAX_CPU
Definition: apic.h:155
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define KeGetPcr()
Definition: ke.h:25
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:325
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define LOCAL_TIMER_VECTOR
Definition: apic.h:163
#define PROFILE_LEVEL
Definition: env_spec_w32.h:698
static __inline ULONG ThisCPU(VOID)
Definition: apic.h:203
void __cdecl _disable(void)
Definition: intrin_arm.h:365
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
Definition: apic.c:678
VOID NTAPI HalEndSystemInterrupt(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:741

◆ MpsTimerInterrupt()

VOID MpsTimerInterrupt ( VOID  )

Referenced by HaliInitBSP().

◆ Read8254Timer()

ULONG Read8254Timer ( VOID  )

◆ SetInterruptGate()

VOID SetInterruptGate ( ULONG  index,
ULONG_PTR  address 
)

Definition at line 849 of file apic.c.

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 }
USHORT Value
Definition: ketypes.h:455
#define KGDT_R0_CODE
Definition: ketypes.h:75
UCHAR SystemSegmentFlag
Definition: ketypes.h:451
USHORT Access
Definition: ketypes.h:388
#define KeGetPcr()
Definition: ke.h:25
USHORT Selector
Definition: ketypes.h:467
UCHAR Present
Definition: ketypes.h:453
UCHAR Reserved
Definition: ketypes.h:449
UCHAR Dpl
Definition: ketypes.h:452
USHORT OffsetLow
Definition: ketypes.h:466
USHORT Reserved0
Definition: ketypes.h:469
GLuint index
Definition: glext.h:6031
USHORT Type
Definition: ketypes.h:470
UCHAR SegmentType
Definition: ketypes.h:450
GLuint address
Definition: glext.h:9393
USHORT Present
Definition: ketypes.h:472
USHORT Offset
Definition: ketypes.h:386
USHORT OffsetMiddle
Definition: ketypes.h:473
USHORT IstIndex
Definition: ketypes.h:468
USHORT ExtendedOffset
Definition: ketypes.h:389
#define index(s, c)
Definition: various.h:29
USHORT Dpl
Definition: ketypes.h:471
ULONG Reserved1
Definition: ketypes.h:475
#define I386_INTERRUPT_GATE
Definition: ketypes.h:63
unsigned short USHORT
Definition: pedump.c:61
#define KIDTENTRY
Definition: ketypes.h:479
UINT64 Alignment
Definition: ketypes.h:477
unsigned int ULONG
Definition: retypes.h:1
USHORT Selector
Definition: ketypes.h:387
ULONG OffsetHigh
Definition: ketypes.h:474

Referenced by HaliInitBSP().

◆ VerifyLocalAPIC()

BOOLEAN VerifyLocalAPIC ( VOID  )

Definition at line 350 of file apic.c.

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 }
#define TRUE
Definition: types.h:120
#define APIC_ID
Definition: apic.h:10
#define APIC_ID_MASK
Definition: apic.h:35
__inline VOID APICWrite(ULONG Offset, ULONG Value)
ULONG APICGetMaxLVT(VOID)
Definition: apic.c:99
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
#define GET_APIC_VERSION(x)
Definition: apic.h:39
#define APIC_VER_MASK
Definition: apic.h:38
ULONG LowPart
Definition: typedefs.h:104
__inline ULONG APICRead(ULONG Offset)
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define APIC_VER
Definition: apic.h:11
#define DPRINT1
Definition: precomp.h:8
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by HaliInitBSP().

◆ WaitFor8254Wraparound()

VOID WaitFor8254Wraparound ( VOID  )

Variable Documentation

◆ APend

CHAR * APend

Referenced by HaliInitBSP().

◆ APICBase

Definition at line 47 of file apic.c.

Referenced by _APICRead(), APICRead(), APICWrite(), and HaliInitBSP().

◆ APICMode

ULONG APICMode

Definition at line 49 of file apic.c.

Referenced by APICSetup(), HaliGetSmpConfig(), and HaliInitBSP().

◆ APstart

CHAR* APstart

Referenced by HaliInitBSP().

◆ BootCPU

ULONG BootCPU

Definition at line 38 of file apic.c.

Referenced by APICSetup(), HaliInitBSP(), and HaliMPProcessorInfo().

◆ CPUCount

ULONG CPUCount

Definition at line 37 of file apic.c.

Referenced by HalAllProcessorsStarted(), HaliMPProcessorInfo(), and HalStartNextProcessor().

◆ CPUMap

CPU_INFO CPUMap[MAX_CPU]

Definition at line 40 of file apic.c.

Referenced by APICCalibrateTimer(), APICSetup(), HaliMPProcessorInfo(), and HalInitializeProcessor().

◆ KernelBase

ULONG_PTR KernelBase

◆ lastregr

ULONG lastregr[MAX_CPU]

Definition at line 52 of file apic.c.

Referenced by APICDump(), and APICRead().

◆ lastregw

ULONG lastregw[MAX_CPU]

Definition at line 54 of file apic.c.

Referenced by APICDump(), and APICWrite().

◆ lastvalr

ULONG lastvalr[MAX_CPU]

Definition at line 53 of file apic.c.

Referenced by APICDump(), and APICRead().

◆ lastvalw

ULONG lastvalw[MAX_CPU]

Definition at line 55 of file apic.c.

Referenced by APICDump(), and APICWrite().

◆ OnlineCPUs

ULONG OnlineCPUs

Definition at line 39 of file apic.c.

Referenced by HalAllProcessorsStarted(), HalInitializeProcessor(), and HalStartNextProcessor().