VirtualBox

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

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

VMM/APIC: Move mostly unused stuff from apic.h to internal header. Added bugref to saved-state compatibility issue.

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