VirtualBox

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

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

VMM/APICInternal.h: move structs with where other structs are declared.

  • 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 61076 2016-05-20 04:12:35Z 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/** Maximum valid offset for a register (16-byte aligned, 4 byte wide access). */
85#define XAPIC_OFF_MAX_VALID (sizeof(XAPICPAGE) - 4 * sizeof(uint32_t))
86
87#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P6
88/** ESR - Send checksum error. */
89# define XAPIC_ESR_SEND_CHKSUM_ERROR RT_BIT(0)
90/** ESR - Send accept error. */
91# define XAPIC_ESR_RECV_CHKSUM_ERROR RT_BIT(1)
92/** ESR - Send accept error. */
93# define XAPIC_ESR_SEND_ACCEPT_ERROR RT_BIT(2)
94/** ESR - Receive accept error. */
95# define XAPIC_ESR_RECV_ACCEPT_ERROR RT_BIT(3)
96#endif
97/** ESR - Redirectable IPI. */
98#define XAPIC_ESR_REDIRECTABLE_IPI RT_BIT(4)
99/** ESR - Send accept error. */
100#define XAPIC_ESR_SEND_ILLEGAL_VECTOR RT_BIT(5)
101/** ESR - Send accept error. */
102#define XAPIC_ESR_RECV_ILLEGAL_VECTOR RT_BIT(6)
103/** ESR - Send accept error. */
104#define XAPIC_ESR_ILLEGAL_REG_ADDRESS RT_BIT(7)
105/** ESR - Valid write-only bits. */
106#define XAPIC_ESR_WO UINT32_C(0x0)
107
108/** TPR - Valid bits. */
109#define XAPIC_TPR UINT32_C(0xff)
110/** TPR - Task-priority class. */
111#define XAPIC_TPR_TP UINT32_C(0xf0)
112/** TPR - Task-priority subclass. */
113#define XAPIC_TPR_TP_SUBCLASS UINT32_C(0x0f)
114/** TPR - Gets the task-priority class. */
115#define XAPIC_TPR_GET_TP(a_Tpr) ((a_Tpr) & XAPIC_TPR_TP)
116/** TPR - Gets the task-priority subclass. */
117#define XAPIC_TPR_GET_TP_SUBCLASS(a_Tpr) ((a_Tpr) & XAPIC_TPR_TP_SUBCLASS)
118
119/** PPR - Valid bits. */
120#define XAPIC_PPR UINT32_C(0xff)
121/** PPR - Processor-priority class. */
122#define XAPIC_PPR_PP UINT32_C(0xf0)
123/** PPR - Processor-priority subclass. */
124#define XAPIC_PPR_PP_SUBCLASS UINT32_C(0x0f)
125/** PPR - Get the processor-priority class. */
126#define XAPIC_PPR_GET_PP(a_Ppr) ((a_Ppr) & XAPIC_PPR_PP)
127/** PPR - Get the processor-priority subclass. */
128#define XAPIC_PPR_GET_PP_SUBCLASS(a_Ppr) ((a_Ppr) & XAPIC_PPR_PP_SUBCLASS)
129
130/** Timer mode - One-shot. */
131#define XAPIC_TIMER_MODE_ONESHOT UINT32_C(0)
132/** Timer mode - Periodic. */
133#define XAPIC_TIMER_MODE_PERIODIC UINT32_C(1)
134/** Timer mode - TSC deadline. */
135#define XAPIC_TIMER_MODE_TSC_DEADLINE UINT32_C(2)
136
137/** LVT - The vector. */
138#define XAPIC_LVT_VECTOR UINT32_C(0xff)
139/** LVT - Gets the vector from an LVT entry. */
140#define XAPIC_LVT_GET_VECTOR(a_Lvt) ((a_Lvt) & XAPIC_LVT_VECTOR)
141/** LVT - The mask. */
142#define XAPIC_LVT_MASK RT_BIT(16)
143/** LVT - Is the LVT masked? */
144#define XAPIC_LVT_IS_MASKED(a_Lvt) RT_BOOL((a_Lvt) & XAPIC_LVT_MASK)
145/** LVT - Timer mode. */
146#define XAPIC_LVT_TIMER_MODE RT_BIT(17)
147/** LVT - Timer TSC-deadline timer mode. */
148#define XAPIC_LVT_TIMER_TSCDEADLINE RT_BIT(18)
149/** LVT - Gets the timer mode. */
150#define XAPIC_LVT_GET_TIMER_MODE(a_Lvt) (XAPICTIMERMODE)(((a_Lvt) >> 17) & UINT32_C(3))
151/** LVT - Delivery mode. */
152#define XAPIC_LVT_DELIVERY_MODE (RT_BIT(8) | RT_BIT(9) | RT_BIT(10))
153/** LVT - Gets the delivery mode. */
154#define XAPIC_LVT_GET_DELIVERY_MODE(a_Lvt) (XAPICDELIVERYMODE)(((a_Lvt) >> 8) & UINT32_C(7))
155/** LVT - Delivery status. */
156#define XAPIC_LVT_DELIVERY_STATUS RT_BIT(12)
157/** LVT - Trigger mode. */
158#define XAPIC_LVT_TRIGGER_MODE RT_BIT(15)
159/** LVT - Gets the trigger mode. */
160#define XAPIC_LVT_GET_TRIGGER_MODE(a_Lvt) (XAPICTRIGGERMODE)(((a_Lvt) >> 15) & UINT32_C(1))
161/** LVT - Remote IRR. */
162#define XAPIC_LVT_REMOTE_IRR RT_BIT(14)
163/** LVT - Interrupt Input Pin Polarity. */
164#define XAPIC_LVT_INTR_INPUT_PIN_POLARITY RT_BIT(13)
165/** LVT - Valid bits common to all LVTs. */
166#define XAPIC_LVT_COMMON (XAPIC_LVT_VECTOR | XAPIC_LVT_DELIVERY_STATUS | XAPIC_LVT_MASK)
167/** LVT CMCI - Valid bits. */
168#define XAPIC_LVT_CMCI_VALID (XAPIC_LVT_COMMON | XAPIC_LVT_DELIVERY_MODE)
169/** LVT Timer - Valid bits. */
170#define XAPIC_LVT_TIMER_VALID (XAPIC_LVT_COMMON | XAPIC_LVT_TIMER_MODE | XAPIC_LVT_TIMER_TSCDEADLINE)
171/** LVT Thermal - Valid bits. */
172#define XAPIC_LVT_THERMAL_VALID (XAPIC_LVT_COMMON | XAPIC_LVT_DELIVERY_MODE)
173/** LVT Perf - Valid bits. */
174#define XAPIC_LVT_PERF_VALID (XAPIC_LVT_COMMON | XAPIC_LVT_DELIVERY_MODE)
175/** LVT LINTx - Valid bits. */
176#define XAPIC_LVT_LINT_VALID ( XAPIC_LVT_COMMON | XAPIC_LVT_DELIVERY_MODE | XAPIC_LVT_DELIVERY_STATUS \
177 | XAPIC_LVT_INTR_INPUT_PIN_POLARITY | XAPIC_LVT_REMOTE_IRR | XAPIC_LVT_TRIGGER_MODE)
178/** LVT Error - Valid bits. */
179#define XAPIC_LVT_ERROR_VALID (XAPIC_LVT_COMMON)
180
181/** SVR - The vector. */
182#define XAPIC_SVR_VECTOR UINT32_C(0xff)
183/** SVR - APIC Software enable. */
184#define XAPIC_SVR_SOFTWARE_ENABLE RT_BIT(8)
185/** SVR - Supress EOI broadcast. */
186#define XAPIC_SVR_SUPRESS_EOI_BROADCAST RT_BIT(12)
187#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
188/** SVR - Valid bits. */
189# define XAPIC_SVR (XAPIC_SVR_VECTOR | XAPIC_SVR_SOFTWARE_ENABLE)
190#else
191# error "Implement Pentium and P6 family APIC architectures"
192#endif
193
194/** DFR - Valid bits. */
195#define XAPIC_DFR UINT32_C(0xf0000000)
196/** DFR - Reserved bits that must always remain set. */
197#define XAPIC_DFR_RSVD_MB1 UINT32_C(0x0fffffff)
198/** DFR - The model. */
199#define XAPIC_DFR_MODEL UINT32_C(0xf)
200/** DFR - Gets the destination model. */
201#define XAPIC_DFR_GET_MODEL(a_uReg) (((a_uReg) >> 28) & XAPIC_DFR_MODEL)
202
203/** LDR - Valid bits. */
204#define XAPIC_LDR UINT32_C(0xff000000)
205/** LDR - Cluster ID mask (x2APIC). */
206#define X2APIC_LDR_CLUSTER_ID UINT32_C(0xffff0000)
207/** LDR - Mask of the LDR cluster ID (x2APIC). */
208#define X2APIC_LDR_GET_CLUSTER_ID(a_uReg) ((a_uReg) & X2APIC_LDR_CLUSTER_ID)
209/** LDR - Mask of the LDR logical ID (x2APIC). */
210#define X2APIC_LDR_LOGICAL_ID UINT32_C(0x0000ffff)
211
212/** LDR - Flat mode logical ID mask. */
213#define XAPIC_LDR_FLAT_LOGICAL_ID UINT32_C(0xff)
214/** LDR - Clustered mode cluster ID mask. */
215#define XAPIC_LDR_CLUSTERED_CLUSTER_ID UINT32_C(0xf0)
216/** LDR - Clustered mode logical ID mask. */
217#define XAPIC_LDR_CLUSTERED_LOGICAL_ID UINT32_C(0x0f)
218/** LDR - Gets the clustered mode cluster ID. */
219#define XAPIC_LDR_CLUSTERED_GET_CLUSTER_ID(a_uReg) ((a_uReg) & XAPIC_LDR_CLUSTERED_CLUSTER_ID)
220
221
222/** EOI - Valid write-only bits. */
223#define XAPIC_EOI_WO UINT32_C(0x0)
224/** Timer ICR - Valid bits. */
225#define XAPIC_TIMER_ICR UINT32_C(0xffffffff)
226/** Timer DCR - Valid bits. */
227#define XAPIC_TIMER_DCR (RT_BIT(0) | RT_BIT(1) | RT_BIT(3))
228
229/** Self IPI - Valid bits. */
230#define XAPIC_SELF_IPI UINT32_C(0xff)
231/** Self IPI - The vector. */
232#define XAPIC_SELF_IPI_VECTOR UINT32_C(0xff)
233/** Self IPI - Gets the vector. */
234#define XAPIC_SELF_IPI_GET_VECTOR(a_uReg) ((a_uReg) & XAPIC_SELF_IPI_VECTOR)
235
236/** ICR Low - The Vector. */
237#define XAPIC_ICR_LO_VECTOR UINT32_C(0xff)
238/** ICR Low - Gets the vector. */
239#define XAPIC_ICR_LO_GET_VECTOR(a_uIcr) ((a_uIcr) & XAPIC_ICR_LO_VECTOR)
240/** ICR Low - The delivery mode. */
241#define XAPIC_ICR_LO_DELIVERY_MODE (RT_BIT(8) | RT_BIT(9) | RT_BIT(10))
242/** ICR Low - The destination mode. */
243#define XAPIC_ICR_LO_DEST_MODE RT_BIT(11)
244/** ICR Low - The delivery status. */
245#define XAPIC_ICR_LO_DELIVERY_STATUS RT_BIT(12)
246/** ICR Low - The level. */
247#define XAPIC_ICR_LO_LEVEL RT_BIT(14)
248/** ICR Low - The trigger mode. */
249#define XAPIC_ICR_TRIGGER_MODE RT_BIT(15)
250/** ICR Low - The destination shorthand. */
251#define XAPIC_ICR_LO_DEST_SHORTHAND (RT_BIT(18) | RT_BIT(19))
252/** ICR Low - Valid write bits. */
253#define XAPIC_ICR_LO_WR ( XAPIC_ICR_LO_VECTOR | XAPIC_ICR_LO_DELIVERY_MODE | XAPIC_ICR_LO_DEST_MODE \
254 | XAPIC_ICR_LO_LEVEL | XAPIC_ICR_TRIGGER_MODE | XAPIC_ICR_LO_DEST_SHORTHAND)
255
256/** ICR High - The destination field. */
257#define XAPIC_ICR_HI_DEST UINT32_C(0xff000000)
258/** ICR High - Get the destination field. */
259#define XAPIC_ICR_HI_GET_DEST(a_u32IcrHi) (((a_u32IcrHi) >> 24) & XAPIC_ICR_HI_DEST)
260/** ICR High - Valid write bits in xAPIC mode. */
261#define XAPIC_ICR_HI_WR XAPIC_ICR_HI_DEST
262
263/** APIC ID broadcast mask - x2APIC mode. */
264#define X2APIC_ID_BROADCAST_MASK UINT32_C(0xffffffff)
265#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
266/** APIC ID broadcast mask - xAPIC mode. */
267# define XAPIC_ID_BROADCAST_MASK UINT32_C(0xff)
268#else
269# error "Implement Pentium and P6 family APIC architectures"
270#endif
271
272/**
273 * The xAPIC sparse 256-bit register.
274 */
275typedef union XAPIC256BITREG
276{
277 /** The sparse-bitmap view. */
278 struct
279 {
280 uint32_t u32Reg;
281 uint32_t uReserved0[3];
282 } u[8];
283 /** The 32-bit view. */
284 uint32_t au32[32];
285} XAPIC256BITREG;
286/** Pointer to an xAPIC sparse bitmap register. */
287typedef XAPIC256BITREG *PXAPIC256BITREG;
288/** Pointer to a const xAPIC sparse bitmap register. */
289typedef XAPIC256BITREG const *PCXAPIC256BITREG;
290AssertCompileSize(XAPIC256BITREG, 128);
291
292/**
293 * The xAPIC memory layout as per Intel/AMD specs.
294 */
295typedef struct XAPICPAGE
296{
297 /* 0x00 - Reserved. */
298 uint32_t uReserved0[8];
299 /* 0x20 - APIC ID. */
300 struct
301 {
302 uint8_t u8Reserved0[3];
303 uint8_t u8ApicId;
304 uint32_t u32Reserved0[3];
305 } id;
306 /* 0x30 - APIC version register. */
307 union
308 {
309 struct
310 {
311#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
312 uint8_t u8Version;
313#else
314# error "Implement Pentium and P6 family APIC architectures"
315#endif
316 uint8_t uReserved0;
317 uint8_t u8MaxLvtEntry;
318 uint8_t fEoiBroadcastSupression : 1;
319 uint8_t u7Reserved1 : 7;
320 uint32_t u32Reserved0[3];
321 } u;
322 struct
323 {
324 uint32_t u32Version;
325 uint32_t u32Reserved0[3];
326 } all;
327 } version;
328 /* 0x40 - Reserved. */
329 uint32_t uReserved1[16];
330 /* 0x80 - Task Priority Register (TPR). */
331 struct
332 {
333 uint8_t u8Tpr;
334 uint8_t u8Reserved0[3];
335 uint32_t u32Reserved0[3];
336 } tpr;
337 /* 0x90 - Arbitration Priority Register (APR). */
338 struct
339 {
340 uint8_t u8Apr;
341 uint8_t u8Reserved0[3];
342 uint32_t u32Reserved0[3];
343 } apr;
344 /* 0xA0 - Processor Priority Register (PPR). */
345 struct
346 {
347 uint8_t u8Ppr;
348 uint8_t u8Reserved0[3];
349 uint32_t u32Reserved0[3];
350 } ppr;
351 /* 0xB0 - End Of Interrupt Register (EOI). */
352 struct
353 {
354 uint32_t u32Eoi;
355 uint32_t u32Reserved0[3];
356 } eoi;
357 /* 0xC0 - Remote Read Register (RRD). */
358 struct
359 {
360 uint32_t u32Rrd;
361 uint32_t u32Reserved0[3];
362 } rrd;
363 /* 0xD0 - Logical Destination Register (LDR). */
364 union
365 {
366 struct
367 {
368 uint8_t u8Reserved0[3];
369 uint8_t u8LogicalApicId;
370 uint32_t u32Reserved0[3];
371 } u;
372 struct
373 {
374 uint32_t u32Ldr;
375 uint32_t u32Reserved0[3];
376 } all;
377 } ldr;
378 /* 0xE0 - Destination Format Register (DFR). */
379 union
380 {
381 struct
382 {
383 uint32_t u28ReservedMb1 : 28; /* MB1 */
384 uint32_t u4Model : 4;
385 uint32_t u32Reserved0[3];
386 } u;
387 struct
388 {
389 uint32_t u32Dfr;
390 uint32_t u32Reserved0[3];
391 } all;
392 } dfr;
393 /* 0xF0 - Spurious-Interrupt Vector Register (SVR). */
394 union
395 {
396 struct
397 {
398 uint32_t u8SpuriousVector : 8;
399 uint32_t fApicSoftwareEnable : 1;
400 uint32_t u3Reserved0 : 3;
401 uint32_t fSupressEoiBroadcast : 1;
402 uint32_t u19Reserved1 : 19;
403 uint32_t u32Reserved0[3];
404 } u;
405 struct
406 {
407 uint32_t u32Svr;
408 uint32_t u32Reserved0[3];
409 } all;
410 } svr;
411 /* 0x100 - In-service Register (ISR). */
412 XAPIC256BITREG isr;
413 /* 0x180 - Trigger Mode Register (TMR). */
414 XAPIC256BITREG tmr;
415 /* 0x200 - Interrupt Request Register (IRR). */
416 XAPIC256BITREG irr;
417 /* 0x280 - Error Status Register (ESR). */
418 union
419 {
420 struct
421 {
422#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
423 uint32_t u4Reserved0 : 4;
424#else
425# error "Implement Pentium and P6 family APIC architectures"
426#endif
427 uint32_t fRedirectableIpi : 1;
428 uint32_t fSendIllegalVector : 1;
429 uint32_t fRcvdIllegalVector : 1;
430 uint32_t fIllegalRegAddr : 1;
431 uint32_t u24Reserved1 : 24;
432 uint32_t u32Reserved0[3];
433 } u;
434 struct
435 {
436 uint32_t u32Errors;
437 uint32_t u32Reserved0[3];
438 } all;
439 } esr;
440 /* 0x290 - Reserved. */
441 uint32_t uReserved2[28];
442 /* 0x300 - Interrupt Command Register (ICR) - Low. */
443 union
444 {
445 struct
446 {
447 uint32_t u8Vector : 8;
448 uint32_t u3DeliveryMode : 3;
449 uint32_t u1DestMode : 1;
450 uint32_t u1DeliveryStatus : 1;
451 uint32_t fReserved0 : 1;
452 uint32_t u1Level : 1;
453 uint32_t u1TriggerMode : 1;
454 uint32_t u2Reserved1 : 2;
455 uint32_t u2DestShorthand : 2;
456 uint32_t u12Reserved2 : 12;
457 uint32_t u32Reserved0[3];
458 } u;
459 struct
460 {
461 uint32_t u32IcrLo;
462 uint32_t u32Reserved0[3];
463 } all;
464 } icr_lo;
465 /* 0x310 - Interrupt Comannd Register (ICR) - High. */
466 union
467 {
468 struct
469 {
470 uint32_t u24Reserved0 : 24;
471 uint32_t u8Dest : 8;
472 uint32_t u32Reserved0[3];
473 } u;
474 struct
475 {
476 uint32_t u32IcrHi;
477 uint32_t u32Reserved0[3];
478 } all;
479 } icr_hi;
480 /* 0x320 - Local Vector Table (LVT) Timer Register. */
481 union
482 {
483 struct
484 {
485 uint32_t u8Vector : 8;
486 uint32_t u4Reserved0 : 4;
487 uint32_t u1DeliveryStatus : 1;
488 uint32_t u3Reserved1 : 3;
489 uint32_t u1Mask : 1;
490 uint32_t u2TimerMode : 2;
491 uint32_t u13Reserved2 : 13;
492 uint32_t u32Reserved0[3];
493 } u;
494 struct
495 {
496 uint32_t u32LvtTimer;
497 uint32_t u32Reserved0[3];
498 } all;
499 } lvt_timer;
500 /* 0x330 - Local Vector Table (LVT) Thermal Sensor Register. */
501#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
502 union
503 {
504 struct
505 {
506 uint32_t u8Vector : 8;
507 uint32_t u3DeliveryMode : 3;
508 uint32_t u1Reserved0 : 1;
509 uint32_t u1DeliveryStatus : 1;
510 uint32_t u3Reserved1 : 3;
511 uint32_t u1Mask : 1;
512 uint32_t u15Reserved2 : 15;
513 uint32_t u32Reserved0[3];
514 } u;
515 struct
516 {
517 uint32_t u32LvtThermal;
518 uint32_t u32Reserved0[3];
519 } all;
520 } lvt_thermal;
521#else
522# error "Implement Pentium and P6 family APIC architectures"
523#endif
524 /* 0x340 - Local Vector Table (LVT) Performance Monitor Counter (PMC) Register. */
525 union
526 {
527 struct
528 {
529 uint32_t u8Vector : 8;
530 uint32_t u3DeliveryMode : 3;
531 uint32_t u1Reserved0 : 1;
532 uint32_t u1DeliveryStatus : 1;
533 uint32_t u3Reserved1 : 3;
534 uint32_t u1Mask : 1;
535 uint32_t u15Reserved2 : 15;
536 uint32_t u32Reserved0[3];
537 } u;
538 struct
539 {
540 uint32_t u32LvtPerf;
541 uint32_t u32Reserved0[3];
542 } all;
543 } lvt_perf;
544 /* 0x350 - Local Vector Table (LVT) LINT0 Register. */
545 union
546 {
547 struct
548 {
549 uint32_t u8Vector : 8;
550 uint32_t u3DeliveryMode : 3;
551 uint32_t u1Reserved0 : 1;
552 uint32_t u1DeliveryStatus : 1;
553 uint32_t u1IntrPolarity : 1;
554 uint32_t u1RemoteIrr : 1;
555 uint32_t u1TriggerMode : 1;
556 uint32_t u1Mask : 1;
557 uint32_t u15Reserved2 : 15;
558 uint32_t u32Reserved0[3];
559 } u;
560 struct
561 {
562 uint32_t u32LvtLint0;
563 uint32_t u32Reserved0[3];
564 } all;
565 } lvt_lint0;
566 /* 0x360 - Local Vector Table (LVT) LINT1 Register. */
567 union
568 {
569 struct
570 {
571 uint32_t u8Vector : 8;
572 uint32_t u3DeliveryMode : 3;
573 uint32_t u1Reserved0 : 1;
574 uint32_t u1DeliveryStatus : 1;
575 uint32_t u1IntrPolarity : 1;
576 uint32_t u1RemoteIrr : 1;
577 uint32_t u1TriggerMode : 1;
578 uint32_t u1Mask : 1;
579 uint32_t u15Reserved2 : 15;
580 uint32_t u32Reserved0[3];
581 } u;
582 struct
583 {
584 uint32_t u32LvtLint1;
585 uint32_t u32Reserved0[3];
586 } all;
587 } lvt_lint1;
588 /* 0x370 - Local Vector Table (LVT) Error Register. */
589 union
590 {
591 struct
592 {
593 uint32_t u8Vector : 8;
594 uint32_t u4Reserved0 : 4;
595 uint32_t u1DeliveryStatus : 1;
596 uint32_t u3Reserved1 : 3;
597 uint32_t u1Mask : 1;
598 uint32_t u15Reserved2 : 15;
599 uint32_t u32Reserved0[3];
600 } u;
601 struct
602 {
603 uint32_t u32LvtError;
604 uint32_t u32Reserved0[3];
605 } all;
606 } lvt_error;
607 /* 0x380 - Timer Initial Counter Register. */
608 struct
609 {
610 uint32_t u32InitialCount;
611 uint32_t u32Reserved0[3];
612 } timer_icr;
613 /* 0x390 - Timer Current Counter Register. */
614 struct
615 {
616 uint32_t u32CurrentCount;
617 uint32_t u32Reserved0[3];
618 } timer_ccr;
619 /* 0x3A0 - Reserved. */
620 uint32_t u32Reserved3[16];
621 /* 0x3E0 - Timer Divide Configuration Register. */
622 union
623 {
624 struct
625 {
626 uint32_t u2DivideValue0 : 2;
627 uint32_t u1Reserved0 : 1;
628 uint32_t u1DivideValue1 : 1;
629 uint32_t u28Reserved1 : 28;
630 uint32_t u32Reserved0[3];
631 } u;
632 struct
633 {
634 uint32_t u32DivideValue;
635 uint32_t u32Reserved0[3];
636 } all;
637 } timer_dcr;
638 /* 0x3F0 - Reserved. */
639 uint8_t u8Reserved0[3088];
640} XAPICPAGE;
641/** Pointer to a XAPICPAGE struct. */
642typedef XAPICPAGE *PXAPICPAGE;
643/** Pointer to a const XAPICPAGE struct. */
644typedef const XAPICPAGE *PCXAPICPAGE;
645AssertCompileSize(XAPICPAGE, 4096);
646AssertCompileMemberOffset(XAPICPAGE, id, XAPIC_OFF_ID);
647AssertCompileMemberOffset(XAPICPAGE, version, XAPIC_OFF_VERSION);
648AssertCompileMemberOffset(XAPICPAGE, tpr, XAPIC_OFF_TPR);
649AssertCompileMemberOffset(XAPICPAGE, apr, XAPIC_OFF_APR);
650AssertCompileMemberOffset(XAPICPAGE, ppr, XAPIC_OFF_PPR);
651AssertCompileMemberOffset(XAPICPAGE, eoi, XAPIC_OFF_EOI);
652AssertCompileMemberOffset(XAPICPAGE, rrd, XAPIC_OFF_RRD);
653AssertCompileMemberOffset(XAPICPAGE, ldr, XAPIC_OFF_LDR);
654AssertCompileMemberOffset(XAPICPAGE, dfr, XAPIC_OFF_DFR);
655AssertCompileMemberOffset(XAPICPAGE, svr, XAPIC_OFF_SVR);
656AssertCompileMemberOffset(XAPICPAGE, isr, XAPIC_OFF_ISR0);
657AssertCompileMemberOffset(XAPICPAGE, tmr, XAPIC_OFF_TMR0);
658AssertCompileMemberOffset(XAPICPAGE, irr, XAPIC_OFF_IRR0);
659AssertCompileMemberOffset(XAPICPAGE, esr, XAPIC_OFF_ESR);
660AssertCompileMemberOffset(XAPICPAGE, icr_lo, XAPIC_OFF_ICR_LO);
661AssertCompileMemberOffset(XAPICPAGE, icr_hi, XAPIC_OFF_ICR_HI);
662AssertCompileMemberOffset(XAPICPAGE, lvt_timer, XAPIC_OFF_LVT_TIMER);
663AssertCompileMemberOffset(XAPICPAGE, lvt_thermal, XAPIC_OFF_LVT_THERMAL);
664AssertCompileMemberOffset(XAPICPAGE, lvt_perf, XAPIC_OFF_LVT_PERF);
665AssertCompileMemberOffset(XAPICPAGE, lvt_lint0, XAPIC_OFF_LVT_LINT0);
666AssertCompileMemberOffset(XAPICPAGE, lvt_lint1, XAPIC_OFF_LVT_LINT1);
667AssertCompileMemberOffset(XAPICPAGE, lvt_error, XAPIC_OFF_LVT_ERROR);
668AssertCompileMemberOffset(XAPICPAGE, timer_icr, XAPIC_OFF_TIMER_ICR);
669AssertCompileMemberOffset(XAPICPAGE, timer_ccr, XAPIC_OFF_TIMER_CCR);
670AssertCompileMemberOffset(XAPICPAGE, timer_dcr, XAPIC_OFF_TIMER_DCR);
671
672/**
673 * The x2APIC memory layout as per Intel/AMD specs.
674 */
675typedef struct X2APICPAGE
676{
677 /* 0x00 - Reserved. */
678 uint32_t uReserved0[8];
679 /* 0x20 - APIC ID. */
680 struct
681 {
682 uint32_t u32ApicId;
683 uint32_t u32Reserved0[3];
684 } id;
685 /* 0x30 - APIC version register. */
686 union
687 {
688 struct
689 {
690 uint8_t u8Version;
691 uint8_t u8Reserved0;
692 uint8_t u8MaxLvtEntry;
693 uint8_t fEoiBroadcastSupression : 1;
694 uint8_t u7Reserved1 : 7;
695 uint32_t u32Reserved0[3];
696 } u;
697 struct
698 {
699 uint32_t u32Version;
700 uint32_t u32Reserved2[3];
701 } all;
702 } version;
703 /* 0x40 - Reserved. */
704 uint32_t uReserved1[16];
705 /* 0x80 - Task Priority Register (TPR). */
706 struct
707 {
708 uint8_t u8Tpr;
709 uint8_t u8Reserved0[3];
710 uint32_t u32Reserved0[3];
711 } tpr;
712 /* 0x90 - Reserved. */
713 uint32_t uReserved2[4];
714 /* 0xA0 - Processor Priority Register (PPR). */
715 struct
716 {
717 uint8_t u8Ppr;
718 uint8_t u8Reserved0[3];
719 uint32_t u32Reserved0[3];
720 } ppr;
721 /* 0xB0 - End Of Interrupt Register (EOI). */
722 struct
723 {
724 uint32_t u32Eoi;
725 uint32_t u32Reserved0[3];
726 } eoi;
727 /* 0xC0 - Remote Read Register (RRD). */
728 struct
729 {
730 uint32_t u32Rrd;
731 uint32_t u32Reserved0[3];
732 } rrd;
733 /* 0xD0 - Logical Destination Register (LDR). */
734 struct
735 {
736 uint32_t u32LogicalApicId;
737 uint32_t u32Reserved1[3];
738 } ldr;
739 /* 0xE0 - Reserved. */
740 uint32_t uReserved3[4];
741 /* 0xF0 - Spurious-Interrupt Vector Register (SVR). */
742 union
743 {
744 struct
745 {
746 uint32_t u8SpuriousVector : 8;
747 uint32_t fApicSoftwareEnable : 1;
748 uint32_t u3Reserved0 : 3;
749 uint32_t fSupressEoiBroadcast : 1;
750 uint32_t u19Reserved1 : 19;
751 uint32_t u32Reserved0[3];
752 } u;
753 struct
754 {
755 uint32_t u32Svr;
756 uint32_t uReserved0[3];
757 } all;
758 } svr;
759 /* 0x100 - In-service Register (ISR). */
760 XAPIC256BITREG isr;
761 /* 0x180 - Trigger Mode Register (TMR). */
762 XAPIC256BITREG tmr;
763 /* 0x200 - Interrupt Request Register (IRR). */
764 XAPIC256BITREG irr;
765 /* 0x280 - Error Status Register (ESR). */
766 union
767 {
768 struct
769 {
770#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
771 uint32_t u4Reserved0 : 4;
772#else
773# error "Implement Pentium and P6 family APIC architectures"
774#endif
775 uint32_t fRedirectableIpi : 1;
776 uint32_t fSendIllegalVector : 1;
777 uint32_t fRcvdIllegalVector : 1;
778 uint32_t fIllegalRegAddr : 1;
779 uint32_t u24Reserved1 : 24;
780 uint32_t uReserved0[3];
781 } u;
782 struct
783 {
784 uint32_t u32Errors;
785 uint32_t u32Reserved0[3];
786 } all;
787 } esr;
788 /* 0x290 - Reserved. */
789 uint32_t uReserved4[28];
790 /* 0x300 - Interrupt Command Register (ICR) - Low. */
791 union
792 {
793 struct
794 {
795 uint32_t u8Vector : 8;
796 uint32_t u3DeliveryMode : 3;
797 uint32_t u1DestMode : 1;
798 uint32_t u2Reserved0 : 2;
799 uint32_t u1Level : 1;
800 uint32_t u1TriggerMode : 1;
801 uint32_t u2Reserved1 : 2;
802 uint32_t u2DestShorthand : 2;
803 uint32_t u12Reserved2 : 12;
804 uint32_t u32Reserved0[3];
805 } u;
806 struct
807 {
808 uint32_t u32IcrLo;
809 uint32_t u32Reserved3[3];
810 } all;
811 } icr_lo;
812 /* 0x310 - Interrupt Comannd Register (ICR) - High. */
813 struct
814 {
815 uint32_t u32IcrHi;
816 uint32_t uReserved1[3];
817 } icr_hi;
818 /* 0x320 - Local Vector Table (LVT) Timer Register. */
819 union
820 {
821 struct
822 {
823 uint32_t u8Vector : 8;
824 uint32_t u4Reserved0 : 4;
825 uint32_t u1DeliveryStatus : 1;
826 uint32_t u3Reserved1 : 3;
827 uint32_t u1Mask : 1;
828 uint32_t u2TimerMode : 2;
829 uint32_t u13Reserved2 : 13;
830 uint32_t u32Reserved0[3];
831 } u;
832 struct
833 {
834 uint32_t u32LvtTimer;
835 uint32_t u32Reserved0[3];
836 } all;
837 } lvt_timer;
838 /* 0x330 - Local Vector Table (LVT) Thermal Sensor Register. */
839 union
840 {
841 struct
842 {
843 uint32_t u8Vector : 8;
844 uint32_t u3DeliveryMode : 3;
845 uint32_t u1Reserved0 : 1;
846 uint32_t u1DeliveryStatus : 1;
847 uint32_t u3Reserved1 : 3;
848 uint32_t u1Mask : 1;
849 uint32_t u15Reserved2 : 15;
850 uint32_t u32Reserved0[3];
851 } u;
852 struct
853 {
854 uint32_t u32LvtThermal;
855 uint32_t uReserved0[3];
856 } all;
857 } lvt_thermal;
858 /* 0x340 - Local Vector Table (LVT) Performance Monitor Counter (PMC) Register. */
859 union
860 {
861 struct
862 {
863 uint32_t u8Vector : 8;
864 uint32_t u3DeliveryMode : 3;
865 uint32_t u1Reserved0 : 1;
866 uint32_t u1DeliveryStatus : 1;
867 uint32_t u3Reserved1 : 3;
868 uint32_t u1Mask : 1;
869 uint32_t u15Reserved2 : 15;
870 uint32_t u32Reserved0[3];
871 } u;
872 struct
873 {
874 uint32_t u32LvtPerf;
875 uint32_t u32Reserved0[3];
876 } all;
877 } lvt_perf;
878 /* 0x350 - Local Vector Table (LVT) LINT0 Register. */
879 union
880 {
881 struct
882 {
883 uint32_t u8Vector : 8;
884 uint32_t u3DeliveryMode : 3;
885 uint32_t u1Reserved0 : 1;
886 uint32_t u1DeliveryStatus : 1;
887 uint32_t u1IntrPolarity : 1;
888 uint32_t u1RemoteIrr : 1;
889 uint32_t u1TriggerMode : 1;
890 uint32_t u1Mask : 1;
891 uint32_t u15Reserved2 : 15;
892 uint32_t u32Reserved0[3];
893 } u;
894 struct
895 {
896 uint32_t u32LvtLint0;
897 uint32_t u32Reserved0[3];
898 } all;
899 } lvt_lint0;
900 /* 0x360 - Local Vector Table (LVT) LINT1 Register. */
901 union
902 {
903 struct
904 {
905 uint32_t u8Vector : 8;
906 uint32_t u3DeliveryMode : 3;
907 uint32_t u1Reserved0 : 1;
908 uint32_t u1DeliveryStatus : 1;
909 uint32_t u1IntrPolarity : 1;
910 uint32_t u1RemoteIrr : 1;
911 uint32_t u1TriggerMode : 1;
912 uint32_t u1Mask : 1;
913 uint32_t u15Reserved2 : 15;
914 uint32_t u32Reserved0[3];
915 } u;
916 struct
917 {
918 uint32_t u32LvtLint1;
919 uint32_t u32Reserved0[3];
920 } all;
921 } lvt_lint1;
922 /* 0x370 - Local Vector Table (LVT) Error Register. */
923 union
924 {
925 struct
926 {
927 uint32_t u8Vector : 8;
928 uint32_t u4Reserved0 : 4;
929 uint32_t u1DeliveryStatus : 1;
930 uint32_t u3Reserved1 : 3;
931 uint32_t u1Mask : 1;
932 uint32_t u15Reserved2 : 15;
933 uint32_t u32Reserved0[3];
934 } u;
935 struct
936 {
937 uint32_t u32LvtError;
938 uint32_t u32Reserved0[3];
939 } all;
940 } lvt_error;
941 /* 0x380 - Timer Initial Counter Register. */
942 struct
943 {
944 uint32_t u32InitialCount;
945 uint32_t u32Reserved0[3];
946 } timer_icr;
947 /* 0x390 - Timer Current Counter Register. */
948 struct
949 {
950 uint32_t u32CurrentCount;
951 uint32_t u32Reserved0[3];
952 } timer_ccr;
953 /* 0x3A0 - Reserved. */
954 uint32_t uReserved5[16];
955 /* 0x3E0 - Timer Divide Configuration Register. */
956 union
957 {
958 struct
959 {
960 uint32_t u2DivideValue0 : 2;
961 uint32_t u1Reserved0 : 1;
962 uint32_t u1DivideValue1 : 1;
963 uint32_t u28Reserved1 : 28;
964 uint32_t u32Reserved0[3];
965 } u;
966 struct
967 {
968 uint32_t u32DivideValue;
969 uint32_t u32Reserved0[3];
970 } all;
971 } timer_dcr;
972 /* 0x3F0 - Self IPI Register. */
973 struct
974 {
975 uint32_t u8Vector : 8;
976 uint32_t u24Reserved0 : 24;
977 uint32_t u32Reserved0[3];
978 } self_ipi;
979 /* 0x400 - Reserved. */
980 uint8_t u8Reserved0[3072];
981} X2APICPAGE;
982/** Pointer to a X2APICPAGE struct. */
983typedef X2APICPAGE *PX2APICPAGE;
984/** Pointer to a const X2APICPAGE struct. */
985typedef const X2APICPAGE *PCX2APICPAGE;
986AssertCompileSize(X2APICPAGE, 4096);
987AssertCompileSize(X2APICPAGE, sizeof(XAPICPAGE));
988AssertCompileMemberOffset(X2APICPAGE, id, XAPIC_OFF_ID);
989AssertCompileMemberOffset(X2APICPAGE, version, XAPIC_OFF_VERSION);
990AssertCompileMemberOffset(X2APICPAGE, tpr, XAPIC_OFF_TPR);
991AssertCompileMemberOffset(X2APICPAGE, ppr, XAPIC_OFF_PPR);
992AssertCompileMemberOffset(X2APICPAGE, eoi, XAPIC_OFF_EOI);
993AssertCompileMemberOffset(X2APICPAGE, rrd, XAPIC_OFF_RRD);
994AssertCompileMemberOffset(X2APICPAGE, ldr, XAPIC_OFF_LDR);
995AssertCompileMemberOffset(X2APICPAGE, svr, XAPIC_OFF_SVR);
996AssertCompileMemberOffset(X2APICPAGE, isr, XAPIC_OFF_ISR0);
997AssertCompileMemberOffset(X2APICPAGE, tmr, XAPIC_OFF_TMR0);
998AssertCompileMemberOffset(X2APICPAGE, irr, XAPIC_OFF_IRR0);
999AssertCompileMemberOffset(X2APICPAGE, esr, XAPIC_OFF_ESR);
1000AssertCompileMemberOffset(X2APICPAGE, icr_lo, XAPIC_OFF_ICR_LO);
1001AssertCompileMemberOffset(X2APICPAGE, icr_hi, XAPIC_OFF_ICR_HI);
1002AssertCompileMemberOffset(X2APICPAGE, lvt_timer, XAPIC_OFF_LVT_TIMER);
1003AssertCompileMemberOffset(X2APICPAGE, lvt_thermal, XAPIC_OFF_LVT_THERMAL);
1004AssertCompileMemberOffset(X2APICPAGE, lvt_perf, XAPIC_OFF_LVT_PERF);
1005AssertCompileMemberOffset(X2APICPAGE, lvt_lint0, XAPIC_OFF_LVT_LINT0);
1006AssertCompileMemberOffset(X2APICPAGE, lvt_lint1, XAPIC_OFF_LVT_LINT1);
1007AssertCompileMemberOffset(X2APICPAGE, lvt_error, XAPIC_OFF_LVT_ERROR);
1008AssertCompileMemberOffset(X2APICPAGE, timer_icr, XAPIC_OFF_TIMER_ICR);
1009AssertCompileMemberOffset(X2APICPAGE, timer_ccr, XAPIC_OFF_TIMER_CCR);
1010AssertCompileMemberOffset(X2APICPAGE, timer_dcr, XAPIC_OFF_TIMER_DCR);
1011AssertCompileMemberOffset(X2APICPAGE, self_ipi, X2APIC_OFF_SELF_IPI);
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