VirtualBox

source: vbox/trunk/include/VBox/vmm/pdmapic.h@ 107401

Last change on this file since 107401 was 107308, checked in by vboxsync, 8 weeks ago

VMM: bugref:10759 Refactor GIC for use with different backends.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.6 KB
Line 
1/** @file
2 * PDM - Pluggable Device Manager, APIC Interface.
3 */
4
5/*
6 * Copyright (C) 2024 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef VBOX_INCLUDED_vmm_pdmapic_h
37#define VBOX_INCLUDED_vmm_pdmapic_h
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42#include <VBox/types.h>
43#include <VBox/apic.h>
44struct PDMDEVREGCB;
45
46/** @defgroup grp_pdm_apic The local APIC PDM API
47 * @ingroup grp_pdm
48 * @{
49 */
50
51RT_C_DECLS_BEGIN
52
53/**
54 * APIC mode argument for apicR3SetCpuIdFeatureLevel.
55 *
56 * Also used in saved-states, CFGM don't change existing values.
57 */
58typedef enum PDMAPICMODE
59{
60 /** Invalid 0 entry. */
61 PDMAPICMODE_INVALID = 0,
62 /** No APIC. */
63 PDMAPICMODE_NONE,
64 /** Standard APIC (X86_CPUID_FEATURE_EDX_APIC). */
65 PDMAPICMODE_APIC,
66 /** Intel X2APIC (X86_CPUID_FEATURE_ECX_X2APIC). */
67 PDMAPICMODE_X2APIC,
68 /** The usual 32-bit paranoia. */
69 PDMAPICMODE_32BIT_HACK = 0x7fffffff
70} PDMAPICMODE;
71
72/**
73 * APIC irq argument for pfnSetInterruptFF and pfnClearInterruptFF.
74 */
75typedef enum PDMAPICIRQ
76{
77 /** Invalid 0 entry. */
78 PDMAPICIRQ_INVALID = 0,
79 /** Normal hardware interrupt. */
80 PDMAPICIRQ_HARDWARE,
81 /** NMI. */
82 PDMAPICIRQ_NMI,
83 /** SMI. */
84 PDMAPICIRQ_SMI,
85 /** ExtINT (HW interrupt via PIC). */
86 PDMAPICIRQ_EXTINT,
87 /** Interrupt arrived, needs to be updated to the IRR. */
88 PDMAPICIRQ_UPDATE_PENDING,
89 /** The usual 32-bit paranoia. */
90 PDMAPICIRQ_32BIT_HACK = 0x7fffffff
91} PDMAPICIRQ;
92
93/**
94 * The type of PDM APIC backend.
95 */
96typedef enum PDMAPICBACKENDTYPE
97{
98 /** None/Invalid PDM APIC backend. */
99 PDMAPICBACKENDTYPE_NONE = 0,
100 /** VirtualBox backend. */
101 PDMAPICBACKENDTYPE_VBOX,
102 /** KVM backend. */
103 PDMAPICBACKENDTYPE_KVM,
104 /** Hyper-V backend. */
105 PDMAPICBACKENDTYPE_HYPERV,
106 /** Hypervisor.Framework backend. */
107 PDMAPICBACKENDTYPE_HVF,
108 /** End of valid PDM APIC backend values. */
109 PDMAPICBACKENDTYPE_END,
110 /** The usual 32-bit paranoia. */
111 PDMAPICBACKENDTYPE_32BIT_HACK = 0x7fffffff
112} PDMAPICBACKENDTYPE;
113
114/**
115 * PDM APIC backend ring-3 API.
116 */
117typedef struct PDMAPICBACKENDR3
118{
119 /**
120 * Returns whether the APIC is hardware enabled or not.
121 *
122 * @returns true if enabled, false otherwise.
123 * @param pVCpu The cross context virtual CPU structure.
124 */
125 DECLR3CALLBACKMEMBER(bool, pfnIsEnabled, (PCVMCPUCC pVCpu));
126
127 /**
128 * Initializes per-VCPU APIC to the state following an INIT reset
129 * ("Wait-for-SIPI" state).
130 *
131 * @param pVCpu The cross context virtual CPU structure.
132 */
133 DECLR3CALLBACKMEMBER(void, pfnInitIpi, (PVMCPUCC pVCpu));
134
135 /**
136 * Gets the APIC base MSR (no checks are performed wrt APIC hardware or its
137 * state).
138 *
139 * @returns The base MSR value.
140 * @param pVCpu The cross context virtual CPU structure.
141 */
142 DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseMsrNoCheck, (PCVMCPUCC pVCpu));
143
144 /**
145 * Gets the APIC base MSR.
146 *
147 * @returns Strict VBox status code.
148 * @param pVCpu The cross context virtual CPU structure.
149 * @param pu64Value Where to store the MSR value.
150 */
151 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnGetBaseMsr, (PVMCPUCC pVCpu, uint64_t *pu64Value));
152
153 /**
154 * Sets the APIC base MSR.
155 *
156 * @returns VBox status code - no informational ones, esp. not
157 * VINF_CPUM_R3_MSR_WRITE. Only the following two:
158 * @retval VINF_SUCCESS
159 * @retval VERR_CPUM_RAISE_GP_0
160 *
161 * @param pVCpu The cross context virtual CPU structure.
162 * @param u64BaseMsr The value to set.
163 */
164 DECLR3CALLBACKMEMBER(int, pfnSetBaseMsr, (PVMCPUCC pVCpu, uint64_t u64BaseMsr));
165
166 /**
167 * Reads a 32-bit register at a specified offset.
168 *
169 * @returns The value at the specified offset.
170 * @param pVCpu The cross context virtual CPU structure.
171 * @param offReg The offset of the register being read.
172 */
173 DECLR3CALLBACKMEMBER(uint32_t, pfnReadRaw32, (PCVMCPUCC pVCpu, uint16_t offReg));
174
175 /**
176 * Reads an APIC MSR.
177 *
178 * @returns Strict VBox status code.
179 * @param pVCpu The cross context virtual CPU structure.
180 * @param u32Reg The MSR being read.
181 * @param pu64Value Where to store the read value.
182 */
183 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsr, (PVMCPUCC pVCpu, uint32_t u32Reg, uint64_t *pu64Value));
184
185 /**
186 * Writes an APIC MSR.
187 *
188 * @returns Strict VBox status code.
189 * @param pVCpu The cross context virtual CPU structure.
190 * @param u32Reg The MSR being written.
191 * @param u64Value The value to write.
192 */
193 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsr, (PVMCPUCC pVCpu, uint32_t u32Reg, uint64_t u64Value));
194
195 /**
196 * Gets the APIC TPR (Task Priority Register).
197 *
198 * @returns VBox status code.
199 * @param pVCpu The cross context virtual CPU structure.
200 * @param pu8Tpr Where to store the TPR.
201 * @param pfPending Where to store whether there is a pending interrupt
202 * (optional, can be NULL).
203 * @param pu8PendingIntr Where to store the highest-priority pending interrupt
204 * (optional, can be NULL).
205 */
206 DECLR3CALLBACKMEMBER(int, pfnGetTpr, (PCVMCPUCC pVCpu, uint8_t *pu8Tpr, bool *pfPending, uint8_t *pu8PendingIntr));
207
208 /**
209 * Sets the TPR (Task Priority Register).
210 *
211 * @retval VINF_SUCCESS
212 * @retval VERR_CPUM_RAISE_GP_0
213 * @retval VERR_PDM_NO_APIC_INSTANCE
214 *
215 * @param pVCpu The cross context virtual CPU structure.
216 * @param u8Tpr The TPR value to set.
217 * @param fForceX2ApicBehaviour Pretend the APIC is in x2APIC mode during this
218 * write.
219 */
220 DECLR3CALLBACKMEMBER(int, pfnSetTpr, (PVMCPUCC pVCpu, uint8_t u8Tpr, bool fForceX2ApicBehaviour));
221
222 /**
223 * Gets the Interrupt Command Register (ICR), without performing any interface
224 * checks.
225 *
226 * @returns The ICR value.
227 * @param pVCpu The cross context virtual CPU structure.
228 */
229 DECLR3CALLBACKMEMBER(uint64_t, pfnGetIcrNoCheck, (PVMCPUCC pVCpu));
230
231 /**
232 * Sets the Interrupt Command Register (ICR).
233 *
234 * @returns Strict VBox status code.
235 * @param pVCpu The cross context virtual CPU structure.
236 * @param u64Icr The ICR (High and Low combined).
237 * @param rcRZ The return code if the operation cannot be performed
238 * in the current context.
239 *
240 * @remarks This function is used by both x2APIC interface and the Hyper-V
241 * interface, see APICHvSetIcr. The Hyper-V spec isn't clear what
242 * happens when invalid bits are set. For the time being, it will
243 * \#GP like a regular x2APIC access.
244 */
245 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnSetIcr, (PVMCPUCC pVCpu, uint64_t uIcr, int rcRZ));
246
247 /**
248 * Gets the APIC timer frequency.
249 *
250 * @returns Strict VBox status code.
251 * @param pVM The cross context VM structure.
252 * @param pu64Value Where to store the timer frequency.
253 */
254 DECLR3CALLBACKMEMBER(int, pfnGetTimerFreq, (PVMCC pVM, uint64_t *pu64Value));
255
256 /**
257 * Assert/de-assert the local APIC's LINT0/LINT1 interrupt pins.
258 *
259 * @returns Strict VBox status code.
260 * @param pVCpu The cross context virtual CPU structure.
261 * @param u8Pin The interrupt pin (0 for LINT0 or 1 for LINT1).
262 * @param u8Level The level (0 for low or 1 for high).
263 * @param rcRZ The return code if the operation cannot be performed in
264 * the current context.
265 *
266 * @note All callers totally ignores the status code!
267 */
268 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnSetLocalInterrupt, (PVMCPUCC pVCpu, uint8_t u8Pin, uint8_t u8Level, int rcRZ));
269
270 /**
271 * Gets the next highest-priority interrupt from the APIC, marking it as an
272 * "in-service" interrupt.
273 *
274 * @returns VBox status code.
275 * @param pVCpu The cross context virtual CPU structure.
276 * @param pu8Vector Where to store the vector.
277 * @param puSrcTag Where to store the interrupt source tag (debugging).
278 */
279 DECLR3CALLBACKMEMBER(int, pfnGetInterrupt, (PVMCPUCC pVCpu, uint8_t *pu8Vector, uint32_t *puSrcTag));
280
281 /**
282 * Posts an interrupt to a target APIC.
283 *
284 * This function handles interrupts received from the system bus or
285 * interrupts generated locally from the LVT or via a self IPI.
286 *
287 * Don't use this function to try and deliver ExtINT style interrupts.
288 *
289 * @returns true if the interrupt was accepted, false otherwise.
290 * @param pVCpu The cross context virtual CPU structure.
291 * @param uVector The vector of the interrupt to be posted.
292 * @param fAutoEoi Whether this interrupt has automatic EOI
293 * treatment.
294 * @param enmTriggerMode The trigger mode of the interrupt.
295 * @param uSrcTag The interrupt source tag (debugging).
296 *
297 * @thread Any.
298 */
299 DECLR3CALLBACKMEMBER(bool, pfnPostInterrupt, (PVMCPUCC pVCpu, uint8_t uVector, XAPICTRIGGERMODE enmTriggerMode, bool fAutoEoi,
300 uint32_t uSrcTag));
301
302 /**
303 * Updating pending interrupts into the IRR if required.
304 *
305 * @param pVCpu The cross context virtual CPU structure.
306 */
307 DECLR3CALLBACKMEMBER(void, pfnUpdatePendingInterrupts, (PVMCPUCC pVCpu));
308
309 /**
310 * Delivers an interrupt message via the system bus.
311 *
312 * @returns VBox status code.
313 * @param pVM The cross context VM structure.
314 * @param uDest The destination mask.
315 * @param uDestMode The destination mode.
316 * @param uDeliveryMode The delivery mode.
317 * @param uVector The interrupt vector.
318 * @param uPolarity The interrupt line polarity.
319 * @param uTriggerMode The trigger mode.
320 * @param uSrcTag The interrupt source tag (debugging).
321 */
322 DECLR3CALLBACKMEMBER(int, pfnBusDeliver, (PVMCC pVM, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode, uint8_t uVector,
323 uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uSrcTag));
324
325 /**
326 * Sets the End-Of-Interrupt (EOI) register.
327 *
328 * @returns Strict VBox status code.
329 * @param pVCpu The cross context virtual CPU structure.
330 * @param uEoi The EOI value.
331 * @param fForceX2ApicBehaviour Pretend the APIC is in x2APIC mode during
332 * this write.
333 */
334 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnSetEoi, (PVMCPUCC pVCpu, uint32_t uEoi, bool fForceX2ApicBehaviour));
335
336 /**
337 * Sets whether Hyper-V compatibility mode (MSR interface) is enabled or not.
338 * @see APICR3HvSetCompatMode for details.
339 *
340 * @returns VBox status code.
341 * @param pVM The cross context VM structure.
342 * @param fHyperVCompatMode Whether the compatibility mode is enabled.
343 */
344 DECLR3CALLBACKMEMBER(int, pfnHvSetCompatMode, (PVMCC pVM, bool fHyperVCompatMode));
345
346 /** @name Reserved for future (MBZ).
347 * @{ */
348 DECLR3CALLBACKMEMBER(int, pfnReserved0, (void));
349 DECLR3CALLBACKMEMBER(int, pfnReserved1, (void));
350 DECLR3CALLBACKMEMBER(int, pfnReserved2, (void));
351 DECLR3CALLBACKMEMBER(int, pfnReserved3, (void));
352 DECLR3CALLBACKMEMBER(int, pfnReserved4, (void));
353 DECLR3CALLBACKMEMBER(int, pfnReserved5, (void));
354 DECLR3CALLBACKMEMBER(int, pfnReserved6, (void));
355 DECLR3CALLBACKMEMBER(int, pfnReserved7, (void));
356 DECLR3CALLBACKMEMBER(int, pfnReserved8, (void));
357 DECLR3CALLBACKMEMBER(int, pfnReserved9, (void));
358 /** @} */
359} PDMAPICBACKENDR3;
360/** Pointer to ring-3 APIC backend. */
361typedef R3PTRTYPE(struct PDMAPICBACKENDR3 *) PPDMAPICBACKENDR3;
362/** Const pointer to ring-3 APIC backend. */
363typedef R3PTRTYPE(const struct PDMAPICBACKENDR3 *) PCPDMAPICBACKENDR3;
364AssertCompileSizeAlignment(PDMAPICBACKENDR3, 8);
365
366/**
367 * PDM APIC backend ring-0 API.
368 */
369typedef struct PDMAPICBACKENDR0
370{
371 /**
372 * Returns whether the APIC is hardware enabled or not.
373 *
374 * @returns true if enabled, false otherwise.
375 * @param pVCpu The cross context virtual CPU structure.
376 */
377 DECLR0CALLBACKMEMBER(bool, pfnIsEnabled, (PCVMCPUCC pVCpu));
378
379 /**
380 * Initializes per-VCPU APIC to the state following an INIT reset
381 * ("Wait-for-SIPI" state).
382 *
383 * @param pVCpu The cross context virtual CPU structure.
384 */
385 DECLR0CALLBACKMEMBER(void, pfnInitIpi, (PVMCPUCC pVCpu));
386
387 /**
388 * Gets the APIC base MSR (no checks are performed wrt APIC hardware or its
389 * state).
390 *
391 * @returns The base MSR value.
392 * @param pVCpu The cross context virtual CPU structure.
393 */
394 DECLR0CALLBACKMEMBER(uint64_t, pfnGetBaseMsrNoCheck, (PCVMCPUCC pVCpu));
395
396 /**
397 * Gets the APIC base MSR.
398 *
399 * @returns Strict VBox status code.
400 * @param pVCpu The cross context virtual CPU structure.
401 * @param pu64Value Where to store the MSR value.
402 */
403 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnGetBaseMsr, (PVMCPUCC pVCpu, uint64_t *pu64Value));
404
405 /**
406 * Sets the APIC base MSR.
407 *
408 * @returns VBox status code.
409 * @param pVCpu The cross context virtual CPU structure.
410 * @param u64BaseMsr The value to set.
411 */
412 DECLR0CALLBACKMEMBER(int, pfnSetBaseMsr, (PVMCPUCC pVCpu, uint64_t u64BaseMsr));
413
414 /**
415 * Reads a 32-bit register at a specified offset.
416 *
417 * @returns The value at the specified offset.
418 * @param pVCpu The cross context virtual CPU structure.
419 * @param offReg The offset of the register being read.
420 */
421 DECLR0CALLBACKMEMBER(uint32_t, pfnReadRaw32, (PCVMCPUCC pVCpu, uint16_t offReg));
422
423 /**
424 * Reads an APIC MSR.
425 *
426 * @returns Strict VBox status code.
427 * @param pVCpu The cross context virtual CPU structure.
428 * @param u32Reg The MSR being read.
429 * @param pu64Value Where to store the read value.
430 */
431 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsr, (PVMCPUCC pVCpu, uint32_t u32Reg, uint64_t *pu64Value));
432
433 /**
434 * Writes an APIC MSR.
435 *
436 * @returns Strict VBox status code.
437 * @param pVCpu The cross context virtual CPU structure.
438 * @param u32Reg The MSR being written.
439 * @param u64Value The value to write.
440 */
441 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsr, (PVMCPUCC pVCpu, uint32_t u32Reg, uint64_t u64Value));
442
443 /**
444 * Gets the APIC TPR (Task Priority Register).
445 *
446 * @returns VBox status code.
447 * @param pVCpu The cross context virtual CPU structure.
448 * @param pu8Tpr Where to store the TPR.
449 * @param pfPending Where to store whether there is a pending interrupt
450 * (optional, can be NULL).
451 * @param pu8PendingIntr Where to store the highest-priority pending interrupt
452 * (optional, can be NULL).
453 */
454 DECLR0CALLBACKMEMBER(int, pfnGetTpr, (PCVMCPUCC pVCpu, uint8_t *pu8Tpr, bool *pfPending, uint8_t *pu8PendingIntr));
455
456 /**
457 * Sets the TPR (Task Priority Register).
458 *
459 * @retval VINF_SUCCESS
460 * @retval VERR_CPUM_RAISE_GP_0
461 * @retval VERR_PDM_NO_APIC_INSTANCE
462 *
463 * @param pVCpu The cross context virtual CPU structure.
464 * @param u8Tpr The TPR value to set.
465 * @param fForceX2ApicBehaviour Pretend the APIC is in x2APIC mode during this
466 * write.
467 */
468 DECLR0CALLBACKMEMBER(int, pfnSetTpr, (PVMCPUCC pVCpu, uint8_t u8Tpr, bool fForceX2ApicBehaviour));
469
470 /**
471 * Gets the Interrupt Command Register (ICR), without performing any interface
472 * checks.
473 *
474 * @returns The ICR value.
475 * @param pVCpu The cross context virtual CPU structure.
476 */
477 DECLR0CALLBACKMEMBER(uint64_t, pfnGetIcrNoCheck, (PVMCPUCC pVCpu));
478
479 /**
480 * Sets the Interrupt Command Register (ICR).
481 *
482 * @returns Strict VBox status code.
483 * @param pVCpu The cross context virtual CPU structure.
484 * @param u64Icr The ICR (High and Low combined).
485 * @param rcRZ The return code if the operation cannot be performed
486 * in the current context.
487 *
488 * @remarks This function is used by both x2APIC interface and the Hyper-V
489 * interface, see APICHvSetIcr. The Hyper-V spec isn't clear what
490 * happens when invalid bits are set. For the time being, it will
491 * \#GP like a regular x2APIC access.
492 */
493 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnSetIcr, (PVMCPUCC pVCpu, uint64_t uIcr, int rcRZ));
494
495 /**
496 * Gets the APIC timer frequency.
497 *
498 * @returns Strict VBox status code.
499 * @param pVM The cross context VM structure.
500 * @param pu64Value Where to store the timer frequency.
501 */
502 DECLR0CALLBACKMEMBER(int, pfnGetTimerFreq, (PVMCC pVM, uint64_t *pu64Value));
503
504 /**
505 * Assert/de-assert the local APIC's LINT0/LINT1 interrupt pins.
506 *
507 * @returns Strict VBox status code.
508 * @param pVCpu The cross context virtual CPU structure.
509 * @param u8Pin The interrupt pin (0 for LINT0 or 1 for LINT1).
510 * @param u8Level The level (0 for low or 1 for high).
511 * @param rcRZ The return code if the operation cannot be performed in
512 * the current context.
513 *
514 * @note All callers totally ignores the status code!
515 */
516 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnSetLocalInterrupt, (PVMCPUCC pVCpu, uint8_t u8Pin, uint8_t u8Level, int rcRZ));
517
518 /**
519 * Gets the next highest-priority interrupt from the APIC, marking it as an
520 * "in-service" interrupt.
521 *
522 * @returns VBox status code.
523 * @param pVCpu The cross context virtual CPU structure.
524 * @param pu8Vector Where to store the vector.
525 * @param puSrcTag Where to store the interrupt source tag (debugging).
526 */
527 DECLR0CALLBACKMEMBER(int, pfnGetInterrupt, (PVMCPUCC pVCpu, uint8_t *pu8Vector, uint32_t *puTagSrc));
528
529 /**
530 * Posts an interrupt to a target APIC.
531 *
532 * This function handles interrupts received from the system bus or
533 * interrupts generated locally from the LVT or via a self IPI.
534 *
535 * Don't use this function to try and deliver ExtINT style interrupts.
536 *
537 * @returns true if the interrupt was accepted, false otherwise.
538 * @param pVCpu The cross context virtual CPU structure.
539 * @param uVector The vector of the interrupt to be posted.
540 * @param fAutoEoi Whether this interrupt has automatic EOI
541 * treatment.
542 * @param enmTriggerMode The trigger mode of the interrupt.
543 * @param uSrcTag The interrupt source tag (debugging).
544 *
545 * @thread Any.
546 */
547 DECLR0CALLBACKMEMBER(bool, pfnPostInterrupt, (PVMCPUCC pVCpu, uint8_t uVector, XAPICTRIGGERMODE enmTriggerMode, bool fAutoEoi,
548 uint32_t uSrcTag));
549
550 /**
551 * Updating pending interrupts into the IRR if required.
552 *
553 * @param pVCpu The cross context virtual CPU structure.
554 */
555 DECLR0CALLBACKMEMBER(void, pfnUpdatePendingInterrupts, (PVMCPUCC pVCpu));
556
557 /**
558 * Delivers an interrupt message via the system bus.
559 *
560 * @returns VBox status code.
561 * @param pVM The cross context VM structure.
562 * @param uDest The destination mask.
563 * @param uDestMode The destination mode.
564 * @param uDeliveryMode The delivery mode.
565 * @param uVector The interrupt vector.
566 * @param uPolarity The interrupt line polarity.
567 * @param uTriggerMode The trigger mode.
568 * @param uSrcTag The interrupt source tag (debugging).
569 */
570 DECLR0CALLBACKMEMBER(int, pfnBusDeliver, (PVMCC pVM, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode, uint8_t uVector,
571 uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uSrcTag));
572
573 /**
574 * Sets the End-Of-Interrupt (EOI) register.
575 *
576 * @returns Strict VBox status code.
577 * @param pVCpu The cross context virtual CPU structure.
578 * @param uEoi The EOI value.
579 * @param fForceX2ApicBehaviour Pretend the APIC is in x2APIC mode during
580 * this write.
581 */
582 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnSetEoi, (PVMCPUCC pVCpu, uint32_t uEoi, bool fForceX2ApicBehaviour));
583
584 /**
585 * Gets the APIC page pointers for the specified VCPU.
586 *
587 * @returns VBox status code.
588 * @param pVCpu The cross context virtual CPU structure.
589 * @param pHCPhys Where to store the host-context physical address.
590 * @param pR0Ptr Where to store the ring-0 address.
591 * @param pR3Ptr Where to store the ring-3 address (optional).
592 */
593 DECLR0CALLBACKMEMBER(int, pfnGetApicPageForCpu, (PCVMCPUCC pVCpu, PRTHCPHYS pHCPhys, PRTR0PTR pR0Ptr, PRTR3PTR pR3Ptr));
594
595 /** @name Reserved for future (MBZ).
596 * @{ */
597 DECLR0CALLBACKMEMBER(int, pfnReserved0, (void));
598 DECLR0CALLBACKMEMBER(int, pfnReserved1, (void));
599 DECLR0CALLBACKMEMBER(int, pfnReserved2, (void));
600 DECLR0CALLBACKMEMBER(int, pfnReserved3, (void));
601 DECLR0CALLBACKMEMBER(int, pfnReserved4, (void));
602 DECLR0CALLBACKMEMBER(int, pfnReserved5, (void));
603 DECLR0CALLBACKMEMBER(int, pfnReserved6, (void));
604 DECLR0CALLBACKMEMBER(int, pfnReserved7, (void));
605 DECLR0CALLBACKMEMBER(int, pfnReserved8, (void));
606 DECLR0CALLBACKMEMBER(int, pfnReserved9, (void));
607 /** @} */
608} PDMAPICBACKENDR0;
609/** Pointer to ring-0 APIC backend. */
610typedef R0PTRTYPE(struct PDMAPICBACKENDR0 *) PPDMAPICBACKENDR0;
611/** Const pointer to ring-0 APIC backend. */
612typedef R0PTRTYPE(const struct PDMAPICBACKENDR0 *) PCPDMAPICBACKENDR0;
613AssertCompileSizeAlignment(PDMAPICBACKENDR0, 8);
614
615/**
616 * PDM APIC backend RC API.
617 */
618typedef struct PDMAPICBACKENDRC
619{
620 /**
621 * Returns whether the APIC is hardware enabled or not.
622 *
623 * @returns true if enabled, false otherwise.
624 * @param pVCpu The cross context virtual CPU structure.
625 */
626 DECLRCCALLBACKMEMBER(bool, pfnIsEnabled, (PCVMCPUCC pVCpu));
627
628 /**
629 * Initializes per-VCPU APIC to the state following an INIT reset
630 * ("Wait-for-SIPI" state).
631 *
632 * @param pVCpu The cross context virtual CPU structure.
633 */
634 DECLRCCALLBACKMEMBER(void, pfnInitIpi, (PVMCPUCC pVCpu));
635
636 /**
637 * Gets the APIC base MSR (no checks are performed wrt APIC hardware or its
638 * state).
639 *
640 * @returns The base MSR value.
641 * @param pVCpu The cross context virtual CPU structure.
642 */
643 DECLRCCALLBACKMEMBER(uint64_t, pfnGetBaseMsrNoCheck, (PCVMCPUCC pVCpu));
644
645 /**
646 * Gets the APIC base MSR.
647 *
648 * @returns Strict VBox status code.
649 * @param pVCpu The cross context virtual CPU structure.
650 * @param pu64Value Where to store the MSR value.
651 */
652 DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnGetBaseMsr, (PVMCPUCC pVCpu, uint64_t *pu64Value));
653
654 /**
655 * Sets the APIC base MSR.
656 *
657 * @returns VBox status code.
658 * @param pVCpu The cross context virtual CPU structure.
659 * @param u64BaseMsr The value to set.
660 */
661 DECLRCCALLBACKMEMBER(int, pfnSetBaseMsr, (PVMCPUCC pVCpu, uint64_t u64BaseMsr));
662
663 /**
664 * Reads a 32-bit register at a specified offset.
665 *
666 * @returns The value at the specified offset.
667 * @param pVCpu The cross context virtual CPU structure.
668 * @param offReg The offset of the register being read.
669 */
670 DECLRCCALLBACKMEMBER(uint32_t, pfnReadRaw32, (PCVMCPUCC pVCpu, uint16_t offReg));
671
672 /**
673 * Reads an APIC MSR.
674 *
675 * @returns Strict VBox status code.
676 * @param pVCpu The cross context virtual CPU structure.
677 * @param u32Reg The MSR being read.
678 * @param pu64Value Where to store the read value.
679 */
680 DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsr, (PVMCPUCC pVCpu, uint32_t u32Reg, uint64_t *pu64Value));
681
682 /**
683 * Writes an APIC MSR.
684 *
685 * @returns Strict VBox status code.
686 * @param pVCpu The cross context virtual CPU structure.
687 * @param u32Reg The MSR being written.
688 * @param u64Value The value to write.
689 */
690 DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsr, (PVMCPUCC pVCpu, uint32_t u32Reg, uint64_t u64Value));
691
692 /**
693 * Gets the APIC TPR (Task Priority Register).
694 *
695 * @returns VBox status code.
696 * @param pVCpu The cross context virtual CPU structure.
697 * @param pu8Tpr Where to store the TPR.
698 * @param pfPending Where to store whether there is a pending interrupt
699 * (optional, can be NULL).
700 * @param pu8PendingIntr Where to store the highest-priority pending interrupt
701 * (optional, can be NULL).
702 */
703 DECLRCCALLBACKMEMBER(int, pfnGetTpr, (PCVMCPUCC pVCpu, uint8_t *pu8Tpr, bool *pfPending, uint8_t *pu8PendingIntr));
704
705 /**
706 * Sets the TPR (Task Priority Register).
707 *
708 * @retval VINF_SUCCESS
709 * @retval VERR_CPUM_RAISE_GP_0
710 * @retval VERR_PDM_NO_APIC_INSTANCE
711 *
712 * @param pVCpu The cross context virtual CPU structure.
713 * @param u8Tpr The TPR value to set.
714 * @param fForceX2ApicBehaviour Pretend the APIC is in x2APIC mode during this
715 * write.
716 */
717 DECLRCCALLBACKMEMBER(int, pfnSetTpr, (PVMCPUCC pVCpu, uint8_t u8Tpr, bool fForceX2ApicBehaviour));
718
719 /**
720 * Gets the Interrupt Command Register (ICR), without performing any interface
721 * checks.
722 *
723 * @returns The ICR value.
724 * @param pVCpu The cross context virtual CPU structure.
725 */
726 DECLRCCALLBACKMEMBER(uint64_t, pfnGetIcrNoCheck, (PVMCPUCC pVCpu));
727
728 /**
729 * Sets the Interrupt Command Register (ICR).
730 *
731 * @returns Strict VBox status code.
732 * @param pVCpu The cross context virtual CPU structure.
733 * @param u64Icr The ICR (High and Low combined).
734 * @param rcRZ The return code if the operation cannot be performed
735 * in the current context.
736 *
737 * @remarks This function is used by both x2APIC interface and the Hyper-V
738 * interface, see APICHvSetIcr. The Hyper-V spec isn't clear what
739 * happens when invalid bits are set. For the time being, it will
740 * \#GP like a regular x2APIC access.
741 */
742 DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnSetIcr, (PVMCPUCC pVCpu, uint64_t uIcr, int rcRZ));
743
744 /**
745 * Gets the APIC timer frequency.
746 *
747 * @returns Strict VBox status code.
748 * @param pVM The cross context VM structure.
749 * @param pu64Value Where to store the timer frequency.
750 */
751 DECLRCCALLBACKMEMBER(int, pfnGetTimerFreq, (PVMCC pVM, uint64_t *pu64Value));
752
753 /**
754 * Assert/de-assert the local APIC's LINT0/LINT1 interrupt pins.
755 *
756 * @returns Strict VBox status code.
757 * @param pVCpu The cross context virtual CPU structure.
758 * @param u8Pin The interrupt pin (0 for LINT0 or 1 for LINT1).
759 * @param u8Level The level (0 for low or 1 for high).
760 * @param rcRZ The return code if the operation cannot be performed in
761 * the current context.
762 *
763 * @note All callers totally ignores the status code!
764 */
765 DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnSetLocalInterrupt, (PVMCPUCC pVCpu, uint8_t u8Pin, uint8_t u8Level, int rcRZ));
766
767 /**
768 * Gets the next highest-priority interrupt from the APIC, marking it as an
769 * "in-service" interrupt.
770 *
771 * @returns VBox status code.
772 * @param pVCpu The cross context virtual CPU structure.
773 * @param pu8Vector Where to store the vector.
774 * @param puSrcTag Where to store the interrupt source tag (debugging).
775 */
776 DECLRCCALLBACKMEMBER(int, pfnGetInterrupt, (PVMCPUCC pVCpu, uint8_t *pu8Vector, uint32_t *puTagSrc));
777
778 /**
779 * Posts an interrupt to a target APIC.
780 *
781 * This function handles interrupts received from the system bus or
782 * interrupts generated locally from the LVT or via a self IPI.
783 *
784 * Don't use this function to try and deliver ExtINT style interrupts.
785 *
786 * @returns true if the interrupt was accepted, false otherwise.
787 * @param pVCpu The cross context virtual CPU structure.
788 * @param uVector The vector of the interrupt to be posted.
789 * @param fAutoEoi Whether this interrupt has automatic EOI
790 * treatment.
791 * @param enmTriggerMode The trigger mode of the interrupt.
792 * @param uSrcTag The interrupt source tag (debugging).
793 *
794 * @thread Any.
795 */
796 DECLRCCALLBACKMEMBER(bool, pfnPostInterrupt, (PVMCPUCC pVCpu, uint8_t uVector, XAPICTRIGGERMODE enmTriggerMode, bool fAutoEoi,
797 uint32_t uSrcTag));
798
799 /**
800 * Updating pending interrupts into the IRR if required.
801 *
802 * @param pVCpu The cross context virtual CPU structure.
803 */
804 DECLRCCALLBACKMEMBER(void, pfnUpdatePendingInterrupts, (PVMCPUCC pVCpu));
805
806 /**
807 * Delivers an interrupt message via the system bus.
808 *
809 * @returns VBox status code.
810 * @param pVM The cross context VM structure.
811 * @param uDest The destination mask.
812 * @param uDestMode The destination mode.
813 * @param uDeliveryMode The delivery mode.
814 * @param uVector The interrupt vector.
815 * @param uPolarity The interrupt line polarity.
816 * @param uTriggerMode The trigger mode.
817 * @param uSrcTag The interrupt source tag (debugging).
818 */
819 DECLRCCALLBACKMEMBER(int, pfnBusDeliver, (PVMCC pVM, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode, uint8_t uVector,
820 uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uSrcTag));
821
822 /**
823 * Sets the End-Of-Interrupt (EOI) register.
824 *
825 * @returns Strict VBox status code.
826 * @param pVCpu The cross context virtual CPU structure.
827 * @param uEoi The EOI value.
828 * @param fForceX2ApicBehaviour Pretend the APIC is in x2APIC mode during
829 * this write.
830 */
831 DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnSetEoi, (PVMCPUCC pVCpu, uint32_t uEoi, bool fForceX2ApicBehaviour));
832
833 /** @name Reserved for future (MBZ).
834 * @{ */
835 DECLRCCALLBACKMEMBER(int, pfnReserved0, (void));
836 DECLRCCALLBACKMEMBER(int, pfnReserved1, (void));
837 DECLRCCALLBACKMEMBER(int, pfnReserved2, (void));
838 DECLRCCALLBACKMEMBER(int, pfnReserved3, (void));
839 DECLRCCALLBACKMEMBER(int, pfnReserved4, (void));
840 DECLRCCALLBACKMEMBER(int, pfnReserved5, (void));
841 DECLRCCALLBACKMEMBER(int, pfnReserved6, (void));
842 DECLRCCALLBACKMEMBER(int, pfnReserved7, (void));
843 DECLRCCALLBACKMEMBER(int, pfnReserved8, (void));
844 DECLRCCALLBACKMEMBER(int, pfnReserved9, (void));
845 DECLRCCALLBACKMEMBER(int, pfnReserved10, (void));
846 DECLRCCALLBACKMEMBER(int, pfnReserved11, (void));
847 DECLRCCALLBACKMEMBER(int, pfnReserved12, (void));
848 /** @} */
849} PDMAPICBACKENDRC;
850/** Pointer to raw-mode context APIC backend. */
851typedef RCPTRTYPE(struct PDMAPICBACKENDRC *) PPDMAPICBACKENDRC;
852/** Const pointer to raw-mode context APIC backend. */
853typedef RCPTRTYPE(const struct PDMAPICBACKENDRC *) PCPDMAPICBACKENDRC;
854AssertCompileSizeAlignment(PDMAPICBACKENDRC, 8);
855AssertCompile(sizeof(PDMAPICBACKENDR3) == sizeof(PDMAPICBACKENDR0));
856
857/** @typedef PDMAPICBACKENDR3
858 * A current context PDM APIC backend. */
859/** @typedef PPDMAPICBACKENDR3
860 * Pointer to a current context PDM APIC backend. */
861/** @typedef PCPDMAPICBACKENDR3
862 * Pointer to a const current context PDM APIC backend. */
863#if defined(IN_RING3) || defined(DOXYGEN_RUNNING)
864typedef PDMAPICBACKENDR3 PDMAPICBACKEND;
865typedef PPDMAPICBACKENDR3 PPDMAPICBACKEND;
866typedef PCPDMAPICBACKENDR3 PCPDMAPICBACKEND;
867#elif defined(IN_RING0)
868typedef PDMAPICBACKENDR0 PDMAPICBACKEND;
869typedef PPDMAPICBACKENDR0 PPDMAPICBACKEND;
870typedef PCPDMAPICBACKENDR0 PCPDMAPICBACKEND;
871#elif defined(IN_RC)
872typedef PDMAPICBACKENDRC PDMAPICBACKEND;
873typedef PPDMAPICBACKENDRC PPDMAPICBACKEND;
874typedef PCPDMAPICBACKENDRC PCPDMAPICBACKEND;
875#else
876# error "Not IN_RING3, IN_RING0 or IN_RC"
877#endif
878
879VMM_INT_DECL(int) PDMApicRegisterBackend(PVMCC pVM, PDMAPICBACKENDTYPE enmBackendType, PCPDMAPICBACKEND pBackend);
880
881VMM_INT_DECL(void) PDMApicUpdatePendingInterrupts(PVMCPUCC pVCpu);
882VMM_INT_DECL(int) PDMApicGetTpr(PCVMCPUCC pVCpu, uint8_t *pu8Tpr, bool *pfPending, uint8_t *pu8PendingIntr);
883VMM_INT_DECL(int) PDMApicSetTpr(PVMCPUCC pVCpu, uint8_t u8Tpr);
884VMM_INT_DECL(bool) PDMApicIsEnabled(PCVMCPUCC pVCpu);
885VMM_INT_DECL(VBOXSTRICTRC) PDMApicReadMsr(PVMCPUCC pVCpu, uint32_t u32Reg, uint64_t *pu64Value);
886VMM_INT_DECL(VBOXSTRICTRC) PDMApicWriteMsr(PVMCPUCC pVCpu, uint32_t u32Reg, uint64_t u64Value);
887VMM_INT_DECL(int) PDMApicGetTimerFreq(PVMCC pVM, uint64_t *pu64Value);
888VMM_INT_DECL(VBOXSTRICTRC) PDMApicSetLocalInterrupt(PVMCPUCC pVCpu, uint8_t u8Pin, uint8_t u8Level, int rcRZ);
889VMM_INT_DECL(uint64_t) PDMApicGetBaseMsrNoCheck(PCVMCPUCC pVCpu);
890VMM_INT_DECL(VBOXSTRICTRC) PDMApicGetBaseMsr(PVMCPUCC pVCpu, uint64_t *pu64Value);
891VMM_INT_DECL(int) PDMApicSetBaseMsr(PVMCPUCC pVCpu, uint64_t u64BaseMsr);
892VMM_INT_DECL(int) PDMApicGetInterrupt(PVMCPUCC pVCpu, uint8_t *pu8Vector, uint32_t *puSrcTag);
893VMM_INT_DECL(int) PDMApicBusDeliver(PVMCC pVM, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode, uint8_t uVector,
894 uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uTagSrc);
895#ifdef IN_RING0
896VMM_INT_DECL(int) PDMR0ApicGetApicPageForCpu(PCVMCPUCC pVCpu, PRTHCPHYS pHCPhys, PRTR0PTR pR0Ptr, PRTR3PTR pR3Ptr);
897#endif
898
899/** @name Hyper-V interface (Ring-3 and all-context API).
900 * @{ */
901#ifdef IN_RING3
902VMMR3_INT_DECL(int) PDMR3ApicHvSetCompatMode(PVM pVM, bool fHyperVCompatMode);
903#endif
904VMM_INT_DECL(void) PDMApicHvSendInterrupt(PVMCPUCC pVCpu, uint8_t uVector, bool fAutoEoi, XAPICTRIGGERMODE enmTriggerMode);
905VMM_INT_DECL(VBOXSTRICTRC) PDMApicHvSetTpr(PVMCPUCC pVCpu, uint8_t uTpr);
906VMM_INT_DECL(uint8_t) PDMApicHvGetTpr(PVMCPUCC pVCpu);
907VMM_INT_DECL(VBOXSTRICTRC) PDMApicHvSetIcr(PVMCPUCC pVCpu, uint64_t uIcr);
908VMM_INT_DECL(uint64_t) PDMApicHvGetIcr(PVMCPUCC pVCpu);
909VMM_INT_DECL(VBOXSTRICTRC) PDMApicHvSetEoi(PVMCPUCC pVCpu, uint32_t uEoi);
910/** @} */
911
912#ifdef IN_RING3
913/** @defgroup grp_pdm_apic_r3 The PDM APIC Host Context Ring-3 API
914 * @{
915 */
916VMMR3_INT_DECL(void) PDMR3ApicInitIpi(PVMCPU pVCpu);
917/** @} */
918#endif /* IN_RING3 */
919
920RT_C_DECLS_END
921
922/** @} */
923
924#endif /* !VBOX_INCLUDED_vmm_pdmapic_h */
925
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