VirtualBox

source: vbox/trunk/src/VBox/Devices/Bus/DevPciInternal.h@ 91605

Last change on this file since 91605 was 90436, checked in by vboxsync, 3 years ago

VMM,Dev*: Handle PDMCritSectEnter failures in relation to the PDM critsect. bugref:6695

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.8 KB
Line 
1/* $Id: DevPciInternal.h 90436 2021-07-30 16:03:48Z vboxsync $ */
2/** @file
3 * DevPCI - Common Internal Header.
4 */
5
6/*
7 * Copyright (C) 2010-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef VBOX_INCLUDED_SRC_Bus_DevPciInternal_h
19#define VBOX_INCLUDED_SRC_Bus_DevPciInternal_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#ifndef PDMPCIDEV_INCLUDE_PRIVATE
25# define PDMPCIDEV_INCLUDE_PRIVATE /* Hack to get pdmpcidevint.h included at the right point. */
26#endif
27#include <VBox/vmm/pdmdev.h>
28
29
30/**
31 * PCI bus shared instance data (common to both PCI buses).
32 *
33 * The PCI device for the bus is always the first one (PDMDEVINSR3::apPciDevs[0]).
34 */
35typedef struct DEVPCIBUS
36{
37 /** Bus number. */
38 uint32_t iBus;
39 /** Number of bridges attached to the bus. */
40 uint32_t cBridges;
41 /** Start device number - always zero (only for DevPCI source compat). */
42 uint32_t iDevSearch;
43 /** Set if PIIX3 type. */
44 uint32_t fTypePiix3 : 1;
45 /** Set if ICH9 type. */
46 uint32_t fTypeIch9 : 1;
47 /** Set if this is a pure bridge, i.e. not part of DEVPCIGLOBALS struct. */
48 uint32_t fPureBridge : 1;
49 /** Reserved for future config flags. */
50 uint32_t uReservedConfigFlags : 29;
51
52 /** Array of bridges attached to the bus. */
53 R3PTRTYPE(PPDMPCIDEV *) papBridgesR3;
54 /** Cache line align apDevices. */
55 uint32_t au32Alignment1[HC_ARCH_BITS == 32 ? 3 + 8 : 2 + 8];
56 /** Array of PCI devices. We assume 32 slots, each with 8 functions. */
57 R3PTRTYPE(PPDMPCIDEV) apDevices[256];
58} DEVPCIBUS;
59/** Pointer to PCI bus shared instance data. */
60typedef DEVPCIBUS *PDEVPCIBUS;
61
62/**
63 * PCI bus ring-3 instance data (common to both PCI buses).
64 */
65typedef struct DEVPCIBUSR3
66{
67 /** R3 pointer to the device instance. */
68 PPDMDEVINSR3 pDevInsR3;
69 /** Pointer to the PCI R3 helpers. */
70 PCPDMPCIHLPR3 pPciHlpR3;
71} DEVPCIBUSR3;
72/** Pointer to PCI bus ring-3 instance data. */
73typedef DEVPCIBUSR3 *PDEVPCIBUSR3;
74
75/**
76 * PCI bus ring-0 instance data (common to both PCI buses).
77 */
78typedef struct DEVPCIBUSR0
79{
80 /** R0 pointer to the device instance. */
81 PPDMDEVINSR0 pDevInsR0;
82 /** Pointer to the PCI R0 helpers. */
83 PCPDMPCIHLPR0 pPciHlpR0;
84} DEVPCIBUSR0;
85/** Pointer to PCI bus ring-0 instance data. */
86typedef DEVPCIBUSR0 *PDEVPCIBUSR0;
87
88/**
89 * PCI bus raw-mode instance data (common to both PCI buses).
90 */
91typedef struct DEVPCIBUSRC
92{
93 /** R0 pointer to the device instance. */
94 PPDMDEVINSRC pDevInsRC;
95 /** Pointer to the PCI raw-mode helpers. */
96 PCPDMPCIHLPRC pPciHlpRC;
97} DEVPCIBUSRC;
98/** Pointer to PCI bus raw-mode instance data. */
99typedef DEVPCIBUSRC *PDEVPCIBUSRC;
100
101/** DEVPCIBUSR3, DEVPCIBUSR0 or DEVPCIBUSRC depending on context. */
102typedef CTX_SUFF(DEVPCIBUS) DEVPCIBUSCC;
103/** PDEVPCIBUSR3, PDEVPCIBUSR0 or PDEVPCIBUSRC depending on context. */
104typedef CTX_SUFF(PDEVPCIBUS) PDEVPCIBUSCC;
105
106
107/** @def DEVPCI_APIC_IRQ_PINS
108 * Number of pins for interrupts if the APIC is used.
109 */
110#define DEVPCI_APIC_IRQ_PINS 8
111/** @def DEVPCI_LEGACY_IRQ_PINS
112 * Number of pins for interrupts (PIRQ#0...PIRQ#3).
113 * @remarks Labling this "legacy" might be a bit off...
114 */
115#define DEVPCI_LEGACY_IRQ_PINS 4
116
117
118/**
119 * PCI Globals - This is the host-to-pci bridge and the root bus, shared data.
120 *
121 * @note Only used by the root bus, not the bridges.
122 */
123typedef struct DEVPCIROOT
124{
125 /** PCI bus which is attached to the host-to-PCI bridge.
126 * @note This must come first so we can share more code with the bridges! */
127 DEVPCIBUS PciBus;
128
129 /** I/O APIC usage flag (always true of ICH9, see constructor). */
130 bool fUseIoApic;
131 /** Reserved for future config flags. */
132 bool afFutureFlags[3+4+8];
133 /** Physical address of PCI config space MMIO region. */
134 uint64_t u64PciConfigMMioAddress;
135 /** Length of PCI config space MMIO region. */
136 uint64_t u64PciConfigMMioLength;
137
138 /** I/O APIC irq levels */
139 volatile uint32_t auPciApicIrqLevels[DEVPCI_APIC_IRQ_PINS];
140 /** Value latched in Configuration Address Port (0CF8h) */
141 uint32_t uConfigReg;
142 /** Alignment padding. */
143 uint32_t u32Alignment1;
144 /** Members only used by the PIIX3 code variant.
145 * (The PCI device for the PCI-to-ISA bridge is PDMDEVINSR3::apPciDevs[1].) */
146 struct
147 {
148 /** ACPI IRQ level */
149 uint32_t iAcpiIrqLevel;
150 /** ACPI PIC IRQ */
151 int32_t iAcpiIrq;
152 /** Irq levels for the four PCI Irqs.
153 * These count how many devices asserted the IRQ line. If greater 0 an IRQ
154 * is sent to the guest. If it drops to 0 the IRQ is deasserted.
155 * @remarks Labling this "legacy" might be a bit off...
156 */
157 volatile uint32_t auPciLegacyIrqLevels[DEVPCI_LEGACY_IRQ_PINS];
158 } Piix3;
159
160 /** The address I/O port handle. */
161 IOMIOPORTHANDLE hIoPortAddress;
162 /** The data I/O port handle. */
163 IOMIOPORTHANDLE hIoPortData;
164 /** The magic I/O port handle. */
165 IOMIOPORTHANDLE hIoPortMagic;
166 /** The MCFG MMIO region. */
167 IOMMMIOHANDLE hMmioMcfg;
168
169#if 1 /* Will be moved into the BIOS "soon". */
170 /** Current bus number - obsolete (still used by DevPCI, but merge will fix that). */
171 uint8_t uPciBiosBus;
172 uint8_t abAlignment2[7];
173 /** The next I/O port address which the PCI BIOS will use. */
174 uint32_t uPciBiosIo;
175 /** The next MMIO address which the PCI BIOS will use. */
176 uint32_t uPciBiosMmio;
177 /** The next 64-bit MMIO address which the PCI BIOS will use. */
178 uint64_t uPciBiosMmio64;
179#endif
180
181} DEVPCIROOT;
182/** Pointer to PCI device globals. */
183typedef DEVPCIROOT *PDEVPCIROOT;
184/** Converts a PCI bus device instance pointer to a DEVPCIBUS pointer. */
185#define DEVINS_2_DEVPCIBUS(pDevIns) (&PDMINS_2_DATA(pDevIns, PDEVPCIROOT)->PciBus)
186/** Converts a pointer to a PCI bus instance to a DEVPCIROOT pointer. */
187#define DEVPCIBUS_2_DEVPCIROOT(pPciBus) RT_FROM_MEMBER(pPciBus, DEVPCIROOT, PciBus)
188
189
190/** @def PCI_LOCK_RET
191 * Acquires the PDM lock. This is a NOP if locking is disabled. */
192#define PCI_LOCK_RET(pDevIns, rcBusy) \
193 do { \
194 int const rcLock = PDMINS_2_DATA_CC(pDevIns, PDEVPCIBUSCC)->CTX_SUFF(pPciHlp)->pfnLock((pDevIns), rcBusy); \
195 if (rcLock == VINF_SUCCESS) \
196 { /* likely */ } \
197 else \
198 return rcLock; \
199 } while (0)
200/** @def PCI_UNLOCK
201 * Releases the PDM lock. This is a NOP if locking is disabled. */
202#define PCI_UNLOCK(pDevIns) \
203 PDMINS_2_DATA_CC(pDevIns, PDEVPCIBUSCC)->CTX_SUFF(pPciHlp)->pfnUnlock(pDevIns)
204
205
206DECLHIDDEN(PPDMDEVINS) devpcibridgeCommonSetIrqRootWalk(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq,
207 PDEVPCIBUS *ppBus, uint8_t *puDevFnBridge, int *piIrqPinBridge);
208
209#ifdef IN_RING3
210
211DECLCALLBACK(void) devpciR3InfoPci(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
212DECLCALLBACK(void) devpciR3InfoPciIrq(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
213DECLCALLBACK(int) devpciR3CommonRegisterDevice(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags,
214 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName);
215DECLCALLBACK(int) devpcibridgeR3CommonRegisterDevice(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags,
216 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName);
217DECLCALLBACK(int) devpciR3CommonIORegionRegister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
218 RTGCPHYS cbRegion, PCIADDRESSSPACE enmType, uint32_t fFlags,
219 uint64_t hHandle, PFNPCIIOREGIONMAP pfnMapUnmap);
220DECLCALLBACK(void) devpciR3CommonInterceptConfigAccesses(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
221 PFNPCICONFIGREAD pfnRead, PFNPCICONFIGWRITE pfnWrite);
222DECLCALLBACK(VBOXSTRICTRC) devpciR3CommonConfigRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
223 uint32_t uAddress, unsigned cb, uint32_t *pu32Value);
224DECLHIDDEN(VBOXSTRICTRC) devpciR3CommonConfigReadWorker(PPDMPCIDEV pPciDev, uint32_t uAddress, unsigned cb, uint32_t *pu32Value);
225DECLCALLBACK(VBOXSTRICTRC) devpciR3CommonConfigWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
226 uint32_t uAddress, unsigned cb, uint32_t u32Value);
227DECLHIDDEN(VBOXSTRICTRC) devpciR3CommonConfigWriteWorker(PPDMDEVINS pDevIns, PDEVPCIBUSCC pBusCC,
228 PPDMPCIDEV pPciDev, uint32_t uAddress, unsigned cb, uint32_t u32Value);
229void devpciR3CommonRestoreConfig(PPDMDEVINS pDevIns, PPDMPCIDEV pDev, uint8_t const *pbSrcConfig);
230int devpciR3CommonRestoreRegions(PSSMHANDLE pSSM, PPDMPCIDEV pPciDev, PPCIIOREGION paIoRegions, bool fNewState);
231void devpciR3ResetDevice(PPDMDEVINS pDevIns, PPDMPCIDEV pDev);
232void devpciR3BiosInitSetRegionAddress(PPDMDEVINS pDevIns, PDEVPCIBUS pBus, PPDMPCIDEV pPciDev, int iRegion, uint64_t addr);
233uint32_t devpciR3GetCfg(PPDMPCIDEV pPciDev, int32_t iRegister, int cb);
234void devpciR3SetCfg(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int32_t iRegister, uint32_t u32, int cb);
235
236DECLINLINE(uint8_t) devpciR3GetByte(PPDMPCIDEV pPciDev, int32_t iRegister)
237{
238 return (uint8_t)devpciR3GetCfg(pPciDev, iRegister, 1);
239}
240
241DECLINLINE(uint16_t) devpciR3GetWord(PPDMPCIDEV pPciDev, int32_t iRegister)
242{
243 return (uint16_t)devpciR3GetCfg(pPciDev, iRegister, 2);
244}
245
246DECLINLINE(uint32_t) devpciR3GetDWord(PPDMPCIDEV pPciDev, int32_t iRegister)
247{
248 return (uint32_t)devpciR3GetCfg(pPciDev, iRegister, 4);
249}
250
251DECLINLINE(void) devpciR3SetByte(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int32_t iRegister, uint8_t u8)
252{
253 devpciR3SetCfg(pDevIns, pPciDev, iRegister, u8, 1);
254}
255
256DECLINLINE(void) devpciR3SetWord(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int32_t iRegister, uint16_t u16)
257{
258 devpciR3SetCfg(pDevIns, pPciDev, iRegister, u16, 2);
259}
260
261DECLINLINE(void) devpciR3SetDWord(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int32_t iRegister, uint32_t u32)
262{
263 devpciR3SetCfg(pDevIns, pPciDev, iRegister, u32, 4);
264}
265
266#endif /* IN_RING3 */
267
268#endif /* !VBOX_INCLUDED_SRC_Bus_DevPciInternal_h */
269
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