VirtualBox

source: vbox/trunk/src/VBox/VMM/include/APICInternal.h@ 61072

Last change on this file since 61072 was 61072, checked in by vboxsync, 9 years ago

VMM/APIC: Get rid of a couple of duplicate macros, and added a couple of ones to x86.h.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 52.7 KB
Line 
1/* $Id: APICInternal.h 61072 2016-05-20 02:59:40Z vboxsync $ */
2/** @file
3 * APIC - Advanced Programmable Interrupt Controller.
4 */
5
6/*
7 * Copyright (C) 2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef ___APICInternal_h
19#define ___APICInternal_h
20
21#include <VBox/sup.h>
22#include <VBox/types.h>
23#include <VBox/vmm/apic.h>
24
25/** @defgroup grp_apic_int Internal
26 * @ingroup grp_apic
27 * @internal
28 * @{
29 */
30
31/** The APIC hardware version we are emulating. */
32#define XAPIC_HARDWARE_VERSION XAPIC_HARDWARE_VERSION_P4
33
34#define VMCPU_TO_XAPICPAGE(a_pVCpu) ((PXAPICPAGE)(CTX_SUFF((a_pVCpu)->apic.s.pvApicPage)))
35#define VMCPU_TO_CXAPICPAGE(a_pVCpu) ((PCXAPICPAGE)(CTX_SUFF((a_pVCpu)->apic.s.pvApicPage)))
36
37#define VMCPU_TO_X2APICPAGE(a_pVCpu) ((PX2APICPAGE)(CTX_SUFF((a_pVCpu)->apic.s.pvApicPage)))
38#define VMCPU_TO_CX2APICPAGE(a_pVCpu) ((PCX2APICPAGE)(CTX_SUFF((a_pVCpu)->apic.s.pvApicPage)))
39
40#define VMCPU_TO_APICCPU(a_pVCpu) (&(a_pVCpu)->apic.s)
41#define VM_TO_APIC(a_pVM) (&(a_pVM)->apic.s)
42#define VM_TO_APICDEV(a_pVM) CTX_SUFF(VM_TO_APIC(a_pVM)->pApicDev)
43
44#define APICCPU_TO_XAPICPAGE(a_ApicCpu) ((PXAPICPAGE)(CTX_SUFF((a_ApicCpu)->pvApicPage)))
45#define APICCPU_TO_CXAPICPAGE(a_ApicCpu) ((PCXAPICPAGE)(CTX_SUFF((a_ApicCpu)->pvApicPage)))
46
47/** Whether the APIC is in X2APIC mode or not. */
48#define XAPIC_IN_X2APIC_MODE(a_pVCpu) ( ( ((a_pVCpu)->apic.s.uApicBaseMsr) \
49 & (MSR_IA32_APICBASE_EN | MSR_IA32_APICBASE_EXTD)) \
50 == (MSR_IA32_APICBASE_EN | MSR_IA32_APICBASE_EXTD) )
51/** Get an xAPIC page offset for an x2APIC MSR value. */
52#define X2APIC_GET_XAPIC_OFF(a_uMsr) ((((a_uMsr) - MSR_IA32_X2APIC_START) << 4) & UINT32_C(0xff0))
53/** Get an x2APIC MSR for an xAPIC page offset. */
54#define XAPIC_GET_X2APIC_MSR(a_offReg) ((((a_offReg) & UINT32_C(0xff0)) >> 4) | MSR_IA32_X2APIC_START)
55
56/** Illegal APIC vector value start. */
57#define XAPIC_ILLEGAL_VECTOR_START UINT8_C(0)
58/** Illegal APIC vector value end (inclusive). */
59#define XAPIC_ILLEGAL_VECTOR_END UINT8_C(15)
60/** Reserved APIC vector value start. */
61#define XAPIC_RSVD_VECTOR_START UINT8_C(16)
62/** Reserved APIC vector value end (inclusive). */
63#define XAPIC_RSVD_VECTOR_END UINT8_C(31)
64
65/** Vector offset in an APIC 256-bit sparse register. */
66#define XAPIC_REG256_VECTOR_OFF(a_Vector) (((a_Vector) & UINT32_C(0xe0)) >> 1)
67/** Bit position at offset in an APIC 256-bit sparse register. */
68#define XAPIC_REG256_VECTOR_BIT(a_Vector) ((a_Vector) & UINT32_C(0x1f))
69
70/** Maximum number of LVT entries for Pentium 4. */
71#define XAPIC_MAX_LVT_ENTRIES_P4 UINT8_C(6)
72/** Size of the APIC ID bits for Pentium 4. */
73#define XAPIC_APIC_ID_BIT_COUNT_P4 UINT8_C(8)
74/** The APIC hardware version number for Pentium 4. */
75#define XAPIC_HARDWARE_VERSION_P4 UINT8_C(0x14)
76
77/** Maximum number of LVT entries for Pentium 6. */
78#define XAPIC_MAX_LVT_ENTRIES_P6 UINT8_C(4)
79/** Size of the APIC ID bits for Pentium 6. */
80#define XAPIC_APIC_ID_BIT_COUNT_P6 UINT8_C(4)
81/** The APIC hardware version number for Pentium 6. */
82#define XAPIC_HARDWARE_VERSION_P6 UINT8_C(0x10)
83
84/**
85 * The xAPIC sparse 256-bit register.
86 */
87typedef union XAPIC256BITREG
88{
89 /** The sparse-bitmap view. */
90 struct
91 {
92 uint32_t u32Reg;
93 uint32_t uReserved0[3];
94 } u[8];
95 /** The 32-bit view. */
96 uint32_t au32[32];
97} XAPIC256BITREG;
98/** Pointer to an xAPIC sparse bitmap register. */
99typedef XAPIC256BITREG *PXAPIC256BITREG;
100/** Pointer to a const xAPIC sparse bitmap register. */
101typedef XAPIC256BITREG const *PCXAPIC256BITREG;
102AssertCompileSize(XAPIC256BITREG, 128);
103
104/**
105 * The xAPIC memory layout as per Intel/AMD specs.
106 */
107typedef struct XAPICPAGE
108{
109 /* 0x00 - Reserved. */
110 uint32_t uReserved0[8];
111 /* 0x20 - APIC ID. */
112 struct
113 {
114 uint8_t u8Reserved0[3];
115 uint8_t u8ApicId;
116 uint32_t u32Reserved0[3];
117 } id;
118 /* 0x30 - APIC version register. */
119 union
120 {
121 struct
122 {
123#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
124 uint8_t u8Version;
125#else
126# error "Implement Pentium and P6 family APIC architectures"
127#endif
128 uint8_t uReserved0;
129 uint8_t u8MaxLvtEntry;
130 uint8_t fEoiBroadcastSupression : 1;
131 uint8_t u7Reserved1 : 7;
132 uint32_t u32Reserved0[3];
133 } u;
134 struct
135 {
136 uint32_t u32Version;
137 uint32_t u32Reserved0[3];
138 } all;
139 } version;
140 /* 0x40 - Reserved. */
141 uint32_t uReserved1[16];
142 /* 0x80 - Task Priority Register (TPR). */
143 struct
144 {
145 uint8_t u8Tpr;
146 uint8_t u8Reserved0[3];
147 uint32_t u32Reserved0[3];
148 } tpr;
149 /* 0x90 - Arbitration Priority Register (APR). */
150 struct
151 {
152 uint8_t u8Apr;
153 uint8_t u8Reserved0[3];
154 uint32_t u32Reserved0[3];
155 } apr;
156 /* 0xA0 - Processor Priority Register (PPR). */
157 struct
158 {
159 uint8_t u8Ppr;
160 uint8_t u8Reserved0[3];
161 uint32_t u32Reserved0[3];
162 } ppr;
163 /* 0xB0 - End Of Interrupt Register (EOI). */
164 struct
165 {
166 uint32_t u32Eoi;
167 uint32_t u32Reserved0[3];
168 } eoi;
169 /* 0xC0 - Remote Read Register (RRD). */
170 struct
171 {
172 uint32_t u32Rrd;
173 uint32_t u32Reserved0[3];
174 } rrd;
175 /* 0xD0 - Logical Destination Register (LDR). */
176 union
177 {
178 struct
179 {
180 uint8_t u8Reserved0[3];
181 uint8_t u8LogicalApicId;
182 uint32_t u32Reserved0[3];
183 } u;
184 struct
185 {
186 uint32_t u32Ldr;
187 uint32_t u32Reserved0[3];
188 } all;
189 } ldr;
190 /* 0xE0 - Destination Format Register (DFR). */
191 union
192 {
193 struct
194 {
195 uint32_t u28ReservedMb1 : 28; /* MB1 */
196 uint32_t u4Model : 4;
197 uint32_t u32Reserved0[3];
198 } u;
199 struct
200 {
201 uint32_t u32Dfr;
202 uint32_t u32Reserved0[3];
203 } all;
204 } dfr;
205 /* 0xF0 - Spurious-Interrupt Vector Register (SVR). */
206 union
207 {
208 struct
209 {
210 uint32_t u8SpuriousVector : 8;
211 uint32_t fApicSoftwareEnable : 1;
212 uint32_t u3Reserved0 : 3;
213 uint32_t fSupressEoiBroadcast : 1;
214 uint32_t u19Reserved1 : 19;
215 uint32_t u32Reserved0[3];
216 } u;
217 struct
218 {
219 uint32_t u32Svr;
220 uint32_t u32Reserved0[3];
221 } all;
222 } svr;
223 /* 0x100 - In-service Register (ISR). */
224 XAPIC256BITREG isr;
225 /* 0x180 - Trigger Mode Register (TMR). */
226 XAPIC256BITREG tmr;
227 /* 0x200 - Interrupt Request Register (IRR). */
228 XAPIC256BITREG irr;
229 /* 0x280 - Error Status Register (ESR). */
230 union
231 {
232 struct
233 {
234#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
235 uint32_t u4Reserved0 : 4;
236#else
237# error "Implement Pentium and P6 family APIC architectures"
238#endif
239 uint32_t fRedirectableIpi : 1;
240 uint32_t fSendIllegalVector : 1;
241 uint32_t fRcvdIllegalVector : 1;
242 uint32_t fIllegalRegAddr : 1;
243 uint32_t u24Reserved1 : 24;
244 uint32_t u32Reserved0[3];
245 } u;
246 struct
247 {
248 uint32_t u32Errors;
249 uint32_t u32Reserved0[3];
250 } all;
251 } esr;
252 /* 0x290 - Reserved. */
253 uint32_t uReserved2[28];
254 /* 0x300 - Interrupt Command Register (ICR) - Low. */
255 union
256 {
257 struct
258 {
259 uint32_t u8Vector : 8;
260 uint32_t u3DeliveryMode : 3;
261 uint32_t u1DestMode : 1;
262 uint32_t u1DeliveryStatus : 1;
263 uint32_t fReserved0 : 1;
264 uint32_t u1Level : 1;
265 uint32_t u1TriggerMode : 1;
266 uint32_t u2Reserved1 : 2;
267 uint32_t u2DestShorthand : 2;
268 uint32_t u12Reserved2 : 12;
269 uint32_t u32Reserved0[3];
270 } u;
271 struct
272 {
273 uint32_t u32IcrLo;
274 uint32_t u32Reserved0[3];
275 } all;
276 } icr_lo;
277 /* 0x310 - Interrupt Comannd Register (ICR) - High. */
278 union
279 {
280 struct
281 {
282 uint32_t u24Reserved0 : 24;
283 uint32_t u8Dest : 8;
284 uint32_t u32Reserved0[3];
285 } u;
286 struct
287 {
288 uint32_t u32IcrHi;
289 uint32_t u32Reserved0[3];
290 } all;
291 } icr_hi;
292 /* 0x320 - Local Vector Table (LVT) Timer Register. */
293 union
294 {
295 struct
296 {
297 uint32_t u8Vector : 8;
298 uint32_t u4Reserved0 : 4;
299 uint32_t u1DeliveryStatus : 1;
300 uint32_t u3Reserved1 : 3;
301 uint32_t u1Mask : 1;
302 uint32_t u2TimerMode : 2;
303 uint32_t u13Reserved2 : 13;
304 uint32_t u32Reserved0[3];
305 } u;
306 struct
307 {
308 uint32_t u32LvtTimer;
309 uint32_t u32Reserved0[3];
310 } all;
311 } lvt_timer;
312 /* 0x330 - Local Vector Table (LVT) Thermal Sensor Register. */
313#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
314 union
315 {
316 struct
317 {
318 uint32_t u8Vector : 8;
319 uint32_t u3DeliveryMode : 3;
320 uint32_t u1Reserved0 : 1;
321 uint32_t u1DeliveryStatus : 1;
322 uint32_t u3Reserved1 : 3;
323 uint32_t u1Mask : 1;
324 uint32_t u15Reserved2 : 15;
325 uint32_t u32Reserved0[3];
326 } u;
327 struct
328 {
329 uint32_t u32LvtThermal;
330 uint32_t u32Reserved0[3];
331 } all;
332 } lvt_thermal;
333#else
334# error "Implement Pentium and P6 family APIC architectures"
335#endif
336 /* 0x340 - Local Vector Table (LVT) Performance Monitor Counter (PMC) Register. */
337 union
338 {
339 struct
340 {
341 uint32_t u8Vector : 8;
342 uint32_t u3DeliveryMode : 3;
343 uint32_t u1Reserved0 : 1;
344 uint32_t u1DeliveryStatus : 1;
345 uint32_t u3Reserved1 : 3;
346 uint32_t u1Mask : 1;
347 uint32_t u15Reserved2 : 15;
348 uint32_t u32Reserved0[3];
349 } u;
350 struct
351 {
352 uint32_t u32LvtPerf;
353 uint32_t u32Reserved0[3];
354 } all;
355 } lvt_perf;
356 /* 0x350 - Local Vector Table (LVT) LINT0 Register. */
357 union
358 {
359 struct
360 {
361 uint32_t u8Vector : 8;
362 uint32_t u3DeliveryMode : 3;
363 uint32_t u1Reserved0 : 1;
364 uint32_t u1DeliveryStatus : 1;
365 uint32_t u1IntrPolarity : 1;
366 uint32_t u1RemoteIrr : 1;
367 uint32_t u1TriggerMode : 1;
368 uint32_t u1Mask : 1;
369 uint32_t u15Reserved2 : 15;
370 uint32_t u32Reserved0[3];
371 } u;
372 struct
373 {
374 uint32_t u32LvtLint0;
375 uint32_t u32Reserved0[3];
376 } all;
377 } lvt_lint0;
378 /* 0x360 - Local Vector Table (LVT) LINT1 Register. */
379 union
380 {
381 struct
382 {
383 uint32_t u8Vector : 8;
384 uint32_t u3DeliveryMode : 3;
385 uint32_t u1Reserved0 : 1;
386 uint32_t u1DeliveryStatus : 1;
387 uint32_t u1IntrPolarity : 1;
388 uint32_t u1RemoteIrr : 1;
389 uint32_t u1TriggerMode : 1;
390 uint32_t u1Mask : 1;
391 uint32_t u15Reserved2 : 15;
392 uint32_t u32Reserved0[3];
393 } u;
394 struct
395 {
396 uint32_t u32LvtLint1;
397 uint32_t u32Reserved0[3];
398 } all;
399 } lvt_lint1;
400 /* 0x370 - Local Vector Table (LVT) Error Register. */
401 union
402 {
403 struct
404 {
405 uint32_t u8Vector : 8;
406 uint32_t u4Reserved0 : 4;
407 uint32_t u1DeliveryStatus : 1;
408 uint32_t u3Reserved1 : 3;
409 uint32_t u1Mask : 1;
410 uint32_t u15Reserved2 : 15;
411 uint32_t u32Reserved0[3];
412 } u;
413 struct
414 {
415 uint32_t u32LvtError;
416 uint32_t u32Reserved0[3];
417 } all;
418 } lvt_error;
419 /* 0x380 - Timer Initial Counter Register. */
420 struct
421 {
422 uint32_t u32InitialCount;
423 uint32_t u32Reserved0[3];
424 } timer_icr;
425 /* 0x390 - Timer Current Counter Register. */
426 struct
427 {
428 uint32_t u32CurrentCount;
429 uint32_t u32Reserved0[3];
430 } timer_ccr;
431 /* 0x3A0 - Reserved. */
432 uint32_t u32Reserved3[16];
433 /* 0x3E0 - Timer Divide Configuration Register. */
434 union
435 {
436 struct
437 {
438 uint32_t u2DivideValue0 : 2;
439 uint32_t u1Reserved0 : 1;
440 uint32_t u1DivideValue1 : 1;
441 uint32_t u28Reserved1 : 28;
442 uint32_t u32Reserved0[3];
443 } u;
444 struct
445 {
446 uint32_t u32DivideValue;
447 uint32_t u32Reserved0[3];
448 } all;
449 } timer_dcr;
450 /* 0x3F0 - Reserved. */
451 uint8_t u8Reserved0[3088];
452} XAPICPAGE;
453/** Pointer to a XAPICPAGE struct. */
454typedef XAPICPAGE *PXAPICPAGE;
455/** Pointer to a const XAPICPAGE struct. */
456typedef const XAPICPAGE *PCXAPICPAGE;
457AssertCompileSize(XAPICPAGE, 4096);
458AssertCompileMemberOffset(XAPICPAGE, id, XAPIC_OFF_ID);
459AssertCompileMemberOffset(XAPICPAGE, version, XAPIC_OFF_VERSION);
460AssertCompileMemberOffset(XAPICPAGE, tpr, XAPIC_OFF_TPR);
461AssertCompileMemberOffset(XAPICPAGE, apr, XAPIC_OFF_APR);
462AssertCompileMemberOffset(XAPICPAGE, ppr, XAPIC_OFF_PPR);
463AssertCompileMemberOffset(XAPICPAGE, eoi, XAPIC_OFF_EOI);
464AssertCompileMemberOffset(XAPICPAGE, rrd, XAPIC_OFF_RRD);
465AssertCompileMemberOffset(XAPICPAGE, ldr, XAPIC_OFF_LDR);
466AssertCompileMemberOffset(XAPICPAGE, dfr, XAPIC_OFF_DFR);
467AssertCompileMemberOffset(XAPICPAGE, svr, XAPIC_OFF_SVR);
468AssertCompileMemberOffset(XAPICPAGE, isr, XAPIC_OFF_ISR0);
469AssertCompileMemberOffset(XAPICPAGE, tmr, XAPIC_OFF_TMR0);
470AssertCompileMemberOffset(XAPICPAGE, irr, XAPIC_OFF_IRR0);
471AssertCompileMemberOffset(XAPICPAGE, esr, XAPIC_OFF_ESR);
472AssertCompileMemberOffset(XAPICPAGE, icr_lo, XAPIC_OFF_ICR_LO);
473AssertCompileMemberOffset(XAPICPAGE, icr_hi, XAPIC_OFF_ICR_HI);
474AssertCompileMemberOffset(XAPICPAGE, lvt_timer, XAPIC_OFF_LVT_TIMER);
475AssertCompileMemberOffset(XAPICPAGE, lvt_thermal, XAPIC_OFF_LVT_THERMAL);
476AssertCompileMemberOffset(XAPICPAGE, lvt_perf, XAPIC_OFF_LVT_PERF);
477AssertCompileMemberOffset(XAPICPAGE, lvt_lint0, XAPIC_OFF_LVT_LINT0);
478AssertCompileMemberOffset(XAPICPAGE, lvt_lint1, XAPIC_OFF_LVT_LINT1);
479AssertCompileMemberOffset(XAPICPAGE, lvt_error, XAPIC_OFF_LVT_ERROR);
480AssertCompileMemberOffset(XAPICPAGE, timer_icr, XAPIC_OFF_TIMER_ICR);
481AssertCompileMemberOffset(XAPICPAGE, timer_ccr, XAPIC_OFF_TIMER_CCR);
482AssertCompileMemberOffset(XAPICPAGE, timer_dcr, XAPIC_OFF_TIMER_DCR);
483
484/**
485 * The x2APIC memory layout as per Intel/AMD specs.
486 */
487typedef struct X2APICPAGE
488{
489 /* 0x00 - Reserved. */
490 uint32_t uReserved0[8];
491 /* 0x20 - APIC ID. */
492 struct
493 {
494 uint32_t u32ApicId;
495 uint32_t u32Reserved0[3];
496 } id;
497 /* 0x30 - APIC version register. */
498 union
499 {
500 struct
501 {
502 uint8_t u8Version;
503 uint8_t u8Reserved0;
504 uint8_t u8MaxLvtEntry;
505 uint8_t fEoiBroadcastSupression : 1;
506 uint8_t u7Reserved1 : 7;
507 uint32_t u32Reserved0[3];
508 } u;
509 struct
510 {
511 uint32_t u32Version;
512 uint32_t u32Reserved2[3];
513 } all;
514 } version;
515 /* 0x40 - Reserved. */
516 uint32_t uReserved1[16];
517 /* 0x80 - Task Priority Register (TPR). */
518 struct
519 {
520 uint8_t u8Tpr;
521 uint8_t u8Reserved0[3];
522 uint32_t u32Reserved0[3];
523 } tpr;
524 /* 0x90 - Reserved. */
525 uint32_t uReserved2[4];
526 /* 0xA0 - Processor Priority Register (PPR). */
527 struct
528 {
529 uint8_t u8Ppr;
530 uint8_t u8Reserved0[3];
531 uint32_t u32Reserved0[3];
532 } ppr;
533 /* 0xB0 - End Of Interrupt Register (EOI). */
534 struct
535 {
536 uint32_t u32Eoi;
537 uint32_t u32Reserved0[3];
538 } eoi;
539 /* 0xC0 - Remote Read Register (RRD). */
540 struct
541 {
542 uint32_t u32Rrd;
543 uint32_t u32Reserved0[3];
544 } rrd;
545 /* 0xD0 - Logical Destination Register (LDR). */
546 struct
547 {
548 uint32_t u32LogicalApicId;
549 uint32_t u32Reserved1[3];
550 } ldr;
551 /* 0xE0 - Reserved. */
552 uint32_t uReserved3[4];
553 /* 0xF0 - Spurious-Interrupt Vector Register (SVR). */
554 union
555 {
556 struct
557 {
558 uint32_t u8SpuriousVector : 8;
559 uint32_t fApicSoftwareEnable : 1;
560 uint32_t u3Reserved0 : 3;
561 uint32_t fSupressEoiBroadcast : 1;
562 uint32_t u19Reserved1 : 19;
563 uint32_t u32Reserved0[3];
564 } u;
565 struct
566 {
567 uint32_t u32Svr;
568 uint32_t uReserved0[3];
569 } all;
570 } svr;
571 /* 0x100 - In-service Register (ISR). */
572 XAPIC256BITREG isr;
573 /* 0x180 - Trigger Mode Register (TMR). */
574 XAPIC256BITREG tmr;
575 /* 0x200 - Interrupt Request Register (IRR). */
576 XAPIC256BITREG irr;
577 /* 0x280 - Error Status Register (ESR). */
578 union
579 {
580 struct
581 {
582#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
583 uint32_t u4Reserved0 : 4;
584#else
585# error "Implement Pentium and P6 family APIC architectures"
586#endif
587 uint32_t fRedirectableIpi : 1;
588 uint32_t fSendIllegalVector : 1;
589 uint32_t fRcvdIllegalVector : 1;
590 uint32_t fIllegalRegAddr : 1;
591 uint32_t u24Reserved1 : 24;
592 uint32_t uReserved0[3];
593 } u;
594 struct
595 {
596 uint32_t u32Errors;
597 uint32_t u32Reserved0[3];
598 } all;
599 } esr;
600 /* 0x290 - Reserved. */
601 uint32_t uReserved4[28];
602 /* 0x300 - Interrupt Command Register (ICR) - Low. */
603 union
604 {
605 struct
606 {
607 uint32_t u8Vector : 8;
608 uint32_t u3DeliveryMode : 3;
609 uint32_t u1DestMode : 1;
610 uint32_t u2Reserved0 : 2;
611 uint32_t u1Level : 1;
612 uint32_t u1TriggerMode : 1;
613 uint32_t u2Reserved1 : 2;
614 uint32_t u2DestShorthand : 2;
615 uint32_t u12Reserved2 : 12;
616 uint32_t u32Reserved0[3];
617 } u;
618 struct
619 {
620 uint32_t u32IcrLo;
621 uint32_t u32Reserved3[3];
622 } all;
623 } icr_lo;
624 /* 0x310 - Interrupt Comannd Register (ICR) - High. */
625 struct
626 {
627 uint32_t u32IcrHi;
628 uint32_t uReserved1[3];
629 } icr_hi;
630 /* 0x320 - Local Vector Table (LVT) Timer Register. */
631 union
632 {
633 struct
634 {
635 uint32_t u8Vector : 8;
636 uint32_t u4Reserved0 : 4;
637 uint32_t u1DeliveryStatus : 1;
638 uint32_t u3Reserved1 : 3;
639 uint32_t u1Mask : 1;
640 uint32_t u2TimerMode : 2;
641 uint32_t u13Reserved2 : 13;
642 uint32_t u32Reserved0[3];
643 } u;
644 struct
645 {
646 uint32_t u32LvtTimer;
647 uint32_t u32Reserved0[3];
648 } all;
649 } lvt_timer;
650 /* 0x330 - Local Vector Table (LVT) Thermal Sensor Register. */
651 union
652 {
653 struct
654 {
655 uint32_t u8Vector : 8;
656 uint32_t u3DeliveryMode : 3;
657 uint32_t u1Reserved0 : 1;
658 uint32_t u1DeliveryStatus : 1;
659 uint32_t u3Reserved1 : 3;
660 uint32_t u1Mask : 1;
661 uint32_t u15Reserved2 : 15;
662 uint32_t u32Reserved0[3];
663 } u;
664 struct
665 {
666 uint32_t u32LvtThermal;
667 uint32_t uReserved0[3];
668 } all;
669 } lvt_thermal;
670 /* 0x340 - Local Vector Table (LVT) Performance Monitor Counter (PMC) Register. */
671 union
672 {
673 struct
674 {
675 uint32_t u8Vector : 8;
676 uint32_t u3DeliveryMode : 3;
677 uint32_t u1Reserved0 : 1;
678 uint32_t u1DeliveryStatus : 1;
679 uint32_t u3Reserved1 : 3;
680 uint32_t u1Mask : 1;
681 uint32_t u15Reserved2 : 15;
682 uint32_t u32Reserved0[3];
683 } u;
684 struct
685 {
686 uint32_t u32LvtPerf;
687 uint32_t u32Reserved0[3];
688 } all;
689 } lvt_perf;
690 /* 0x350 - Local Vector Table (LVT) LINT0 Register. */
691 union
692 {
693 struct
694 {
695 uint32_t u8Vector : 8;
696 uint32_t u3DeliveryMode : 3;
697 uint32_t u1Reserved0 : 1;
698 uint32_t u1DeliveryStatus : 1;
699 uint32_t u1IntrPolarity : 1;
700 uint32_t u1RemoteIrr : 1;
701 uint32_t u1TriggerMode : 1;
702 uint32_t u1Mask : 1;
703 uint32_t u15Reserved2 : 15;
704 uint32_t u32Reserved0[3];
705 } u;
706 struct
707 {
708 uint32_t u32LvtLint0;
709 uint32_t u32Reserved0[3];
710 } all;
711 } lvt_lint0;
712 /* 0x360 - Local Vector Table (LVT) LINT1 Register. */
713 union
714 {
715 struct
716 {
717 uint32_t u8Vector : 8;
718 uint32_t u3DeliveryMode : 3;
719 uint32_t u1Reserved0 : 1;
720 uint32_t u1DeliveryStatus : 1;
721 uint32_t u1IntrPolarity : 1;
722 uint32_t u1RemoteIrr : 1;
723 uint32_t u1TriggerMode : 1;
724 uint32_t u1Mask : 1;
725 uint32_t u15Reserved2 : 15;
726 uint32_t u32Reserved0[3];
727 } u;
728 struct
729 {
730 uint32_t u32LvtLint1;
731 uint32_t u32Reserved0[3];
732 } all;
733 } lvt_lint1;
734 /* 0x370 - Local Vector Table (LVT) Error Register. */
735 union
736 {
737 struct
738 {
739 uint32_t u8Vector : 8;
740 uint32_t u4Reserved0 : 4;
741 uint32_t u1DeliveryStatus : 1;
742 uint32_t u3Reserved1 : 3;
743 uint32_t u1Mask : 1;
744 uint32_t u15Reserved2 : 15;
745 uint32_t u32Reserved0[3];
746 } u;
747 struct
748 {
749 uint32_t u32LvtError;
750 uint32_t u32Reserved0[3];
751 } all;
752 } lvt_error;
753 /* 0x380 - Timer Initial Counter Register. */
754 struct
755 {
756 uint32_t u32InitialCount;
757 uint32_t u32Reserved0[3];
758 } timer_icr;
759 /* 0x390 - Timer Current Counter Register. */
760 struct
761 {
762 uint32_t u32CurrentCount;
763 uint32_t u32Reserved0[3];
764 } timer_ccr;
765 /* 0x3A0 - Reserved. */
766 uint32_t uReserved5[16];
767 /* 0x3E0 - Timer Divide Configuration Register. */
768 union
769 {
770 struct
771 {
772 uint32_t u2DivideValue0 : 2;
773 uint32_t u1Reserved0 : 1;
774 uint32_t u1DivideValue1 : 1;
775 uint32_t u28Reserved1 : 28;
776 uint32_t u32Reserved0[3];
777 } u;
778 struct
779 {
780 uint32_t u32DivideValue;
781 uint32_t u32Reserved0[3];
782 } all;
783 } timer_dcr;
784 /* 0x3F0 - Self IPI Register. */
785 struct
786 {
787 uint32_t u8Vector : 8;
788 uint32_t u24Reserved0 : 24;
789 uint32_t u32Reserved0[3];
790 } self_ipi;
791 /* 0x400 - Reserved. */
792 uint8_t u8Reserved0[3072];
793} X2APICPAGE;
794/** Pointer to a X2APICPAGE struct. */
795typedef X2APICPAGE *PX2APICPAGE;
796/** Pointer to a const X2APICPAGE struct. */
797typedef const X2APICPAGE *PCX2APICPAGE;
798AssertCompileSize(X2APICPAGE, 4096);
799AssertCompileSize(X2APICPAGE, sizeof(XAPICPAGE));
800AssertCompileMemberOffset(X2APICPAGE, id, XAPIC_OFF_ID);
801AssertCompileMemberOffset(X2APICPAGE, version, XAPIC_OFF_VERSION);
802AssertCompileMemberOffset(X2APICPAGE, tpr, XAPIC_OFF_TPR);
803AssertCompileMemberOffset(X2APICPAGE, ppr, XAPIC_OFF_PPR);
804AssertCompileMemberOffset(X2APICPAGE, eoi, XAPIC_OFF_EOI);
805AssertCompileMemberOffset(X2APICPAGE, rrd, XAPIC_OFF_RRD);
806AssertCompileMemberOffset(X2APICPAGE, ldr, XAPIC_OFF_LDR);
807AssertCompileMemberOffset(X2APICPAGE, svr, XAPIC_OFF_SVR);
808AssertCompileMemberOffset(X2APICPAGE, isr, XAPIC_OFF_ISR0);
809AssertCompileMemberOffset(X2APICPAGE, tmr, XAPIC_OFF_TMR0);
810AssertCompileMemberOffset(X2APICPAGE, irr, XAPIC_OFF_IRR0);
811AssertCompileMemberOffset(X2APICPAGE, esr, XAPIC_OFF_ESR);
812AssertCompileMemberOffset(X2APICPAGE, icr_lo, XAPIC_OFF_ICR_LO);
813AssertCompileMemberOffset(X2APICPAGE, icr_hi, XAPIC_OFF_ICR_HI);
814AssertCompileMemberOffset(X2APICPAGE, lvt_timer, XAPIC_OFF_LVT_TIMER);
815AssertCompileMemberOffset(X2APICPAGE, lvt_thermal, XAPIC_OFF_LVT_THERMAL);
816AssertCompileMemberOffset(X2APICPAGE, lvt_perf, XAPIC_OFF_LVT_PERF);
817AssertCompileMemberOffset(X2APICPAGE, lvt_lint0, XAPIC_OFF_LVT_LINT0);
818AssertCompileMemberOffset(X2APICPAGE, lvt_lint1, XAPIC_OFF_LVT_LINT1);
819AssertCompileMemberOffset(X2APICPAGE, lvt_error, XAPIC_OFF_LVT_ERROR);
820AssertCompileMemberOffset(X2APICPAGE, timer_icr, XAPIC_OFF_TIMER_ICR);
821AssertCompileMemberOffset(X2APICPAGE, timer_ccr, XAPIC_OFF_TIMER_CCR);
822AssertCompileMemberOffset(X2APICPAGE, timer_dcr, XAPIC_OFF_TIMER_DCR);
823AssertCompileMemberOffset(X2APICPAGE, self_ipi, X2APIC_OFF_SELF_IPI);
824
825/** Maximum valid offset for a register (16-byte aligned, 4 byte wide access). */
826#define XAPIC_OFF_MAX_VALID (sizeof(XAPICPAGE) - 4 * sizeof(uint32_t))
827
828#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P6
829/** ESR - Send checksum error. */
830# define XAPIC_ESR_SEND_CHKSUM_ERROR RT_BIT(0)
831/** ESR - Send accept error. */
832# define XAPIC_ESR_RECV_CHKSUM_ERROR RT_BIT(1)
833/** ESR - Send accept error. */
834# define XAPIC_ESR_SEND_ACCEPT_ERROR RT_BIT(2)
835/** ESR - Receive accept error. */
836# define XAPIC_ESR_RECV_ACCEPT_ERROR RT_BIT(3)
837#endif
838/** ESR - Redirectable IPI. */
839#define XAPIC_ESR_REDIRECTABLE_IPI RT_BIT(4)
840/** ESR - Send accept error. */
841#define XAPIC_ESR_SEND_ILLEGAL_VECTOR RT_BIT(5)
842/** ESR - Send accept error. */
843#define XAPIC_ESR_RECV_ILLEGAL_VECTOR RT_BIT(6)
844/** ESR - Send accept error. */
845#define XAPIC_ESR_ILLEGAL_REG_ADDRESS RT_BIT(7)
846/** ESR - Valid write-only bits. */
847#define XAPIC_ESR_WO UINT32_C(0x0)
848
849/** TPR - Valid bits. */
850#define XAPIC_TPR UINT32_C(0xff)
851/** TPR - Task-priority class. */
852#define XAPIC_TPR_TP UINT32_C(0xf0)
853/** TPR - Task-priority subclass. */
854#define XAPIC_TPR_TP_SUBCLASS UINT32_C(0x0f)
855/** TPR - Gets the task-priority class. */
856#define XAPIC_TPR_GET_TP(a_Tpr) ((a_Tpr) & XAPIC_TPR_TP)
857/** TPR - Gets the task-priority subclass. */
858#define XAPIC_TPR_GET_TP_SUBCLASS(a_Tpr) ((a_Tpr) & XAPIC_TPR_TP_SUBCLASS)
859
860/** PPR - Valid bits. */
861#define XAPIC_PPR UINT32_C(0xff)
862/** PPR - Processor-priority class. */
863#define XAPIC_PPR_PP UINT32_C(0xf0)
864/** PPR - Processor-priority subclass. */
865#define XAPIC_PPR_PP_SUBCLASS UINT32_C(0x0f)
866/** PPR - Get the processor-priority class. */
867#define XAPIC_PPR_GET_PP(a_Ppr) ((a_Ppr) & XAPIC_PPR_PP)
868/** PPR - Get the processor-priority subclass. */
869#define XAPIC_PPR_GET_PP_SUBCLASS(a_Ppr) ((a_Ppr) & XAPIC_PPR_PP_SUBCLASS)
870
871/** Timer mode - One-shot. */
872#define XAPIC_TIMER_MODE_ONESHOT UINT32_C(0)
873/** Timer mode - Periodic. */
874#define XAPIC_TIMER_MODE_PERIODIC UINT32_C(1)
875/** Timer mode - TSC deadline. */
876#define XAPIC_TIMER_MODE_TSC_DEADLINE UINT32_C(2)
877
878/** LVT - The vector. */
879#define XAPIC_LVT_VECTOR UINT32_C(0xff)
880/** LVT - Gets the vector from an LVT entry. */
881#define XAPIC_LVT_GET_VECTOR(a_Lvt) ((a_Lvt) & XAPIC_LVT_VECTOR)
882/** LVT - The mask. */
883#define XAPIC_LVT_MASK RT_BIT(16)
884/** LVT - Is the LVT masked? */
885#define XAPIC_LVT_IS_MASKED(a_Lvt) RT_BOOL((a_Lvt) & XAPIC_LVT_MASK)
886/** LVT - Timer mode. */
887#define XAPIC_LVT_TIMER_MODE RT_BIT(17)
888/** LVT - Timer TSC-deadline timer mode. */
889#define XAPIC_LVT_TIMER_TSCDEADLINE RT_BIT(18)
890/** LVT - Gets the timer mode. */
891#define XAPIC_LVT_GET_TIMER_MODE(a_Lvt) (XAPICTIMERMODE)(((a_Lvt) >> 17) & UINT32_C(3))
892/** LVT - Delivery mode. */
893#define XAPIC_LVT_DELIVERY_MODE (RT_BIT(8) | RT_BIT(9) | RT_BIT(10))
894/** LVT - Gets the delivery mode. */
895#define XAPIC_LVT_GET_DELIVERY_MODE(a_Lvt) (XAPICDELIVERYMODE)(((a_Lvt) >> 8) & UINT32_C(7))
896/** LVT - Delivery status. */
897#define XAPIC_LVT_DELIVERY_STATUS RT_BIT(12)
898/** LVT - Trigger mode. */
899#define XAPIC_LVT_TRIGGER_MODE RT_BIT(15)
900/** LVT - Gets the trigger mode. */
901#define XAPIC_LVT_GET_TRIGGER_MODE(a_Lvt) (XAPICTRIGGERMODE)(((a_Lvt) >> 15) & UINT32_C(1))
902/** LVT - Remote IRR. */
903#define XAPIC_LVT_REMOTE_IRR RT_BIT(14)
904/** LVT - Interrupt Input Pin Polarity. */
905#define XAPIC_LVT_INTR_INPUT_PIN_POLARITY RT_BIT(13)
906/** LVT - Valid bits common to all LVTs. */
907#define XAPIC_LVT_COMMON (XAPIC_LVT_VECTOR | XAPIC_LVT_DELIVERY_STATUS | XAPIC_LVT_MASK)
908/** LVT CMCI - Valid bits. */
909#define XAPIC_LVT_CMCI_VALID (XAPIC_LVT_COMMON | XAPIC_LVT_DELIVERY_MODE)
910/** LVT Timer - Valid bits. */
911#define XAPIC_LVT_TIMER_VALID (XAPIC_LVT_COMMON | XAPIC_LVT_TIMER_MODE | XAPIC_LVT_TIMER_TSCDEADLINE)
912/** LVT Thermal - Valid bits. */
913#define XAPIC_LVT_THERMAL_VALID (XAPIC_LVT_COMMON | XAPIC_LVT_DELIVERY_MODE)
914/** LVT Perf - Valid bits. */
915#define XAPIC_LVT_PERF_VALID (XAPIC_LVT_COMMON | XAPIC_LVT_DELIVERY_MODE)
916/** LVT LINTx - Valid bits. */
917#define XAPIC_LVT_LINT_VALID ( XAPIC_LVT_COMMON | XAPIC_LVT_DELIVERY_MODE | XAPIC_LVT_DELIVERY_STATUS \
918 | XAPIC_LVT_INTR_INPUT_PIN_POLARITY | XAPIC_LVT_REMOTE_IRR | XAPIC_LVT_TRIGGER_MODE)
919/** LVT Error - Valid bits. */
920#define XAPIC_LVT_ERROR_VALID (XAPIC_LVT_COMMON)
921
922/** SVR - The vector. */
923#define XAPIC_SVR_VECTOR UINT32_C(0xff)
924/** SVR - APIC Software enable. */
925#define XAPIC_SVR_SOFTWARE_ENABLE RT_BIT(8)
926/** SVR - Supress EOI broadcast. */
927#define XAPIC_SVR_SUPRESS_EOI_BROADCAST RT_BIT(12)
928#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
929/** SVR - Valid bits. */
930# define XAPIC_SVR (XAPIC_SVR_VECTOR | XAPIC_SVR_SOFTWARE_ENABLE)
931#else
932# error "Implement Pentium and P6 family APIC architectures"
933#endif
934
935/** DFR - Valid bits. */
936#define XAPIC_DFR UINT32_C(0xf0000000)
937/** DFR - Reserved bits that must always remain set. */
938#define XAPIC_DFR_RSVD_MB1 UINT32_C(0x0fffffff)
939/** DFR - The model. */
940#define XAPIC_DFR_MODEL UINT32_C(0xf)
941/** DFR - Gets the destination model. */
942#define XAPIC_DFR_GET_MODEL(a_uReg) (((a_uReg) >> 28) & XAPIC_DFR_MODEL)
943
944/** LDR - Valid bits. */
945#define XAPIC_LDR UINT32_C(0xff000000)
946/** LDR - Cluster ID mask (x2APIC). */
947#define X2APIC_LDR_CLUSTER_ID UINT32_C(0xffff0000)
948/** LDR - Mask of the LDR cluster ID (x2APIC). */
949#define X2APIC_LDR_GET_CLUSTER_ID(a_uReg) ((a_uReg) & X2APIC_LDR_CLUSTER_ID)
950/** LDR - Mask of the LDR logical ID (x2APIC). */
951#define X2APIC_LDR_LOGICAL_ID UINT32_C(0x0000ffff)
952
953/** LDR - Flat mode logical ID mask. */
954#define XAPIC_LDR_FLAT_LOGICAL_ID UINT32_C(0xff)
955/** LDR - Clustered mode cluster ID mask. */
956#define XAPIC_LDR_CLUSTERED_CLUSTER_ID UINT32_C(0xf0)
957/** LDR - Clustered mode logical ID mask. */
958#define XAPIC_LDR_CLUSTERED_LOGICAL_ID UINT32_C(0x0f)
959/** LDR - Gets the clustered mode cluster ID. */
960#define XAPIC_LDR_CLUSTERED_GET_CLUSTER_ID(a_uReg) ((a_uReg) & XAPIC_LDR_CLUSTERED_CLUSTER_ID)
961
962
963/** EOI - Valid write-only bits. */
964#define XAPIC_EOI_WO UINT32_C(0x0)
965/** Timer ICR - Valid bits. */
966#define XAPIC_TIMER_ICR UINT32_C(0xffffffff)
967/** Timer DCR - Valid bits. */
968#define XAPIC_TIMER_DCR (RT_BIT(0) | RT_BIT(1) | RT_BIT(3))
969
970/** Self IPI - Valid bits. */
971#define XAPIC_SELF_IPI UINT32_C(0xff)
972/** Self IPI - The vector. */
973#define XAPIC_SELF_IPI_VECTOR UINT32_C(0xff)
974/** Self IPI - Gets the vector. */
975#define XAPIC_SELF_IPI_GET_VECTOR(a_uReg) ((a_uReg) & XAPIC_SELF_IPI_VECTOR)
976
977/** ICR Low - The Vector. */
978#define XAPIC_ICR_LO_VECTOR UINT32_C(0xff)
979/** ICR Low - Gets the vector. */
980#define XAPIC_ICR_LO_GET_VECTOR(a_uIcr) ((a_uIcr) & XAPIC_ICR_LO_VECTOR)
981/** ICR Low - The delivery mode. */
982#define XAPIC_ICR_LO_DELIVERY_MODE (RT_BIT(8) | RT_BIT(9) | RT_BIT(10))
983/** ICR Low - The destination mode. */
984#define XAPIC_ICR_LO_DEST_MODE RT_BIT(11)
985/** ICR Low - The delivery status. */
986#define XAPIC_ICR_LO_DELIVERY_STATUS RT_BIT(12)
987/** ICR Low - The level. */
988#define XAPIC_ICR_LO_LEVEL RT_BIT(14)
989/** ICR Low - The trigger mode. */
990#define XAPIC_ICR_TRIGGER_MODE RT_BIT(15)
991/** ICR Low - The destination shorthand. */
992#define XAPIC_ICR_LO_DEST_SHORTHAND (RT_BIT(18) | RT_BIT(19))
993/** ICR Low - Valid write bits. */
994#define XAPIC_ICR_LO_WR ( XAPIC_ICR_LO_VECTOR | XAPIC_ICR_LO_DELIVERY_MODE | XAPIC_ICR_LO_DEST_MODE \
995 | XAPIC_ICR_LO_LEVEL | XAPIC_ICR_TRIGGER_MODE | XAPIC_ICR_LO_DEST_SHORTHAND)
996
997/** ICR High - The destination field. */
998#define XAPIC_ICR_HI_DEST UINT32_C(0xff000000)
999/** ICR High - Get the destination field. */
1000#define XAPIC_ICR_HI_GET_DEST(a_u32IcrHi) (((a_u32IcrHi) >> 24) & XAPIC_ICR_HI_DEST)
1001/** ICR High - Valid write bits in xAPIC mode. */
1002#define XAPIC_ICR_HI_WR XAPIC_ICR_HI_DEST
1003
1004/** APIC ID broadcast mask - x2APIC mode. */
1005#define X2APIC_ID_BROADCAST_MASK UINT32_C(0xffffffff)
1006#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
1007/** APIC ID broadcast mask - xAPIC mode. */
1008# define XAPIC_ID_BROADCAST_MASK UINT32_C(0xff)
1009#else
1010# error "Implement Pentium and P6 family APIC architectures"
1011#endif
1012
1013/**
1014 * APIC MSR access error.
1015 * @note The values must match the array indices in apicMsrAccessError().
1016 */
1017typedef enum APICMSRACCESS
1018{
1019 /* MSR read while not in x2APIC. */
1020 APICMSRACCESS_INVALID_READ_MODE = 0,
1021 /* MSR write while not in x2APIC. */
1022 APICMSRACCESS_INVALID_WRITE_MODE,
1023 /* MSR read for a reserved/unknown/invalid MSR. */
1024 APICMSRACCESS_READ_RSVD_OR_UNKNOWN,
1025 /* MSR write for a reserved/unknown/invalid MSR. */
1026 APICMSRACCESS_WRITE_RSVD_OR_UNKNOWN,
1027 /* MSR read for a write-only MSR. */
1028 APICMSRACCESS_READ_WRITE_ONLY,
1029 /* MSR write for a read-only MSR. */
1030 APICMSRACCESS_WRITE_READ_ONLY,
1031 /* MSR read to reserved bits. */
1032 APICMSRACCESS_READ_RSVD_BITS,
1033 /* MSR write to reserved bits. */
1034 APICMSRACCESS_WRITE_RSVD_BITS,
1035 /* MSR write with invalid value. */
1036 APICMSRACCESS_WRITE_INVALID,
1037 /** MSR write disallowed due to incompatible config. */
1038 APICMSRACCESS_WRITE_DISALLOWED_CONFIG,
1039 /* Count of enum members (don't use). */
1040 APICMSRACCESS_COUNT
1041} APICMSRACCESS;
1042
1043/** @name xAPIC Destination Format Register bits.
1044 * See Intel spec. 10.6.2.2 "Logical Destination Mode".
1045 * @{ */
1046typedef enum XAPICDESTFORMAT
1047{
1048 XAPICDESTFORMAT_FLAT = 0xf,
1049 XAPICDESTFORMAT_CLUSTER = 0
1050} XAPICDESTFORMAT;
1051/** @} */
1052
1053/** @name xAPIC Timer Mode bits.
1054 * See Intel spec. 10.5.1 "Local Vector Table".
1055 * @{ */
1056typedef enum XAPICTIMERMODE
1057{
1058 XAPICTIMERMODE_ONESHOT = XAPIC_TIMER_MODE_ONESHOT,
1059 XAPICTIMERMODE_PERIODIC = XAPIC_TIMER_MODE_PERIODIC,
1060 XAPICTIMERMODE_TSC_DEADLINE = XAPIC_TIMER_MODE_TSC_DEADLINE
1061} XAPICTIMERMODE;
1062/** @} */
1063
1064/** @name xAPIC Interrupt Command Register bits.
1065 * See Intel spec. 10.6.1 "Interrupt Command Register (ICR)".
1066 * See Intel spec. 10.5.1 "Local Vector Table".
1067 * @{ */
1068/**
1069 * xAPIC trigger mode.
1070 */
1071typedef enum XAPICTRIGGERMODE
1072{
1073 XAPICTRIGGERMODE_EDGE = 0,
1074 XAPICTRIGGERMODE_LEVEL
1075} XAPICTRIGGERMODE;
1076
1077/**
1078 * xAPIC destination shorthand.
1079 */
1080typedef enum XAPICDESTSHORTHAND
1081{
1082 XAPICDESTSHORTHAND_NONE = 0,
1083 XAPICDESTSHORTHAND_SELF,
1084 XAPIDDESTSHORTHAND_ALL_INCL_SELF,
1085 XAPICDESTSHORTHAND_ALL_EXCL_SELF
1086} XAPICDESTSHORTHAND;
1087
1088/**
1089 * xAPIC INIT level de-assert delivery mode.
1090 */
1091typedef enum XAPICINITLEVEL
1092{
1093 XAPICINITLEVEL_DEASSERT = 0,
1094 XAPICINITLEVEL_ASSERT
1095} XAPICLEVEL;
1096
1097/**
1098 * xAPIC destination mode.
1099 */
1100typedef enum XAPICDESTMODE
1101{
1102 XAPICDESTMODE_PHYSICAL = 0,
1103 XAPICDESTMODE_LOGICAL
1104} XAPICDESTMODE;
1105
1106/**
1107 * xAPIC delivery mode type.
1108 */
1109typedef enum XAPICDELIVERYMODE
1110{
1111 XAPICDELIVERYMODE_FIXED = 0,
1112 XAPICDELIVERYMODE_LOWEST_PRIO = 1,
1113 XAPICDELIVERYMODE_SMI = 2,
1114 XAPICDELIVERYMODE_NMI = 4,
1115 XAPICDELIVERYMODE_INIT = 5,
1116 XAPICDELIVERYMODE_INIT_LEVEL_DEASSERT = 5, /* Yes, also 5. */
1117 XAPICDELIVERYMODE_STARTUP = 6,
1118 XAPICDELIVERYMODE_EXTINT = 7
1119} XAPICDELIVERYMODE;
1120/** @} */
1121
1122/**
1123 * APIC operating modes.
1124 *
1125 * The values match hardware states.
1126 * See Intel spec. 10.12.1 "Detecting and Enabling x2APIC Mode".
1127 */
1128typedef enum APICMODE
1129{
1130 APICMODE_DISABLED = 0,
1131 APICMODE_INVALID,
1132 APICMODE_XAPIC,
1133 APICMODE_X2APIC
1134} APICMODE;
1135
1136/**
1137 * APIC Pending-Interrupt Bitmap (PIB).
1138 */
1139typedef struct APICPIB
1140{
1141 uint64_t volatile aVectorBitmap[4];
1142 uint32_t volatile fOutstandingNotification;
1143 uint8_t au8Reserved[28];
1144} APICPIB;
1145AssertCompileMemberOffset(APICPIB, fOutstandingNotification, 256 / 8);
1146AssertCompileSize(APICPIB, 64);
1147/** Pointer to a pending-interrupt bitmap. */
1148typedef APICPIB *PAPICPIB;
1149/** Pointer to a const pending-interrupt bitmap. */
1150typedef const APICPIB *PCAPICPIB;
1151
1152/**
1153 * APIC PDM instance data (per-VM).
1154 */
1155typedef struct APICDEV
1156{
1157 /** The device instance - R3 Ptr. */
1158 PPDMDEVINSR3 pDevInsR3;
1159 /** The APIC helpers - R3 Ptr. */
1160 PCPDMAPICHLPR3 pApicHlpR3;
1161 /** The PDM critical section - R3 Ptr. */
1162 R3PTRTYPE(PPDMCRITSECT) pCritSectR3;
1163 /** Alignment padding. */
1164 R3PTRTYPE(void *) pvAlignment0;
1165
1166 /** The device instance - R0 Ptr. */
1167 PPDMDEVINSR0 pDevInsR0;
1168 /** The APIC helpers - R0 Ptr. */
1169 PCPDMAPICHLPR0 pApicHlpR0;
1170 /** The PDM critical section - R0 Ptr. */
1171 R0PTRTYPE(PPDMCRITSECT) pCritSectR0;
1172 /** Alignment padding. */
1173 R0PTRTYPE(void *) pvAlignment1;
1174
1175 /** The device instance - RC Ptr. */
1176 PPDMDEVINSRC pDevInsRC;
1177 /** The APIC helpers - RC Ptr. */
1178 PCPDMAPICHLPRC pApicHlpRC;
1179 /** The PDM critical section - RC Ptr. */
1180 RCPTRTYPE(PPDMCRITSECT) pCritSectRC;
1181 /** Alignment padding. */
1182 RCPTRTYPE(void *) pvAlignment2;
1183} APICDEV;
1184/** Pointer to an APIC device. */
1185typedef APICDEV *PAPICDEV;
1186/** Pointer to a const APIC device. */
1187typedef APICDEV const *PCAPICDEV;
1188
1189/**
1190 * APIC VM Instance data.
1191 */
1192typedef struct APIC
1193{
1194 /** @name The APIC PDM device instance.
1195 * @{ */
1196 /** The APIC device - R0 ptr. */
1197 R0PTRTYPE(PAPICDEV) pApicDevR0;
1198 /** The APIC device - R3 ptr. */
1199 R3PTRTYPE(PAPICDEV) pApicDevR3;
1200 /** The APIC device - RC ptr. */
1201 RCPTRTYPE(PAPICDEV) pApicDevRC;
1202 /** Alignment padding. */
1203 RTRCPTR RCPtrAlignment0;
1204 /** @} */
1205
1206 /** @name The APIC pending-interrupt bitmap (PIB).
1207 * @{ */
1208 /** The host-context physical address of the PIB. */
1209 RTHCPHYS HCPhysApicPib;
1210 /** The ring-0 memory object of the PIB. */
1211 RTR0MEMOBJ hMemObjApicPibR0;
1212 /** The ring-3 mapping of the memory object of the PIB. */
1213 RTR0MEMOBJ hMapObjApicPibR0;
1214 /** The APIC PIB virtual address - R0 ptr. */
1215 R0PTRTYPE(void *) pvApicPibR0;
1216 /** The APIC PIB virtual address - R3 ptr. */
1217 R3PTRTYPE(void *) pvApicPibR3;
1218 /** The APIC PIB virtual address - RC ptr. */
1219 RCPTRTYPE(void *) pvApicPibRC;
1220 /** Alignment padding. */
1221 RTRCPTR RCPtrAlignment1;
1222 /** The size of the page in bytes. */
1223 uint32_t cbApicPib;
1224 /** Alignment padding. */
1225 uint32_t u32Aligment0;
1226 /** @} */
1227
1228 /** @name Other miscellaneous data.
1229 * @{ */
1230 /** Whether full APIC register virtualization is enabled. */
1231 bool fVirtApicRegsEnabled;
1232 /** Whether posted-interrupt processing is enabled. */
1233 bool fPostedIntrsEnabled;
1234 /** Whether TSC-deadline timer mode is supported for the guest. */
1235 bool fSupportsTscDeadline;
1236 /** Whether this VM has an IO-APIC. */
1237 bool fIoApicPresent;
1238 /** Whether RZ is enabled or not (applies to MSR handling as well). */
1239 bool fRZEnabled;
1240 /** Alignment padding. */
1241 bool afAlignment0[7];
1242 /** The original APIC mode from CFGM. */
1243 APICMODE enmOriginalMode;
1244 /** @} */
1245} APIC;
1246/** Pointer to APIC VM instance data. */
1247typedef APIC *PAPIC;
1248/** Pointer to const APIC VM instance data. */
1249typedef APIC const *PCAPIC;
1250
1251/**
1252 * APIC VMCPU Instance data.
1253 */
1254typedef struct APICCPU
1255{
1256 /** @name The APIC page.
1257 * @{ */
1258 /** The host-context physical address of the page. */
1259 RTHCPHYS HCPhysApicPage;
1260 /** The ring-0 memory object of the page. */
1261 RTR0MEMOBJ hMemObjApicPageR0;
1262 /** The ring-3 mapping of the memory object of the page. */
1263 RTR0MEMOBJ hMapObjApicPageR0;
1264 /** The APIC page virtual address - R0 ptr. */
1265 R0PTRTYPE(void *) pvApicPageR0;
1266 /** The APIC page virtual address - R3 ptr. */
1267 R3PTRTYPE(void *) pvApicPageR3;
1268 /** The APIC page virtual address - RC ptr. */
1269 RCPTRTYPE(void *) pvApicPageRC;
1270 /** Alignment padding. */
1271 RTRCPTR RCPtrAlignment0;
1272 /** The size of the page in bytes. */
1273 uint32_t cbApicPage;
1274 /** @} */
1275
1276 /** @name Auxiliary state.
1277 * @{ */
1278 /** The error status register's internal state. */
1279 uint32_t uEsrInternal;
1280 /** The APIC base MSR.*/
1281 uint64_t volatile uApicBaseMsr;
1282 /** @} */
1283
1284 /** @name The pending-interrupt bitmaps (PIB).
1285 * @{ */
1286 /** The host-context physical address of the page. */
1287 RTHCPHYS HCPhysApicPib;
1288 /** The APIC PIB virtual address - R0 ptr. */
1289 R0PTRTYPE(void *) pvApicPibR0;
1290 /** The APIC PIB virtual address - R3 ptr. */
1291 R3PTRTYPE(void *) pvApicPibR3;
1292 /** The APIC PIB virtual address - RC ptr. */
1293 RCPTRTYPE(void *) pvApicPibRC;
1294 /** Alignment padding. */
1295 RTRCPTR RCPtrAlignment1;
1296 /** The APIC PIB for level-sensitive interrupts. */
1297 APICPIB ApicPibLevel;
1298 /** @} */
1299
1300 /** @name The APIC timer.
1301 * @{ */
1302 /** The timer - R0 ptr. */
1303 PTMTIMERR0 pTimerR0;
1304 /** The timer - R3 ptr. */
1305 PTMTIMERR3 pTimerR3;
1306 /** The timer - RC ptr. */
1307 PTMTIMERRC pTimerRC;
1308 /** Alignment padding. */
1309 RTRCPTR RCPtrAlignment2;
1310 /** The timer critical sect protecting @a u64TimerInitial */
1311 PDMCRITSECT TimerCritSect;
1312 /** The time stamp when the timer was initialized. */
1313 uint64_t u64TimerInitial;
1314 /** Cache of timer initial count of the frequency hint to TM. */
1315 uint32_t uHintedTimerInitialCount;
1316 /** Cache of timer shift of the frequency hint to TM. */
1317 uint32_t uHintedTimerShift;
1318 /** The timer description. */
1319 char szTimerDesc[32];
1320 /** @} */
1321
1322#ifdef VBOX_WITH_STATISTICS
1323 /** @name APIC statistics.
1324 * @{ */
1325 /** Number of MMIO reads in R0. */
1326 STAMCOUNTER StatMmioReadR0;
1327 /** Number of MMIO reads in R3. */
1328 STAMCOUNTER StatMmioReadR3;
1329 /** Number of MMIO reads in RC. */
1330 STAMCOUNTER StatMmioReadRC;
1331
1332 /** Number of MMIO writes in R0. */
1333 STAMCOUNTER StatMmioWriteR0;
1334 /** Number of MMIO writes in R3. */
1335 STAMCOUNTER StatMmioWriteR3;
1336 /** Number of MMIO writes in RC. */
1337 STAMCOUNTER StatMmioWriteRC;
1338
1339 /** Number of MSR reads in R0. */
1340 STAMCOUNTER StatMsrReadR0;
1341 /** Number of MSR reads in R3. */
1342 STAMCOUNTER StatMsrReadR3;
1343 /** Number of MSR reads in RC. */
1344 STAMCOUNTER StatMsrReadRC;
1345
1346 /** Number of MSR writes in R0. */
1347 STAMCOUNTER StatMsrWriteR0;
1348 /** Number of MSR writes in R3. */
1349 STAMCOUNTER StatMsrWriteR3;
1350 /** Number of MSR writes in RC. */
1351 STAMCOUNTER StatMsrWriteRC;
1352
1353 /** Profiling of APICUpdatePendingInterrupts(). */
1354 STAMPROFILE StatUpdatePendingIntrs;
1355 /** Profiling of APICPostInterrupt(). */
1356 STAMPROFILE StatPostIntr;
1357 /** Number of times an interrupt is already pending in
1358 * APICPostInterrupts().*/
1359 STAMCOUNTER StatPostIntrAlreadyPending;
1360 /** Number of times the timer callback is invoked. */
1361 STAMCOUNTER StatTimerCallback;
1362 /** Number of times the TPR is written. */
1363 STAMCOUNTER StatTprWrite;
1364 /** Number of times the TPR is read. */
1365 STAMCOUNTER StatTprRead;
1366 /** Number of times the EOI is written. */
1367 STAMCOUNTER StatEoiWrite;
1368 /** Number of times TPR masks an interrupt in APICGetInterrupt(). */
1369 STAMCOUNTER StatMaskedByTpr;
1370 /** Number of times PPR masks an interrupt in APICGetInterrupt(). */
1371 STAMCOUNTER StatMaskedByPpr;
1372 /** @} */
1373#endif
1374} APICCPU;
1375/** Pointer to APIC VMCPU instance data. */
1376typedef APICCPU *PAPICCPU;
1377/** Pointer to a const APIC VMCPU instance data. */
1378typedef APICCPU const *PCAPICCPU;
1379AssertCompileMemberAlignment(APICCPU, uApicBaseMsr, 8);
1380
1381/**
1382 * Gets the timer shift value.
1383 *
1384 * @returns The timer shift value.
1385 * @param pXApicPage The xAPIC page.
1386 */
1387DECLINLINE(uint8_t) apicGetTimerShift(PCXAPICPAGE pXApicPage)
1388{
1389 /* See Intel spec. 10.5.4 "APIC Timer". */
1390 uint32_t uShift = pXApicPage->timer_dcr.u.u2DivideValue0 | (pXApicPage->timer_dcr.u.u1DivideValue1 << 2);
1391 return (uShift + 1) & 7;
1392}
1393
1394RT_C_DECLS_BEGIN
1395
1396const char *apicGetModeName(APICMODE enmMode);
1397const char *apicGetDestFormatName(XAPICDESTFORMAT enmDestFormat);
1398const char *apicGetDeliveryModeName(XAPICDELIVERYMODE enmDeliveryMode);
1399const char *apicGetDestModeName(XAPICDESTMODE enmDestMode);
1400const char *apicGetTriggerModeName(XAPICTRIGGERMODE enmTriggerMode);
1401const char *apicGetDestShorthandName(XAPICDESTSHORTHAND enmDestShorthand);
1402const char *apicGetTimerModeName(XAPICTIMERMODE enmTimerMode);
1403void apicHintTimerFreq(PAPICCPU pApicCpu, uint32_t uInitialCount, uint8_t uTimerShift);
1404APICMODE apicGetMode(uint64_t uApicBaseMsr);
1405
1406VMMDECL(uint64_t) APICGetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu);
1407VMMDECL(VBOXSTRICTRC) APICSetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t uBase);
1408VMMDECL(uint8_t) APICGetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr);
1409VMMDECL(void) APICSetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr);
1410VMMDECL(uint64_t) APICGetTimerFreq(PPDMDEVINS pDevIns);
1411VMMDECL(int) APICReadMmio(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
1412VMMDECL(int) APICWriteMmio(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb);
1413VMMDECL(VBOXSTRICTRC) APICReadMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Val);
1414VMMDECL(VBOXSTRICTRC) APICWriteMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Val);
1415VMMDECL(int) APICGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *puVector, uint32_t *puTagSrc);
1416VMMDECL(void) APICSetInterruptFF(PVMCPU pVCpu, PDMAPICIRQ enmType);
1417VMMDECL(void) APICClearInterruptFF(PVMCPU pVCpu, PDMAPICIRQ enmType);
1418VMMDECL(VBOXSTRICTRC) APICLocalInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level, int rcRZ);
1419VMMDECL(int) APICBusDeliver(PPDMDEVINS pDevIns, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode,
1420 uint8_t uVector, uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uTagSrc);
1421
1422VMM_INT_DECL(void) APICPostInterrupt(PVMCPU pVCpu, uint8_t uVector, XAPICTRIGGERMODE enmTriggerMode);
1423VMM_INT_DECL(void) APICStartTimer(PVMCPU pVCpu, uint32_t uInitialCount);
1424VMM_INT_DECL(void) APICStopTimer(PVMCPU pVCpu);
1425VMM_INT_DECL(void) APICUpdateCpuIdForMode(PVM pVM, APICMODE enmMode);
1426
1427RT_C_DECLS_END
1428
1429/** @} */
1430
1431#endif
1432
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette