VirtualBox

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

Last change on this file since 96933 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 42.0 KB
Line 
1/* $Id: APICInternal.h 96407 2022-08-22 17:43:14Z vboxsync $ */
2/** @file
3 * APIC - Advanced Programmable Interrupt Controller.
4 */
5
6/*
7 * Copyright (C) 2016-2022 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#ifndef VMM_INCLUDED_SRC_include_APICInternal_h
29#define VMM_INCLUDED_SRC_include_APICInternal_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#include <VBox/apic.h>
35#include <VBox/sup.h>
36#include <VBox/vmm/pdmdev.h>
37
38/** @defgroup grp_apic_int Internal
39 * @ingroup grp_apic
40 * @internal
41 * @{
42 */
43
44/** The APIC hardware version we are emulating. */
45#define XAPIC_HARDWARE_VERSION XAPIC_HARDWARE_VERSION_P4
46
47#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
48#define XAPIC_SVR_VALID XAPIC_SVR_VALID_P4
49#define XAPIC_ID_BROADCAST_MASK XAPIC_ID_BROADCAST_MASK_P4
50#else
51# error "Implement Pentium and P6 family APIC architectures"
52#endif
53
54#define VMCPU_TO_XAPICPAGE(a_pVCpu) ((PXAPICPAGE)(CTX_SUFF((a_pVCpu)->apic.s.pvApicPage)))
55#define VMCPU_TO_CXAPICPAGE(a_pVCpu) ((PCXAPICPAGE)(CTX_SUFF((a_pVCpu)->apic.s.pvApicPage)))
56
57#define VMCPU_TO_X2APICPAGE(a_pVCpu) ((PX2APICPAGE)(CTX_SUFF((a_pVCpu)->apic.s.pvApicPage)))
58#define VMCPU_TO_CX2APICPAGE(a_pVCpu) ((PCX2APICPAGE)(CTX_SUFF((a_pVCpu)->apic.s.pvApicPage)))
59
60#define VMCPU_TO_APICCPU(a_pVCpu) (&(a_pVCpu)->apic.s)
61#define VM_TO_APIC(a_pVM) (&(a_pVM)->apic.s)
62#define VM_TO_APICDEV(a_pVM) CTX_SUFF(VM_TO_APIC(a_pVM)->pApicDev)
63#ifdef IN_RING3
64# define VMCPU_TO_DEVINS(a_pVCpu) ((a_pVCpu)->pVMR3->apic.s.pDevInsR3)
65#elif defined(IN_RING0)
66# define VMCPU_TO_DEVINS(a_pVCpu) ((a_pVCpu)->pGVM->apicr0.s.pDevInsR0)
67#endif
68
69#define APICCPU_TO_XAPICPAGE(a_ApicCpu) ((PXAPICPAGE)(CTX_SUFF((a_ApicCpu)->pvApicPage)))
70#define APICCPU_TO_CXAPICPAGE(a_ApicCpu) ((PCXAPICPAGE)(CTX_SUFF((a_ApicCpu)->pvApicPage)))
71
72/** Vector offset in an APIC 256-bit sparse register. */
73#define XAPIC_REG256_VECTOR_OFF(a_Vector) (((a_Vector) & UINT32_C(0xe0)) >> 1)
74/** Bit position at offset in an APIC 256-bit sparse register. */
75#define XAPIC_REG256_VECTOR_BIT(a_Vector) ((a_Vector) & UINT32_C(0x1f))
76
77/** Maximum valid offset for a register (16-byte aligned, 4 byte wide access). */
78#define XAPIC_OFF_MAX_VALID (sizeof(XAPICPAGE) - 4 * sizeof(uint32_t))
79
80/** Whether the APIC is in X2APIC mode or not. */
81#define XAPIC_IN_X2APIC_MODE(a_pVCpu) ( ( ((a_pVCpu)->apic.s.uApicBaseMsr) \
82 & (MSR_IA32_APICBASE_EN | MSR_IA32_APICBASE_EXTD)) \
83 == (MSR_IA32_APICBASE_EN | MSR_IA32_APICBASE_EXTD) )
84
85/**
86 * The xAPIC sparse 256-bit register.
87 */
88typedef union XAPIC256BITREG
89{
90 /** The sparse-bitmap view. */
91 struct
92 {
93 uint32_t u32Reg;
94 uint32_t uReserved0[3];
95 } u[8];
96 /** The 32-bit view. */
97 uint32_t au32[32];
98} XAPIC256BITREG;
99/** Pointer to an xAPIC sparse bitmap register. */
100typedef XAPIC256BITREG *PXAPIC256BITREG;
101/** Pointer to a const xAPIC sparse bitmap register. */
102typedef XAPIC256BITREG const *PCXAPIC256BITREG;
103AssertCompileSize(XAPIC256BITREG, 128);
104
105/**
106 * The xAPIC memory layout as per Intel/AMD specs.
107 */
108typedef struct XAPICPAGE
109{
110 /* 0x00 - Reserved. */
111 uint32_t uReserved0[8];
112 /* 0x20 - APIC ID. */
113 struct
114 {
115 uint8_t u8Reserved0[3];
116 uint8_t u8ApicId;
117 uint32_t u32Reserved0[3];
118 } id;
119 /* 0x30 - APIC version register. */
120 union
121 {
122 struct
123 {
124#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
125 uint8_t u8Version;
126#else
127# error "Implement Pentium and P6 family APIC architectures"
128#endif
129 uint8_t uReserved0;
130 uint8_t u8MaxLvtEntry;
131 uint8_t fEoiBroadcastSupression : 1;
132 uint8_t u7Reserved1 : 7;
133 uint32_t u32Reserved0[3];
134 } u;
135 struct
136 {
137 uint32_t u32Version;
138 uint32_t u32Reserved0[3];
139 } all;
140 } version;
141 /* 0x40 - Reserved. */
142 uint32_t uReserved1[16];
143 /* 0x80 - Task Priority Register (TPR). */
144 struct
145 {
146 uint8_t u8Tpr;
147 uint8_t u8Reserved0[3];
148 uint32_t u32Reserved0[3];
149 } tpr;
150 /* 0x90 - Arbitration Priority Register (APR). */
151 struct
152 {
153 uint8_t u8Apr;
154 uint8_t u8Reserved0[3];
155 uint32_t u32Reserved0[3];
156 } apr;
157 /* 0xA0 - Processor Priority Register (PPR). */
158 struct
159 {
160 uint8_t u8Ppr;
161 uint8_t u8Reserved0[3];
162 uint32_t u32Reserved0[3];
163 } ppr;
164 /* 0xB0 - End Of Interrupt Register (EOI). */
165 struct
166 {
167 uint32_t u32Eoi;
168 uint32_t u32Reserved0[3];
169 } eoi;
170 /* 0xC0 - Remote Read Register (RRD). */
171 struct
172 {
173 uint32_t u32Rrd;
174 uint32_t u32Reserved0[3];
175 } rrd;
176 /* 0xD0 - Logical Destination Register (LDR). */
177 union
178 {
179 struct
180 {
181 uint8_t u8Reserved0[3];
182 uint8_t u8LogicalApicId;
183 uint32_t u32Reserved0[3];
184 } u;
185 struct
186 {
187 uint32_t u32Ldr;
188 uint32_t u32Reserved0[3];
189 } all;
190 } ldr;
191 /* 0xE0 - Destination Format Register (DFR). */
192 union
193 {
194 struct
195 {
196 uint32_t u28ReservedMb1 : 28; /* MB1 */
197 uint32_t u4Model : 4;
198 uint32_t u32Reserved0[3];
199 } u;
200 struct
201 {
202 uint32_t u32Dfr;
203 uint32_t u32Reserved0[3];
204 } all;
205 } dfr;
206 /* 0xF0 - Spurious-Interrupt Vector Register (SVR). */
207 union
208 {
209 struct
210 {
211 uint32_t u8SpuriousVector : 8;
212 uint32_t fApicSoftwareEnable : 1;
213 uint32_t u3Reserved0 : 3;
214 uint32_t fSupressEoiBroadcast : 1;
215 uint32_t u19Reserved1 : 19;
216 uint32_t u32Reserved0[3];
217 } u;
218 struct
219 {
220 uint32_t u32Svr;
221 uint32_t u32Reserved0[3];
222 } all;
223 } svr;
224 /* 0x100 - In-service Register (ISR). */
225 XAPIC256BITREG isr;
226 /* 0x180 - Trigger Mode Register (TMR). */
227 XAPIC256BITREG tmr;
228 /* 0x200 - Interrupt Request Register (IRR). */
229 XAPIC256BITREG irr;
230 /* 0x280 - Error Status Register (ESR). */
231 union
232 {
233 struct
234 {
235#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
236 uint32_t u4Reserved0 : 4;
237#else
238# error "Implement Pentium and P6 family APIC architectures"
239#endif
240 uint32_t fRedirectableIpi : 1;
241 uint32_t fSendIllegalVector : 1;
242 uint32_t fRcvdIllegalVector : 1;
243 uint32_t fIllegalRegAddr : 1;
244 uint32_t u24Reserved1 : 24;
245 uint32_t u32Reserved0[3];
246 } u;
247 struct
248 {
249 uint32_t u32Errors;
250 uint32_t u32Reserved0[3];
251 } all;
252 } esr;
253 /* 0x290 - Reserved. */
254 uint32_t uReserved2[28];
255 /* 0x300 - Interrupt Command Register (ICR) - Low. */
256 union
257 {
258 struct
259 {
260 uint32_t u8Vector : 8;
261 uint32_t u3DeliveryMode : 3;
262 uint32_t u1DestMode : 1;
263 uint32_t u1DeliveryStatus : 1;
264 uint32_t fReserved0 : 1;
265 uint32_t u1Level : 1;
266 uint32_t u1TriggerMode : 1;
267 uint32_t u2Reserved1 : 2;
268 uint32_t u2DestShorthand : 2;
269 uint32_t u12Reserved2 : 12;
270 uint32_t u32Reserved0[3];
271 } u;
272 struct
273 {
274 uint32_t u32IcrLo;
275 uint32_t u32Reserved0[3];
276 } all;
277 } icr_lo;
278 /* 0x310 - Interrupt Comannd Register (ICR) - High. */
279 union
280 {
281 struct
282 {
283 uint32_t u24Reserved0 : 24;
284 uint32_t u8Dest : 8;
285 uint32_t u32Reserved0[3];
286 } u;
287 struct
288 {
289 uint32_t u32IcrHi;
290 uint32_t u32Reserved0[3];
291 } all;
292 } icr_hi;
293 /* 0x320 - Local Vector Table (LVT) Timer Register. */
294 union
295 {
296 struct
297 {
298 uint32_t u8Vector : 8;
299 uint32_t u4Reserved0 : 4;
300 uint32_t u1DeliveryStatus : 1;
301 uint32_t u3Reserved1 : 3;
302 uint32_t u1Mask : 1;
303 uint32_t u2TimerMode : 2;
304 uint32_t u13Reserved2 : 13;
305 uint32_t u32Reserved0[3];
306 } u;
307 struct
308 {
309 uint32_t u32LvtTimer;
310 uint32_t u32Reserved0[3];
311 } all;
312 } lvt_timer;
313 /* 0x330 - Local Vector Table (LVT) Thermal Sensor Register. */
314#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
315 union
316 {
317 struct
318 {
319 uint32_t u8Vector : 8;
320 uint32_t u3DeliveryMode : 3;
321 uint32_t u1Reserved0 : 1;
322 uint32_t u1DeliveryStatus : 1;
323 uint32_t u3Reserved1 : 3;
324 uint32_t u1Mask : 1;
325 uint32_t u15Reserved2 : 15;
326 uint32_t u32Reserved0[3];
327 } u;
328 struct
329 {
330 uint32_t u32LvtThermal;
331 uint32_t u32Reserved0[3];
332 } all;
333 } lvt_thermal;
334#else
335# error "Implement Pentium and P6 family APIC architectures"
336#endif
337 /* 0x340 - Local Vector Table (LVT) Performance Monitor Counter (PMC) Register. */
338 union
339 {
340 struct
341 {
342 uint32_t u8Vector : 8;
343 uint32_t u3DeliveryMode : 3;
344 uint32_t u1Reserved0 : 1;
345 uint32_t u1DeliveryStatus : 1;
346 uint32_t u3Reserved1 : 3;
347 uint32_t u1Mask : 1;
348 uint32_t u15Reserved2 : 15;
349 uint32_t u32Reserved0[3];
350 } u;
351 struct
352 {
353 uint32_t u32LvtPerf;
354 uint32_t u32Reserved0[3];
355 } all;
356 } lvt_perf;
357 /* 0x350 - Local Vector Table (LVT) LINT0 Register. */
358 union
359 {
360 struct
361 {
362 uint32_t u8Vector : 8;
363 uint32_t u3DeliveryMode : 3;
364 uint32_t u1Reserved0 : 1;
365 uint32_t u1DeliveryStatus : 1;
366 uint32_t u1IntrPolarity : 1;
367 uint32_t u1RemoteIrr : 1;
368 uint32_t u1TriggerMode : 1;
369 uint32_t u1Mask : 1;
370 uint32_t u15Reserved2 : 15;
371 uint32_t u32Reserved0[3];
372 } u;
373 struct
374 {
375 uint32_t u32LvtLint0;
376 uint32_t u32Reserved0[3];
377 } all;
378 } lvt_lint0;
379 /* 0x360 - Local Vector Table (LVT) LINT1 Register. */
380 union
381 {
382 struct
383 {
384 uint32_t u8Vector : 8;
385 uint32_t u3DeliveryMode : 3;
386 uint32_t u1Reserved0 : 1;
387 uint32_t u1DeliveryStatus : 1;
388 uint32_t u1IntrPolarity : 1;
389 uint32_t u1RemoteIrr : 1;
390 uint32_t u1TriggerMode : 1;
391 uint32_t u1Mask : 1;
392 uint32_t u15Reserved2 : 15;
393 uint32_t u32Reserved0[3];
394 } u;
395 struct
396 {
397 uint32_t u32LvtLint1;
398 uint32_t u32Reserved0[3];
399 } all;
400 } lvt_lint1;
401 /* 0x370 - Local Vector Table (LVT) Error Register. */
402 union
403 {
404 struct
405 {
406 uint32_t u8Vector : 8;
407 uint32_t u4Reserved0 : 4;
408 uint32_t u1DeliveryStatus : 1;
409 uint32_t u3Reserved1 : 3;
410 uint32_t u1Mask : 1;
411 uint32_t u15Reserved2 : 15;
412 uint32_t u32Reserved0[3];
413 } u;
414 struct
415 {
416 uint32_t u32LvtError;
417 uint32_t u32Reserved0[3];
418 } all;
419 } lvt_error;
420 /* 0x380 - Timer Initial Counter Register. */
421 struct
422 {
423 uint32_t u32InitialCount;
424 uint32_t u32Reserved0[3];
425 } timer_icr;
426 /* 0x390 - Timer Current Counter Register. */
427 struct
428 {
429 uint32_t u32CurrentCount;
430 uint32_t u32Reserved0[3];
431 } timer_ccr;
432 /* 0x3A0 - Reserved. */
433 uint32_t u32Reserved3[16];
434 /* 0x3E0 - Timer Divide Configuration Register. */
435 union
436 {
437 struct
438 {
439 uint32_t u2DivideValue0 : 2;
440 uint32_t u1Reserved0 : 1;
441 uint32_t u1DivideValue1 : 1;
442 uint32_t u28Reserved1 : 28;
443 uint32_t u32Reserved0[3];
444 } u;
445 struct
446 {
447 uint32_t u32DivideValue;
448 uint32_t u32Reserved0[3];
449 } all;
450 } timer_dcr;
451 /* 0x3F0 - Reserved. */
452 uint8_t u8Reserved0[3088];
453} XAPICPAGE;
454/** Pointer to a XAPICPAGE struct. */
455typedef XAPICPAGE *PXAPICPAGE;
456/** Pointer to a const XAPICPAGE struct. */
457typedef const XAPICPAGE *PCXAPICPAGE;
458AssertCompileSize(XAPICPAGE, 4096);
459AssertCompileMemberOffset(XAPICPAGE, id, XAPIC_OFF_ID);
460AssertCompileMemberOffset(XAPICPAGE, version, XAPIC_OFF_VERSION);
461AssertCompileMemberOffset(XAPICPAGE, tpr, XAPIC_OFF_TPR);
462AssertCompileMemberOffset(XAPICPAGE, apr, XAPIC_OFF_APR);
463AssertCompileMemberOffset(XAPICPAGE, ppr, XAPIC_OFF_PPR);
464AssertCompileMemberOffset(XAPICPAGE, eoi, XAPIC_OFF_EOI);
465AssertCompileMemberOffset(XAPICPAGE, rrd, XAPIC_OFF_RRD);
466AssertCompileMemberOffset(XAPICPAGE, ldr, XAPIC_OFF_LDR);
467AssertCompileMemberOffset(XAPICPAGE, dfr, XAPIC_OFF_DFR);
468AssertCompileMemberOffset(XAPICPAGE, svr, XAPIC_OFF_SVR);
469AssertCompileMemberOffset(XAPICPAGE, isr, XAPIC_OFF_ISR0);
470AssertCompileMemberOffset(XAPICPAGE, tmr, XAPIC_OFF_TMR0);
471AssertCompileMemberOffset(XAPICPAGE, irr, XAPIC_OFF_IRR0);
472AssertCompileMemberOffset(XAPICPAGE, esr, XAPIC_OFF_ESR);
473AssertCompileMemberOffset(XAPICPAGE, icr_lo, XAPIC_OFF_ICR_LO);
474AssertCompileMemberOffset(XAPICPAGE, icr_hi, XAPIC_OFF_ICR_HI);
475AssertCompileMemberOffset(XAPICPAGE, lvt_timer, XAPIC_OFF_LVT_TIMER);
476AssertCompileMemberOffset(XAPICPAGE, lvt_thermal, XAPIC_OFF_LVT_THERMAL);
477AssertCompileMemberOffset(XAPICPAGE, lvt_perf, XAPIC_OFF_LVT_PERF);
478AssertCompileMemberOffset(XAPICPAGE, lvt_lint0, XAPIC_OFF_LVT_LINT0);
479AssertCompileMemberOffset(XAPICPAGE, lvt_lint1, XAPIC_OFF_LVT_LINT1);
480AssertCompileMemberOffset(XAPICPAGE, lvt_error, XAPIC_OFF_LVT_ERROR);
481AssertCompileMemberOffset(XAPICPAGE, timer_icr, XAPIC_OFF_TIMER_ICR);
482AssertCompileMemberOffset(XAPICPAGE, timer_ccr, XAPIC_OFF_TIMER_CCR);
483AssertCompileMemberOffset(XAPICPAGE, timer_dcr, XAPIC_OFF_TIMER_DCR);
484
485/**
486 * The x2APIC memory layout as per Intel/AMD specs.
487 */
488typedef struct X2APICPAGE
489{
490 /* 0x00 - Reserved. */
491 uint32_t uReserved0[8];
492 /* 0x20 - APIC ID. */
493 struct
494 {
495 uint32_t u32ApicId;
496 uint32_t u32Reserved0[3];
497 } id;
498 /* 0x30 - APIC version register. */
499 union
500 {
501 struct
502 {
503 uint8_t u8Version;
504 uint8_t u8Reserved0;
505 uint8_t u8MaxLvtEntry;
506 uint8_t fEoiBroadcastSupression : 1;
507 uint8_t u7Reserved1 : 7;
508 uint32_t u32Reserved0[3];
509 } u;
510 struct
511 {
512 uint32_t u32Version;
513 uint32_t u32Reserved2[3];
514 } all;
515 } version;
516 /* 0x40 - Reserved. */
517 uint32_t uReserved1[16];
518 /* 0x80 - Task Priority Register (TPR). */
519 struct
520 {
521 uint8_t u8Tpr;
522 uint8_t u8Reserved0[3];
523 uint32_t u32Reserved0[3];
524 } tpr;
525 /* 0x90 - Reserved. */
526 uint32_t uReserved2[4];
527 /* 0xA0 - Processor Priority Register (PPR). */
528 struct
529 {
530 uint8_t u8Ppr;
531 uint8_t u8Reserved0[3];
532 uint32_t u32Reserved0[3];
533 } ppr;
534 /* 0xB0 - End Of Interrupt Register (EOI). */
535 struct
536 {
537 uint32_t u32Eoi;
538 uint32_t u32Reserved0[3];
539 } eoi;
540 /* 0xC0 - Remote Read Register (RRD). */
541 struct
542 {
543 uint32_t u32Rrd;
544 uint32_t u32Reserved0[3];
545 } rrd;
546 /* 0xD0 - Logical Destination Register (LDR). */
547 struct
548 {
549 uint32_t u32LogicalApicId;
550 uint32_t u32Reserved1[3];
551 } ldr;
552 /* 0xE0 - Reserved. */
553 uint32_t uReserved3[4];
554 /* 0xF0 - Spurious-Interrupt Vector Register (SVR). */
555 union
556 {
557 struct
558 {
559 uint32_t u8SpuriousVector : 8;
560 uint32_t fApicSoftwareEnable : 1;
561 uint32_t u3Reserved0 : 3;
562 uint32_t fSupressEoiBroadcast : 1;
563 uint32_t u19Reserved1 : 19;
564 uint32_t u32Reserved0[3];
565 } u;
566 struct
567 {
568 uint32_t u32Svr;
569 uint32_t uReserved0[3];
570 } all;
571 } svr;
572 /* 0x100 - In-service Register (ISR). */
573 XAPIC256BITREG isr;
574 /* 0x180 - Trigger Mode Register (TMR). */
575 XAPIC256BITREG tmr;
576 /* 0x200 - Interrupt Request Register (IRR). */
577 XAPIC256BITREG irr;
578 /* 0x280 - Error Status Register (ESR). */
579 union
580 {
581 struct
582 {
583#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
584 uint32_t u4Reserved0 : 4;
585#else
586# error "Implement Pentium and P6 family APIC architectures"
587#endif
588 uint32_t fRedirectableIpi : 1;
589 uint32_t fSendIllegalVector : 1;
590 uint32_t fRcvdIllegalVector : 1;
591 uint32_t fIllegalRegAddr : 1;
592 uint32_t u24Reserved1 : 24;
593 uint32_t uReserved0[3];
594 } u;
595 struct
596 {
597 uint32_t u32Errors;
598 uint32_t u32Reserved0[3];
599 } all;
600 } esr;
601 /* 0x290 - Reserved. */
602 uint32_t uReserved4[28];
603 /* 0x300 - Interrupt Command Register (ICR) - Low. */
604 union
605 {
606 struct
607 {
608 uint32_t u8Vector : 8;
609 uint32_t u3DeliveryMode : 3;
610 uint32_t u1DestMode : 1;
611 uint32_t u2Reserved0 : 2;
612 uint32_t u1Level : 1;
613 uint32_t u1TriggerMode : 1;
614 uint32_t u2Reserved1 : 2;
615 uint32_t u2DestShorthand : 2;
616 uint32_t u12Reserved2 : 12;
617 uint32_t u32Reserved0[3];
618 } u;
619 struct
620 {
621 uint32_t u32IcrLo;
622 uint32_t u32Reserved3[3];
623 } all;
624 } icr_lo;
625 /* 0x310 - Interrupt Comannd Register (ICR) - High. */
626 struct
627 {
628 uint32_t u32IcrHi;
629 uint32_t uReserved1[3];
630 } icr_hi;
631 /* 0x320 - Local Vector Table (LVT) Timer Register. */
632 union
633 {
634 struct
635 {
636 uint32_t u8Vector : 8;
637 uint32_t u4Reserved0 : 4;
638 uint32_t u1DeliveryStatus : 1;
639 uint32_t u3Reserved1 : 3;
640 uint32_t u1Mask : 1;
641 uint32_t u2TimerMode : 2;
642 uint32_t u13Reserved2 : 13;
643 uint32_t u32Reserved0[3];
644 } u;
645 struct
646 {
647 uint32_t u32LvtTimer;
648 uint32_t u32Reserved0[3];
649 } all;
650 } lvt_timer;
651 /* 0x330 - Local Vector Table (LVT) Thermal Sensor Register. */
652 union
653 {
654 struct
655 {
656 uint32_t u8Vector : 8;
657 uint32_t u3DeliveryMode : 3;
658 uint32_t u1Reserved0 : 1;
659 uint32_t u1DeliveryStatus : 1;
660 uint32_t u3Reserved1 : 3;
661 uint32_t u1Mask : 1;
662 uint32_t u15Reserved2 : 15;
663 uint32_t u32Reserved0[3];
664 } u;
665 struct
666 {
667 uint32_t u32LvtThermal;
668 uint32_t uReserved0[3];
669 } all;
670 } lvt_thermal;
671 /* 0x340 - Local Vector Table (LVT) Performance Monitor Counter (PMC) Register. */
672 union
673 {
674 struct
675 {
676 uint32_t u8Vector : 8;
677 uint32_t u3DeliveryMode : 3;
678 uint32_t u1Reserved0 : 1;
679 uint32_t u1DeliveryStatus : 1;
680 uint32_t u3Reserved1 : 3;
681 uint32_t u1Mask : 1;
682 uint32_t u15Reserved2 : 15;
683 uint32_t u32Reserved0[3];
684 } u;
685 struct
686 {
687 uint32_t u32LvtPerf;
688 uint32_t u32Reserved0[3];
689 } all;
690 } lvt_perf;
691 /* 0x350 - Local Vector Table (LVT) LINT0 Register. */
692 union
693 {
694 struct
695 {
696 uint32_t u8Vector : 8;
697 uint32_t u3DeliveryMode : 3;
698 uint32_t u1Reserved0 : 1;
699 uint32_t u1DeliveryStatus : 1;
700 uint32_t u1IntrPolarity : 1;
701 uint32_t u1RemoteIrr : 1;
702 uint32_t u1TriggerMode : 1;
703 uint32_t u1Mask : 1;
704 uint32_t u15Reserved2 : 15;
705 uint32_t u32Reserved0[3];
706 } u;
707 struct
708 {
709 uint32_t u32LvtLint0;
710 uint32_t u32Reserved0[3];
711 } all;
712 } lvt_lint0;
713 /* 0x360 - Local Vector Table (LVT) LINT1 Register. */
714 union
715 {
716 struct
717 {
718 uint32_t u8Vector : 8;
719 uint32_t u3DeliveryMode : 3;
720 uint32_t u1Reserved0 : 1;
721 uint32_t u1DeliveryStatus : 1;
722 uint32_t u1IntrPolarity : 1;
723 uint32_t u1RemoteIrr : 1;
724 uint32_t u1TriggerMode : 1;
725 uint32_t u1Mask : 1;
726 uint32_t u15Reserved2 : 15;
727 uint32_t u32Reserved0[3];
728 } u;
729 struct
730 {
731 uint32_t u32LvtLint1;
732 uint32_t u32Reserved0[3];
733 } all;
734 } lvt_lint1;
735 /* 0x370 - Local Vector Table (LVT) Error Register. */
736 union
737 {
738 struct
739 {
740 uint32_t u8Vector : 8;
741 uint32_t u4Reserved0 : 4;
742 uint32_t u1DeliveryStatus : 1;
743 uint32_t u3Reserved1 : 3;
744 uint32_t u1Mask : 1;
745 uint32_t u15Reserved2 : 15;
746 uint32_t u32Reserved0[3];
747 } u;
748 struct
749 {
750 uint32_t u32LvtError;
751 uint32_t u32Reserved0[3];
752 } all;
753 } lvt_error;
754 /* 0x380 - Timer Initial Counter Register. */
755 struct
756 {
757 uint32_t u32InitialCount;
758 uint32_t u32Reserved0[3];
759 } timer_icr;
760 /* 0x390 - Timer Current Counter Register. */
761 struct
762 {
763 uint32_t u32CurrentCount;
764 uint32_t u32Reserved0[3];
765 } timer_ccr;
766 /* 0x3A0 - Reserved. */
767 uint32_t uReserved5[16];
768 /* 0x3E0 - Timer Divide Configuration Register. */
769 union
770 {
771 struct
772 {
773 uint32_t u2DivideValue0 : 2;
774 uint32_t u1Reserved0 : 1;
775 uint32_t u1DivideValue1 : 1;
776 uint32_t u28Reserved1 : 28;
777 uint32_t u32Reserved0[3];
778 } u;
779 struct
780 {
781 uint32_t u32DivideValue;
782 uint32_t u32Reserved0[3];
783 } all;
784 } timer_dcr;
785 /* 0x3F0 - Self IPI Register. */
786 struct
787 {
788 uint32_t u8Vector : 8;
789 uint32_t u24Reserved0 : 24;
790 uint32_t u32Reserved0[3];
791 } self_ipi;
792 /* 0x400 - Reserved. */
793 uint8_t u8Reserved0[3072];
794} X2APICPAGE;
795/** Pointer to a X2APICPAGE struct. */
796typedef X2APICPAGE *PX2APICPAGE;
797/** Pointer to a const X2APICPAGE struct. */
798typedef const X2APICPAGE *PCX2APICPAGE;
799AssertCompileSize(X2APICPAGE, 4096);
800AssertCompileSize(X2APICPAGE, sizeof(XAPICPAGE));
801AssertCompileMemberOffset(X2APICPAGE, id, XAPIC_OFF_ID);
802AssertCompileMemberOffset(X2APICPAGE, version, XAPIC_OFF_VERSION);
803AssertCompileMemberOffset(X2APICPAGE, tpr, XAPIC_OFF_TPR);
804AssertCompileMemberOffset(X2APICPAGE, ppr, XAPIC_OFF_PPR);
805AssertCompileMemberOffset(X2APICPAGE, eoi, XAPIC_OFF_EOI);
806AssertCompileMemberOffset(X2APICPAGE, rrd, XAPIC_OFF_RRD);
807AssertCompileMemberOffset(X2APICPAGE, ldr, XAPIC_OFF_LDR);
808AssertCompileMemberOffset(X2APICPAGE, svr, XAPIC_OFF_SVR);
809AssertCompileMemberOffset(X2APICPAGE, isr, XAPIC_OFF_ISR0);
810AssertCompileMemberOffset(X2APICPAGE, tmr, XAPIC_OFF_TMR0);
811AssertCompileMemberOffset(X2APICPAGE, irr, XAPIC_OFF_IRR0);
812AssertCompileMemberOffset(X2APICPAGE, esr, XAPIC_OFF_ESR);
813AssertCompileMemberOffset(X2APICPAGE, icr_lo, XAPIC_OFF_ICR_LO);
814AssertCompileMemberOffset(X2APICPAGE, icr_hi, XAPIC_OFF_ICR_HI);
815AssertCompileMemberOffset(X2APICPAGE, lvt_timer, XAPIC_OFF_LVT_TIMER);
816AssertCompileMemberOffset(X2APICPAGE, lvt_thermal, XAPIC_OFF_LVT_THERMAL);
817AssertCompileMemberOffset(X2APICPAGE, lvt_perf, XAPIC_OFF_LVT_PERF);
818AssertCompileMemberOffset(X2APICPAGE, lvt_lint0, XAPIC_OFF_LVT_LINT0);
819AssertCompileMemberOffset(X2APICPAGE, lvt_lint1, XAPIC_OFF_LVT_LINT1);
820AssertCompileMemberOffset(X2APICPAGE, lvt_error, XAPIC_OFF_LVT_ERROR);
821AssertCompileMemberOffset(X2APICPAGE, timer_icr, XAPIC_OFF_TIMER_ICR);
822AssertCompileMemberOffset(X2APICPAGE, timer_ccr, XAPIC_OFF_TIMER_CCR);
823AssertCompileMemberOffset(X2APICPAGE, timer_dcr, XAPIC_OFF_TIMER_DCR);
824AssertCompileMemberOffset(X2APICPAGE, self_ipi, X2APIC_OFF_SELF_IPI);
825
826/**
827 * APIC MSR access error.
828 * @note The values must match the array indices in apicMsrAccessError().
829 */
830typedef enum APICMSRACCESS
831{
832 /** MSR read while not in x2APIC. */
833 APICMSRACCESS_INVALID_READ_MODE = 0,
834 /** MSR write while not in x2APIC. */
835 APICMSRACCESS_INVALID_WRITE_MODE,
836 /** MSR read for a reserved/unknown/invalid MSR. */
837 APICMSRACCESS_READ_RSVD_OR_UNKNOWN,
838 /** MSR write for a reserved/unknown/invalid MSR. */
839 APICMSRACCESS_WRITE_RSVD_OR_UNKNOWN,
840 /** MSR read for a write-only MSR. */
841 APICMSRACCESS_READ_WRITE_ONLY,
842 /** MSR write for a read-only MSR. */
843 APICMSRACCESS_WRITE_READ_ONLY,
844 /** MSR read to reserved bits. */
845 APICMSRACCESS_READ_RSVD_BITS,
846 /** MSR write to reserved bits. */
847 APICMSRACCESS_WRITE_RSVD_BITS,
848 /** MSR write with invalid value. */
849 APICMSRACCESS_WRITE_INVALID,
850 /** MSR write disallowed due to incompatible config. */
851 APICMSRACCESS_WRITE_DISALLOWED_CONFIG,
852 /** MSR read disallowed due to incompatible config. */
853 APICMSRACCESS_READ_DISALLOWED_CONFIG,
854 /** Count of enum members (don't use). */
855 APICMSRACCESS_COUNT
856} APICMSRACCESS;
857
858
859/** @def APIC_CACHE_LINE_SIZE
860 * Padding (in bytes) for aligning data in different cache lines. Present
861 * generation x86 CPUs use 64-byte cache lines[1]. However, Intel NetBurst
862 * architecture supposedly uses 128-byte cache lines[2]. Since 128 is a
863 * multiple of 64, we use the larger one here.
864 *
865 * [1] - Intel spec "Table 11-1. Characteristics of the Caches, TLBs, Store
866 * Buffer, and Write Combining Buffer in Intel 64 and IA-32 Processors"
867 * [2] - Intel spec. 8.10.6.7 "Place Locks and Semaphores in Aligned, 128-Byte
868 * Blocks of Memory".
869 */
870#define APIC_CACHE_LINE_SIZE 128
871
872/**
873 * APIC Pending-Interrupt Bitmap (PIB).
874 */
875typedef struct APICPIB
876{
877 uint64_t volatile au64VectorBitmap[4];
878 uint32_t volatile fOutstandingNotification;
879 uint8_t au8Reserved[APIC_CACHE_LINE_SIZE - sizeof(uint32_t) - (sizeof(uint64_t) * 4)];
880} APICPIB;
881AssertCompileMemberOffset(APICPIB, fOutstandingNotification, 256 / 8);
882AssertCompileSize(APICPIB, APIC_CACHE_LINE_SIZE);
883/** Pointer to a pending-interrupt bitmap. */
884typedef APICPIB *PAPICPIB;
885/** Pointer to a const pending-interrupt bitmap. */
886typedef const APICPIB *PCAPICPIB;
887
888/**
889 * APIC PDM instance data (per-VM).
890 */
891typedef struct APICDEV
892{
893 /** The MMIO handle. */
894 IOMMMIOHANDLE hMmio;
895} APICDEV;
896/** Pointer to an APIC device. */
897typedef APICDEV *PAPICDEV;
898/** Pointer to a const APIC device. */
899typedef APICDEV const *PCAPICDEV;
900
901
902/**
903 * The APIC GVM instance data.
904 */
905typedef struct APICR0PERVM
906{
907 /** The ring-0 device instance. */
908 PPDMDEVINSR0 pDevInsR0;
909} APICR0PERVM;
910
911
912/**
913 * APIC VM Instance data.
914 */
915typedef struct APIC
916{
917 /** The ring-3 device instance. */
918 PPDMDEVINSR3 pDevInsR3;
919
920 /** @name The APIC pending-interrupt bitmap (PIB).
921 * @{ */
922 /** The host-context physical address of the PIB. */
923 RTHCPHYS HCPhysApicPib;
924 /** The ring-0 memory object of the PIB. */
925 RTR0MEMOBJ hMemObjApicPibR0;
926 /** The ring-3 mapping of the memory object of the PIB. */
927 RTR0MEMOBJ hMapObjApicPibR0;
928 /** The APIC PIB virtual address - R0 ptr. */
929 R0PTRTYPE(void *) pvApicPibR0;
930 /** The APIC PIB virtual address - R3 ptr. */
931 R3PTRTYPE(void *) pvApicPibR3;
932 /** The size of the page in bytes. */
933 uint32_t cbApicPib;
934 /** @} */
935
936 /** @name Other miscellaneous data.
937 * @{ */
938 /** Whether full APIC register virtualization is enabled. */
939 bool fVirtApicRegsEnabled;
940 /** Whether posted-interrupt processing is enabled. */
941 bool fPostedIntrsEnabled;
942 /** Whether TSC-deadline timer mode is supported for the guest. */
943 bool fSupportsTscDeadline;
944 /** Whether this VM has an IO-APIC. */
945 bool fIoApicPresent;
946 /** Whether R0 is enabled or not (applies to MSR handling as well). */
947 bool fR0Enabled;
948 /** Whether RC is enabled or not (applies to MSR handling as well). */
949 bool fRCEnabled;
950 /** Whether Hyper-V x2APIC compatibility mode is enabled. */
951 bool fHyperVCompatMode;
952 /** Enable horrible macOS workaround where the ID register has the value
953 * shifted up 24 bits to be compatible with buggy code in
954 * i386_init.c/vstart(). Only applied if we're in typical macOS 64-bit
955 * kernel load area and macOS kernel selector value (8), as we must not ever
956 * apply this to the EFI code. */
957 bool fMacOSWorkaround;
958 /** The max supported APIC mode from CFGM. */
959 PDMAPICMODE enmMaxMode;
960 /** @} */
961} APIC;
962/** Pointer to APIC VM instance data. */
963typedef APIC *PAPIC;
964/** Pointer to const APIC VM instance data. */
965typedef APIC const *PCAPIC;
966AssertCompileMemberAlignment(APIC, cbApicPib, 8);
967AssertCompileSizeAlignment(APIC, 8);
968
969/**
970 * APIC VMCPU Instance data.
971 */
972typedef struct APICCPU
973{
974 /** @name The APIC page.
975 * @{ */
976 /** The host-context physical address of the page. */
977 RTHCPHYS HCPhysApicPage;
978 /** The ring-0 memory object of the page. */
979 RTR0MEMOBJ hMemObjApicPageR0;
980 /** The ring-3 mapping of the memory object of the page. */
981 RTR0MEMOBJ hMapObjApicPageR0;
982 /** The APIC page virtual address - R0 ptr. */
983 R0PTRTYPE(void *) pvApicPageR0;
984 /** The APIC page virtual address - R3 ptr. */
985 R3PTRTYPE(void *) pvApicPageR3;
986 /** The size of the page in bytes. */
987 uint32_t cbApicPage;
988 /** @} */
989
990 /** @name Auxiliary state.
991 * @{ */
992 /** The error status register's internal state. */
993 uint32_t uEsrInternal;
994 /** The APIC base MSR.*/
995 uint64_t volatile uApicBaseMsr;
996 /** @} */
997
998 /** @name The pending-interrupt bitmaps (PIB).
999 * @{ */
1000 /** The host-context physical address of the page. */
1001 RTHCPHYS HCPhysApicPib;
1002 /** The APIC PIB virtual address - R0 ptr. */
1003 R0PTRTYPE(void *) pvApicPibR0;
1004 /** The APIC PIB virtual address - R3 ptr. */
1005 R3PTRTYPE(void *) pvApicPibR3;
1006 /** The APIC PIB for level-sensitive interrupts. */
1007 APICPIB ApicPibLevel;
1008 /** @} */
1009
1010 /** @name Other miscellaneous data.
1011 * @{ */
1012 /** Whether the LINT0 interrupt line is active. */
1013 bool volatile fActiveLint0;
1014 /** Whether the LINT1 interrupt line is active. */
1015 bool volatile fActiveLint1;
1016 /** Alignment padding. */
1017 uint8_t auAlignment2[6];
1018 /** The source tags corresponding to each interrupt vector (debugging). */
1019 uint32_t auSrcTags[256];
1020 /** @} */
1021
1022 /** @name The APIC timer.
1023 * @{ */
1024 /** The timer. */
1025 TMTIMERHANDLE hTimer;
1026 /** The time stamp when the timer was initialized.
1027 * @note Access protected by the timer critsect. */
1028 uint64_t u64TimerInitial;
1029 /** Cache of timer initial count of the frequency hint to TM. */
1030 uint32_t uHintedTimerInitialCount;
1031 /** Cache of timer shift of the frequency hint to TM. */
1032 uint32_t uHintedTimerShift;
1033 /** The timer description. */
1034 char szTimerDesc[16];
1035 /** @} */
1036
1037 /** @name Log Max counters
1038 * @{ */
1039 uint32_t cLogMaxAccessError;
1040 uint32_t cLogMaxSetApicBaseAddr;
1041 uint32_t cLogMaxGetApicBaseAddr;
1042 uint32_t uAlignment4;
1043 /** @} */
1044
1045 /** @name APIC statistics.
1046 * @{ */
1047#ifdef VBOX_WITH_STATISTICS
1048 /** Number of MMIO reads in RZ. */
1049 STAMCOUNTER StatMmioReadRZ;
1050 /** Number of MMIO reads in R3. */
1051 STAMCOUNTER StatMmioReadR3;
1052
1053 /** Number of MMIO writes in RZ. */
1054 STAMCOUNTER StatMmioWriteRZ;
1055 /** Number of MMIO writes in R3. */
1056 STAMCOUNTER StatMmioWriteR3;
1057
1058 /** Number of MSR reads in RZ. */
1059 STAMCOUNTER StatMsrReadRZ;
1060 /** Number of MSR reads in R3. */
1061 STAMCOUNTER StatMsrReadR3;
1062
1063 /** Number of MSR writes in RZ. */
1064 STAMCOUNTER StatMsrWriteRZ;
1065 /** Number of MSR writes in R3. */
1066 STAMCOUNTER StatMsrWriteR3;
1067
1068 /** Profiling of APICUpdatePendingInterrupts(). */
1069 STAMPROFILE StatUpdatePendingIntrs;
1070 /** Profiling of apicPostInterrupt(). */
1071 STAMPROFILE StatPostIntr;
1072 /** Number of times an interrupt is already pending in
1073 * apicPostInterrupts().*/
1074 STAMCOUNTER StatPostIntrAlreadyPending;
1075 /** Number of times the timer callback is invoked. */
1076 STAMCOUNTER StatTimerCallback;
1077 /** Number of times the TPR is written. */
1078 STAMCOUNTER StatTprWrite;
1079 /** Number of times the TPR is read. */
1080 STAMCOUNTER StatTprRead;
1081 /** Number of times the EOI is written. */
1082 STAMCOUNTER StatEoiWrite;
1083 /** Number of times TPR masks an interrupt in apicGetInterrupt(). */
1084 STAMCOUNTER StatMaskedByTpr;
1085 /** Number of times PPR masks an interrupt in apicGetInterrupt(). */
1086 STAMCOUNTER StatMaskedByPpr;
1087 /** Number of times the timer ICR is written. */
1088 STAMCOUNTER StatTimerIcrWrite;
1089 /** Number of times the ICR Lo (send IPI) is written. */
1090 STAMCOUNTER StatIcrLoWrite;
1091 /** Number of times the ICR Hi is written. */
1092 STAMCOUNTER StatIcrHiWrite;
1093 /** Number of times the full ICR (x2APIC send IPI) is written. */
1094 STAMCOUNTER StatIcrFullWrite;
1095 /** Number of times the DCR is written. */
1096 STAMCOUNTER StatDcrWrite;
1097 /** Number of times the DFR is written. */
1098 STAMCOUNTER StatDfrWrite;
1099 /** Number of times the LDR is written. */
1100 STAMCOUNTER StatLdrWrite;
1101 /** Number of times the APIC-ID MSR is read. */
1102 STAMCOUNTER StatIdMsrRead;
1103 /** Number of times the LVT timer is written. */
1104 STAMCOUNTER StatLvtTimerWrite;
1105#endif
1106 /** Number of apicPostInterrupt() calls. */
1107 STAMCOUNTER StatPostIntrCnt;
1108 /** Number of interrupts broken down by vector. */
1109 STAMCOUNTER aStatVectors[256];
1110 /** @} */
1111} APICCPU;
1112/** Pointer to APIC VMCPU instance data. */
1113typedef APICCPU *PAPICCPU;
1114/** Pointer to a const APIC VMCPU instance data. */
1115typedef APICCPU const *PCAPICCPU;
1116AssertCompileMemberAlignment(APICCPU, uApicBaseMsr, 8);
1117
1118/**
1119 * APIC operating modes as returned by apicGetMode().
1120 *
1121 * The values match hardware states.
1122 * See Intel spec. 10.12.1 "Detecting and Enabling x2APIC Mode".
1123 */
1124typedef enum APICMODE
1125{
1126 APICMODE_DISABLED = 0,
1127 APICMODE_INVALID,
1128 APICMODE_XAPIC,
1129 APICMODE_X2APIC
1130} APICMODE;
1131
1132/**
1133 * Gets the timer shift value.
1134 *
1135 * @returns The timer shift value.
1136 * @param pXApicPage The xAPIC page.
1137 */
1138DECLINLINE(uint8_t) apicGetTimerShift(PCXAPICPAGE pXApicPage)
1139{
1140 /* See Intel spec. 10.5.4 "APIC Timer". */
1141 uint32_t uShift = pXApicPage->timer_dcr.u.u2DivideValue0 | (pXApicPage->timer_dcr.u.u1DivideValue1 << 2);
1142 return (uShift + 1) & 7;
1143}
1144
1145
1146const char *apicGetModeName(APICMODE enmMode);
1147const char *apicGetDestFormatName(XAPICDESTFORMAT enmDestFormat);
1148const char *apicGetDeliveryModeName(XAPICDELIVERYMODE enmDeliveryMode);
1149const char *apicGetDestModeName(XAPICDESTMODE enmDestMode);
1150const char *apicGetTriggerModeName(XAPICTRIGGERMODE enmTriggerMode);
1151const char *apicGetDestShorthandName(XAPICDESTSHORTHAND enmDestShorthand);
1152const char *apicGetTimerModeName(XAPICTIMERMODE enmTimerMode);
1153void apicHintTimerFreq(PPDMDEVINS pDevIns, PAPICCPU pApicCpu, uint32_t uInitialCount, uint8_t uTimerShift);
1154APICMODE apicGetMode(uint64_t uApicBaseMsr);
1155
1156DECLCALLBACK(VBOXSTRICTRC) apicReadMmio(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb);
1157DECLCALLBACK(VBOXSTRICTRC) apicWriteMmio(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb);
1158
1159bool apicPostInterrupt(PVMCPUCC pVCpu, uint8_t uVector, XAPICTRIGGERMODE enmTriggerMode, uint32_t uSrcTag);
1160void apicStartTimer(PVMCPUCC pVCpu, uint32_t uInitialCount);
1161void apicClearInterruptFF(PVMCPUCC pVCpu, PDMAPICIRQ enmType);
1162void apicInitIpi(PVMCPUCC pVCpu);
1163void apicResetCpu(PVMCPUCC pVCpu, bool fResetApicBaseMsr);
1164
1165DECLCALLBACK(int) apicR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg);
1166DECLCALLBACK(int) apicR3Destruct(PPDMDEVINS pDevIns);
1167DECLCALLBACK(void) apicR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta);
1168DECLCALLBACK(void) apicR3Reset(PPDMDEVINS pDevIns);
1169DECLCALLBACK(int) apicR3InitComplete(PPDMDEVINS pDevIns);
1170
1171/** @} */
1172
1173#endif /* !VMM_INCLUDED_SRC_include_APICInternal_h */
1174
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