[23] | 1 | /* $Id: PDMDevMiscHlp.cpp 100108 2023-06-07 20:05:13Z vboxsync $ */
|
---|
[1] | 2 | /** @file
|
---|
[12980] | 3 | * PDM - Pluggable Device and Driver Manager, Misc. Device Helpers.
|
---|
[1] | 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[98103] | 7 | * Copyright (C) 2006-2023 Oracle and/or its affiliates.
|
---|
[1] | 8 | *
|
---|
[96407] | 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
|
---|
[1] | 26 | */
|
---|
| 27 |
|
---|
| 28 |
|
---|
[57358] | 29 | /*********************************************************************************************************************************
|
---|
| 30 | * Header Files *
|
---|
| 31 | *********************************************************************************************************************************/
|
---|
[1] | 32 | #define LOG_GROUP LOG_GROUP_PDM_DEVICE
|
---|
| 33 | #include "PDMInternal.h"
|
---|
[35346] | 34 | #include <VBox/vmm/pdm.h>
|
---|
[40274] | 35 | #include <VBox/vmm/pgm.h>
|
---|
[45808] | 36 | #include <VBox/vmm/hm.h>
|
---|
[99821] | 37 | #ifndef VBOX_VMM_TARGET_ARMV8
|
---|
| 38 | # include <VBox/vmm/apic.h>
|
---|
| 39 | #endif
|
---|
[35346] | 40 | #include <VBox/vmm/vm.h>
|
---|
| 41 | #include <VBox/vmm/vmm.h>
|
---|
[1] | 42 |
|
---|
| 43 | #include <VBox/log.h>
|
---|
| 44 | #include <VBox/err.h>
|
---|
[84677] | 45 | #include <VBox/msi.h>
|
---|
[1] | 46 | #include <iprt/asm.h>
|
---|
| 47 | #include <iprt/assert.h>
|
---|
| 48 | #include <iprt/thread.h>
|
---|
| 49 |
|
---|
| 50 |
|
---|
[40907] | 51 | #include "PDMInline.h"
|
---|
| 52 | #include "dtrace/VBoxVMM.h"
|
---|
[1] | 53 |
|
---|
[40907] | 54 |
|
---|
| 55 |
|
---|
[26001] | 56 | /** @name Ring-3 PIC Helpers
|
---|
[1] | 57 | * @{
|
---|
| 58 | */
|
---|
| 59 |
|
---|
[81909] | 60 | /** @interface_method_impl{PDMPICHLP,pfnSetInterruptFF} */
|
---|
[1] | 61 | static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
|
---|
| 62 | {
|
---|
| 63 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[64655] | 64 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[78208] | 65 |
|
---|
| 66 | /* IRQ state should be loaded as-is by "LoadExec". Changes can be made from LoadDone. */
|
---|
| 67 | Assert(pVM->enmVMState != VMSTATE_LOADING || pVM->pdm.s.fStateLoaded);
|
---|
| 68 |
|
---|
[99051] | 69 | #if defined(VBOX_VMM_TARGET_ARMV8)
|
---|
| 70 | AssertReleaseFailed();
|
---|
[100108] | 71 | RT_NOREF(pVM);
|
---|
[99051] | 72 | #else
|
---|
[100108] | 73 | PVMCPU pVCpu = pVM->apCpusR3[0]; /* for PIC we always deliver to CPU 0, SMP uses APIC */
|
---|
[64655] | 74 | APICLocalInterrupt(pVCpu, 0 /* u8Pin */, 1 /* u8Level */, VINF_SUCCESS /* rcRZ */);
|
---|
[99051] | 75 | #endif
|
---|
[1] | 76 | }
|
---|
| 77 |
|
---|
| 78 |
|
---|
[81909] | 79 | /** @interface_method_impl{PDMPICHLP,pfnClearInterruptFF} */
|
---|
[1] | 80 | static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
|
---|
| 81 | {
|
---|
| 82 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[19141] | 83 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[78208] | 84 |
|
---|
| 85 | /* IRQ state should be loaded as-is by "LoadExec". Changes can be made from LoadDone. */
|
---|
| 86 | Assert(pVM->enmVMState != VMSTATE_LOADING || pVM->pdm.s.fStateLoaded);
|
---|
| 87 |
|
---|
[99051] | 88 | #if defined(VBOX_VMM_TARGET_ARMV8)
|
---|
| 89 | AssertReleaseFailed();
|
---|
[100108] | 90 | RT_NOREF(pVM);
|
---|
[99051] | 91 | #else
|
---|
[100108] | 92 | PVMCPU pVCpu = pVM->apCpusR3[0]; /* for PIC we always deliver to CPU 0, SMP uses APIC */
|
---|
[64655] | 93 | APICLocalInterrupt(pVCpu, 0 /* u8Pin */, 0 /* u8Level */, VINF_SUCCESS /* rcRZ */);
|
---|
[99051] | 94 | #endif
|
---|
[1] | 95 | }
|
---|
| 96 |
|
---|
| 97 |
|
---|
[81909] | 98 | /** @interface_method_impl{PDMPICHLP,pfnLock} */
|
---|
[1] | 99 | static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
|
---|
| 100 | {
|
---|
| 101 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 102 | return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
|
---|
[1] | 103 | }
|
---|
| 104 |
|
---|
| 105 |
|
---|
[81909] | 106 | /** @interface_method_impl{PDMPICHLP,pfnUnlock} */
|
---|
[1] | 107 | static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns)
|
---|
| 108 | {
|
---|
| 109 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 110 | pdmUnlock(pDevIns->Internal.s.pVMR3);
|
---|
[1] | 111 | }
|
---|
| 112 |
|
---|
| 113 |
|
---|
[12980] | 114 | /**
|
---|
| 115 | * PIC Device Helpers.
|
---|
| 116 | */
|
---|
[81909] | 117 | const PDMPICHLP g_pdmR3DevPicHlp =
|
---|
[12980] | 118 | {
|
---|
[81909] | 119 | PDM_PICHLP_VERSION,
|
---|
[12980] | 120 | pdmR3PicHlp_SetInterruptFF,
|
---|
| 121 | pdmR3PicHlp_ClearInterruptFF,
|
---|
| 122 | pdmR3PicHlp_Lock,
|
---|
| 123 | pdmR3PicHlp_Unlock,
|
---|
[81909] | 124 | PDM_PICHLP_VERSION /* the end */
|
---|
[12980] | 125 | };
|
---|
| 126 |
|
---|
| 127 | /** @} */
|
---|
| 128 |
|
---|
| 129 |
|
---|
[26001] | 130 | /** @name Ring-3 I/O APIC Helpers
|
---|
[12980] | 131 | * @{
|
---|
| 132 | */
|
---|
| 133 |
|
---|
[81938] | 134 | /** @interface_method_impl{PDMIOAPICHLP,pfnApicBusDeliver} */
|
---|
[64655] | 135 | static DECLCALLBACK(int) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
|
---|
| 136 | uint8_t u8DeliveryMode, uint8_t uVector, uint8_t u8Polarity,
|
---|
| 137 | uint8_t u8TriggerMode, uint32_t uTagSrc)
|
---|
[1] | 138 | {
|
---|
| 139 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[64655] | 140 | LogFlow(("pdmR3IoApicHlp_ApicBusDeliver: caller='%s'/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 uVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
|
---|
| 141 | pDevIns->pReg->szName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc));
|
---|
[99051] | 142 | #if defined(VBOX_VMM_TARGET_ARMV8)
|
---|
| 143 | AssertReleaseFailed();
|
---|
[100108] | 144 | RT_NOREF(pDevIns, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc);
|
---|
[99051] | 145 | return VERR_NOT_IMPLEMENTED;
|
---|
| 146 | #else
|
---|
[100108] | 147 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[64655] | 148 | return APICBusDeliver(pVM, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc);
|
---|
[99051] | 149 | #endif
|
---|
[1] | 150 | }
|
---|
| 151 |
|
---|
| 152 |
|
---|
[81938] | 153 | /** @interface_method_impl{PDMIOAPICHLP,pfnLock} */
|
---|
[1] | 154 | static DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
|
---|
| 155 | {
|
---|
| 156 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 157 | LogFlow(("pdmR3IoApicHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[12970] | 158 | return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
|
---|
[1] | 159 | }
|
---|
| 160 |
|
---|
| 161 |
|
---|
[81938] | 162 | /** @interface_method_impl{PDMIOAPICHLP,pfnUnlock} */
|
---|
[1] | 163 | static DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns)
|
---|
| 164 | {
|
---|
| 165 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 166 | LogFlow(("pdmR3IoApicHlp_Unlock: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[12970] | 167 | pdmUnlock(pDevIns->Internal.s.pVMR3);
|
---|
[1] | 168 | }
|
---|
| 169 |
|
---|
| 170 |
|
---|
[89065] | 171 | /** @interface_method_impl{PDMIOAPICHLP,pfnLockIsOwner} */
|
---|
| 172 | static DECLCALLBACK(bool) pdmR3IoApicHlp_LockIsOwner(PPDMDEVINS pDevIns)
|
---|
| 173 | {
|
---|
| 174 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 175 | LogFlow(("pdmR3IoApicHlp_LockIsOwner: caller='%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
| 176 | return pdmLockIsOwner(pDevIns->Internal.s.pVMR3);
|
---|
| 177 | }
|
---|
| 178 |
|
---|
| 179 |
|
---|
[84677] | 180 | /** @interface_method_impl{PDMIOAPICHLP,pfnIommuMsiRemap} */
|
---|
[88078] | 181 | static DECLCALLBACK(int) pdmR3IoApicHlp_IommuMsiRemap(PPDMDEVINS pDevIns, uint16_t idDevice, PCMSIMSG pMsiIn, PMSIMSG pMsiOut)
|
---|
[84677] | 182 | {
|
---|
| 183 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 184 | LogFlow(("pdmR3IoApicHlp_IommuRemapMsi: caller='%s'/%d: pMsiIn=(%#RX64, %#RU32)\n", pDevIns->pReg->szName,
|
---|
| 185 | pDevIns->iInstance, pMsiIn->Addr.u64, pMsiIn->Data.u32));
|
---|
| 186 |
|
---|
[88639] | 187 | #if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
|
---|
[88631] | 188 | if (pdmIommuIsPresent(pDevIns))
|
---|
| 189 | return pdmIommuMsiRemap(pDevIns, idDevice, pMsiIn, pMsiOut);
|
---|
[84677] | 190 | #else
|
---|
[98993] | 191 | RT_NOREF(pDevIns, idDevice, pMsiIn, pMsiOut);
|
---|
[86070] | 192 | #endif
|
---|
[88631] | 193 | return VERR_IOMMU_NOT_PRESENT;
|
---|
[84677] | 194 | }
|
---|
| 195 |
|
---|
| 196 |
|
---|
[12980] | 197 | /**
|
---|
| 198 | * I/O APIC Device Helpers.
|
---|
| 199 | */
|
---|
[81938] | 200 | const PDMIOAPICHLP g_pdmR3DevIoApicHlp =
|
---|
[12980] | 201 | {
|
---|
[81938] | 202 | PDM_IOAPICHLP_VERSION,
|
---|
[12980] | 203 | pdmR3IoApicHlp_ApicBusDeliver,
|
---|
| 204 | pdmR3IoApicHlp_Lock,
|
---|
| 205 | pdmR3IoApicHlp_Unlock,
|
---|
[89065] | 206 | pdmR3IoApicHlp_LockIsOwner,
|
---|
[84677] | 207 | pdmR3IoApicHlp_IommuMsiRemap,
|
---|
[81938] | 208 | PDM_IOAPICHLP_VERSION /* the end */
|
---|
[12980] | 209 | };
|
---|
| 210 |
|
---|
| 211 | /** @} */
|
---|
| 212 |
|
---|
| 213 |
|
---|
| 214 |
|
---|
| 215 |
|
---|
[26001] | 216 | /** @name Ring-3 PCI Bus Helpers
|
---|
[12980] | 217 | * @{
|
---|
| 218 | */
|
---|
| 219 |
|
---|
[26152] | 220 | /** @interface_method_impl{PDMPCIHLPR3,pfnIsaSetIrq} */
|
---|
[40907] | 221 | static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
|
---|
[1] | 222 | {
|
---|
| 223 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[40907] | 224 | Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
|
---|
| 225 | PDMIsaSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel, uTagSrc);
|
---|
[1] | 226 | }
|
---|
| 227 |
|
---|
[82316] | 228 |
|
---|
[26152] | 229 | /** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSetIrq} */
|
---|
[84826] | 230 | static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, int iIrq, int iLevel, uint32_t uTagSrc)
|
---|
[1] | 231 | {
|
---|
| 232 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[84826] | 233 | Log4(("pdmR3PciHlp_IoApicSetIrq: uBusDevFn=%#x iIrq=%d iLevel=%d uTagSrc=%#x\n", uBusDevFn, iIrq, iLevel, uTagSrc));
|
---|
| 234 | PDMIoApicSetIrq(pDevIns->Internal.s.pVMR3, uBusDevFn, iIrq, iLevel, uTagSrc);
|
---|
[1] | 235 | }
|
---|
| 236 |
|
---|
[82316] | 237 |
|
---|
[32935] | 238 | /** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSendMsi} */
|
---|
[84826] | 239 | static DECLCALLBACK(void) pdmR3PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc)
|
---|
[32935] | 240 | {
|
---|
| 241 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[84826] | 242 | Assert(PCIBDF_IS_VALID(uBusDevFn));
|
---|
| 243 | Log4(("pdmR3PciHlp_IoApicSendMsi: uBusDevFn=%#x Msi (Addr=%#RX64 Data=%#x) uTagSrc=%#x\n", uBusDevFn,
|
---|
| 244 | pMsi->Addr.u64, pMsi->Data.u32, uTagSrc));
|
---|
[89620] | 245 | PDMIoApicSendMsi(pDevIns->Internal.s.pVMR3, uBusDevFn, pMsi, uTagSrc);
|
---|
[32935] | 246 | }
|
---|
[1] | 247 |
|
---|
[7635] | 248 |
|
---|
[26152] | 249 | /** @interface_method_impl{PDMPCIHLPR3,pfnLock} */
|
---|
[1] | 250 | static DECLCALLBACK(int) pdmR3PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
|
---|
| 251 | {
|
---|
| 252 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 253 | LogFlow(("pdmR3PciHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[12970] | 254 | return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
|
---|
[1] | 255 | }
|
---|
| 256 |
|
---|
| 257 |
|
---|
[26152] | 258 | /** @interface_method_impl{PDMPCIHLPR3,pfnUnlock} */
|
---|
[1] | 259 | static DECLCALLBACK(void) pdmR3PciHlp_Unlock(PPDMDEVINS pDevIns)
|
---|
| 260 | {
|
---|
| 261 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 262 | LogFlow(("pdmR3PciHlp_Unlock: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[12970] | 263 | pdmUnlock(pDevIns->Internal.s.pVMR3);
|
---|
[1] | 264 | }
|
---|
| 265 |
|
---|
| 266 |
|
---|
[80960] | 267 | /** @interface_method_impl{PDMPCIHLPR3,pfnGetBusByNo} */
|
---|
| 268 | static DECLCALLBACK(PPDMDEVINS) pdmR3PciHlp_GetBusByNo(PPDMDEVINS pDevIns, uint32_t idxPdmBus)
|
---|
[1] | 269 | {
|
---|
| 270 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[45808] | 271 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[80960] | 272 | AssertReturn(idxPdmBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses), NULL);
|
---|
| 273 | PPDMDEVINS pRetDevIns = pVM->pdm.s.aPciBuses[idxPdmBus].pDevInsR3;
|
---|
| 274 | LogFlow(("pdmR3PciHlp_GetBusByNo: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pRetDevIns));
|
---|
| 275 | return pRetDevIns;
|
---|
[1] | 276 | }
|
---|
| 277 |
|
---|
| 278 |
|
---|
[26001] | 279 | /**
|
---|
| 280 | * PCI Bus Device Helpers.
|
---|
| 281 | */
|
---|
| 282 | const PDMPCIHLPR3 g_pdmR3DevPciHlp =
|
---|
| 283 | {
|
---|
| 284 | PDM_PCIHLPR3_VERSION,
|
---|
| 285 | pdmR3PciHlp_IsaSetIrq,
|
---|
| 286 | pdmR3PciHlp_IoApicSetIrq,
|
---|
[32935] | 287 | pdmR3PciHlp_IoApicSendMsi,
|
---|
[26001] | 288 | pdmR3PciHlp_Lock,
|
---|
| 289 | pdmR3PciHlp_Unlock,
|
---|
[80960] | 290 | pdmR3PciHlp_GetBusByNo,
|
---|
[26001] | 291 | PDM_PCIHLPR3_VERSION, /* the end */
|
---|
| 292 | };
|
---|
| 293 |
|
---|
| 294 | /** @} */
|
---|
| 295 |
|
---|
| 296 |
|
---|
[87691] | 297 | /** @name Ring-3 IOMMU Helpers
|
---|
| 298 | * @{
|
---|
| 299 | */
|
---|
| 300 |
|
---|
| 301 | /** @interface_method_impl{PDMIOMMUHLPR3,pfnLock} */
|
---|
| 302 | static DECLCALLBACK(int) pdmR3IommuHlp_Lock(PPDMDEVINS pDevIns, int rc)
|
---|
| 303 | {
|
---|
| 304 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 305 | LogFlowFunc(("caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 306 | return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
|
---|
| 307 | }
|
---|
| 308 |
|
---|
| 309 |
|
---|
| 310 | /** @interface_method_impl{PDMIOMMUHLPR3,pfnUnlock} */
|
---|
| 311 | static DECLCALLBACK(void) pdmR3IommuHlp_Unlock(PPDMDEVINS pDevIns)
|
---|
| 312 | {
|
---|
| 313 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 314 | LogFlowFunc(("caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
| 315 | pdmUnlock(pDevIns->Internal.s.pVMR3);
|
---|
| 316 | }
|
---|
| 317 |
|
---|
| 318 |
|
---|
[88567] | 319 | /** @interface_method_impl{PDMIOMMUHLPR3,pfnLockIsOwner} */
|
---|
| 320 | static DECLCALLBACK(bool) pdmR3IommuHlp_LockIsOwner(PPDMDEVINS pDevIns)
|
---|
| 321 | {
|
---|
| 322 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 323 | LogFlowFunc(("caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
| 324 | return pdmLockIsOwner(pDevIns->Internal.s.pVMR3);
|
---|
| 325 | }
|
---|
| 326 |
|
---|
| 327 |
|
---|
[88580] | 328 | /** @interface_method_impl{PDMIOMMUHLPR3,pfnSendMsi} */
|
---|
[89200] | 329 | static DECLCALLBACK(void) pdmR3IommuHlp_SendMsi(PPDMDEVINS pDevIns, PCMSIMSG pMsi, uint32_t uTagSrc)
|
---|
[88580] | 330 | {
|
---|
| 331 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 332 | LogFlowFunc(("caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[89620] | 333 | PDMIoApicSendMsi(pDevIns->Internal.s.pVMR3, NIL_PCIBDF, pMsi, uTagSrc);
|
---|
[88580] | 334 | }
|
---|
| 335 |
|
---|
| 336 |
|
---|
[83263] | 337 | /**
|
---|
| 338 | * IOMMU Device Helpers.
|
---|
| 339 | */
|
---|
| 340 | const PDMIOMMUHLPR3 g_pdmR3DevIommuHlp =
|
---|
| 341 | {
|
---|
| 342 | PDM_IOMMUHLPR3_VERSION,
|
---|
[87691] | 343 | pdmR3IommuHlp_Lock,
|
---|
| 344 | pdmR3IommuHlp_Unlock,
|
---|
[88567] | 345 | pdmR3IommuHlp_LockIsOwner,
|
---|
[88580] | 346 | pdmR3IommuHlp_SendMsi,
|
---|
[83263] | 347 | PDM_IOMMUHLPR3_VERSION /* the end */
|
---|
| 348 | };
|
---|
[26001] | 349 |
|
---|
[87691] | 350 | /** @} */
|
---|
[26001] | 351 |
|
---|
[87691] | 352 |
|
---|
[26001] | 353 | /** @name Ring-3 HPET Helpers
|
---|
[81369] | 354 | * @{
|
---|
[26001] | 355 | */
|
---|
| 356 |
|
---|
[26152] | 357 | /** @interface_method_impl{PDMHPETHLPR3,pfnSetLegacyMode} */
|
---|
[27126] | 358 | static DECLCALLBACK(int) pdmR3HpetHlp_SetLegacyMode(PPDMDEVINS pDevIns, bool fActivated)
|
---|
[25995] | 359 | {
|
---|
| 360 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[27126] | 361 | LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: fActivated=%RTbool\n", pDevIns->pReg->szName, pDevIns->iInstance, fActivated));
|
---|
[27121] | 362 |
|
---|
[27126] | 363 | size_t i;
|
---|
| 364 | int rc = VINF_SUCCESS;
|
---|
| 365 | static const char * const s_apszDevsToNotify[] =
|
---|
[27121] | 366 | {
|
---|
[27126] | 367 | "i8254",
|
---|
| 368 | "mc146818"
|
---|
| 369 | };
|
---|
| 370 | for (i = 0; i < RT_ELEMENTS(s_apszDevsToNotify); i++)
|
---|
| 371 | {
|
---|
| 372 | PPDMIBASE pBase;
|
---|
[44351] | 373 | rc = PDMR3QueryDevice(pDevIns->Internal.s.pVMR3->pUVM, "i8254", 0, &pBase);
|
---|
[27126] | 374 | if (RT_SUCCESS(rc))
|
---|
| 375 | {
|
---|
| 376 | PPDMIHPETLEGACYNOTIFY pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIHPETLEGACYNOTIFY);
|
---|
[39402] | 377 | AssertLogRelMsgBreakStmt(pPort, ("%s\n", s_apszDevsToNotify[i]), rc = VERR_PDM_HPET_LEGACY_NOTIFY_MISSING);
|
---|
[27126] | 378 | pPort->pfnModeChanged(pPort, fActivated);
|
---|
| 379 | }
|
---|
| 380 | else if ( rc == VERR_PDM_DEVICE_NOT_FOUND
|
---|
| 381 | || rc == VERR_PDM_DEVICE_INSTANCE_NOT_FOUND)
|
---|
| 382 | rc = VINF_SUCCESS; /* the device isn't configured, ignore. */
|
---|
| 383 | else
|
---|
| 384 | AssertLogRelMsgFailedBreak(("%s -> %Rrc\n", s_apszDevsToNotify[i], rc));
|
---|
[27121] | 385 | }
|
---|
| 386 |
|
---|
[27126] | 387 | /* Don't bother cleaning up, any failure here will cause a guru meditation. */
|
---|
[27121] | 388 |
|
---|
[27126] | 389 | LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[27121] | 390 | return rc;
|
---|
[25995] | 391 | }
|
---|
| 392 |
|
---|
[27127] | 393 |
|
---|
[26939] | 394 | /** @interface_method_impl{PDMHPETHLPR3,pfnSetIrq} */
|
---|
| 395 | static DECLCALLBACK(int) pdmR3HpetHlp_SetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
|
---|
| 396 | {
|
---|
| 397 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 398 | LogFlow(("pdmR3HpetHlp_SetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, iIrq, iLevel));
|
---|
[40907] | 399 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 400 |
|
---|
| 401 | pdmLock(pVM);
|
---|
| 402 | uint32_t uTagSrc;
|
---|
| 403 | if (iLevel & PDM_IRQ_LEVEL_HIGH)
|
---|
| 404 | {
|
---|
| 405 | pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
|
---|
| 406 | if (iLevel == PDM_IRQ_LEVEL_HIGH)
|
---|
| 407 | VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
|
---|
| 408 | else
|
---|
| 409 | VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
|
---|
| 410 | }
|
---|
| 411 | else
|
---|
| 412 | uTagSrc = pDevIns->Internal.s.uLastIrqTag;
|
---|
| 413 |
|
---|
| 414 | PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); /* (The API takes the lock recursively.) */
|
---|
| 415 |
|
---|
| 416 | if (iLevel == PDM_IRQ_LEVEL_LOW)
|
---|
| 417 | VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
|
---|
| 418 | pdmUnlock(pVM);
|
---|
[26939] | 419 | return 0;
|
---|
| 420 | }
|
---|
| 421 |
|
---|
[27127] | 422 |
|
---|
[25995] | 423 | /**
|
---|
| 424 | * HPET Device Helpers.
|
---|
| 425 | */
|
---|
| 426 | const PDMHPETHLPR3 g_pdmR3DevHpetHlp =
|
---|
| 427 | {
|
---|
| 428 | PDM_HPETHLPR3_VERSION,
|
---|
[26939] | 429 | pdmR3HpetHlp_SetLegacyMode,
|
---|
| 430 | pdmR3HpetHlp_SetIrq,
|
---|
[25995] | 431 | PDM_HPETHLPR3_VERSION, /* the end */
|
---|
| 432 | };
|
---|
[12980] | 433 |
|
---|
[25995] | 434 | /** @} */
|
---|
[12980] | 435 |
|
---|
[25995] | 436 |
|
---|
[35738] | 437 | /** @name Ring-3 Raw PCI Device Helpers
|
---|
[81369] | 438 | * @{
|
---|
[35738] | 439 | */
|
---|
[25995] | 440 |
|
---|
[35738] | 441 | /** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetRCHelpers} */
|
---|
| 442 | static DECLCALLBACK(PCPDMPCIRAWHLPRC) pdmR3PciRawHlp_GetRCHelpers(PPDMDEVINS pDevIns)
|
---|
| 443 | {
|
---|
| 444 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[45808] | 445 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 446 | VM_ASSERT_EMT(pVM);
|
---|
| 447 |
|
---|
[35738] | 448 | RTRCPTR pRCHelpers = NIL_RTRCPTR;
|
---|
[93901] | 449 | #if 0
|
---|
[70948] | 450 | if (VM_IS_RAW_MODE_ENABLED(pVM))
|
---|
[45808] | 451 | {
|
---|
| 452 | int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCPciRawHlp", &pRCHelpers);
|
---|
| 453 | AssertReleaseRC(rc);
|
---|
| 454 | AssertRelease(pRCHelpers);
|
---|
| 455 | }
|
---|
[93901] | 456 | #else
|
---|
[93902] | 457 | RT_NOREF(pVM, pDevIns);
|
---|
[93901] | 458 | #endif
|
---|
[45808] | 459 |
|
---|
[35738] | 460 | LogFlow(("pdmR3PciRawHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
|
---|
| 461 | pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
|
---|
| 462 | return pRCHelpers;
|
---|
| 463 | }
|
---|
[35676] | 464 |
|
---|
| 465 |
|
---|
[35738] | 466 | /** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetR0Helpers} */
|
---|
| 467 | static DECLCALLBACK(PCPDMPCIRAWHLPR0) pdmR3PciRawHlp_GetR0Helpers(PPDMDEVINS pDevIns)
|
---|
| 468 | {
|
---|
| 469 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[45808] | 470 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 471 | VM_ASSERT_EMT(pVM);
|
---|
[35738] | 472 | PCPDMHPETHLPR0 pR0Helpers = NIL_RTR0PTR;
|
---|
[45808] | 473 | int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0PciRawHlp", &pR0Helpers);
|
---|
[35738] | 474 | AssertReleaseRC(rc);
|
---|
| 475 | AssertRelease(pR0Helpers);
|
---|
| 476 | LogFlow(("pdmR3PciRawHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
|
---|
| 477 | pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
|
---|
| 478 | return pR0Helpers;
|
---|
| 479 | }
|
---|
| 480 |
|
---|
| 481 |
|
---|
| 482 | /**
|
---|
| 483 | * Raw PCI Device Helpers.
|
---|
| 484 | */
|
---|
| 485 | const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp =
|
---|
| 486 | {
|
---|
| 487 | PDM_PCIRAWHLPR3_VERSION,
|
---|
| 488 | pdmR3PciRawHlp_GetRCHelpers,
|
---|
| 489 | pdmR3PciRawHlp_GetR0Helpers,
|
---|
| 490 | PDM_PCIRAWHLPR3_VERSION, /* the end */
|
---|
| 491 | };
|
---|
| 492 |
|
---|
| 493 | /** @} */
|
---|
| 494 |
|
---|
| 495 |
|
---|
[12980] | 496 | /* none yet */
|
---|
| 497 |
|
---|
[1] | 498 | /**
|
---|
[60404] | 499 | * Firmware Device Helpers.
|
---|
| 500 | */
|
---|
| 501 | const PDMFWHLPR3 g_pdmR3DevFirmwareHlp =
|
---|
| 502 | {
|
---|
| 503 | PDM_FWHLPR3_VERSION,
|
---|
| 504 | PDM_FWHLPR3_VERSION
|
---|
| 505 | };
|
---|
| 506 |
|
---|
| 507 | /**
|
---|
[12980] | 508 | * DMAC Device Helpers.
|
---|
[1] | 509 | */
|
---|
[12980] | 510 | const PDMDMACHLP g_pdmR3DevDmacHlp =
|
---|
[1] | 511 | {
|
---|
[12980] | 512 | PDM_DMACHLP_VERSION
|
---|
| 513 | };
|
---|
[1] | 514 |
|
---|
| 515 |
|
---|
| 516 |
|
---|
| 517 |
|
---|
[12980] | 518 | /* none yet */
|
---|
[1] | 519 |
|
---|
| 520 | /**
|
---|
[12980] | 521 | * RTC Device Helpers.
|
---|
[1] | 522 | */
|
---|
[12980] | 523 | const PDMRTCHLP g_pdmR3DevRtcHlp =
|
---|
[1] | 524 | {
|
---|
[12980] | 525 | PDM_RTCHLP_VERSION
|
---|
| 526 | };
|
---|
[60404] | 527 |
|
---|