VirtualBox

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

Last change on this file since 107922 was 107113, checked in by vboxsync, 3 months ago

VMM: bugref:10759 Restructure the APIC to allow different backends to be used.

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