VirtualBox

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

Last change on this file was 108434, checked in by vboxsync, 5 weeks ago

VMM/NEM/Hyper-V: Started implementing a NEM/Hyper-V specific APIC emulation utilizing the LocalApicEmulation feature of Hyper-V, bugref:9993

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

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