VirtualBox

source: vbox/trunk/include/VBox/vmm/pdmpci.h

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.1 KB
Line 
1/** @file
2 * PDM - Pluggable Device Manager, raw PCI Devices. (VMM)
3 */
4
5/*
6 * Copyright (C) 2010-2023 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_pdmpci_h
37#define VBOX_INCLUDED_vmm_pdmpci_h
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42#include <VBox/types.h>
43#include <VBox/rawpci.h>
44
45RT_C_DECLS_BEGIN
46
47/** @defgroup grp_pdm_pciraw The raw PCI Devices API
48 * @ingroup grp_pdm
49 * @{
50 */
51
52typedef struct PDMIPCIRAW *PPDMIPCIRAW;
53typedef struct PDMIPCIRAW
54{
55 /**
56 * Notify virtual device that interrupt has arrived.
57 * For this callback to be called, interface have to be
58 * registered with PDMIPCIRAWUP::pfnRegisterInterruptListener.
59 *
60 * @note no level parameter, as we can only support flip-flop.
61 *
62 * @param pInterface Pointer to this interface structure.
63 * @param iGuestIrq Guest interrupt number, passed earlier when registering listener.
64 *
65 * @thread Any thread.
66 */
67 DECLR3CALLBACKMEMBER(int, pfnInterruptRequest,(PPDMIPCIRAW pInterface, int32_t iGuestIrq));
68} PDMIPCIRAW;
69
70typedef struct PDMIPCIRAWUP *PPDMIPCIRAWUP;
71typedef struct PDMIPCIRAWUP
72{
73 /**
74 * Host PCI MMIO access function.
75 */
76
77 /**
78 * Request driver info about PCI region on host PCI device.
79 *
80 * @returns true, if region is present, and out parameters are correct
81 * @param pInterface Pointer to this interface structure.
82 * @param iRegion Region number.
83 * @param pGCPhysRegion Where to store region base address (guest).
84 * @param pcbRegion Where to store region size.
85 *
86 * @param pfFlags If region is MMIO or IO.
87 * @thread Any thread.
88 */
89 DECLR3CALLBACKMEMBER(bool, pfnGetRegionInfo, (PPDMIPCIRAWUP pInterface,
90 uint32_t iRegion,
91 RTGCPHYS *pGCPhysRegion,
92 uint64_t *pcbRegion,
93 uint32_t *pfFlags));
94
95 /**
96 * Request driver to map part of host device's MMIO region to the VM process and maybe kernel.
97 * Shall only be issued within earlier obtained with pfnGetRegionInfo()
98 * host physical address ranges for the device BARs. Even if failed, device still may function
99 * using pfnMmio* and pfnPio* operations, just much slower.
100 *
101 * @returns status code
102 * @param pInterface Pointer to this interface structure.
103 * @param iRegion Number of the region.
104 * @param StartAddress Host physical address of start.
105 * @param cbRegion Size of the region.
106 * @param fFlags Flags, currently lowest significant bit set if R0 mapping requested too
107 * @param ppvAddressR3 Where to store mapped region address for R3 (can be 0, if cannot map into userland)
108 * @param ppvAddressR0 Where to store mapped region address for R0 (can be 0, if cannot map into kernel)
109 *
110 * @thread Any thread.
111 */
112 DECLR3CALLBACKMEMBER(int, pfnMapRegion, (PPDMIPCIRAWUP pInterface,
113 uint32_t iRegion,
114 RTHCPHYS StartAddress,
115 uint64_t cbRegion,
116 uint32_t fFlags,
117 PRTR3PTR ppvAddressR3,
118 PRTR0PTR ppvAddressR0));
119
120 /**
121 * Request driver to unmap part of host device's MMIO region to the VM process.
122 * Shall only be issued with pointer earlier obtained with pfnMapRegion().
123 *
124 * @returns status code
125 * @param pInterface Pointer to this interface structure
126 * @param iRegion Number of the region.
127 * @param StartAddress Host physical address of start.
128 * @param cbRegion Size of the region.
129 * @param pvAddressR3 R3 address of mapped region.
130 * @param pvAddressR0 R0 address of mapped region.
131 *
132 * @thread Any thread.
133 */
134 DECLR3CALLBACKMEMBER(int, pfnUnmapRegion, (PPDMIPCIRAWUP pInterface,
135 uint32_t iRegion,
136 RTHCPHYS StartAddress,
137 uint64_t cbRegion,
138 RTR3PTR pvAddressR3,
139 RTR0PTR pvAddressR0));
140
141 /**
142 * Request port IO write.
143 *
144 * @returns status code
145 * @param pInterface Pointer to this interface structure.
146 * @param uPort I/O port address.
147 * @param uValue Value to write.
148 * @param cb Access width.
149 *
150 * @thread EMT thread.
151 */
152 DECLR3CALLBACKMEMBER(int, pfnPioWrite, (PPDMIPCIRAWUP pInterface,
153 RTIOPORT uPort,
154 uint32_t uValue,
155 unsigned cb));
156
157 /**
158 * Request port IO read.
159 *
160 * @returns status code
161 * @param pInterface Pointer to this interface structure.
162 * @param uPort I/O port address.
163 * @param puValue Place to store read value.
164 * @param cb Access width.
165 *
166 * @thread EMT thread.
167 */
168 DECLR3CALLBACKMEMBER(int, pfnPioRead, (PPDMIPCIRAWUP pInterface,
169 RTIOPORT uPort,
170 uint32_t *puValue,
171 unsigned cb));
172
173
174 /**
175 * Request MMIO write.
176 *
177 * This callback is only called if driver wants to receive MMIO via pu32Flags
178 * argument of pfnPciDeviceConstructStart().
179 *
180 * @returns status code
181 * @param pInterface Pointer to this interface structure.
182 * @param Address Guest physical address.
183 * @param pvValue Address of value to write.
184 * @param cb Access width.
185 *
186 * @todo Why is this @a Address documented as guest physical
187 * address and given a host ring-0 address type?
188 *
189 * @thread EMT thread.
190 */
191 DECLR3CALLBACKMEMBER(int, pfnMmioWrite, (PPDMIPCIRAWUP pInterface,
192 RTR0PTR Address,
193 void const *pvValue,
194 unsigned cb));
195
196 /**
197 * Request MMIO read.
198 *
199 * @returns status code
200 * @param pInterface Pointer to this interface structure.
201 * @param Address Guest physical address.
202 * @param pvValue Place to store read value.
203 * @param cb Access width.
204 *
205 * @todo Why is this @a Address documented as guest physical
206 * address and given a host ring-0 address type?
207 *
208 * @thread EMT thread.
209 */
210 DECLR3CALLBACKMEMBER(int, pfnMmioRead, (PPDMIPCIRAWUP pInterface,
211 RTR0PTR Address,
212 void *pvValue,
213 unsigned cb));
214
215 /**
216 * Host PCI config space accessors.
217 */
218 /**
219 * Request driver to write value to host device's PCI config space.
220 * Host specific way (PIO or MCFG) is used to perform actual operation.
221 *
222 * @returns status code
223 * @param pInterface Pointer to this interface structure.
224 * @param offCfgSpace Offset in PCI config space.
225 * @param pvValue Value to write.
226 * @param cb Access width.
227 *
228 * @thread EMT thread.
229 */
230 DECLR3CALLBACKMEMBER(int, pfnPciCfgWrite, (PPDMIPCIRAWUP pInterface,
231 uint32_t offCfgSpace,
232 void *pvValue,
233 unsigned cb));
234 /**
235 * Request driver to read value from host device's PCI config space.
236 * Host specific way (PIO or MCFG) is used to perform actual operation.
237 *
238 * @returns status code
239 * @param pInterface Pointer to this interface structure.
240 * @param offCfgSpace Offset in PCI config space.
241 * @param pvValue Where to store read value.
242 * @param cb Access width.
243 *
244 * @thread EMT thread.
245 */
246 DECLR3CALLBACKMEMBER(int, pfnPciCfgRead, (PPDMIPCIRAWUP pInterface,
247 uint32_t offCfgSpace,
248 void *pvValue,
249 unsigned cb));
250
251 /**
252 * Request to enable interrupt notifications. Please note that this is purely
253 * R3 interface, so it's up to implementor to perform necessary machinery
254 * for communications with host OS kernel driver. Typical implementation will start
255 * userland thread waiting on shared semaphore (such as using SUPSEMEVENT),
256 * notified by the kernel interrupt handler, and then will call
257 * upper port pfnInterruptRequest() based on data provided by the driver.
258 * This apporach is taken, as calling VBox code from an asyncronous R0
259 * interrupt handler when VMM may not be even running doesn't look
260 * like a good idea.
261 *
262 * @returns status code
263 * @param pInterface Pointer to this interface structure.
264 * @param uGuestIrq Guest IRQ to be passed to pfnInterruptRequest().
265 *
266 * @thread Any thread, pfnInterruptRequest() will be usually invoked on a dedicated thread.
267 */
268 DECLR3CALLBACKMEMBER(int, pfnEnableInterruptNotifications, (PPDMIPCIRAWUP pInterface, uint8_t uGuestIrq));
269
270 /**
271 * Request to disable interrupt notifications.
272 *
273 * @returns status code
274 * @param pInterface Pointer to this interface structure.
275 *
276 * @thread Any thread.
277 */
278 DECLR3CALLBACKMEMBER(int, pfnDisableInterruptNotifications, (PPDMIPCIRAWUP pInterface));
279
280 /** @name Notification APIs.
281 * @{
282 */
283
284 /**
285 * Notify driver when raw PCI device construction starts.
286 *
287 * Have to be the first operation as initializes internal state and opens host
288 * device driver.
289 *
290 * @returns status code
291 * @param pInterface Pointer to this interface structure.
292 * @param uHostPciAddress Host PCI address of device attached.
293 * @param uGuestPciAddress Guest PCI address of device attached.
294 * @param pszDeviceName Human readable device name.
295 * @param fDeviceFlags Flags for the host device.
296 * @param pfFlags Flags for virtual device, from the upper driver.
297 *
298 * @thread Any thread.
299 */
300 DECLR3CALLBACKMEMBER(int, pfnPciDeviceConstructStart, (PPDMIPCIRAWUP pInterface,
301 uint32_t uHostPciAddress,
302 uint32_t uGuestPciAddress,
303 const char *pszDeviceName,
304 uint32_t fDeviceFlags,
305 uint32_t *pfFlags));
306
307 /**
308 * Notify driver when raw PCI device construction completes, so that it may
309 * perform further actions depending on success or failure of this operation.
310 * Standard action is to raise global IHostPciDevicePlugEvent.
311 *
312 * @param pInterface Pointer to this interface structure.
313 * @param rc Result code of the operation.
314 *
315 * @thread Any thread.
316 */
317 DECLR3CALLBACKMEMBER(void, pfnPciDeviceConstructComplete, (PPDMIPCIRAWUP pInterface, int rc));
318
319 /**
320 * Notify driver on finalization of raw PCI device.
321 *
322 * @param pInterface Pointer to this interface structure.
323 * @param fFlags Flags.
324 *
325 * @thread Any thread.
326 */
327 DECLR3CALLBACKMEMBER(int, pfnPciDeviceDestruct, (PPDMIPCIRAWUP pInterface, uint32_t fFlags));
328
329 /**
330 * Notify driver on guest power state change.
331 *
332 * @param pInterface Pointer to this interface structure.
333 * @param enmState New power state.
334 * @param pu64Param State-specific in/out parameter. For now only used during power-on to provide VM caps.
335 *
336 * @thread Any thread.
337 */
338 DECLR3CALLBACKMEMBER(int, pfnPciDevicePowerStateChange, (PPDMIPCIRAWUP pInterface,
339 PCIRAWPOWERSTATE enmState,
340 uint64_t *pu64Param));
341
342 /**
343 * Notify driver about runtime error.
344 *
345 * @param pInterface Pointer to this interface structure.
346 * @param fFatal If error is fatal.
347 * @param pszErrorId Error ID.
348 * @param pszMessage Error message.
349 *
350 * @thread Any thread.
351 */
352 DECLR3CALLBACKMEMBER(int, pfnReportRuntimeError, (PPDMIPCIRAWUP pInterface,
353 bool fFatal,
354 const char *pszErrorId,
355 const char *pszMessage));
356 /** @} */
357} PDMIPCIRAWUP;
358
359/**
360 * Init R0 PCI module.
361 */
362PCIRAWR0DECL(int) PciRawR0Init(void);
363/**
364 * Process request (in R0).
365 */
366PCIRAWR0DECL(int) PciRawR0ProcessReq(PGVM pGVM, PSUPDRVSESSION pSession, PPCIRAWSENDREQ pReq);
367/**
368 * Terminate R0 PCI module.
369 */
370PCIRAWR0DECL(void) PciRawR0Term(void);
371
372/**
373 * Per-VM R0 module init.
374 */
375PCIRAWR0DECL(int) PciRawR0InitVM(PGVM pGVM);
376
377/**
378 * Per-VM R0 module termination routine.
379 */
380PCIRAWR0DECL(void) PciRawR0TermVM(PGVM pGVM);
381
382/**
383 * Flags returned by pfnPciDeviceConstructStart(), to notify device
384 * how it shall handle device IO traffic.
385 */
386typedef enum PCIRAWDEVICEFLAGS
387{
388 /** Intercept port IO (R3 PIO always go to the driver). */
389 PCIRAWRFLAG_CAPTURE_PIO = (1 << 0),
390 /** Intercept MMIO. */
391 PCIRAWRFLAG_CAPTURE_MMIO = (1 << 1),
392 /** Allow bus mastering by physical device (requires IOMMU). */
393 PCIRAWRFLAG_ALLOW_BM = (1 << 2),
394 /** Allow R3 MMIO mapping. */
395 PCIRAWRFLAG_ALLOW_R3MAP = (1 << 3),
396
397 /** The usual 32-bit type blow up. */
398 PCIRAWRFLAG_32BIT_HACK = 0x7fffffff
399} PCIRAWDEVICEFLAGS;
400
401#define PDMIPCIRAWUP_IID "06daa17f-097b-4ebe-a626-15f467b1de12"
402#define PDMIPCIRAW_IID "68c6e4c4-4223-47e0-9134-e3c297992543"
403
404/** @} */
405
406RT_C_DECLS_END
407
408#endif /* !VBOX_INCLUDED_vmm_pdmpci_h */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use