VirtualBox

source: vbox/trunk/src/VBox/VMM/include/GICInternal.h@ 109021

Last change on this file since 109021 was 109021, checked in by vboxsync, 3 weeks ago

VMM/GIC: bugref:10877 GIC ITS, work-in-progress.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.8 KB
Line 
1/* $Id: GICInternal.h 109021 2025-04-18 08:56:15Z vboxsync $ */
2/** @file
3 * GIC - Generic Interrupt Controller Architecture (GIC).
4 */
5
6/*
7 * Copyright (C) 2023-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_GICInternal_h
29#define VMM_INCLUDED_SRC_include_GICInternal_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#include <VBox/gic.h>
35#include <VBox/vmm/pdmdev.h>
36#include <VBox/vmm/pdmgic.h>
37#include <VBox/vmm/stam.h>
38
39#include "GITSInternal.h"
40
41/** @defgroup grp_gic_int Internal
42 * @ingroup grp_gic
43 * @internal
44 * @{
45 */
46
47#ifdef VBOX_INCLUDED_vmm_pdmgic_h
48/** The VirtualBox GIC backend. */
49extern const PDMGICBACKEND g_GicBackend;
50# ifdef RT_OS_DARWIN
51/** The Hypervisor.Framework GIC backend. */
52extern const PDMGICBACKEND g_GicHvfBackend;
53# elif defined(RT_OS_WINDOWS)
54/** The Hyper-V GIC backend. */
55extern const PDMGICBACKEND g_GicHvBackend;
56# elif defined(RT_OS_LINUX)
57/** The KVM GIC backend. */
58extern const PDMGICBACKEND g_GicKvmBackend;
59# endif
60#endif
61
62#define VMCPU_TO_GICCPU(a_pVCpu) (&(a_pVCpu)->gic.s)
63#define VM_TO_GIC(a_pVM) (&(a_pVM)->gic.s)
64#define VM_TO_GICDEV(a_pVM) CTX_SUFF(VM_TO_GIC(a_pVM)->pGicDev)
65#define GICDEV_TO_GITSDEV(a_GicDev) (&(a_GicDev)->Gits)
66#ifdef IN_RING3
67# define VMCPU_TO_DEVINS(a_pVCpu) ((a_pVCpu)->pVMR3->gic.s.pDevInsR3)
68#elif defined(IN_RING0)
69# error "Not implemented!"
70#endif
71
72/** Acquire the device critical section. */
73#define GIC_CRIT_SECT_ENTER(a_pDevIns) \
74 do \
75 { \
76 int const rcLock = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VINF_SUCCESS); \
77 PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock); \
78 } while(0)
79
80/** Release the device critical section. */
81#define GIC_CRIT_SECT_LEAVE(a_pDevIns) PDMDevHlpCritSectLeave((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo))
82
83/** Returns whether the critical section is held. */
84#define GIC_CRIT_SECT_IS_OWNER(a_pDevIns) PDMDevHlpCritSectIsOwner((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo))
85
86/**
87 * GIC PDM instance data (per-VM).
88 */
89typedef struct GICDEV
90{
91 /** @name Distributor register state.
92 * @{
93 */
94 /** Interrupt group bitmap. */
95 uint32_t bmIntrGroup[64];
96 /** Interrupt config bitmap (edge-triggered vs level-sensitive). */
97 uint32_t bmIntrConfig[128];
98 /** Interrupt enabled bitmap. */
99 uint32_t bmIntrEnabled[64];
100 /** Interrupt pending bitmap. */
101 uint32_t bmIntrPending[64];
102 /** Interrupt active bitmap. */
103 uint32_t bmIntrActive[64];
104 /** Interrupt priorities. */
105 uint8_t abIntrPriority[2048];
106 /** Interrupt routing info. */
107 uint32_t au32IntrRouting[2048];
108 /** Interrupt routine mode bitmap. */
109 uint32_t bmIntrRoutingMode[64];
110 /** Flag whether group 0 interrupts are enabled. */
111 bool fIntrGroup0Enabled;
112 /** Flag whether group 1 interrupts are enabled. */
113 bool fIntrGroup1Enabled;
114 /** Flag whether affinity routing is enabled. */
115 bool fAffRoutingEnabled;
116 /** Alignment. */
117 bool fPadding0;
118 /** @} */
119
120 /** @name Configurables.
121 * @{ */
122 /** The GIC architecture revision (GICD_PIDR2.ArchRev and GICR_PIDR2.ArchRev). */
123 uint8_t uArchRev;
124 /** The GIC architecture minor revision (currently 1 as we only support GICv3.1). */
125 uint8_t uArchRevMinor;
126 /** The maximum SPI supported (GICD_TYPER.ItLinesNumber). */
127 uint8_t uMaxSpi;
128 /** Whether extended SPIs are supported (GICD_ESPI). */
129 bool fExtSpi;
130 /** The maximum extended SPI supported (GICD_TYPER.ESPI_range). */
131 uint8_t uMaxExtSpi;
132 /** Whether extended PPIs are supported. */
133 bool fExtPpi;
134 /** The maximum extended PPI supported (GICR_TYPER.PPInum). */
135 uint8_t uMaxExtPpi;
136 /** Whether range-selector is supported (GICD_TYPER.RSS and ICC_CTLR_EL1.RSS). */
137 bool fRangeSel;
138 /** Whether NMIs are supported (GICD_TYPER.NMI). */
139 bool fNmi;
140 /** Whether message-based interrupts are supported (GICD_TYPER.MBIS). */
141 bool fMbi;
142 /** Whether non-zero affinity 3 levels are supported (GICD_TYPER.A3V) and
143 * (ICC_CTLR.A3V). */
144 bool fAff3Levels;
145 /** Whether LPIs are supported (GICD_TYPER.PLPIS). */
146 bool fLpi;
147 /** The maximum LPI supported (GICD_TYPER.num_LPI). */
148 uint8_t uMaxLpi;
149 /** Padding. */
150 bool afPadding0[3];
151 /** @} */
152
153 /** @name GITS device data and LPIs.
154 * @{ */
155 /** ITS device state. */
156 GITSDEV Gits;
157 /** LPI config table. */
158 uint8_t abLpiConfig[4096];
159 /** The LPI config table base register (GICR_PROPBASER). */
160 RTUINT64U uLpiConfigBaseReg;
161 /** The LPI pending table base register (GICR_PENDBASER). */
162 RTUINT64U uLpiPendingBaseReg;
163 /** Whether LPIs are enabled (GICR_CTLR.EnableLpis of all redistributors). */
164 bool fEnableLpis;
165 /** Padding. */
166 bool afPadding1[7];
167 /** @} */
168
169 /** @name MMIO data.
170 * @{ */
171 /** The distributor MMIO handle. */
172 IOMMMIOHANDLE hMmioDist;
173 /** The redistributor MMIO handle. */
174 IOMMMIOHANDLE hMmioReDist;
175 /** The interrupt translation service MMIO handle. */
176 IOMMMIOHANDLE hMmioGits;
177 /** @} */
178} GICDEV;
179/** Pointer to a GIC device. */
180typedef GICDEV *PGICDEV;
181/** Pointer to a const GIC device. */
182typedef GICDEV const *PCGICDEV;
183AssertCompileMemberSizeAlignment(GICDEV, Gits, 8);
184AssertCompileMemberAlignment(GICDEV, abLpiConfig, 8);
185AssertCompileMemberAlignment(GICDEV, hMmioDist, 8);
186
187/**
188 * GIC VM Instance data.
189 */
190typedef struct GIC
191{
192 /** The ring-3 device instance. */
193 PPDMDEVINSR3 pDevInsR3;
194} GIC;
195/** Pointer to GIC VM instance data. */
196typedef GIC *PGIC;
197/** Pointer to const GIC VM instance data. */
198typedef GIC const *PCGIC;
199AssertCompileSizeAlignment(GIC, 8);
200
201/**
202 * GIC VMCPU Instance data.
203 */
204typedef struct GICCPU
205{
206 /** @name Redistributor register state.
207 * @{ */
208 /** Interrupt group bitmap. */
209 uint32_t bmIntrGroup[3];
210 /** Interrupt config bitmap (edge-triggered vs level-sensitive). */
211 uint32_t bmIntrConfig[6];
212 /** Interrupt enabled bitmap. */
213 uint32_t bmIntrEnabled[3];
214 /** Interrupt pending bitmap. */
215 uint32_t bmIntrPending[3];
216 /** Interrupt active bitmap. */
217 uint32_t bmIntrActive[3];
218 /** Interrupt priorities. */
219 uint8_t abIntrPriority[96];
220 /** @} */
221
222 /** @name ICC system register state.
223 * @{ */
224 /** The control register (ICC_CTLR_EL1). */
225 uint64_t uIccCtlr;
226 /** The interrupt priority mask of the CPU interface (ICC_PMR_EL1). */
227 uint8_t bIntrPriorityMask;
228 /** The index to the current running priority. */
229 uint8_t idxRunningPriority;
230 /** The running priorities caused by preemption. */
231 uint8_t abRunningPriorities[256];
232 /** The active priorities group 0 bitmap. */
233 uint32_t bmActivePriorityGroup0[4];
234 /** The active priorities group 0 bitmap. */
235 uint32_t bmActivePriorityGroup1[4];
236 /** The binary point register for group 0 interrupts. */
237 uint8_t bBinaryPtGroup0;
238 /** The binary point register for group 1 interrupts. */
239 uint8_t bBinaryPtGroup1;
240 /** Flag whether group 0 interrupts are enabled. */
241 bool fIntrGroup0Enabled;
242 /** Flag whether group 1 interrupts are enabled. */
243 bool fIntrGroup1Enabled;
244 /** @} */
245
246 /** @name LPIs.
247 * @{ */
248 /** LPI pending bitmap. */
249 uint64_t bmLpiPending[64];
250 /** @} */
251
252 /** @name Statistics.
253 * @{ */
254#ifdef VBOX_WITH_STATISTICS
255 /** Number of MMIO reads. */
256 STAMCOUNTER StatMmioRead;
257 /** Number of MMIO writes. */
258 STAMCOUNTER StatMmioWrite;
259 /** Number of MSR reads. */
260 STAMCOUNTER StatSysRegRead;
261 /** Number of MSR writes. */
262 STAMCOUNTER StatSysRegWrite;
263 /** Number of set SPI callbacks. */
264 STAMCOUNTER StatSetSpi;
265 /** Number of set PPI callbacks. */
266 STAMCOUNTER StatSetPpi;
267 /** Number of SGIs generated. */
268 STAMCOUNTER StatSetSgi;
269
270 /** Profiling of interrupt acknowledge (IAR). */
271 STAMPROFILE StatProfIntrAck;
272 /** Profiling of set SPI callback. */
273 STAMPROFILE StatProfSetSpi;
274 /** Profiling of set PPI callback. */
275 STAMPROFILE StatProfSetPpi;
276 /** Profiling of set SGI function. */
277 STAMPROFILE StatProfSetSgi;
278#endif
279 /** @} */
280} GICCPU;
281/** Pointer to GIC VMCPU instance data. */
282typedef GICCPU *PGICCPU;
283/** Pointer to a const GIC VMCPU instance data. */
284typedef GICCPU const *PCGICCPU;
285/* Ensure the LPI pending bitmap's capacity is sufficient for the number of LPIs we support. */
286AssertCompileMemberSize(GICCPU, bmLpiPending, RT_ELEMENTS(GICDEV::abLpiConfig) / 8);
287AssertCompileMemberAlignment(GICCPU, bmLpiPending, 8);
288
289DECL_HIDDEN_CALLBACK(VBOXSTRICTRC) gicDistMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb);
290DECL_HIDDEN_CALLBACK(VBOXSTRICTRC) gicDistMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb);
291DECL_HIDDEN_CALLBACK(VBOXSTRICTRC) gicReDistMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb);
292DECL_HIDDEN_CALLBACK(VBOXSTRICTRC) gicReDistMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb);
293DECL_HIDDEN_CALLBACK(VBOXSTRICTRC) gicItsMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb);
294DECL_HIDDEN_CALLBACK(VBOXSTRICTRC) gicItsMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb);
295
296DECLHIDDEN(void) gicDistReadLpiConfigTableFromMem(PPDMDEVINS pDevIns);
297
298DECLHIDDEN(void) gicResetCpu(PPDMDEVINS pDevIns, PVMCPUCC pVCpu);
299DECLHIDDEN(void) gicReset(PPDMDEVINS pDevIns);
300DECLHIDDEN(uint16_t) gicReDistGetIntIdFromIndex(uint16_t idxIntr);
301DECLHIDDEN(uint16_t) gicDistGetIntIdFromIndex(uint16_t idxIntr);
302
303DECLCALLBACK(int) gicR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg);
304DECLCALLBACK(int) gicR3Destruct(PPDMDEVINS pDevIns);
305DECLCALLBACK(void) gicR3Reset(PPDMDEVINS pDevIns);
306
307/** @} */
308
309#endif /* !VMM_INCLUDED_SRC_include_GICInternal_h */
310
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