[23] | 1 | /* $Id: PDMDevHlp.cpp 80191 2019-08-08 00:36:57Z vboxsync $ */
|
---|
[1] | 2 | /** @file
|
---|
[12980] | 3 | * PDM - Pluggable Device and Driver Manager, Device Helpers.
|
---|
[1] | 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[76553] | 7 | * Copyright (C) 2006-2019 Oracle Corporation
|
---|
[1] | 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
|
---|
[5999] | 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.
|
---|
[1] | 16 | */
|
---|
| 17 |
|
---|
| 18 |
|
---|
[57358] | 19 | /*********************************************************************************************************************************
|
---|
| 20 | * Header Files *
|
---|
| 21 | *********************************************************************************************************************************/
|
---|
[80191] | 22 | #define VBOX_BUGREF_9217_PART_I
|
---|
[1] | 23 | #define LOG_GROUP LOG_GROUP_PDM_DEVICE
|
---|
[64373] | 24 | #define PDMPCIDEV_INCLUDE_PRIVATE /* Hack to get pdmpcidevint.h included at the right point. */
|
---|
[1] | 25 | #include "PDMInternal.h"
|
---|
[35346] | 26 | #include <VBox/vmm/pdm.h>
|
---|
| 27 | #include <VBox/vmm/mm.h>
|
---|
[45808] | 28 | #include <VBox/vmm/hm.h>
|
---|
[35346] | 29 | #include <VBox/vmm/pgm.h>
|
---|
| 30 | #include <VBox/vmm/iom.h>
|
---|
[40274] | 31 | #ifdef VBOX_WITH_REM
|
---|
| 32 | # include <VBox/vmm/rem.h>
|
---|
| 33 | #endif
|
---|
[35346] | 34 | #include <VBox/vmm/dbgf.h>
|
---|
| 35 | #include <VBox/vmm/vmapi.h>
|
---|
| 36 | #include <VBox/vmm/vm.h>
|
---|
| 37 | #include <VBox/vmm/uvm.h>
|
---|
| 38 | #include <VBox/vmm/vmm.h>
|
---|
[1] | 39 |
|
---|
| 40 | #include <VBox/version.h>
|
---|
| 41 | #include <VBox/log.h>
|
---|
| 42 | #include <VBox/err.h>
|
---|
| 43 | #include <iprt/asm.h>
|
---|
| 44 | #include <iprt/assert.h>
|
---|
[29521] | 45 | #include <iprt/ctype.h>
|
---|
[1] | 46 | #include <iprt/string.h>
|
---|
| 47 | #include <iprt/thread.h>
|
---|
| 48 |
|
---|
[40907] | 49 | #include "dtrace/VBoxVMM.h"
|
---|
| 50 | #include "PDMInline.h"
|
---|
[1] | 51 |
|
---|
[40907] | 52 |
|
---|
[57358] | 53 | /*********************************************************************************************************************************
|
---|
| 54 | * Defined Constants And Macros *
|
---|
| 55 | *********************************************************************************************************************************/
|
---|
[18534] | 56 | /** @def PDM_DEVHLP_DEADLOCK_DETECTION
|
---|
| 57 | * Define this to enable the deadlock detection when accessing physical memory.
|
---|
| 58 | */
|
---|
[18791] | 59 | #if /*defined(DEBUG_bird) ||*/ defined(DOXYGEN_RUNNING)
|
---|
[25748] | 60 | # define PDM_DEVHLP_DEADLOCK_DETECTION /**< @todo enable DevHlp deadlock detection! */
|
---|
[18534] | 61 | #endif
|
---|
| 62 |
|
---|
| 63 |
|
---|
[34241] | 64 |
|
---|
| 65 | /**
|
---|
| 66 | * Wrapper around PDMR3LdrGetSymbolRCLazy.
|
---|
| 67 | */
|
---|
| 68 | DECLINLINE(int) pdmR3DevGetSymbolRCLazy(PPDMDEVINS pDevIns, const char *pszSymbol, PRTRCPTR ppvValue)
|
---|
| 69 | {
|
---|
[45808] | 70 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[70948] | 71 | if (!VM_IS_RAW_MODE_ENABLED(pVM))
|
---|
[45808] | 72 | {
|
---|
| 73 | *ppvValue = NIL_RTRCPTR;
|
---|
| 74 | return VINF_SUCCESS;
|
---|
| 75 | }
|
---|
| 76 | return PDMR3LdrGetSymbolRCLazy(pVM,
|
---|
[34241] | 77 | pDevIns->Internal.s.pDevR3->pReg->szRCMod,
|
---|
| 78 | pDevIns->Internal.s.pDevR3->pszRCSearchPath,
|
---|
| 79 | pszSymbol, ppvValue);
|
---|
| 80 | }
|
---|
| 81 |
|
---|
| 82 |
|
---|
| 83 | /**
|
---|
| 84 | * Wrapper around PDMR3LdrGetSymbolR0Lazy.
|
---|
| 85 | */
|
---|
| 86 | DECLINLINE(int) pdmR3DevGetSymbolR0Lazy(PPDMDEVINS pDevIns, const char *pszSymbol, PRTR0PTR ppvValue)
|
---|
| 87 | {
|
---|
| 88 | return PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3,
|
---|
| 89 | pDevIns->Internal.s.pDevR3->pReg->szR0Mod,
|
---|
| 90 | pDevIns->Internal.s.pDevR3->pszR0SearchPath,
|
---|
| 91 | pszSymbol, ppvValue);
|
---|
| 92 | }
|
---|
| 93 |
|
---|
| 94 |
|
---|
[12980] | 95 | /** @name R3 DevHlp
|
---|
| 96 | * @{
|
---|
[1] | 97 | */
|
---|
| 98 |
|
---|
| 99 |
|
---|
[26152] | 100 | /** @interface_method_impl{PDMDEVHLPR3,pfnIOPortRegister} */
|
---|
[39136] | 101 | static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTHCPTR pvUser, PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
|
---|
[1] | 102 | PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc)
|
---|
| 103 | {
|
---|
| 104 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 105 | LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pfnOut=%p pfnIn=%p pfnOutStr=%p pfnInStr=%p p32_tszDesc=%p:{%s}\n", pDevIns->pReg->szName, pDevIns->iInstance,
|
---|
[1] | 106 | Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc, pszDesc));
|
---|
[12970] | 107 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[1] | 108 |
|
---|
[20687] | 109 | #if 0 /** @todo needs a real string cache for this */
|
---|
| 110 | if (pDevIns->iInstance > 0)
|
---|
| 111 | {
|
---|
| 112 | char *pszDesc2 = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_DESC, "%s [%u]", pszDesc, pDevIns->iInstance);
|
---|
| 113 | if (pszDesc2)
|
---|
| 114 | pszDesc = pszDesc2;
|
---|
| 115 | }
|
---|
| 116 | #endif
|
---|
| 117 |
|
---|
[39078] | 118 | int rc = IOMR3IOPortRegisterR3(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser,
|
---|
| 119 | pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc);
|
---|
[1] | 120 |
|
---|
[26165] | 121 | LogFlow(("pdmR3DevHlp_IOPortRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 122 | return rc;
|
---|
| 123 | }
|
---|
| 124 |
|
---|
| 125 |
|
---|
[26157] | 126 | /** @interface_method_impl{PDMDEVHLPR3,pfnIOPortRegisterRC} */
|
---|
[39136] | 127 | static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterRC(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTRCPTR pvUser,
|
---|
[1] | 128 | const char *pszOut, const char *pszIn,
|
---|
| 129 | const char *pszOutStr, const char *pszInStr, const char *pszDesc)
|
---|
| 130 | {
|
---|
| 131 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[80090] | 132 | Assert(pDevIns->pReg->szRCMod[0]);
|
---|
| 133 | Assert(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC);
|
---|
[26165] | 134 | LogFlow(("pdmR3DevHlp_IOPortRegisterRC: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pszOut=%p:{%s} pszIn=%p:{%s} pszOutStr=%p:{%s} pszInStr=%p:{%s} pszDesc=%p:{%s}\n", pDevIns->pReg->szName, pDevIns->iInstance,
|
---|
[1] | 135 | Port, cPorts, pvUser, pszOut, pszOut, pszIn, pszIn, pszOutStr, pszOutStr, pszInStr, pszInStr, pszDesc, pszDesc));
|
---|
| 136 |
|
---|
[80090] | 137 | #if 0
|
---|
[1] | 138 | /*
|
---|
| 139 | * Resolve the functions (one of the can be NULL).
|
---|
| 140 | */
|
---|
[80090] | 141 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 142 | VM_ASSERT_EMT(pVM);
|
---|
[1] | 143 | int rc = VINF_SUCCESS;
|
---|
[45808] | 144 | if ( pDevIns->pReg->szRCMod[0]
|
---|
| 145 | && (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
|
---|
[70948] | 146 | && VM_IS_RAW_MODE_ENABLED(pVM))
|
---|
[1] | 147 | {
|
---|
[13815] | 148 | RTRCPTR RCPtrIn = NIL_RTRCPTR;
|
---|
[1] | 149 | if (pszIn)
|
---|
| 150 | {
|
---|
[34241] | 151 | rc = pdmR3DevGetSymbolRCLazy(pDevIns, pszIn, &RCPtrIn);
|
---|
[26160] | 152 | AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pReg->szRCMod, pszIn));
|
---|
[1] | 153 | }
|
---|
[13815] | 154 | RTRCPTR RCPtrOut = NIL_RTRCPTR;
|
---|
[13816] | 155 | if (pszOut && RT_SUCCESS(rc))
|
---|
[1] | 156 | {
|
---|
[34241] | 157 | rc = pdmR3DevGetSymbolRCLazy(pDevIns, pszOut, &RCPtrOut);
|
---|
[26160] | 158 | AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pReg->szRCMod, pszOut));
|
---|
[1] | 159 | }
|
---|
[13815] | 160 | RTRCPTR RCPtrInStr = NIL_RTRCPTR;
|
---|
[13816] | 161 | if (pszInStr && RT_SUCCESS(rc))
|
---|
[1] | 162 | {
|
---|
[34241] | 163 | rc = pdmR3DevGetSymbolRCLazy(pDevIns, pszInStr, &RCPtrInStr);
|
---|
[26160] | 164 | AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pReg->szRCMod, pszInStr));
|
---|
[1] | 165 | }
|
---|
[13815] | 166 | RTRCPTR RCPtrOutStr = NIL_RTRCPTR;
|
---|
[13816] | 167 | if (pszOutStr && RT_SUCCESS(rc))
|
---|
[1] | 168 | {
|
---|
[34241] | 169 | rc = pdmR3DevGetSymbolRCLazy(pDevIns, pszOutStr, &RCPtrOutStr);
|
---|
[26160] | 170 | AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pReg->szRCMod, pszOutStr));
|
---|
[1] | 171 | }
|
---|
| 172 |
|
---|
[13816] | 173 | if (RT_SUCCESS(rc))
|
---|
[20687] | 174 | {
|
---|
| 175 | #if 0 /** @todo needs a real string cache for this */
|
---|
| 176 | if (pDevIns->iInstance > 0)
|
---|
| 177 | {
|
---|
| 178 | char *pszDesc2 = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_DESC, "%s [%u]", pszDesc, pDevIns->iInstance);
|
---|
| 179 | if (pszDesc2)
|
---|
| 180 | pszDesc = pszDesc2;
|
---|
| 181 | }
|
---|
| 182 | #endif
|
---|
| 183 |
|
---|
[45808] | 184 | rc = IOMR3IOPortRegisterRC(pVM, pDevIns, Port, cPorts, pvUser, RCPtrOut, RCPtrIn, RCPtrOutStr, RCPtrInStr, pszDesc);
|
---|
[20687] | 185 | }
|
---|
[1] | 186 | }
|
---|
[70948] | 187 | else if (VM_IS_RAW_MODE_ENABLED(pVM))
|
---|
[1] | 188 | {
|
---|
[45808] | 189 | AssertMsgFailed(("No RC module for this driver!\n"));
|
---|
[1] | 190 | rc = VERR_INVALID_PARAMETER;
|
---|
| 191 | }
|
---|
[80090] | 192 | #else
|
---|
| 193 | RT_NOREF(pDevIns, Port, cPorts, pvUser, pszOut, pszIn, pszOutStr, pszInStr, pszDesc);
|
---|
| 194 | int rc = VINF_SUCCESS;
|
---|
| 195 | #endif
|
---|
[1] | 196 |
|
---|
[26165] | 197 | LogFlow(("pdmR3DevHlp_IOPortRegisterRC: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 198 | return rc;
|
---|
| 199 | }
|
---|
| 200 |
|
---|
| 201 |
|
---|
[26152] | 202 | /** @interface_method_impl{PDMDEVHLPR3,pfnIOPortRegisterR0} */
|
---|
[39136] | 203 | static DECLCALLBACK(int) pdmR3DevHlp_IOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTR0PTR pvUser,
|
---|
[1] | 204 | const char *pszOut, const char *pszIn,
|
---|
| 205 | const char *pszOutStr, const char *pszInStr, const char *pszDesc)
|
---|
| 206 | {
|
---|
| 207 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 208 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[26165] | 209 | LogFlow(("pdmR3DevHlp_IOPortRegisterR0: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pszOut=%p:{%s} pszIn=%p:{%s} pszOutStr=%p:{%s} pszInStr=%p:{%s} pszDesc=%p:{%s}\n", pDevIns->pReg->szName, pDevIns->iInstance,
|
---|
[1] | 210 | Port, cPorts, pvUser, pszOut, pszOut, pszIn, pszIn, pszOutStr, pszOutStr, pszInStr, pszInStr, pszDesc, pszDesc));
|
---|
| 211 |
|
---|
| 212 | /*
|
---|
| 213 | * Resolve the functions (one of the can be NULL).
|
---|
| 214 | */
|
---|
| 215 | int rc = VINF_SUCCESS;
|
---|
[26160] | 216 | if ( pDevIns->pReg->szR0Mod[0]
|
---|
| 217 | && (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0))
|
---|
[1] | 218 | {
|
---|
[2270] | 219 | R0PTRTYPE(PFNIOMIOPORTIN) pfnR0PtrIn = 0;
|
---|
[1] | 220 | if (pszIn)
|
---|
| 221 | {
|
---|
[34241] | 222 | rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pszIn, &pfnR0PtrIn);
|
---|
[26160] | 223 | AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pReg->szR0Mod, pszIn));
|
---|
[1] | 224 | }
|
---|
[2270] | 225 | R0PTRTYPE(PFNIOMIOPORTOUT) pfnR0PtrOut = 0;
|
---|
[13816] | 226 | if (pszOut && RT_SUCCESS(rc))
|
---|
[1] | 227 | {
|
---|
[34241] | 228 | rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pszOut, &pfnR0PtrOut);
|
---|
[26160] | 229 | AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pReg->szR0Mod, pszOut));
|
---|
[1] | 230 | }
|
---|
[2270] | 231 | R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnR0PtrInStr = 0;
|
---|
[13816] | 232 | if (pszInStr && RT_SUCCESS(rc))
|
---|
[1] | 233 | {
|
---|
[34241] | 234 | rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pszInStr, &pfnR0PtrInStr);
|
---|
[26160] | 235 | AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pReg->szR0Mod, pszInStr));
|
---|
[1] | 236 | }
|
---|
[2270] | 237 | R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnR0PtrOutStr = 0;
|
---|
[13816] | 238 | if (pszOutStr && RT_SUCCESS(rc))
|
---|
[1] | 239 | {
|
---|
[34241] | 240 | rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pszOutStr, &pfnR0PtrOutStr);
|
---|
[26160] | 241 | AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pReg->szR0Mod, pszOutStr));
|
---|
[1] | 242 | }
|
---|
| 243 |
|
---|
[13816] | 244 | if (RT_SUCCESS(rc))
|
---|
[20687] | 245 | {
|
---|
| 246 | #if 0 /** @todo needs a real string cache for this */
|
---|
| 247 | if (pDevIns->iInstance > 0)
|
---|
| 248 | {
|
---|
| 249 | char *pszDesc2 = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_DESC, "%s [%u]", pszDesc, pDevIns->iInstance);
|
---|
| 250 | if (pszDesc2)
|
---|
| 251 | pszDesc = pszDesc2;
|
---|
| 252 | }
|
---|
| 253 | #endif
|
---|
| 254 |
|
---|
[12970] | 255 | rc = IOMR3IOPortRegisterR0(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts, pvUser, pfnR0PtrOut, pfnR0PtrIn, pfnR0PtrOutStr, pfnR0PtrInStr, pszDesc);
|
---|
[20687] | 256 | }
|
---|
[1] | 257 | }
|
---|
| 258 | else
|
---|
| 259 | {
|
---|
| 260 | AssertMsgFailed(("No R0 module for this driver!\n"));
|
---|
| 261 | rc = VERR_INVALID_PARAMETER;
|
---|
| 262 | }
|
---|
| 263 |
|
---|
[26165] | 264 | LogFlow(("pdmR3DevHlp_IOPortRegisterR0: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 265 | return rc;
|
---|
| 266 | }
|
---|
| 267 |
|
---|
| 268 |
|
---|
[26152] | 269 | /** @interface_method_impl{PDMDEVHLPR3,pfnIOPortDeregister} */
|
---|
[39136] | 270 | static DECLCALLBACK(int) pdmR3DevHlp_IOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts)
|
---|
[1] | 271 | {
|
---|
| 272 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 273 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[26165] | 274 | LogFlow(("pdmR3DevHlp_IOPortDeregister: caller='%s'/%d: Port=%#x cPorts=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance,
|
---|
[1] | 275 | Port, cPorts));
|
---|
| 276 |
|
---|
[12970] | 277 | int rc = IOMR3IOPortDeregister(pDevIns->Internal.s.pVMR3, pDevIns, Port, cPorts);
|
---|
[1] | 278 |
|
---|
[26165] | 279 | LogFlow(("pdmR3DevHlp_IOPortDeregister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 280 | return rc;
|
---|
| 281 | }
|
---|
| 282 |
|
---|
| 283 |
|
---|
[26152] | 284 | /** @interface_method_impl{PDMDEVHLPR3,pfnMMIORegister} */
|
---|
[63682] | 285 | static DECLCALLBACK(int) pdmR3DevHlp_MMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTHCPTR pvUser,
|
---|
[1] | 286 | PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
|
---|
[39111] | 287 | uint32_t fFlags, const char *pszDesc)
|
---|
[1] | 288 | {
|
---|
| 289 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[39111] | 290 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 291 | VM_ASSERT_EMT(pVM);
|
---|
[63682] | 292 | LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: GCPhysStart=%RGp cbRange=%RGp pvUser=%p pfnWrite=%p pfnRead=%p pfnFill=%p fFlags=%#x pszDesc=%p:{%s}\n",
|
---|
[39111] | 293 | pDevIns->pReg->szName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc, fFlags, pszDesc));
|
---|
[1] | 294 |
|
---|
[39111] | 295 | if (pDevIns->iInstance > 0)
|
---|
| 296 | {
|
---|
| 297 | char *pszDesc2 = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_DESC, "%s [%u]", pszDesc, pDevIns->iInstance);
|
---|
| 298 | if (pszDesc2)
|
---|
| 299 | pszDesc = pszDesc2;
|
---|
| 300 | }
|
---|
[1] | 301 |
|
---|
[39111] | 302 | int rc = IOMR3MmioRegisterR3(pVM, pDevIns, GCPhysStart, cbRange, pvUser,
|
---|
| 303 | pfnWrite, pfnRead, pfnFill, fFlags, pszDesc);
|
---|
| 304 |
|
---|
[26165] | 305 | LogFlow(("pdmR3DevHlp_MMIORegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 306 | return rc;
|
---|
| 307 | }
|
---|
| 308 |
|
---|
| 309 |
|
---|
[26157] | 310 | /** @interface_method_impl{PDMDEVHLPR3,pfnMMIORegisterRC} */
|
---|
[63682] | 311 | static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterRC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTRCPTR pvUser,
|
---|
[39078] | 312 | const char *pszWrite, const char *pszRead, const char *pszFill)
|
---|
[1] | 313 | {
|
---|
| 314 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[80090] | 315 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
| 316 | Assert(pDevIns->pReg->szR0Mod[0]);
|
---|
| 317 | Assert(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0);
|
---|
[63682] | 318 | LogFlow(("pdmR3DevHlp_MMIORegisterRC: caller='%s'/%d: GCPhysStart=%RGp cbRange=%RGp pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n",
|
---|
[26165] | 319 | pDevIns->pReg->szName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pszWrite, pszWrite, pszRead, pszRead, pszFill, pszFill));
|
---|
[1] | 320 |
|
---|
[80090] | 321 | #if 0
|
---|
[1] | 322 | /*
|
---|
| 323 | * Resolve the functions.
|
---|
| 324 | * Not all function have to present, leave it to IOM to enforce this.
|
---|
| 325 | */
|
---|
| 326 | int rc = VINF_SUCCESS;
|
---|
[45808] | 327 | if ( pDevIns->pReg->szRCMod[0]
|
---|
| 328 | && (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
|
---|
[80090] | 329 | && VM_IS_RAW_MODE_ENABLED(pDevIns->Internal.s.pVMR3))
|
---|
[1] | 330 | {
|
---|
[13815] | 331 | RTRCPTR RCPtrWrite = NIL_RTRCPTR;
|
---|
[1] | 332 | if (pszWrite)
|
---|
[34241] | 333 | rc = pdmR3DevGetSymbolRCLazy(pDevIns, pszWrite, &RCPtrWrite);
|
---|
[13815] | 334 |
|
---|
| 335 | RTRCPTR RCPtrRead = NIL_RTRCPTR;
|
---|
[1] | 336 | int rc2 = VINF_SUCCESS;
|
---|
| 337 | if (pszRead)
|
---|
[34241] | 338 | rc2 = pdmR3DevGetSymbolRCLazy(pDevIns, pszRead, &RCPtrRead);
|
---|
[13815] | 339 |
|
---|
| 340 | RTRCPTR RCPtrFill = NIL_RTRCPTR;
|
---|
[1] | 341 | int rc3 = VINF_SUCCESS;
|
---|
| 342 | if (pszFill)
|
---|
[34241] | 343 | rc3 = pdmR3DevGetSymbolRCLazy(pDevIns, pszFill, &RCPtrFill);
|
---|
[13815] | 344 |
|
---|
[13816] | 345 | if (RT_SUCCESS(rc) && RT_SUCCESS(rc2) && RT_SUCCESS(rc3))
|
---|
[80090] | 346 | rc = IOMR3MmioRegisterRC(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser, RCPtrWrite, RCPtrRead, RCPtrFill);
|
---|
[1] | 347 | else
|
---|
| 348 | {
|
---|
[26160] | 349 | AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pReg->szRCMod, pszWrite));
|
---|
| 350 | AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n", pDevIns->pReg->szRCMod, pszRead));
|
---|
| 351 | AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n", pDevIns->pReg->szRCMod, pszFill));
|
---|
[13816] | 352 | if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
|
---|
[1] | 353 | rc = rc2;
|
---|
[13816] | 354 | if (RT_FAILURE(rc3) && RT_SUCCESS(rc))
|
---|
[1] | 355 | rc = rc3;
|
---|
| 356 | }
|
---|
| 357 | }
|
---|
[80090] | 358 | else if (VM_IS_RAW_MODE_ENABLED(pDevIns->Internal.s.pVMR3))
|
---|
[1] | 359 | {
|
---|
[45808] | 360 | AssertMsgFailed(("No RC module for this driver!\n"));
|
---|
[1] | 361 | rc = VERR_INVALID_PARAMETER;
|
---|
| 362 | }
|
---|
[80090] | 363 | #else
|
---|
| 364 | int rc = VINF_SUCCESS;
|
---|
| 365 | RT_NOREF(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, pszFill);
|
---|
| 366 | #endif
|
---|
[1] | 367 |
|
---|
[26165] | 368 | LogFlow(("pdmR3DevHlp_MMIORegisterRC: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 369 | return rc;
|
---|
| 370 | }
|
---|
| 371 |
|
---|
[26152] | 372 | /** @interface_method_impl{PDMDEVHLPR3,pfnMMIORegisterR0} */
|
---|
[63682] | 373 | static DECLCALLBACK(int) pdmR3DevHlp_MMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTR0PTR pvUser,
|
---|
[39078] | 374 | const char *pszWrite, const char *pszRead, const char *pszFill)
|
---|
[1] | 375 | {
|
---|
| 376 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 377 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[80090] | 378 | Assert(pDevIns->pReg->szR0Mod[0]);
|
---|
| 379 | Assert(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0);
|
---|
[63682] | 380 | LogFlow(("pdmR3DevHlp_MMIORegisterHC: caller='%s'/%d: GCPhysStart=%RGp cbRange=%RGp pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n",
|
---|
[26165] | 381 | pDevIns->pReg->szName, pDevIns->iInstance, GCPhysStart, cbRange, pvUser, pszWrite, pszWrite, pszRead, pszRead, pszFill, pszFill));
|
---|
[1] | 382 |
|
---|
| 383 | /*
|
---|
| 384 | * Resolve the functions.
|
---|
| 385 | * Not all function have to present, leave it to IOM to enforce this.
|
---|
| 386 | */
|
---|
| 387 | int rc = VINF_SUCCESS;
|
---|
[80090] | 388 | if ( pDevIns->pReg->szR0Mod[0]
|
---|
| 389 | && (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0))
|
---|
[1] | 390 | {
|
---|
[2270] | 391 | R0PTRTYPE(PFNIOMMMIOWRITE) pfnR0PtrWrite = 0;
|
---|
[1] | 392 | if (pszWrite)
|
---|
[34241] | 393 | rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pszWrite, &pfnR0PtrWrite);
|
---|
[2270] | 394 | R0PTRTYPE(PFNIOMMMIOREAD) pfnR0PtrRead = 0;
|
---|
[1] | 395 | int rc2 = VINF_SUCCESS;
|
---|
| 396 | if (pszRead)
|
---|
[34241] | 397 | rc2 = pdmR3DevGetSymbolR0Lazy(pDevIns, pszRead, &pfnR0PtrRead);
|
---|
[2270] | 398 | R0PTRTYPE(PFNIOMMMIOFILL) pfnR0PtrFill = 0;
|
---|
[1] | 399 | int rc3 = VINF_SUCCESS;
|
---|
| 400 | if (pszFill)
|
---|
[34241] | 401 | rc3 = pdmR3DevGetSymbolR0Lazy(pDevIns, pszFill, &pfnR0PtrFill);
|
---|
[13816] | 402 | if (RT_SUCCESS(rc) && RT_SUCCESS(rc2) && RT_SUCCESS(rc3))
|
---|
[63682] | 403 | rc = IOMR3MmioRegisterR0(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvUser,
|
---|
| 404 | pfnR0PtrWrite, pfnR0PtrRead, pfnR0PtrFill);
|
---|
[1] | 405 | else
|
---|
| 406 | {
|
---|
[26160] | 407 | AssertMsgRC(rc, ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pReg->szR0Mod, pszWrite));
|
---|
| 408 | AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n", pDevIns->pReg->szR0Mod, pszRead));
|
---|
| 409 | AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n", pDevIns->pReg->szR0Mod, pszFill));
|
---|
[13816] | 410 | if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
|
---|
[1] | 411 | rc = rc2;
|
---|
[13816] | 412 | if (RT_FAILURE(rc3) && RT_SUCCESS(rc))
|
---|
[1] | 413 | rc = rc3;
|
---|
| 414 | }
|
---|
| 415 | }
|
---|
| 416 | else
|
---|
| 417 | {
|
---|
| 418 | AssertMsgFailed(("No R0 module for this driver!\n"));
|
---|
| 419 | rc = VERR_INVALID_PARAMETER;
|
---|
| 420 | }
|
---|
| 421 |
|
---|
[26165] | 422 | LogFlow(("pdmR3DevHlp_MMIORegisterR0: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 423 | return rc;
|
---|
| 424 | }
|
---|
| 425 |
|
---|
| 426 |
|
---|
[26152] | 427 | /** @interface_method_impl{PDMDEVHLPR3,pfnMMIODeregister} */
|
---|
[63682] | 428 | static DECLCALLBACK(int) pdmR3DevHlp_MMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange)
|
---|
[1] | 429 | {
|
---|
| 430 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 431 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[63682] | 432 | LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: GCPhysStart=%RGp cbRange=%RGp\n",
|
---|
[26165] | 433 | pDevIns->pReg->szName, pDevIns->iInstance, GCPhysStart, cbRange));
|
---|
[1] | 434 |
|
---|
[37452] | 435 | int rc = IOMR3MmioDeregister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange);
|
---|
[1] | 436 |
|
---|
[26165] | 437 | LogFlow(("pdmR3DevHlp_MMIODeregister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 438 | return rc;
|
---|
| 439 | }
|
---|
| 440 |
|
---|
| 441 |
|
---|
[26157] | 442 | /**
|
---|
| 443 | * @copydoc PDMDEVHLPR3::pfnMMIO2Register
|
---|
| 444 | */
|
---|
[64387] | 445 | static DECLCALLBACK(int) pdmR3DevHlp_MMIO2Register(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cb,
|
---|
[64373] | 446 | uint32_t fFlags, void **ppv, const char *pszDesc)
|
---|
[26157] | 447 | {
|
---|
| 448 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 449 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[64373] | 450 | LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: pPciDev=%p (%#x) iRegion=%#x cb=%#RGp fFlags=%RX32 ppv=%p pszDescp=%p:{%s}\n",
|
---|
[64378] | 451 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->uDevFn : UINT32_MAX, iRegion,
|
---|
[64373] | 452 | cb, fFlags, ppv, pszDesc, pszDesc));
|
---|
| 453 | AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 == pDevIns, VERR_INVALID_PARAMETER);
|
---|
[26157] | 454 |
|
---|
| 455 | /** @todo PGMR3PhysMMIO2Register mangles the description, move it here and
|
---|
| 456 | * use a real string cache. */
|
---|
[64373] | 457 | int rc = PGMR3PhysMMIO2Register(pDevIns->Internal.s.pVMR3, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion,
|
---|
| 458 | cb, fFlags, ppv, pszDesc);
|
---|
[26157] | 459 |
|
---|
[26165] | 460 | LogFlow(("pdmR3DevHlp_MMIO2Register: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 461 | return rc;
|
---|
| 462 | }
|
---|
| 463 |
|
---|
| 464 |
|
---|
| 465 | /**
|
---|
[64115] | 466 | * @interface_method_impl{PDMDEVHLPR3,pfnMMIOExPreRegister}
|
---|
[26157] | 467 | */
|
---|
[64115] | 468 | static DECLCALLBACK(int)
|
---|
[64387] | 469 | pdmR3DevHlp_MMIOExPreRegister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cbRegion, uint32_t fFlags,
|
---|
[64353] | 470 | const char *pszDesc,
|
---|
[64115] | 471 | RTHCPTR pvUser, PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
|
---|
| 472 | RTR0PTR pvUserR0, const char *pszWriteR0, const char *pszReadR0, const char *pszFillR0,
|
---|
| 473 | RTRCPTR pvUserRC, const char *pszWriteRC, const char *pszReadRC, const char *pszFillRC)
|
---|
[26157] | 474 | {
|
---|
| 475 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[64115] | 476 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 477 | VM_ASSERT_EMT(pVM);
|
---|
[64353] | 478 | LogFlow(("pdmR3DevHlp_MMIOExPreRegister: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x cbRegion=%#RGp fFlags=%RX32 pszDesc=%p:{%s}\n"
|
---|
[64115] | 479 | " pvUser=%p pfnWrite=%p pfnRead=%p pfnFill=%p\n"
|
---|
| 480 | " pvUserR0=%p pszWriteR0=%s pszReadR0=%s pszFillR0=%s\n"
|
---|
| 481 | " pvUserRC=%p pszWriteRC=%s pszReadRC=%s pszFillRC=%s\n",
|
---|
[64378] | 482 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->uDevFn : UINT32_MAX, iRegion, cbRegion,
|
---|
[64353] | 483 | fFlags, pszDesc, pszDesc,
|
---|
[64115] | 484 | pvUser, pfnWrite, pfnRead, pfnFill,
|
---|
| 485 | pvUserR0, pszWriteR0, pszReadR0, pszFillR0,
|
---|
| 486 | pvUserRC, pszWriteRC, pszReadRC, pszFillRC));
|
---|
[64373] | 487 | AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 == pDevIns, VERR_INVALID_PARAMETER);
|
---|
[64115] | 488 |
|
---|
| 489 | /*
|
---|
| 490 | * Resolve the functions.
|
---|
| 491 | */
|
---|
| 492 | AssertLogRelReturn( (!pszWriteR0 && !pszReadR0 && !pszFillR0)
|
---|
| 493 | || (pDevIns->pReg->szR0Mod[0] && (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)),
|
---|
| 494 | VERR_INVALID_PARAMETER);
|
---|
| 495 | AssertLogRelReturn( (!pszWriteRC && !pszReadRC && !pszFillRC)
|
---|
| 496 | || (pDevIns->pReg->szRCMod[0] && (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)),
|
---|
| 497 | VERR_INVALID_PARAMETER);
|
---|
| 498 |
|
---|
| 499 | /* Ring-0 */
|
---|
| 500 | int rc;
|
---|
| 501 | R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteR0 = 0;
|
---|
| 502 | if (pszWriteR0)
|
---|
| 503 | {
|
---|
| 504 | rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pszWriteR0, &pfnWriteR0);
|
---|
| 505 | AssertLogRelMsgRCReturn(rc, ("pszWriteR0=%s rc=%Rrc\n", pszWriteR0, rc), rc);
|
---|
| 506 | }
|
---|
| 507 |
|
---|
| 508 | R0PTRTYPE(PFNIOMMMIOREAD) pfnReadR0 = 0;
|
---|
| 509 | if (pszReadR0)
|
---|
| 510 | {
|
---|
| 511 | rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pszReadR0, &pfnReadR0);
|
---|
| 512 | AssertLogRelMsgRCReturn(rc, ("pszReadR0=%s rc=%Rrc\n", pszReadR0, rc), rc);
|
---|
| 513 | }
|
---|
| 514 | R0PTRTYPE(PFNIOMMMIOFILL) pfnFillR0 = 0;
|
---|
| 515 | if (pszFillR0)
|
---|
| 516 | {
|
---|
| 517 | rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pszFillR0, &pfnFillR0);
|
---|
| 518 | AssertLogRelMsgRCReturn(rc, ("pszFillR0=%s rc=%Rrc\n", pszFillR0, rc), rc);
|
---|
| 519 | }
|
---|
| 520 |
|
---|
| 521 | /* Raw-mode */
|
---|
[80090] | 522 | #if 0
|
---|
[64115] | 523 | RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteRC = 0;
|
---|
| 524 | if (pszWriteRC)
|
---|
| 525 | {
|
---|
| 526 | rc = pdmR3DevGetSymbolRCLazy(pDevIns, pszWriteRC, &pfnWriteRC);
|
---|
| 527 | AssertLogRelMsgRCReturn(rc, ("pszWriteRC=%s rc=%Rrc\n", pszWriteRC, rc), rc);
|
---|
| 528 | }
|
---|
| 529 |
|
---|
| 530 | RCPTRTYPE(PFNIOMMMIOREAD) pfnReadRC = 0;
|
---|
| 531 | if (pszReadRC)
|
---|
| 532 | {
|
---|
| 533 | rc = pdmR3DevGetSymbolRCLazy(pDevIns, pszReadRC, &pfnReadRC);
|
---|
| 534 | AssertLogRelMsgRCReturn(rc, ("pszReadRC=%s rc=%Rrc\n", pszReadRC, rc), rc);
|
---|
| 535 | }
|
---|
| 536 | RCPTRTYPE(PFNIOMMMIOFILL) pfnFillRC = 0;
|
---|
| 537 | if (pszFillRC)
|
---|
| 538 | {
|
---|
| 539 | rc = pdmR3DevGetSymbolRCLazy(pDevIns, pszFillRC, &pfnFillRC);
|
---|
| 540 | AssertLogRelMsgRCReturn(rc, ("pszFillRC=%s rc=%Rrc\n", pszFillRC, rc), rc);
|
---|
| 541 | }
|
---|
[80090] | 542 | #else
|
---|
| 543 | RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteRC = 0;
|
---|
| 544 | RCPTRTYPE(PFNIOMMMIOREAD) pfnReadRC = 0;
|
---|
| 545 | RCPTRTYPE(PFNIOMMMIOFILL) pfnFillRC = 0;
|
---|
| 546 | RT_NOREF(pszWriteRC, pszReadRC, pszFillRC);
|
---|
| 547 | #endif
|
---|
[64115] | 548 |
|
---|
[80090] | 549 |
|
---|
[64115] | 550 | /*
|
---|
| 551 | * Call IOM to make the registration.
|
---|
| 552 | */
|
---|
[64373] | 553 | rc = IOMR3MmioExPreRegister(pVM, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion, cbRegion, fFlags, pszDesc,
|
---|
[64115] | 554 | pvUser, pfnWrite, pfnRead, pfnFill,
|
---|
| 555 | pvUserR0, pfnWriteR0, pfnReadR0, pfnFillR0,
|
---|
| 556 | pvUserRC, pfnWriteRC, pfnReadRC, pfnFillRC);
|
---|
| 557 |
|
---|
| 558 | LogFlow(("pdmR3DevHlp_MMIOExPreRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 559 | return rc;
|
---|
| 560 | }
|
---|
| 561 |
|
---|
| 562 |
|
---|
| 563 | /**
|
---|
| 564 | * @copydoc PDMDEVHLPR3::pfnMMIOExDeregister
|
---|
| 565 | */
|
---|
[64387] | 566 | static DECLCALLBACK(int) pdmR3DevHlp_MMIOExDeregister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion)
|
---|
[64115] | 567 | {
|
---|
| 568 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26157] | 569 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[64373] | 570 | LogFlow(("pdmR3DevHlp_MMIOExDeregister: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x\n",
|
---|
[64378] | 571 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->uDevFn : UINT32_MAX, iRegion));
|
---|
[26157] | 572 |
|
---|
[49812] | 573 | AssertReturn(iRegion <= UINT8_MAX || iRegion == UINT32_MAX, VERR_INVALID_PARAMETER);
|
---|
[64373] | 574 | AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 == pDevIns, VERR_INVALID_PARAMETER);
|
---|
[26157] | 575 |
|
---|
[64373] | 576 | int rc = PGMR3PhysMMIOExDeregister(pDevIns->Internal.s.pVMR3, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion);
|
---|
[26157] | 577 |
|
---|
[64115] | 578 | LogFlow(("pdmR3DevHlp_MMIOExDeregister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 579 | return rc;
|
---|
| 580 | }
|
---|
| 581 |
|
---|
| 582 |
|
---|
| 583 | /**
|
---|
[64115] | 584 | * @copydoc PDMDEVHLPR3::pfnMMIOExMap
|
---|
[26157] | 585 | */
|
---|
[64387] | 586 | static DECLCALLBACK(int) pdmR3DevHlp_MMIOExMap(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS GCPhys)
|
---|
[26157] | 587 | {
|
---|
| 588 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 589 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[64373] | 590 | LogFlow(("pdmR3DevHlp_MMIOExMap: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x GCPhys=%#RGp\n",
|
---|
[64378] | 591 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->uDevFn : UINT32_MAX, iRegion, GCPhys));
|
---|
[64373] | 592 | AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 != NULL, VERR_INVALID_PARAMETER);
|
---|
[26157] | 593 |
|
---|
[64373] | 594 | int rc = PGMR3PhysMMIOExMap(pDevIns->Internal.s.pVMR3, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion, GCPhys);
|
---|
[26157] | 595 |
|
---|
[64115] | 596 | LogFlow(("pdmR3DevHlp_MMIOExMap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 597 | return rc;
|
---|
| 598 | }
|
---|
| 599 |
|
---|
| 600 |
|
---|
| 601 | /**
|
---|
[64115] | 602 | * @copydoc PDMDEVHLPR3::pfnMMIOExUnmap
|
---|
[26157] | 603 | */
|
---|
[64387] | 604 | static DECLCALLBACK(int) pdmR3DevHlp_MMIOExUnmap(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS GCPhys)
|
---|
[26157] | 605 | {
|
---|
| 606 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 607 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[64373] | 608 | LogFlow(("pdmR3DevHlp_MMIOExUnmap: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x GCPhys=%#RGp\n",
|
---|
[64378] | 609 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->uDevFn : UINT32_MAX, iRegion, GCPhys));
|
---|
[64373] | 610 | AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 != NULL, VERR_INVALID_PARAMETER);
|
---|
[26157] | 611 |
|
---|
[64373] | 612 | int rc = PGMR3PhysMMIOExUnmap(pDevIns->Internal.s.pVMR3, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion, GCPhys);
|
---|
[26157] | 613 |
|
---|
[64115] | 614 | LogFlow(("pdmR3DevHlp_MMIOExUnmap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 615 | return rc;
|
---|
| 616 | }
|
---|
| 617 |
|
---|
| 618 |
|
---|
| 619 | /**
|
---|
[65299] | 620 | * @copydoc PDMDEVHLPR3::pfnMMIOExReduce
|
---|
| 621 | */
|
---|
| 622 | static DECLCALLBACK(int) pdmR3DevHlp_MMIOExReduce(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cbRegion)
|
---|
| 623 | {
|
---|
| 624 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 625 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
| 626 | LogFlow(("pdmR3DevHlp_MMIOExReduce: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x cbRegion=%RGp\n",
|
---|
| 627 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->uDevFn : UINT32_MAX, iRegion, cbRegion));
|
---|
| 628 | AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 != NULL, VERR_INVALID_PARAMETER);
|
---|
| 629 |
|
---|
| 630 | int rc = PGMR3PhysMMIOExReduce(pDevIns->Internal.s.pVMR3, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion, cbRegion);
|
---|
| 631 |
|
---|
| 632 | LogFlow(("pdmR3DevHlp_MMIOExReduce: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 633 | return rc;
|
---|
| 634 | }
|
---|
| 635 |
|
---|
| 636 |
|
---|
| 637 | /**
|
---|
[26157] | 638 | * @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2
|
---|
| 639 | */
|
---|
[64387] | 640 | static DECLCALLBACK(int) pdmR3DevHlp_MMHyperMapMMIO2(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS off,
|
---|
[64373] | 641 | RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr)
|
---|
[26157] | 642 | {
|
---|
| 643 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[80118] | 644 | #ifndef PGM_WITHOUT_MAPPINGS
|
---|
[26157] | 645 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 646 | VM_ASSERT_EMT(pVM);
|
---|
[64373] | 647 | LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x off=%RGp cb=%RGp pszDesc=%p:{%s} pRCPtr=%p\n",
|
---|
[64378] | 648 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->uDevFn : UINT32_MAX, iRegion, off, cb, pszDesc, pszDesc, pRCPtr));
|
---|
[64373] | 649 | AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 == pDevIns, VERR_INVALID_PARAMETER);
|
---|
[26157] | 650 |
|
---|
| 651 | if (pDevIns->iInstance > 0)
|
---|
| 652 | {
|
---|
| 653 | char *pszDesc2 = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_DESC, "%s [%u]", pszDesc, pDevIns->iInstance);
|
---|
| 654 | if (pszDesc2)
|
---|
| 655 | pszDesc = pszDesc2;
|
---|
| 656 | }
|
---|
| 657 |
|
---|
[64373] | 658 | int rc = MMR3HyperMapMMIO2(pVM, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion, off, cb, pszDesc, pRCPtr);
|
---|
[26157] | 659 |
|
---|
[80118] | 660 | #else
|
---|
| 661 | RT_NOREF(pDevIns, pPciDev, iRegion, off, cb, pszDesc, pRCPtr);
|
---|
| 662 | AssertFailed();
|
---|
| 663 | int rc = VERR_RAW_MODE_NOT_SUPPORTED;
|
---|
| 664 | #endif
|
---|
[26165] | 665 | LogFlow(("pdmR3DevHlp_MMHyperMapMMIO2: caller='%s'/%d: returns %Rrc *pRCPtr=%RRv\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *pRCPtr));
|
---|
[26157] | 666 | return rc;
|
---|
| 667 | }
|
---|
| 668 |
|
---|
| 669 |
|
---|
| 670 | /**
|
---|
| 671 | * @copydoc PDMDEVHLPR3::pfnMMIO2MapKernel
|
---|
| 672 | */
|
---|
[64387] | 673 | static DECLCALLBACK(int) pdmR3DevHlp_MMIO2MapKernel(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS off,
|
---|
[64373] | 674 | RTGCPHYS cb,const char *pszDesc, PRTR0PTR pR0Ptr)
|
---|
[26157] | 675 | {
|
---|
| 676 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 677 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 678 | VM_ASSERT_EMT(pVM);
|
---|
[64373] | 679 | LogFlow(("pdmR3DevHlp_MMIO2MapKernel: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x off=%RGp cb=%RGp pszDesc=%p:{%s} pR0Ptr=%p\n",
|
---|
[64378] | 680 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->uDevFn : UINT32_MAX, iRegion, off, cb, pszDesc, pszDesc, pR0Ptr));
|
---|
[64373] | 681 | AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 == pDevIns, VERR_INVALID_PARAMETER);
|
---|
[26157] | 682 |
|
---|
| 683 | if (pDevIns->iInstance > 0)
|
---|
| 684 | {
|
---|
| 685 | char *pszDesc2 = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_DESC, "%s [%u]", pszDesc, pDevIns->iInstance);
|
---|
| 686 | if (pszDesc2)
|
---|
| 687 | pszDesc = pszDesc2;
|
---|
| 688 | }
|
---|
| 689 |
|
---|
[64373] | 690 | int rc = PGMR3PhysMMIO2MapKernel(pVM, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion, off, cb, pszDesc, pR0Ptr);
|
---|
[26157] | 691 |
|
---|
[26165] | 692 | LogFlow(("pdmR3DevHlp_MMIO2MapKernel: caller='%s'/%d: returns %Rrc *pR0Ptr=%RHv\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *pR0Ptr));
|
---|
[26157] | 693 | return rc;
|
---|
| 694 | }
|
---|
| 695 |
|
---|
| 696 |
|
---|
[77299] | 697 | /**
|
---|
| 698 | * @copydoc PDMDEVHLPR3::pfnMMIOExChangeRegionNo
|
---|
| 699 | */
|
---|
| 700 | static DECLCALLBACK(int) pdmR3DevHlp_MMIOExChangeRegionNo(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
|
---|
| 701 | uint32_t iNewRegion)
|
---|
| 702 | {
|
---|
| 703 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 704 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 705 | VM_ASSERT_EMT(pVM);
|
---|
| 706 | LogFlow(("pdmR3DevHlp_MMIOExChangeRegionNo: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x iNewRegion=%#x\n",
|
---|
| 707 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->uDevFn : UINT32_MAX, iRegion, iNewRegion));
|
---|
| 708 | AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 == pDevIns, VERR_INVALID_PARAMETER);
|
---|
| 709 |
|
---|
| 710 | int rc = PGMR3PhysMMIOExChangeRegionNo(pVM, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion, iNewRegion);
|
---|
| 711 |
|
---|
| 712 | LogFlow(("pdmR3DevHlp_MMIOExChangeRegionNo: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 713 | return rc;
|
---|
| 714 | }
|
---|
| 715 |
|
---|
| 716 |
|
---|
[26152] | 717 | /** @interface_method_impl{PDMDEVHLPR3,pfnROMRegister} */
|
---|
[39136] | 718 | static DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange,
|
---|
[34163] | 719 | const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc)
|
---|
[1] | 720 | {
|
---|
| 721 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 722 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[34163] | 723 | LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: GCPhysStart=%RGp cbRange=%#x pvBinary=%p cbBinary=%#x fFlags=%#RX32 pszDesc=%p:{%s}\n",
|
---|
| 724 | pDevIns->pReg->szName, pDevIns->iInstance, GCPhysStart, cbRange, pvBinary, cbBinary, fFlags, pszDesc, pszDesc));
|
---|
[1] | 725 |
|
---|
[20687] | 726 | /** @todo can we mangle pszDesc? */
|
---|
[34163] | 727 | int rc = PGMR3PhysRomRegister(pDevIns->Internal.s.pVMR3, pDevIns, GCPhysStart, cbRange, pvBinary, cbBinary, fFlags, pszDesc);
|
---|
[1] | 728 |
|
---|
[26165] | 729 | LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 730 | return rc;
|
---|
| 731 | }
|
---|
| 732 |
|
---|
| 733 |
|
---|
[26157] | 734 | /** @interface_method_impl{PDMDEVHLPR3,pfnROMProtectShadow} */
|
---|
[39136] | 735 | static DECLCALLBACK(int) pdmR3DevHlp_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, PGMROMPROT enmProt)
|
---|
[26157] | 736 | {
|
---|
| 737 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 738 | LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: GCPhysStart=%RGp cbRange=%#x enmProt=%d\n",
|
---|
[26165] | 739 | pDevIns->pReg->szName, pDevIns->iInstance, GCPhysStart, cbRange, enmProt));
|
---|
[26157] | 740 |
|
---|
| 741 | int rc = PGMR3PhysRomProtect(pDevIns->Internal.s.pVMR3, GCPhysStart, cbRange, enmProt);
|
---|
| 742 |
|
---|
[26165] | 743 | LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 744 | return rc;
|
---|
| 745 | }
|
---|
| 746 |
|
---|
| 747 |
|
---|
[26152] | 748 | /** @interface_method_impl{PDMDEVHLPR3,pfnSSMRegister} */
|
---|
[22480] | 749 | static DECLCALLBACK(int) pdmR3DevHlp_SSMRegister(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
|
---|
| 750 | PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
|
---|
[1] | 751 | PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
|
---|
| 752 | PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)
|
---|
| 753 | {
|
---|
| 754 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 755 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[56985] | 756 | LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: uVersion=%#x cbGuess=%#x pszBefore=%p:{%s}\n"
|
---|
[22480] | 757 | " pfnLivePrep=%p pfnLiveExec=%p pfnLiveVote=%p pfnSavePrep=%p pfnSaveExec=%p pfnSaveDone=%p pszLoadPrep=%p pfnLoadExec=%p pfnLoadDone=%p\n",
|
---|
[26165] | 758 | pDevIns->pReg->szName, pDevIns->iInstance, uVersion, cbGuess, pszBefore, pszBefore,
|
---|
[22480] | 759 | pfnLivePrep, pfnLiveExec, pfnLiveVote,
|
---|
| 760 | pfnSavePrep, pfnSaveExec, pfnSaveDone,
|
---|
| 761 | pfnLoadPrep, pfnLoadExec, pfnLoadDone));
|
---|
[1] | 762 |
|
---|
[26165] | 763 | int rc = SSMR3RegisterDevice(pDevIns->Internal.s.pVMR3, pDevIns, pDevIns->pReg->szName, pDevIns->iInstance,
|
---|
[22480] | 764 | uVersion, cbGuess, pszBefore,
|
---|
| 765 | pfnLivePrep, pfnLiveExec, pfnLiveVote,
|
---|
[13594] | 766 | pfnSavePrep, pfnSaveExec, pfnSaveDone,
|
---|
| 767 | pfnLoadPrep, pfnLoadExec, pfnLoadDone);
|
---|
[1] | 768 |
|
---|
[26165] | 769 | LogFlow(("pdmR3DevHlp_SSMRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 770 | return rc;
|
---|
| 771 | }
|
---|
| 772 |
|
---|
| 773 |
|
---|
[26152] | 774 | /** @interface_method_impl{PDMDEVHLPR3,pfnTMTimerCreate} */
|
---|
[20087] | 775 | static DECLCALLBACK(int) pdmR3DevHlp_TMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
|
---|
[1] | 776 | {
|
---|
| 777 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[20687] | 778 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 779 | VM_ASSERT_EMT(pVM);
|
---|
[20087] | 780 | LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pvUser=%p fFlags=%#x pszDesc=%p:{%s} ppTimer=%p\n",
|
---|
[26165] | 781 | pDevIns->pReg->szName, pDevIns->iInstance, enmClock, pfnCallback, pvUser, fFlags, pszDesc, pszDesc, ppTimer));
|
---|
[1] | 782 |
|
---|
[20687] | 783 | if (pDevIns->iInstance > 0) /** @todo use a string cache here later. */
|
---|
| 784 | {
|
---|
| 785 | char *pszDesc2 = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_DESC, "%s [%u]", pszDesc, pDevIns->iInstance);
|
---|
| 786 | if (pszDesc2)
|
---|
| 787 | pszDesc = pszDesc2;
|
---|
| 788 | }
|
---|
[1] | 789 |
|
---|
[20687] | 790 | int rc = TMR3TimerCreateDevice(pVM, pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
|
---|
[20087] | 791 |
|
---|
[26165] | 792 | LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 793 | return rc;
|
---|
| 794 | }
|
---|
| 795 |
|
---|
| 796 |
|
---|
[26158] | 797 | /** @interface_method_impl{PDMDEVHLPR3,pfnTMUtcNow} */
|
---|
| 798 | static DECLCALLBACK(PRTTIMESPEC) pdmR3DevHlp_TMUtcNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime)
|
---|
[26157] | 799 | {
|
---|
| 800 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26158] | 801 | LogFlow(("pdmR3DevHlp_TMUtcNow: caller='%s'/%d: pTime=%p\n",
|
---|
[26165] | 802 | pDevIns->pReg->szName, pDevIns->iInstance, pTime));
|
---|
[26157] | 803 |
|
---|
[26158] | 804 | pTime = TMR3UtcNow(pDevIns->Internal.s.pVMR3, pTime);
|
---|
[26157] | 805 |
|
---|
[26165] | 806 | LogFlow(("pdmR3DevHlp_TMUtcNow: caller='%s'/%d: returns %RU64\n", pDevIns->pReg->szName, pDevIns->iInstance, RTTimeSpecGetNano(pTime)));
|
---|
[26157] | 807 | return pTime;
|
---|
| 808 | }
|
---|
| 809 |
|
---|
| 810 |
|
---|
[33799] | 811 | /** @interface_method_impl{PDMDEVHLPR3,pfnTMTimeVirtGet} */
|
---|
| 812 | static DECLCALLBACK(uint64_t) pdmR3DevHlp_TMTimeVirtGet(PPDMDEVINS pDevIns)
|
---|
| 813 | {
|
---|
| 814 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[56985] | 815 | LogFlow(("pdmR3DevHlp_TMTimeVirtGet: caller='%s'/%d\n",
|
---|
[33799] | 816 | pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
| 817 |
|
---|
| 818 | uint64_t u64Time = TMVirtualSyncGet(pDevIns->Internal.s.pVMR3);
|
---|
| 819 |
|
---|
| 820 | LogFlow(("pdmR3DevHlp_TMTimeVirtGet: caller='%s'/%d: returns %RU64\n", pDevIns->pReg->szName, pDevIns->iInstance, u64Time));
|
---|
| 821 | return u64Time;
|
---|
| 822 | }
|
---|
| 823 |
|
---|
| 824 |
|
---|
| 825 | /** @interface_method_impl{PDMDEVHLPR3,pfnTMTimeVirtGetFreq} */
|
---|
| 826 | static DECLCALLBACK(uint64_t) pdmR3DevHlp_TMTimeVirtGetFreq(PPDMDEVINS pDevIns)
|
---|
| 827 | {
|
---|
| 828 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[56985] | 829 | LogFlow(("pdmR3DevHlp_TMTimeVirtGetFreq: caller='%s'/%d\n",
|
---|
[33799] | 830 | pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
| 831 |
|
---|
| 832 | uint64_t u64Freq = TMVirtualGetFreq(pDevIns->Internal.s.pVMR3);
|
---|
| 833 |
|
---|
| 834 | LogFlow(("pdmR3DevHlp_TMTimeVirtGetFreq: caller='%s'/%d: returns %RU64\n", pDevIns->pReg->szName, pDevIns->iInstance, u64Freq));
|
---|
| 835 | return u64Freq;
|
---|
| 836 | }
|
---|
| 837 |
|
---|
| 838 |
|
---|
| 839 | /** @interface_method_impl{PDMDEVHLPR3,pfnTMTimeVirtGetNano} */
|
---|
| 840 | static DECLCALLBACK(uint64_t) pdmR3DevHlp_TMTimeVirtGetNano(PPDMDEVINS pDevIns)
|
---|
| 841 | {
|
---|
| 842 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[56985] | 843 | LogFlow(("pdmR3DevHlp_TMTimeVirtGetNano: caller='%s'/%d\n",
|
---|
[33799] | 844 | pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
| 845 |
|
---|
[43765] | 846 | uint64_t u64Time = TMVirtualGet(pDevIns->Internal.s.pVMR3);
|
---|
[33799] | 847 | uint64_t u64Nano = TMVirtualToNano(pDevIns->Internal.s.pVMR3, u64Time);
|
---|
| 848 |
|
---|
| 849 | LogFlow(("pdmR3DevHlp_TMTimeVirtGetNano: caller='%s'/%d: returns %RU64\n", pDevIns->pReg->szName, pDevIns->iInstance, u64Nano));
|
---|
| 850 | return u64Nano;
|
---|
| 851 | }
|
---|
| 852 |
|
---|
| 853 |
|
---|
[45645] | 854 | /** @interface_method_impl{PDMDEVHLPR3,pfnGetSupDrvSession} */
|
---|
| 855 | static DECLCALLBACK(PSUPDRVSESSION) pdmR3DevHlp_GetSupDrvSession(PPDMDEVINS pDevIns)
|
---|
| 856 | {
|
---|
| 857 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[56985] | 858 | LogFlow(("pdmR3DevHlp_GetSupDrvSession: caller='%s'/%d\n",
|
---|
[45645] | 859 | pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
| 860 |
|
---|
| 861 | PSUPDRVSESSION pSession = pDevIns->Internal.s.pVMR3->pSession;
|
---|
| 862 |
|
---|
| 863 | LogFlow(("pdmR3DevHlp_GetSupDrvSession: caller='%s'/%d: returns %#p\n", pDevIns->pReg->szName, pDevIns->iInstance, pSession));
|
---|
| 864 | return pSession;
|
---|
| 865 | }
|
---|
| 866 |
|
---|
| 867 |
|
---|
[68986] | 868 | /** @interface_method_impl{PDMDEVHLPR3,pfnQueryGenericUserObject} */
|
---|
| 869 | static DECLCALLBACK(void *) pdmR3DevHlp_QueryGenericUserObject(PPDMDEVINS pDevIns, PCRTUUID pUuid)
|
---|
| 870 | {
|
---|
| 871 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 872 | LogFlow(("pdmR3DevHlp_QueryGenericUserObject: caller='%s'/%d: pUuid=%p:%RTuuid\n",
|
---|
| 873 | pDevIns->pReg->szName, pDevIns->iInstance, pUuid, pUuid));
|
---|
| 874 |
|
---|
| 875 | #if defined(DEBUG_bird) || defined(DEBUG_ramshankar) || defined(DEBUG_sunlover) || defined(DEBUG_michael) || defined(DEBUG_andy)
|
---|
[68993] | 876 | AssertMsgFailed(("'%s' wants %RTuuid - external only interface!\n", pDevIns->pReg->szName, pUuid));
|
---|
[68986] | 877 | #endif
|
---|
| 878 |
|
---|
| 879 | void *pvRet;
|
---|
| 880 | PUVM pUVM = pDevIns->Internal.s.pVMR3->pUVM;
|
---|
| 881 | if (pUVM->pVmm2UserMethods->pfnQueryGenericObject)
|
---|
| 882 | pvRet = pUVM->pVmm2UserMethods->pfnQueryGenericObject(pUVM->pVmm2UserMethods, pUVM, pUuid);
|
---|
| 883 | else
|
---|
| 884 | pvRet = NULL;
|
---|
| 885 |
|
---|
| 886 | LogRel(("pdmR3DevHlp_QueryGenericUserObject: caller='%s'/%d: returns %#p for %RTuuid\n",
|
---|
| 887 | pDevIns->pReg->szName, pDevIns->iInstance, pvRet, pUuid));
|
---|
| 888 | return pvRet;
|
---|
| 889 | }
|
---|
| 890 |
|
---|
| 891 |
|
---|
[26157] | 892 | /** @interface_method_impl{PDMDEVHLPR3,pfnPhysRead} */
|
---|
| 893 | static DECLCALLBACK(int) pdmR3DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
|
---|
| 894 | {
|
---|
| 895 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 896 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 897 | LogFlow(("pdmR3DevHlp_PhysRead: caller='%s'/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
|
---|
[26165] | 898 | pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
|
---|
[26157] | 899 |
|
---|
| 900 | #if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
|
---|
| 901 | if (!VM_IS_EMT(pVM))
|
---|
| 902 | {
|
---|
| 903 | char szNames[128];
|
---|
| 904 | uint32_t cLocks = PDMR3CritSectCountOwned(pVM, szNames, sizeof(szNames));
|
---|
| 905 | AssertMsg(cLocks == 0, ("cLocks=%u %s\n", cLocks, szNames));
|
---|
| 906 | }
|
---|
| 907 | #endif
|
---|
| 908 |
|
---|
[56048] | 909 | VBOXSTRICTRC rcStrict;
|
---|
[26157] | 910 | if (VM_IS_EMT(pVM))
|
---|
[56048] | 911 | rcStrict = PGMPhysRead(pVM, GCPhys, pvBuf, cbRead, PGMACCESSORIGIN_DEVICE);
|
---|
[26157] | 912 | else
|
---|
[56048] | 913 | rcStrict = PGMR3PhysReadExternal(pVM, GCPhys, pvBuf, cbRead, PGMACCESSORIGIN_DEVICE);
|
---|
| 914 | AssertMsg(rcStrict == VINF_SUCCESS, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); /** @todo track down the users for this bugger. */
|
---|
[26157] | 915 |
|
---|
[56048] | 916 | Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict) ));
|
---|
| 917 | return VBOXSTRICTRC_VAL(rcStrict);
|
---|
[26157] | 918 | }
|
---|
| 919 |
|
---|
| 920 |
|
---|
| 921 | /** @interface_method_impl{PDMDEVHLPR3,pfnPhysWrite} */
|
---|
| 922 | static DECLCALLBACK(int) pdmR3DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
|
---|
| 923 | {
|
---|
| 924 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 925 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 926 | LogFlow(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
|
---|
[26165] | 927 | pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
|
---|
[26157] | 928 |
|
---|
| 929 | #if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
|
---|
| 930 | if (!VM_IS_EMT(pVM))
|
---|
| 931 | {
|
---|
| 932 | char szNames[128];
|
---|
| 933 | uint32_t cLocks = PDMR3CritSectCountOwned(pVM, szNames, sizeof(szNames));
|
---|
| 934 | AssertMsg(cLocks == 0, ("cLocks=%u %s\n", cLocks, szNames));
|
---|
| 935 | }
|
---|
| 936 | #endif
|
---|
| 937 |
|
---|
[56048] | 938 | VBOXSTRICTRC rcStrict;
|
---|
[26157] | 939 | if (VM_IS_EMT(pVM))
|
---|
[56048] | 940 | rcStrict = PGMPhysWrite(pVM, GCPhys, pvBuf, cbWrite, PGMACCESSORIGIN_DEVICE);
|
---|
[26157] | 941 | else
|
---|
[56048] | 942 | rcStrict = PGMR3PhysWriteExternal(pVM, GCPhys, pvBuf, cbWrite, PGMACCESSORIGIN_DEVICE);
|
---|
| 943 | AssertMsg(rcStrict == VINF_SUCCESS, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); /** @todo track down the users for this bugger. */
|
---|
[26157] | 944 |
|
---|
[56048] | 945 | Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict) ));
|
---|
| 946 | return VBOXSTRICTRC_VAL(rcStrict);
|
---|
[26157] | 947 | }
|
---|
| 948 |
|
---|
| 949 |
|
---|
| 950 | /** @interface_method_impl{PDMDEVHLPR3,pfnPhysGCPhys2CCPtr} */
|
---|
| 951 | static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPhys2CCPtr(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv, PPGMPAGEMAPLOCK pLock)
|
---|
| 952 | {
|
---|
| 953 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 954 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 955 | LogFlow(("pdmR3DevHlp_PhysGCPhys2CCPtr: caller='%s'/%d: GCPhys=%RGp fFlags=%#x ppv=%p pLock=%p\n",
|
---|
[26165] | 956 | pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, fFlags, ppv, pLock));
|
---|
[26157] | 957 | AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
|
---|
| 958 |
|
---|
| 959 | #if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
|
---|
| 960 | if (!VM_IS_EMT(pVM))
|
---|
| 961 | {
|
---|
| 962 | char szNames[128];
|
---|
| 963 | uint32_t cLocks = PDMR3CritSectCountOwned(pVM, szNames, sizeof(szNames));
|
---|
| 964 | AssertMsg(cLocks == 0, ("cLocks=%u %s\n", cLocks, szNames));
|
---|
| 965 | }
|
---|
| 966 | #endif
|
---|
| 967 |
|
---|
| 968 | int rc = PGMR3PhysGCPhys2CCPtrExternal(pVM, GCPhys, ppv, pLock);
|
---|
| 969 |
|
---|
[26165] | 970 | Log(("pdmR3DevHlp_PhysGCPhys2CCPtr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 971 | return rc;
|
---|
| 972 | }
|
---|
| 973 |
|
---|
| 974 |
|
---|
| 975 | /** @interface_method_impl{PDMDEVHLPR3,pfnPhysGCPhys2CCPtrReadOnly} */
|
---|
| 976 | static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, const void **ppv, PPGMPAGEMAPLOCK pLock)
|
---|
| 977 | {
|
---|
| 978 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 979 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 980 | LogFlow(("pdmR3DevHlp_PhysGCPhys2CCPtrReadOnly: caller='%s'/%d: GCPhys=%RGp fFlags=%#x ppv=%p pLock=%p\n",
|
---|
[26165] | 981 | pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, fFlags, ppv, pLock));
|
---|
[26157] | 982 | AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
|
---|
| 983 |
|
---|
| 984 | #if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
|
---|
| 985 | if (!VM_IS_EMT(pVM))
|
---|
| 986 | {
|
---|
| 987 | char szNames[128];
|
---|
| 988 | uint32_t cLocks = PDMR3CritSectCountOwned(pVM, szNames, sizeof(szNames));
|
---|
| 989 | AssertMsg(cLocks == 0, ("cLocks=%u %s\n", cLocks, szNames));
|
---|
| 990 | }
|
---|
| 991 | #endif
|
---|
| 992 |
|
---|
| 993 | int rc = PGMR3PhysGCPhys2CCPtrReadOnlyExternal(pVM, GCPhys, ppv, pLock);
|
---|
| 994 |
|
---|
[26165] | 995 | Log(("pdmR3DevHlp_PhysGCPhys2CCPtrReadOnly: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 996 | return rc;
|
---|
| 997 | }
|
---|
| 998 |
|
---|
| 999 |
|
---|
| 1000 | /** @interface_method_impl{PDMDEVHLPR3,pfnPhysReleasePageMappingLock} */
|
---|
| 1001 | static DECLCALLBACK(void) pdmR3DevHlp_PhysReleasePageMappingLock(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock)
|
---|
| 1002 | {
|
---|
| 1003 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1004 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1005 | LogFlow(("pdmR3DevHlp_PhysReleasePageMappingLock: caller='%s'/%d: pLock=%p\n",
|
---|
[26165] | 1006 | pDevIns->pReg->szName, pDevIns->iInstance, pLock));
|
---|
[26157] | 1007 |
|
---|
| 1008 | PGMPhysReleasePageMappingLock(pVM, pLock);
|
---|
| 1009 |
|
---|
[26165] | 1010 | Log(("pdmR3DevHlp_PhysReleasePageMappingLock: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[26157] | 1011 | }
|
---|
| 1012 |
|
---|
| 1013 |
|
---|
[77241] | 1014 | /** @interface_method_impl{PDMDEVHLPR3,pfnPhysBulkGCPhys2CCPtr} */
|
---|
| 1015 | static DECLCALLBACK(int) pdmR3DevHlp_PhysBulkGCPhys2CCPtr(PPDMDEVINS pDevIns, uint32_t cPages, PCRTGCPHYS paGCPhysPages,
|
---|
| 1016 | uint32_t fFlags, void **papvPages, PPGMPAGEMAPLOCK paLocks)
|
---|
| 1017 | {
|
---|
| 1018 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1019 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1020 | LogFlow(("pdmR3DevHlp_PhysBulkGCPhys2CCPtr: caller='%s'/%d: cPages=%#x paGCPhysPages=%p (%RGp,..) fFlags=%#x papvPages=%p paLocks=%p\n",
|
---|
| 1021 | pDevIns->pReg->szName, pDevIns->iInstance, cPages, paGCPhysPages, paGCPhysPages[0], fFlags, papvPages, paLocks));
|
---|
| 1022 | AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
|
---|
| 1023 | AssertReturn(cPages > 0, VERR_INVALID_PARAMETER);
|
---|
| 1024 |
|
---|
| 1025 | #if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
|
---|
| 1026 | if (!VM_IS_EMT(pVM))
|
---|
| 1027 | {
|
---|
| 1028 | char szNames[128];
|
---|
| 1029 | uint32_t cLocks = PDMR3CritSectCountOwned(pVM, szNames, sizeof(szNames));
|
---|
| 1030 | AssertMsg(cLocks == 0, ("cLocks=%u %s\n", cLocks, szNames));
|
---|
| 1031 | }
|
---|
| 1032 | #endif
|
---|
| 1033 |
|
---|
| 1034 | int rc = PGMR3PhysBulkGCPhys2CCPtrExternal(pVM, cPages, paGCPhysPages, papvPages, paLocks);
|
---|
| 1035 |
|
---|
| 1036 | Log(("pdmR3DevHlp_PhysBulkGCPhys2CCPtr: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 1037 | return rc;
|
---|
| 1038 | }
|
---|
| 1039 |
|
---|
| 1040 |
|
---|
| 1041 | /** @interface_method_impl{PDMDEVHLPR3,pfnPhysBulkGCPhys2CCPtrReadOnly} */
|
---|
| 1042 | static DECLCALLBACK(int) pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, uint32_t cPages, PCRTGCPHYS paGCPhysPages,
|
---|
| 1043 | uint32_t fFlags, const void **papvPages, PPGMPAGEMAPLOCK paLocks)
|
---|
| 1044 | {
|
---|
| 1045 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1046 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1047 | LogFlow(("pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly: caller='%s'/%d: cPages=%#x paGCPhysPages=%p (%RGp,...) fFlags=%#x papvPages=%p paLocks=%p\n",
|
---|
| 1048 | pDevIns->pReg->szName, pDevIns->iInstance, cPages, paGCPhysPages, paGCPhysPages[0], fFlags, papvPages, paLocks));
|
---|
| 1049 | AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
|
---|
| 1050 | AssertReturn(cPages > 0, VERR_INVALID_PARAMETER);
|
---|
| 1051 |
|
---|
| 1052 | #if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
|
---|
| 1053 | if (!VM_IS_EMT(pVM))
|
---|
| 1054 | {
|
---|
| 1055 | char szNames[128];
|
---|
| 1056 | uint32_t cLocks = PDMR3CritSectCountOwned(pVM, szNames, sizeof(szNames));
|
---|
| 1057 | AssertMsg(cLocks == 0, ("cLocks=%u %s\n", cLocks, szNames));
|
---|
| 1058 | }
|
---|
| 1059 | #endif
|
---|
| 1060 |
|
---|
| 1061 | int rc = PGMR3PhysBulkGCPhys2CCPtrReadOnlyExternal(pVM, cPages, paGCPhysPages, papvPages, paLocks);
|
---|
| 1062 |
|
---|
| 1063 | Log(("pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 1064 | return rc;
|
---|
| 1065 | }
|
---|
| 1066 |
|
---|
| 1067 |
|
---|
[77249] | 1068 | /** @interface_method_impl{PDMDEVHLPR3,pfnPhysBulkReleasePageMappingLocks} */
|
---|
[77241] | 1069 | static DECLCALLBACK(void) pdmR3DevHlp_PhysBulkReleasePageMappingLocks(PPDMDEVINS pDevIns, uint32_t cPages, PPGMPAGEMAPLOCK paLocks)
|
---|
| 1070 | {
|
---|
| 1071 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1072 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1073 | LogFlow(("pdmR3DevHlp_PhysBulkReleasePageMappingLocks: caller='%s'/%d: cPages=%#x paLocks=%p\n",
|
---|
| 1074 | pDevIns->pReg->szName, pDevIns->iInstance, cPages, paLocks));
|
---|
| 1075 | Assert(cPages > 0);
|
---|
| 1076 |
|
---|
| 1077 | PGMPhysBulkReleasePageMappingLocks(pVM, cPages, paLocks);
|
---|
| 1078 |
|
---|
| 1079 | Log(("pdmR3DevHlp_PhysBulkReleasePageMappingLocks: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
| 1080 | }
|
---|
| 1081 |
|
---|
| 1082 |
|
---|
[26157] | 1083 | /** @interface_method_impl{PDMDEVHLPR3,pfnPhysReadGCVirt} */
|
---|
| 1084 | static DECLCALLBACK(int) pdmR3DevHlp_PhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)
|
---|
| 1085 | {
|
---|
| 1086 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1087 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1088 | VM_ASSERT_EMT(pVM);
|
---|
| 1089 | LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: pvDst=%p GCVirt=%RGv cb=%#x\n",
|
---|
[26165] | 1090 | pDevIns->pReg->szName, pDevIns->iInstance, pvDst, GCVirtSrc, cb));
|
---|
[26157] | 1091 |
|
---|
| 1092 | PVMCPU pVCpu = VMMGetCpu(pVM);
|
---|
| 1093 | if (!pVCpu)
|
---|
| 1094 | return VERR_ACCESS_DENIED;
|
---|
| 1095 | #if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
|
---|
| 1096 | /** @todo SMP. */
|
---|
| 1097 | #endif
|
---|
| 1098 |
|
---|
| 1099 | int rc = PGMPhysSimpleReadGCPtr(pVCpu, pvDst, GCVirtSrc, cb);
|
---|
| 1100 |
|
---|
[26165] | 1101 | LogFlow(("pdmR3DevHlp_PhysReadGCVirt: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 1102 |
|
---|
| 1103 | return rc;
|
---|
| 1104 | }
|
---|
| 1105 |
|
---|
| 1106 |
|
---|
| 1107 | /** @interface_method_impl{PDMDEVHLPR3,pfnPhysWriteGCVirt} */
|
---|
| 1108 | static DECLCALLBACK(int) pdmR3DevHlp_PhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)
|
---|
| 1109 | {
|
---|
| 1110 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1111 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1112 | VM_ASSERT_EMT(pVM);
|
---|
| 1113 | LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: GCVirtDst=%RGv pvSrc=%p cb=%#x\n",
|
---|
[26165] | 1114 | pDevIns->pReg->szName, pDevIns->iInstance, GCVirtDst, pvSrc, cb));
|
---|
[26157] | 1115 |
|
---|
| 1116 | PVMCPU pVCpu = VMMGetCpu(pVM);
|
---|
| 1117 | if (!pVCpu)
|
---|
| 1118 | return VERR_ACCESS_DENIED;
|
---|
| 1119 | #if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
|
---|
| 1120 | /** @todo SMP. */
|
---|
| 1121 | #endif
|
---|
| 1122 |
|
---|
| 1123 | int rc = PGMPhysSimpleWriteGCPtr(pVCpu, GCVirtDst, pvSrc, cb);
|
---|
| 1124 |
|
---|
[26165] | 1125 | LogFlow(("pdmR3DevHlp_PhysWriteGCVirt: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 1126 |
|
---|
| 1127 | return rc;
|
---|
| 1128 | }
|
---|
| 1129 |
|
---|
| 1130 |
|
---|
| 1131 | /** @interface_method_impl{PDMDEVHLPR3,pfnPhysGCPtr2GCPhys} */
|
---|
| 1132 | static DECLCALLBACK(int) pdmR3DevHlp_PhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys)
|
---|
| 1133 | {
|
---|
| 1134 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1135 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1136 | VM_ASSERT_EMT(pVM);
|
---|
| 1137 | LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: GCPtr=%RGv pGCPhys=%p\n",
|
---|
[26165] | 1138 | pDevIns->pReg->szName, pDevIns->iInstance, GCPtr, pGCPhys));
|
---|
[26157] | 1139 |
|
---|
| 1140 | PVMCPU pVCpu = VMMGetCpu(pVM);
|
---|
| 1141 | if (!pVCpu)
|
---|
| 1142 | return VERR_ACCESS_DENIED;
|
---|
| 1143 | #if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
|
---|
| 1144 | /** @todo SMP. */
|
---|
| 1145 | #endif
|
---|
| 1146 |
|
---|
| 1147 | int rc = PGMPhysGCPtr2GCPhys(pVCpu, GCPtr, pGCPhys);
|
---|
| 1148 |
|
---|
[26165] | 1149 | LogFlow(("pdmR3DevHlp_PhysGCPtr2GCPhys: caller='%s'/%d: returns %Rrc *pGCPhys=%RGp\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *pGCPhys));
|
---|
[26157] | 1150 |
|
---|
| 1151 | return rc;
|
---|
| 1152 | }
|
---|
| 1153 |
|
---|
| 1154 |
|
---|
| 1155 | /** @interface_method_impl{PDMDEVHLPR3,pfnMMHeapAlloc} */
|
---|
| 1156 | static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAlloc(PPDMDEVINS pDevIns, size_t cb)
|
---|
| 1157 | {
|
---|
| 1158 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 1159 | LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: cb=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, cb));
|
---|
[26157] | 1160 |
|
---|
| 1161 | void *pv = MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE_USER, cb);
|
---|
| 1162 |
|
---|
[26165] | 1163 | LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pv));
|
---|
[26157] | 1164 | return pv;
|
---|
| 1165 | }
|
---|
| 1166 |
|
---|
| 1167 |
|
---|
| 1168 | /** @interface_method_impl{PDMDEVHLPR3,pfnMMHeapAllocZ} */
|
---|
| 1169 | static DECLCALLBACK(void *) pdmR3DevHlp_MMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb)
|
---|
| 1170 | {
|
---|
| 1171 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 1172 | LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: cb=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, cb));
|
---|
[26157] | 1173 |
|
---|
| 1174 | void *pv = MMR3HeapAllocZ(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE_USER, cb);
|
---|
| 1175 |
|
---|
[26165] | 1176 | LogFlow(("pdmR3DevHlp_MMHeapAllocZ: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pv));
|
---|
[26157] | 1177 | return pv;
|
---|
| 1178 | }
|
---|
| 1179 |
|
---|
| 1180 |
|
---|
| 1181 | /** @interface_method_impl{PDMDEVHLPR3,pfnMMHeapFree} */
|
---|
| 1182 | static DECLCALLBACK(void) pdmR3DevHlp_MMHeapFree(PPDMDEVINS pDevIns, void *pv)
|
---|
| 1183 | {
|
---|
[62643] | 1184 | PDMDEV_ASSERT_DEVINS(pDevIns); RT_NOREF_PV(pDevIns);
|
---|
[26165] | 1185 | LogFlow(("pdmR3DevHlp_MMHeapFree: caller='%s'/%d: pv=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pv));
|
---|
[26157] | 1186 |
|
---|
| 1187 | MMR3HeapFree(pv);
|
---|
| 1188 |
|
---|
[26165] | 1189 | LogFlow(("pdmR3DevHlp_MMHeapAlloc: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[26157] | 1190 | }
|
---|
| 1191 |
|
---|
| 1192 |
|
---|
| 1193 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMState} */
|
---|
| 1194 | static DECLCALLBACK(VMSTATE) pdmR3DevHlp_VMState(PPDMDEVINS pDevIns)
|
---|
| 1195 | {
|
---|
| 1196 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1197 |
|
---|
| 1198 | VMSTATE enmVMState = VMR3GetState(pDevIns->Internal.s.pVMR3);
|
---|
| 1199 |
|
---|
[26165] | 1200 | LogFlow(("pdmR3DevHlp_VMState: caller='%s'/%d: returns %d (%s)\n", pDevIns->pReg->szName, pDevIns->iInstance,
|
---|
[26157] | 1201 | enmVMState, VMR3GetStateName(enmVMState)));
|
---|
| 1202 | return enmVMState;
|
---|
| 1203 | }
|
---|
| 1204 |
|
---|
| 1205 |
|
---|
| 1206 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMTeleportedAndNotFullyResumedYet} */
|
---|
| 1207 | static DECLCALLBACK(bool) pdmR3DevHlp_VMTeleportedAndNotFullyResumedYet(PPDMDEVINS pDevIns)
|
---|
| 1208 | {
|
---|
| 1209 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1210 |
|
---|
| 1211 | bool fRc = VMR3TeleportedAndNotFullyResumedYet(pDevIns->Internal.s.pVMR3);
|
---|
| 1212 |
|
---|
[26165] | 1213 | LogFlow(("pdmR3DevHlp_VMState: caller='%s'/%d: returns %RTbool\n", pDevIns->pReg->szName, pDevIns->iInstance,
|
---|
[26157] | 1214 | fRc));
|
---|
| 1215 | return fRc;
|
---|
| 1216 | }
|
---|
| 1217 |
|
---|
| 1218 |
|
---|
| 1219 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMSetError} */
|
---|
| 1220 | static DECLCALLBACK(int) pdmR3DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
|
---|
| 1221 | {
|
---|
| 1222 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1223 | va_list args;
|
---|
| 1224 | va_start(args, pszFormat);
|
---|
| 1225 | int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
|
---|
| 1226 | va_end(args);
|
---|
| 1227 | return rc;
|
---|
| 1228 | }
|
---|
| 1229 |
|
---|
| 1230 |
|
---|
| 1231 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMSetErrorV} */
|
---|
| 1232 | static DECLCALLBACK(int) pdmR3DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
|
---|
| 1233 | {
|
---|
| 1234 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1235 | int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR3, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
|
---|
| 1236 | return rc;
|
---|
| 1237 | }
|
---|
| 1238 |
|
---|
| 1239 |
|
---|
| 1240 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMSetRuntimeError} */
|
---|
| 1241 | static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
|
---|
| 1242 | {
|
---|
| 1243 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1244 | va_list args;
|
---|
| 1245 | va_start(args, pszFormat);
|
---|
| 1246 | int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR3, fFlags, pszErrorId, pszFormat, args);
|
---|
| 1247 | va_end(args);
|
---|
| 1248 | return rc;
|
---|
| 1249 | }
|
---|
| 1250 |
|
---|
| 1251 |
|
---|
| 1252 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMSetRuntimeErrorV} */
|
---|
| 1253 | static DECLCALLBACK(int) pdmR3DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
|
---|
| 1254 | {
|
---|
| 1255 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1256 | int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR3, fFlags, pszErrorId, pszFormat, va);
|
---|
| 1257 | return rc;
|
---|
| 1258 | }
|
---|
| 1259 |
|
---|
| 1260 |
|
---|
| 1261 | /** @interface_method_impl{PDMDEVHLPR3,pfnDBGFStopV} */
|
---|
| 1262 | static DECLCALLBACK(int) pdmR3DevHlp_DBGFStopV(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args)
|
---|
| 1263 | {
|
---|
| 1264 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1265 | #ifdef LOG_ENABLED
|
---|
| 1266 | va_list va2;
|
---|
| 1267 | va_copy(va2, args);
|
---|
| 1268 | LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: pszFile=%p:{%s} iLine=%d pszFunction=%p:{%s} pszFormat=%p:{%s} (%N)\n",
|
---|
[26165] | 1269 | pDevIns->pReg->szName, pDevIns->iInstance, pszFile, pszFile, iLine, pszFunction, pszFunction, pszFormat, pszFormat, pszFormat, &va2));
|
---|
[26157] | 1270 | va_end(va2);
|
---|
| 1271 | #endif
|
---|
| 1272 |
|
---|
| 1273 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1274 | VM_ASSERT_EMT(pVM);
|
---|
| 1275 | int rc = DBGFR3EventSrcV(pVM, DBGFEVENT_DEV_STOP, pszFile, iLine, pszFunction, pszFormat, args);
|
---|
| 1276 | if (rc == VERR_DBGF_NOT_ATTACHED)
|
---|
| 1277 | rc = VINF_SUCCESS;
|
---|
| 1278 |
|
---|
[26165] | 1279 | LogFlow(("pdmR3DevHlp_DBGFStopV: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 1280 | return rc;
|
---|
| 1281 | }
|
---|
| 1282 |
|
---|
| 1283 |
|
---|
| 1284 | /** @interface_method_impl{PDMDEVHLPR3,pfnDBGFInfoRegister} */
|
---|
| 1285 | static DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler)
|
---|
| 1286 | {
|
---|
| 1287 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1288 | LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: pszName=%p:{%s} pszDesc=%p:{%s} pfnHandler=%p\n",
|
---|
[26165] | 1289 | pDevIns->pReg->szName, pDevIns->iInstance, pszName, pszName, pszDesc, pszDesc, pfnHandler));
|
---|
[26157] | 1290 |
|
---|
| 1291 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1292 | VM_ASSERT_EMT(pVM);
|
---|
| 1293 | int rc = DBGFR3InfoRegisterDevice(pVM, pszName, pszDesc, pfnHandler, pDevIns);
|
---|
| 1294 |
|
---|
[26165] | 1295 | LogFlow(("pdmR3DevHlp_DBGFInfoRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 1296 | return rc;
|
---|
| 1297 | }
|
---|
| 1298 |
|
---|
| 1299 |
|
---|
[80154] | 1300 | /** @interface_method_impl{PDMDEVHLPR3,pfnDBGFInfoRegisterArgv} */
|
---|
| 1301 | static DECLCALLBACK(int) pdmR3DevHlp_DBGFInfoRegisterArgv(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFINFOARGVDEV pfnHandler)
|
---|
| 1302 | {
|
---|
| 1303 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1304 | LogFlow(("pdmR3DevHlp_DBGFInfoRegisterArgv: caller='%s'/%d: pszName=%p:{%s} pszDesc=%p:{%s} pfnHandler=%p\n",
|
---|
| 1305 | pDevIns->pReg->szName, pDevIns->iInstance, pszName, pszName, pszDesc, pszDesc, pfnHandler));
|
---|
| 1306 |
|
---|
| 1307 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1308 | VM_ASSERT_EMT(pVM);
|
---|
| 1309 | int rc = DBGFR3InfoRegisterDeviceArgv(pVM, pszName, pszDesc, pfnHandler, pDevIns);
|
---|
| 1310 |
|
---|
| 1311 | LogFlow(("pdmR3DevHlp_DBGFInfoRegisterArgv: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 1312 | return rc;
|
---|
| 1313 | }
|
---|
| 1314 |
|
---|
| 1315 |
|
---|
[44691] | 1316 | /** @interface_method_impl{PDMDEVHLPR3,pfnDBGFRegRegister} */
|
---|
| 1317 | static DECLCALLBACK(int) pdmR3DevHlp_DBGFRegRegister(PPDMDEVINS pDevIns, PCDBGFREGDESC paRegisters)
|
---|
| 1318 | {
|
---|
| 1319 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1320 | LogFlow(("pdmR3DevHlp_DBGFRegRegister: caller='%s'/%d: paRegisters=%p\n",
|
---|
| 1321 | pDevIns->pReg->szName, pDevIns->iInstance, paRegisters));
|
---|
| 1322 |
|
---|
| 1323 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1324 | VM_ASSERT_EMT(pVM);
|
---|
| 1325 | int rc = DBGFR3RegRegisterDevice(pVM, paRegisters, pDevIns, pDevIns->pReg->szName, pDevIns->iInstance);
|
---|
| 1326 |
|
---|
| 1327 | LogFlow(("pdmR3DevHlp_DBGFRegRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 1328 | return rc;
|
---|
| 1329 | }
|
---|
| 1330 |
|
---|
| 1331 |
|
---|
[37410] | 1332 | /** @interface_method_impl{PDMDEVHLPR3,pfnDBGFTraceBuf} */
|
---|
| 1333 | static DECLCALLBACK(RTTRACEBUF) pdmR3DevHlp_DBGFTraceBuf(PPDMDEVINS pDevIns)
|
---|
| 1334 | {
|
---|
| 1335 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1336 | RTTRACEBUF hTraceBuf = pDevIns->Internal.s.pVMR3->hTraceBufR3;
|
---|
| 1337 | LogFlow(("pdmR3DevHlp_DBGFTraceBuf: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, hTraceBuf));
|
---|
| 1338 | return hTraceBuf;
|
---|
| 1339 | }
|
---|
| 1340 |
|
---|
| 1341 |
|
---|
[26157] | 1342 | /** @interface_method_impl{PDMDEVHLPR3,pfnSTAMRegister} */
|
---|
[62643] | 1343 | static DECLCALLBACK(void) pdmR3DevHlp_STAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName,
|
---|
| 1344 | STAMUNIT enmUnit, const char *pszDesc)
|
---|
[26157] | 1345 | {
|
---|
| 1346 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1347 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1348 | VM_ASSERT_EMT(pVM);
|
---|
| 1349 |
|
---|
| 1350 | STAM_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc);
|
---|
[62643] | 1351 | RT_NOREF_PV(pVM); RT_NOREF6(pDevIns, pvSample, enmType, pszName, enmUnit, pszDesc);
|
---|
[26157] | 1352 | }
|
---|
| 1353 |
|
---|
| 1354 |
|
---|
| 1355 |
|
---|
| 1356 | /** @interface_method_impl{PDMDEVHLPR3,pfnSTAMRegisterF} */
|
---|
| 1357 | static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
|
---|
| 1358 | STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...)
|
---|
| 1359 | {
|
---|
| 1360 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1361 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1362 | VM_ASSERT_EMT(pVM);
|
---|
| 1363 |
|
---|
| 1364 | va_list args;
|
---|
| 1365 | va_start(args, pszName);
|
---|
| 1366 | int rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args);
|
---|
| 1367 | va_end(args);
|
---|
| 1368 | AssertRC(rc);
|
---|
| 1369 |
|
---|
| 1370 | NOREF(pVM);
|
---|
| 1371 | }
|
---|
| 1372 |
|
---|
| 1373 |
|
---|
| 1374 | /** @interface_method_impl{PDMDEVHLPR3,pfnSTAMRegisterV} */
|
---|
| 1375 | static DECLCALLBACK(void) pdmR3DevHlp_STAMRegisterV(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
|
---|
| 1376 | STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args)
|
---|
| 1377 | {
|
---|
| 1378 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1379 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1380 | VM_ASSERT_EMT(pVM);
|
---|
| 1381 |
|
---|
| 1382 | int rc = STAMR3RegisterV(pVM, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args);
|
---|
| 1383 | AssertRC(rc);
|
---|
| 1384 |
|
---|
| 1385 | NOREF(pVM);
|
---|
| 1386 | }
|
---|
| 1387 |
|
---|
| 1388 |
|
---|
[64373] | 1389 | /**
|
---|
| 1390 | * @interface_method_impl{PDMDEVHLPR3,pfnPCIRegister}
|
---|
| 1391 | */
|
---|
[64387] | 1392 | static DECLCALLBACK(int) pdmR3DevHlp_PCIRegister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t idxDevCfg, uint32_t fFlags,
|
---|
[64373] | 1393 | uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName)
|
---|
[1] | 1394 | {
|
---|
| 1395 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 1396 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[1] | 1397 | VM_ASSERT_EMT(pVM);
|
---|
[64373] | 1398 | LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: pPciDev=%p:{.config={%#.256Rhxs} idxDevCfg=%d fFlags=%#x uPciDevNo=%#x uPciFunNo=%#x pszName=%p:{%s}\n",
|
---|
| 1399 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev->abConfig, idxDevCfg, fFlags, uPciDevNo, uPciFunNo, pszName, pszName ? pszName : ""));
|
---|
[1] | 1400 |
|
---|
| 1401 | /*
|
---|
| 1402 | * Validate input.
|
---|
| 1403 | */
|
---|
[64373] | 1404 | AssertLogRelMsgReturn(RT_VALID_PTR(pPciDev),
|
---|
| 1405 | ("'%s'/%d: Invalid pPciDev value: %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pPciDev),
|
---|
| 1406 | VERR_INVALID_POINTER);
|
---|
| 1407 | AssertLogRelMsgReturn(PDMPciDevGetVendorId(pPciDev),
|
---|
| 1408 | ("'%s'/%d: Vendor ID is not set!\n", pDevIns->pReg->szName, pDevIns->iInstance),
|
---|
| 1409 | VERR_INVALID_POINTER);
|
---|
| 1410 | AssertLogRelMsgReturn(idxDevCfg < 256 || idxDevCfg == PDMPCIDEVREG_CFG_NEXT,
|
---|
| 1411 | ("'%s'/%d: Invalid config selector: %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, idxDevCfg),
|
---|
| 1412 | VERR_OUT_OF_RANGE);
|
---|
| 1413 | AssertLogRelMsgReturn( uPciDevNo < 32
|
---|
| 1414 | || uPciDevNo == PDMPCIDEVREG_DEV_NO_FIRST_UNUSED
|
---|
| 1415 | || uPciDevNo == PDMPCIDEVREG_DEV_NO_SAME_AS_PREV,
|
---|
| 1416 | ("'%s'/%d: Invalid PCI device number: %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, uPciDevNo),
|
---|
| 1417 | VERR_INVALID_PARAMETER);
|
---|
| 1418 | AssertLogRelMsgReturn( uPciFunNo < 8
|
---|
| 1419 | || uPciFunNo == PDMPCIDEVREG_FUN_NO_FIRST_UNUSED,
|
---|
| 1420 | ("'%s'/%d: Invalid PCI funcion number: %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, uPciFunNo),
|
---|
| 1421 | VERR_INVALID_PARAMETER);
|
---|
| 1422 | AssertLogRelMsgReturn(!(fFlags & ~PDMPCIDEVREG_F_VALID_MASK),
|
---|
| 1423 | ("'%s'/%d: Invalid flags: %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, fFlags),
|
---|
| 1424 | VERR_INVALID_FLAGS);
|
---|
| 1425 | if (!pszName)
|
---|
| 1426 | pszName = pDevIns->pReg->szName;
|
---|
| 1427 | AssertLogRelReturn(RT_VALID_PTR(pszName), VERR_INVALID_POINTER);
|
---|
| 1428 |
|
---|
| 1429 | /*
|
---|
| 1430 | * Find the last(/previous) registered PCI device (for linking and more),
|
---|
| 1431 | * checking for duplicate registration attempts while doing so.
|
---|
| 1432 | */
|
---|
| 1433 | uint32_t idxDevCfgNext = 0;
|
---|
| 1434 | PPDMPCIDEV pPrevPciDev = pDevIns->Internal.s.pHeadPciDevR3;
|
---|
| 1435 | while (pPrevPciDev)
|
---|
[1] | 1436 | {
|
---|
[64373] | 1437 | AssertLogRelMsgReturn(pPrevPciDev != pPciDev,
|
---|
| 1438 | ("'%s'/%d attempted to register the same PCI device (%p) twice\n",
|
---|
| 1439 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev),
|
---|
| 1440 | VERR_DUPLICATE);
|
---|
| 1441 | AssertLogRelMsgReturn(pPrevPciDev->Int.s.idxDevCfg != idxDevCfg,
|
---|
| 1442 | ("'%s'/%d attempted to use the same device config index (%u) twice\n",
|
---|
| 1443 | pDevIns->pReg->szName, pDevIns->iInstance, idxDevCfg),
|
---|
| 1444 | VERR_ALREADY_LOADED);
|
---|
| 1445 | if (pPrevPciDev->Int.s.idxDevCfg >= idxDevCfgNext)
|
---|
| 1446 | idxDevCfgNext = pPrevPciDev->Int.s.idxDevCfg + 1;
|
---|
| 1447 |
|
---|
| 1448 | if (!pPrevPciDev->Int.s.pNextR3)
|
---|
| 1449 | break;
|
---|
| 1450 | pPrevPciDev = pPrevPciDev->Int.s.pNextR3;
|
---|
[1] | 1451 | }
|
---|
[64373] | 1452 |
|
---|
| 1453 | /*
|
---|
| 1454 | * Resolve the PCI configuration node for the device. The default (zero'th)
|
---|
| 1455 | * is the same as the PDM device, the rest are "PciCfg1..255" CFGM sub-nodes.
|
---|
| 1456 | */
|
---|
| 1457 | if (idxDevCfg == PDMPCIDEVREG_CFG_NEXT)
|
---|
[1] | 1458 | {
|
---|
[64373] | 1459 | idxDevCfg = idxDevCfgNext;
|
---|
| 1460 | AssertLogRelMsgReturn(idxDevCfg < 256, ("'%s'/%d: PDMPCIDEVREG_IDX_DEV_CFG_NEXT ran out of valid indexes (ends at 255)\n",
|
---|
| 1461 | pDevIns->pReg->szName, pDevIns->iInstance),
|
---|
| 1462 | VERR_OUT_OF_RANGE);
|
---|
[1] | 1463 | }
|
---|
[64373] | 1464 |
|
---|
| 1465 | PCFGMNODE pCfg = pDevIns->Internal.s.pCfgHandle;
|
---|
| 1466 | if (idxDevCfg != 0)
|
---|
| 1467 | pCfg = CFGMR3GetChildF(pDevIns->Internal.s.pCfgHandle, "PciCfg%u", idxDevCfg);
|
---|
| 1468 |
|
---|
| 1469 | /*
|
---|
| 1470 | * We resolve PDMPCIDEVREG_DEV_NO_SAME_AS_PREV, the PCI bus handles
|
---|
| 1471 | * PDMPCIDEVREG_DEV_NO_FIRST_UNUSED and PDMPCIDEVREG_FUN_NO_FIRST_UNUSED.
|
---|
| 1472 | */
|
---|
| 1473 | uint8_t const uPciDevNoRaw = uPciDevNo;
|
---|
[64844] | 1474 | uint32_t uDefPciBusNo = 0;
|
---|
[64373] | 1475 | if (uPciDevNo == PDMPCIDEVREG_DEV_NO_SAME_AS_PREV)
|
---|
[1] | 1476 | {
|
---|
[64406] | 1477 | if (pPrevPciDev)
|
---|
[64844] | 1478 | {
|
---|
| 1479 | uPciDevNo = pPrevPciDev->uDevFn >> 3;
|
---|
| 1480 | uDefPciBusNo = pPrevPciDev->Int.s.pPdmBusR3->iBus;
|
---|
| 1481 | }
|
---|
[64406] | 1482 | else
|
---|
| 1483 | {
|
---|
| 1484 | /* Look for PCI device registered with an earlier device instance so we can more
|
---|
| 1485 | easily have multiple functions spanning multiple PDM device instances. */
|
---|
| 1486 | PPDMPCIDEV pOtherPciDev = NULL;
|
---|
| 1487 | PPDMDEVINS pPrevIns = pDevIns->Internal.s.pDevR3->pInstances;
|
---|
| 1488 | while (pPrevIns != pDevIns && pPrevIns)
|
---|
| 1489 | {
|
---|
| 1490 | pOtherPciDev = pPrevIns->Internal.s.pHeadPciDevR3;
|
---|
| 1491 | pPrevIns = pPrevIns->Internal.s.pNextR3;
|
---|
| 1492 | }
|
---|
| 1493 | Assert(pPrevIns == pDevIns);
|
---|
| 1494 | AssertLogRelMsgReturn(pOtherPciDev,
|
---|
| 1495 | ("'%s'/%d: Can't use PDMPCIDEVREG_DEV_NO_SAME_AS_PREV without a previously registered PCI device by the same or earlier PDM device instance!\n",
|
---|
| 1496 | pDevIns->pReg->szName, pDevIns->iInstance),
|
---|
| 1497 | VERR_WRONG_ORDER);
|
---|
| 1498 |
|
---|
| 1499 | while (pOtherPciDev->Int.s.pNextR3)
|
---|
| 1500 | pOtherPciDev = pOtherPciDev->Int.s.pNextR3;
|
---|
[64844] | 1501 | uPciDevNo = pOtherPciDev->uDevFn >> 3;
|
---|
| 1502 | uDefPciBusNo = pOtherPciDev->Int.s.pPdmBusR3->iBus;
|
---|
[64406] | 1503 | }
|
---|
[1] | 1504 | }
|
---|
| 1505 |
|
---|
| 1506 | /*
|
---|
| 1507 | * Choose the PCI bus for the device.
|
---|
[13215] | 1508 | *
|
---|
| 1509 | * This is simple. If the device was configured for a particular bus, the PCIBusNo
|
---|
| 1510 | * configuration value will be set. If not the default bus is 0.
|
---|
[1] | 1511 | */
|
---|
[64373] | 1512 | /** @cfgm{/Devices/NAME/XX/[PciCfgYY/]PCIBusNo, uint8_t, 0, 7, 0}
|
---|
[64844] | 1513 | * Selects the PCI bus number of a device. The default value isn't necessarily
|
---|
| 1514 | * zero if the device is registered using PDMPCIDEVREG_DEV_NO_SAME_AS_PREV, it
|
---|
| 1515 | * will then also inherit the bus number from the previously registered device.
|
---|
[64373] | 1516 | */
|
---|
| 1517 | uint8_t u8Bus;
|
---|
[64844] | 1518 | int rc = CFGMR3QueryU8Def(pCfg, "PCIBusNo", &u8Bus, (uint8_t)uDefPciBusNo);
|
---|
[64373] | 1519 | AssertLogRelMsgRCReturn(rc, ("Configuration error: PCIBusNo query failed with rc=%Rrc (%s/%d)\n",
|
---|
| 1520 | rc, pDevIns->pReg->szName, pDevIns->iInstance), rc);
|
---|
| 1521 | AssertLogRelMsgReturn(u8Bus < RT_ELEMENTS(pVM->pdm.s.aPciBuses),
|
---|
| 1522 | ("Configuration error: PCIBusNo=%d, max is %d. (%s/%d)\n", u8Bus,
|
---|
| 1523 | RT_ELEMENTS(pVM->pdm.s.aPciBuses), pDevIns->pReg->szName, pDevIns->iInstance),
|
---|
| 1524 | VERR_PDM_NO_PCI_BUS);
|
---|
| 1525 | PPDMPCIBUS pBus = pPciDev->Int.s.pPdmBusR3 = &pVM->pdm.s.aPciBuses[u8Bus];
|
---|
[13215] | 1526 | if (pBus->pDevInsR3)
|
---|
| 1527 | {
|
---|
[1] | 1528 | /*
|
---|
| 1529 | * Check the configuration for PCI device and function assignment.
|
---|
| 1530 | */
|
---|
[64373] | 1531 | /** @cfgm{/Devices/NAME/XX/[PciCfgYY/]PCIDeviceNo, uint8_t, 0, 31}
|
---|
| 1532 | * Overrides the default PCI device number of a device.
|
---|
| 1533 | */
|
---|
| 1534 | uint8_t uCfgDevice;
|
---|
| 1535 | rc = CFGMR3QueryU8(pCfg, "PCIDeviceNo", &uCfgDevice);
|
---|
[13816] | 1536 | if (RT_SUCCESS(rc))
|
---|
[1] | 1537 | {
|
---|
[64373] | 1538 | AssertMsgReturn(uCfgDevice <= 31,
|
---|
| 1539 | ("Configuration error: PCIDeviceNo=%d, max is 31. (%s/%d/%d)\n",
|
---|
| 1540 | uCfgDevice, pDevIns->pReg->szName, pDevIns->iInstance, idxDevCfg),
|
---|
[39402] | 1541 | VERR_PDM_BAD_PCI_CONFIG);
|
---|
[64373] | 1542 | uPciDevNo = uCfgDevice;
|
---|
| 1543 | }
|
---|
| 1544 | else
|
---|
| 1545 | AssertMsgReturn(rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT,
|
---|
| 1546 | ("Configuration error: PCIDeviceNo query failed with rc=%Rrc (%s/%d/%d)\n",
|
---|
| 1547 | rc, pDevIns->pReg->szName, pDevIns->iInstance, idxDevCfg),
|
---|
| 1548 | rc);
|
---|
[1] | 1549 |
|
---|
[64373] | 1550 | /** @cfgm{/Devices/NAME/XX/[PciCfgYY/]PCIFunctionNo, uint8_t, 0, 7}
|
---|
| 1551 | * Overrides the default PCI function number of a device.
|
---|
| 1552 | */
|
---|
| 1553 | uint8_t uCfgFunction;
|
---|
| 1554 | rc = CFGMR3QueryU8(pCfg, "PCIFunctionNo", &uCfgFunction);
|
---|
| 1555 | if (RT_SUCCESS(rc))
|
---|
| 1556 | {
|
---|
| 1557 | AssertMsgReturn(uCfgFunction <= 7,
|
---|
| 1558 | ("Configuration error: PCIFunctionNo=%#x, max is 7. (%s/%d/%d)\n",
|
---|
| 1559 | uCfgFunction, pDevIns->pReg->szName, pDevIns->iInstance, idxDevCfg),
|
---|
[39402] | 1560 | VERR_PDM_BAD_PCI_CONFIG);
|
---|
[64373] | 1561 | uPciFunNo = uCfgFunction;
|
---|
| 1562 | }
|
---|
| 1563 | else
|
---|
| 1564 | AssertMsgReturn(rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT,
|
---|
| 1565 | ("Configuration error: PCIFunctionNo query failed with rc=%Rrc (%s/%d/%d)\n",
|
---|
| 1566 | rc, pDevIns->pReg->szName, pDevIns->iInstance, idxDevCfg),
|
---|
| 1567 | rc);
|
---|
[39402] | 1568 |
|
---|
[64373] | 1569 |
|
---|
| 1570 | /*
|
---|
| 1571 | * Initialize the internal data. We only do the wipe and the members
|
---|
| 1572 | * owned by PDM, the PCI bus does the rest in the registration call.
|
---|
| 1573 | */
|
---|
| 1574 | RT_ZERO(pPciDev->Int);
|
---|
| 1575 |
|
---|
| 1576 | pPciDev->Int.s.idxDevCfg = idxDevCfg;
|
---|
| 1577 | pPciDev->Int.s.fReassignableDevNo = uPciDevNoRaw >= VBOX_PCI_MAX_DEVICES;
|
---|
| 1578 | pPciDev->Int.s.fReassignableFunNo = uPciFunNo >= VBOX_PCI_MAX_FUNCTIONS;
|
---|
| 1579 | pPciDev->Int.s.pDevInsR3 = pDevIns;
|
---|
| 1580 | pPciDev->Int.s.pPdmBusR3 = pBus;
|
---|
| 1581 | if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
|
---|
| 1582 | {
|
---|
| 1583 | pPciDev->Int.s.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns);
|
---|
| 1584 | pPciDev->Int.s.pPdmBusR0 = MMHyperR3ToR0(pVM, pBus);
|
---|
[1] | 1585 | }
|
---|
[64373] | 1586 | else
|
---|
[1] | 1587 | {
|
---|
[64373] | 1588 | pPciDev->Int.s.pDevInsR0 = NIL_RTR0PTR;
|
---|
| 1589 | pPciDev->Int.s.pPdmBusR0 = NIL_RTR0PTR;
|
---|
[1] | 1590 | }
|
---|
| 1591 |
|
---|
[64373] | 1592 | if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
|
---|
| 1593 | {
|
---|
| 1594 | pPciDev->Int.s.pDevInsRC = MMHyperR3ToRC(pVM, pDevIns);
|
---|
| 1595 | pPciDev->Int.s.pPdmBusRC = MMHyperR3ToRC(pVM, pBus);
|
---|
| 1596 | }
|
---|
| 1597 | else
|
---|
| 1598 | {
|
---|
| 1599 | pPciDev->Int.s.pDevInsRC = NIL_RTRCPTR;
|
---|
| 1600 | pPciDev->Int.s.pPdmBusRC = NIL_RTRCPTR;
|
---|
| 1601 | }
|
---|
| 1602 |
|
---|
| 1603 | /* Set some of the public members too. */
|
---|
| 1604 | pPciDev->pszNameR3 = pszName;
|
---|
| 1605 |
|
---|
[1] | 1606 | /*
|
---|
| 1607 | * Call the pci bus device to do the actual registration.
|
---|
| 1608 | */
|
---|
| 1609 | pdmLock(pVM);
|
---|
[64373] | 1610 | rc = pBus->pfnRegisterR3(pBus->pDevInsR3, pPciDev, fFlags, uPciDevNo, uPciFunNo, pszName);
|
---|
[1] | 1611 | pdmUnlock(pVM);
|
---|
[13816] | 1612 | if (RT_SUCCESS(rc))
|
---|
[1] | 1613 | {
|
---|
[12970] | 1614 |
|
---|
[64373] | 1615 | /*
|
---|
| 1616 | * Link it.
|
---|
| 1617 | */
|
---|
| 1618 | if (pPrevPciDev)
|
---|
| 1619 | {
|
---|
| 1620 | Assert(!pPrevPciDev->Int.s.pNextR3);
|
---|
| 1621 | pPrevPciDev->Int.s.pNextR3 = pPciDev;
|
---|
| 1622 | if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
|
---|
| 1623 | pPrevPciDev->Int.s.pNextR0 = MMHyperR3ToR0(pVM, pPciDev);
|
---|
| 1624 | else
|
---|
| 1625 | pPrevPciDev->Int.s.pNextR0 = NIL_RTR0PTR;
|
---|
| 1626 | if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
|
---|
| 1627 | pPrevPciDev->Int.s.pNextRC = MMHyperR3ToRC(pVM, pPciDev);
|
---|
| 1628 | else
|
---|
| 1629 | pPrevPciDev->Int.s.pNextRC = NIL_RTRCPTR;
|
---|
| 1630 | }
|
---|
[12970] | 1631 | else
|
---|
[64373] | 1632 | {
|
---|
| 1633 | Assert(!pDevIns->Internal.s.pHeadPciDevR3);
|
---|
| 1634 | pDevIns->Internal.s.pHeadPciDevR3 = pPciDev;
|
---|
| 1635 | if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
|
---|
| 1636 | pDevIns->Internal.s.pHeadPciDevR0 = MMHyperR3ToR0(pVM, pPciDev);
|
---|
| 1637 | else
|
---|
| 1638 | pDevIns->Internal.s.pHeadPciDevR0 = NIL_RTR0PTR;
|
---|
| 1639 | if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
|
---|
| 1640 | pDevIns->Internal.s.pHeadPciDevRC = MMHyperR3ToRC(pVM, pPciDev);
|
---|
| 1641 | else
|
---|
| 1642 | pDevIns->Internal.s.pHeadPciDevRC = NIL_RTRCPTR;
|
---|
| 1643 | }
|
---|
[12970] | 1644 |
|
---|
[1] | 1645 | Log(("PDM: Registered device '%s'/%d as PCI device %d on bus %d\n",
|
---|
[64373] | 1646 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev->uDevFn, pBus->iBus));
|
---|
[1] | 1647 | }
|
---|
| 1648 | }
|
---|
| 1649 | else
|
---|
| 1650 | {
|
---|
[13215] | 1651 | AssertLogRelMsgFailed(("Configuration error: No PCI bus available. This could be related to init order too!\n"));
|
---|
[1] | 1652 | rc = VERR_PDM_NO_PCI_BUS;
|
---|
| 1653 | }
|
---|
| 1654 |
|
---|
[26165] | 1655 | LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 1656 | return rc;
|
---|
| 1657 | }
|
---|
| 1658 |
|
---|
| 1659 |
|
---|
[64373] | 1660 | /** @interface_method_impl{PDMDEVHLPR3,pfnPCIRegisterMsi} */
|
---|
[64387] | 1661 | static DECLCALLBACK(int) pdmR3DevHlp_PCIRegisterMsi(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PPDMMSIREG pMsiReg)
|
---|
[64373] | 1662 | {
|
---|
| 1663 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1664 | if (!pPciDev) /* NULL is an alias for the default PCI device. */
|
---|
| 1665 | pPciDev = pDevIns->Internal.s.pHeadPciDevR3;
|
---|
| 1666 | AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
|
---|
| 1667 | LogFlow(("pdmR3DevHlp_PCIRegisterMsi: caller='%s'/%d: pPciDev=%p:{%#x} pMsgReg=%p:{cMsiVectors=%d, cMsixVectors=%d}\n",
|
---|
[64378] | 1668 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev->uDevFn, pMsiReg, pMsiReg->cMsiVectors, pMsiReg->cMsixVectors));
|
---|
[64373] | 1669 |
|
---|
| 1670 | PPDMPCIBUS pBus = pPciDev->Int.s.pPdmBusR3; Assert(pBus);
|
---|
| 1671 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1672 | pdmLock(pVM);
|
---|
| 1673 | int rc;
|
---|
| 1674 | if (pBus->pfnRegisterMsiR3)
|
---|
| 1675 | rc = pBus->pfnRegisterMsiR3(pBus->pDevInsR3, pPciDev, pMsiReg);
|
---|
| 1676 | else
|
---|
| 1677 | rc = VERR_NOT_IMPLEMENTED;
|
---|
| 1678 | pdmUnlock(pVM);
|
---|
| 1679 |
|
---|
| 1680 | LogFlow(("pdmR3DevHlp_PCIRegisterMsi: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 1681 | return rc;
|
---|
| 1682 | }
|
---|
| 1683 |
|
---|
| 1684 |
|
---|
[26152] | 1685 | /** @interface_method_impl{PDMDEVHLPR3,pfnPCIIORegionRegister} */
|
---|
[64387] | 1686 | static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
|
---|
[64373] | 1687 | RTGCPHYS cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)
|
---|
[1] | 1688 | {
|
---|
| 1689 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 1690 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[2597] | 1691 | VM_ASSERT_EMT(pVM);
|
---|
[64373] | 1692 | if (!pPciDev) /* NULL is an alias for the default PCI device. */
|
---|
| 1693 | pPciDev = pDevIns->Internal.s.pHeadPciDevR3;
|
---|
| 1694 | AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
|
---|
| 1695 | LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%d cbRegion=%RGp enmType=%d pfnCallback=%p\n",
|
---|
[64378] | 1696 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev->uDevFn, iRegion, cbRegion, enmType, pfnCallback));
|
---|
[1] | 1697 |
|
---|
| 1698 | /*
|
---|
| 1699 | * Validate input.
|
---|
| 1700 | */
|
---|
[64373] | 1701 | if (iRegion >= VBOX_PCI_NUM_REGIONS)
|
---|
[1] | 1702 | {
|
---|
[64373] | 1703 | Assert(iRegion < VBOX_PCI_NUM_REGIONS);
|
---|
[26165] | 1704 | LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Rrc (iRegion)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 1705 | return VERR_INVALID_PARAMETER;
|
---|
| 1706 | }
|
---|
[63685] | 1707 |
|
---|
[36157] | 1708 | switch ((int)enmType)
|
---|
[1] | 1709 | {
|
---|
[15099] | 1710 | case PCI_ADDRESS_SPACE_IO:
|
---|
| 1711 | /*
|
---|
| 1712 | * Sanity check: don't allow to register more than 32K of the PCI I/O space.
|
---|
| 1713 | */
|
---|
[63685] | 1714 | AssertLogRelMsgReturn(cbRegion <= _32K,
|
---|
| 1715 | ("caller='%s'/%d: %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, cbRegion),
|
---|
| 1716 | VERR_INVALID_PARAMETER);
|
---|
[15099] | 1717 | break;
|
---|
[15126] | 1718 |
|
---|
[1] | 1719 | case PCI_ADDRESS_SPACE_MEM:
|
---|
| 1720 | case PCI_ADDRESS_SPACE_MEM_PREFETCH:
|
---|
[15099] | 1721 | /*
|
---|
[63685] | 1722 | * Sanity check: Don't allow to register more than 2GB of the PCI MMIO space.
|
---|
[15099] | 1723 | */
|
---|
[64327] | 1724 | AssertLogRelMsgReturn(cbRegion <= MM_MMIO_32_MAX,
|
---|
| 1725 | ("caller='%s'/%d: %RGp (max %RGp)\n",
|
---|
| 1726 | pDevIns->pReg->szName, pDevIns->iInstance, cbRegion, (RTGCPHYS)MM_MMIO_32_MAX),
|
---|
[63685] | 1727 | VERR_OUT_OF_RANGE);
|
---|
[1] | 1728 | break;
|
---|
[63685] | 1729 |
|
---|
| 1730 | case PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_MEM:
|
---|
| 1731 | case PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_MEM_PREFETCH:
|
---|
| 1732 | /*
|
---|
| 1733 | * Sanity check: Don't allow to register more than 64GB of the 64-bit PCI MMIO space.
|
---|
| 1734 | */
|
---|
[64327] | 1735 | AssertLogRelMsgReturn(cbRegion <= MM_MMIO_64_MAX,
|
---|
| 1736 | ("caller='%s'/%d: %RGp (max %RGp)\n",
|
---|
| 1737 | pDevIns->pReg->szName, pDevIns->iInstance, cbRegion, MM_MMIO_64_MAX),
|
---|
[63685] | 1738 | VERR_OUT_OF_RANGE);
|
---|
| 1739 | break;
|
---|
| 1740 |
|
---|
[1] | 1741 | default:
|
---|
| 1742 | AssertMsgFailed(("enmType=%#x is unknown\n", enmType));
|
---|
[26165] | 1743 | LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Rrc (enmType)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 1744 | return VERR_INVALID_PARAMETER;
|
---|
| 1745 | }
|
---|
| 1746 | if (!pfnCallback)
|
---|
| 1747 | {
|
---|
| 1748 | Assert(pfnCallback);
|
---|
[26165] | 1749 | LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Rrc (callback)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 1750 | return VERR_INVALID_PARAMETER;
|
---|
| 1751 | }
|
---|
[2597] | 1752 | AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING);
|
---|
[1] | 1753 |
|
---|
| 1754 | /*
|
---|
[64373] | 1755 | * We're currently restricted to page aligned MMIO regions.
|
---|
[1] | 1756 | */
|
---|
[64373] | 1757 | if ( ((enmType & ~(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_MEM_PREFETCH)) == PCI_ADDRESS_SPACE_MEM)
|
---|
| 1758 | && cbRegion != RT_ALIGN_64(cbRegion, PAGE_SIZE))
|
---|
[1] | 1759 | {
|
---|
[64373] | 1760 | Log(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: aligning cbRegion %RGp -> %RGp\n",
|
---|
| 1761 | pDevIns->pReg->szName, pDevIns->iInstance, cbRegion, RT_ALIGN_64(cbRegion, PAGE_SIZE)));
|
---|
| 1762 | cbRegion = RT_ALIGN_64(cbRegion, PAGE_SIZE);
|
---|
| 1763 | }
|
---|
[15126] | 1764 |
|
---|
[64373] | 1765 | /*
|
---|
| 1766 | * For registering PCI MMIO memory or PCI I/O memory, the size of the region must be a power of 2!
|
---|
| 1767 | */
|
---|
| 1768 | int iLastSet = ASMBitLastSetU64(cbRegion);
|
---|
| 1769 | Assert(iLastSet > 0);
|
---|
| 1770 | uint64_t cbRegionAligned = RT_BIT_64(iLastSet - 1);
|
---|
| 1771 | if (cbRegion > cbRegionAligned)
|
---|
| 1772 | cbRegion = cbRegionAligned * 2; /* round up */
|
---|
[15099] | 1773 |
|
---|
[64373] | 1774 | PPDMPCIBUS pBus = pPciDev->Int.s.pPdmBusR3;
|
---|
| 1775 | Assert(pBus);
|
---|
| 1776 | pdmLock(pVM);
|
---|
| 1777 | int rc = pBus->pfnIORegionRegisterR3(pBus->pDevInsR3, pPciDev, iRegion, cbRegion, enmType, pfnCallback);
|
---|
| 1778 | pdmUnlock(pVM);
|
---|
[1] | 1779 |
|
---|
[26165] | 1780 | LogFlow(("pdmR3DevHlp_PCIIORegionRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 1781 | return rc;
|
---|
| 1782 | }
|
---|
| 1783 |
|
---|
| 1784 |
|
---|
[26152] | 1785 | /** @interface_method_impl{PDMDEVHLPR3,pfnPCISetConfigCallbacks} */
|
---|
[64387] | 1786 | static DECLCALLBACK(void) pdmR3DevHlp_PCISetConfigCallbacks(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
|
---|
[2597] | 1787 | PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld)
|
---|
| 1788 | {
|
---|
| 1789 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 1790 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[2597] | 1791 | VM_ASSERT_EMT(pVM);
|
---|
[64373] | 1792 | if (!pPciDev) /* NULL is an alias for the default PCI device. */
|
---|
| 1793 | pPciDev = pDevIns->Internal.s.pHeadPciDevR3;
|
---|
| 1794 | AssertReturnVoid(pPciDev);
|
---|
[2597] | 1795 | LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: pPciDev=%p pfnRead=%p ppfnReadOld=%p pfnWrite=%p ppfnWriteOld=%p\n",
|
---|
[26165] | 1796 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld));
|
---|
[2597] | 1797 |
|
---|
| 1798 | /*
|
---|
| 1799 | * Validate input and resolve defaults.
|
---|
| 1800 | */
|
---|
| 1801 | AssertPtr(pfnRead);
|
---|
| 1802 | AssertPtr(pfnWrite);
|
---|
| 1803 | AssertPtrNull(ppfnReadOld);
|
---|
| 1804 | AssertPtrNull(ppfnWriteOld);
|
---|
| 1805 | AssertPtrNull(pPciDev);
|
---|
| 1806 |
|
---|
[64373] | 1807 | PPDMPCIBUS pBus = pPciDev->Int.s.pPdmBusR3;
|
---|
[2597] | 1808 | AssertRelease(pBus);
|
---|
| 1809 | AssertRelease(VMR3GetState(pVM) != VMSTATE_RUNNING);
|
---|
| 1810 |
|
---|
| 1811 | /*
|
---|
| 1812 | * Do the job.
|
---|
| 1813 | */
|
---|
| 1814 | pdmLock(pVM);
|
---|
| 1815 | pBus->pfnSetConfigCallbacksR3(pBus->pDevInsR3, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld);
|
---|
| 1816 | pdmUnlock(pVM);
|
---|
| 1817 |
|
---|
[26165] | 1818 | LogFlow(("pdmR3DevHlp_PCISetConfigCallbacks: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[2597] | 1819 | }
|
---|
| 1820 |
|
---|
| 1821 |
|
---|
[44897] | 1822 | /** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysRead} */
|
---|
[64373] | 1823 | static DECLCALLBACK(int)
|
---|
[64387] | 1824 | pdmR3DevHlp_PCIPhysRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
|
---|
[44897] | 1825 | {
|
---|
| 1826 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[64373] | 1827 | if (!pPciDev) /* NULL is an alias for the default PCI device. */
|
---|
| 1828 | pPciDev = pDevIns->Internal.s.pHeadPciDevR3;
|
---|
| 1829 | AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
|
---|
[44897] | 1830 |
|
---|
[44902] | 1831 | #ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
|
---|
[44897] | 1832 | /*
|
---|
| 1833 | * Just check the busmaster setting here and forward the request to the generic read helper.
|
---|
| 1834 | */
|
---|
[64373] | 1835 | if (PCIDevIsBusmaster(pPciDev))
|
---|
| 1836 | { /* likely */ }
|
---|
| 1837 | else
|
---|
[44897] | 1838 | {
|
---|
[44898] | 1839 | Log(("pdmR3DevHlp_PCIPhysRead: caller='%s'/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbRead=%#zx\n",
|
---|
[44897] | 1840 | pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, GCPhys, cbRead));
|
---|
[69100] | 1841 | memset(pvBuf, 0xff, cbRead);
|
---|
[44897] | 1842 | return VERR_PDM_NOT_PCI_BUS_MASTER;
|
---|
| 1843 | }
|
---|
[44902] | 1844 | #endif
|
---|
[44897] | 1845 |
|
---|
| 1846 | return pDevIns->pHlpR3->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead);
|
---|
| 1847 | }
|
---|
| 1848 |
|
---|
| 1849 |
|
---|
[58126] | 1850 | /** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysWrite} */
|
---|
[64373] | 1851 | static DECLCALLBACK(int)
|
---|
[64387] | 1852 | pdmR3DevHlp_PCIPhysWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
|
---|
[44897] | 1853 | {
|
---|
| 1854 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[64373] | 1855 | if (!pPciDev) /* NULL is an alias for the default PCI device. */
|
---|
| 1856 | pPciDev = pDevIns->Internal.s.pHeadPciDevR3;
|
---|
| 1857 | AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
|
---|
[44897] | 1858 |
|
---|
[44902] | 1859 | #ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
|
---|
[44897] | 1860 | /*
|
---|
| 1861 | * Just check the busmaster setting here and forward the request to the generic read helper.
|
---|
| 1862 | */
|
---|
[64373] | 1863 | if (PCIDevIsBusmaster(pPciDev))
|
---|
| 1864 | { /* likely */ }
|
---|
| 1865 | else
|
---|
[44897] | 1866 | {
|
---|
[44898] | 1867 | Log(("pdmR3DevHlp_PCIPhysWrite: caller='%s'/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbWrite=%#zx\n",
|
---|
[44897] | 1868 | pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, GCPhys, cbWrite));
|
---|
| 1869 | return VERR_PDM_NOT_PCI_BUS_MASTER;
|
---|
| 1870 | }
|
---|
[44902] | 1871 | #endif
|
---|
[44897] | 1872 |
|
---|
| 1873 | return pDevIns->pHlpR3->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
|
---|
| 1874 | }
|
---|
| 1875 |
|
---|
| 1876 |
|
---|
[26152] | 1877 | /** @interface_method_impl{PDMDEVHLPR3,pfnPCISetIrq} */
|
---|
[64387] | 1878 | static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrq(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
|
---|
[1] | 1879 | {
|
---|
| 1880 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[64373] | 1881 | if (!pPciDev) /* NULL is an alias for the default PCI device. */
|
---|
| 1882 | pPciDev = pDevIns->Internal.s.pHeadPciDevR3;
|
---|
| 1883 | AssertReturnVoid(pPciDev);
|
---|
| 1884 | LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: pPciDev=%p:{%#x} iIrq=%d iLevel=%d\n",
|
---|
[64378] | 1885 | pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev->uDevFn, iIrq, iLevel));
|
---|
[1] | 1886 |
|
---|
| 1887 | /*
|
---|
| 1888 | * Validate input.
|
---|
| 1889 | */
|
---|
[40907] | 1890 | Assert(iIrq == 0);
|
---|
| 1891 | Assert((uint32_t)iLevel <= PDM_IRQ_LEVEL_FLIP_FLOP);
|
---|
[1] | 1892 |
|
---|
| 1893 | /*
|
---|
| 1894 | * Must have a PCI device registered!
|
---|
| 1895 | */
|
---|
[64373] | 1896 | PPDMPCIBUS pBus = pPciDev->Int.s.pPdmBusR3;
|
---|
| 1897 | Assert(pBus);
|
---|
| 1898 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1899 |
|
---|
| 1900 | pdmLock(pVM);
|
---|
| 1901 | uint32_t uTagSrc;
|
---|
| 1902 | if (iLevel & PDM_IRQ_LEVEL_HIGH)
|
---|
[1] | 1903 | {
|
---|
[64373] | 1904 | pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
|
---|
| 1905 | if (iLevel == PDM_IRQ_LEVEL_HIGH)
|
---|
| 1906 | VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
|
---|
[40907] | 1907 | else
|
---|
[64373] | 1908 | VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
|
---|
[1] | 1909 | }
|
---|
| 1910 | else
|
---|
[64373] | 1911 | uTagSrc = pDevIns->Internal.s.uLastIrqTag;
|
---|
[1] | 1912 |
|
---|
[64373] | 1913 | pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, iIrq, iLevel, uTagSrc);
|
---|
| 1914 |
|
---|
| 1915 | if (iLevel == PDM_IRQ_LEVEL_LOW)
|
---|
| 1916 | VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
|
---|
| 1917 | pdmUnlock(pVM);
|
---|
| 1918 |
|
---|
[26165] | 1919 | LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[1] | 1920 | }
|
---|
| 1921 |
|
---|
| 1922 |
|
---|
[26152] | 1923 | /** @interface_method_impl{PDMDEVHLPR3,pfnPCISetIrqNoWait} */
|
---|
[64387] | 1924 | static DECLCALLBACK(void) pdmR3DevHlp_PCISetIrqNoWait(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
|
---|
[1] | 1925 | {
|
---|
[64373] | 1926 | pdmR3DevHlp_PCISetIrq(pDevIns, pPciDev, iIrq, iLevel);
|
---|
[1] | 1927 | }
|
---|
| 1928 |
|
---|
| 1929 |
|
---|
[26152] | 1930 | /** @interface_method_impl{PDMDEVHLPR3,pfnISASetIrq} */
|
---|
[1] | 1931 | static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
|
---|
| 1932 | {
|
---|
| 1933 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 1934 | LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, iIrq, iLevel));
|
---|
[1] | 1935 |
|
---|
| 1936 | /*
|
---|
| 1937 | * Validate input.
|
---|
| 1938 | */
|
---|
[40907] | 1939 | Assert(iIrq < 16);
|
---|
| 1940 | Assert((uint32_t)iLevel <= PDM_IRQ_LEVEL_FLIP_FLOP);
|
---|
[1] | 1941 |
|
---|
[12970] | 1942 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[1] | 1943 |
|
---|
[40907] | 1944 | /*
|
---|
| 1945 | * Do the job.
|
---|
| 1946 | */
|
---|
| 1947 | pdmLock(pVM);
|
---|
| 1948 | uint32_t uTagSrc;
|
---|
| 1949 | if (iLevel & PDM_IRQ_LEVEL_HIGH)
|
---|
| 1950 | {
|
---|
| 1951 | pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
|
---|
| 1952 | if (iLevel == PDM_IRQ_LEVEL_HIGH)
|
---|
| 1953 | VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
|
---|
| 1954 | else
|
---|
| 1955 | VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
|
---|
| 1956 | }
|
---|
| 1957 | else
|
---|
| 1958 | uTagSrc = pDevIns->Internal.s.uLastIrqTag;
|
---|
| 1959 |
|
---|
| 1960 | PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); /* (The API takes the lock recursively.) */
|
---|
| 1961 |
|
---|
| 1962 | if (iLevel == PDM_IRQ_LEVEL_LOW)
|
---|
| 1963 | VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
|
---|
| 1964 | pdmUnlock(pVM);
|
---|
| 1965 |
|
---|
[26165] | 1966 | LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[1] | 1967 | }
|
---|
| 1968 |
|
---|
[7635] | 1969 |
|
---|
[26152] | 1970 | /** @interface_method_impl{PDMDEVHLPR3,pfnISASetIrqNoWait} */
|
---|
[1] | 1971 | static DECLCALLBACK(void) pdmR3DevHlp_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
|
---|
| 1972 | {
|
---|
| 1973 | pdmR3DevHlp_ISASetIrq(pDevIns, iIrq, iLevel);
|
---|
| 1974 | }
|
---|
| 1975 |
|
---|
| 1976 |
|
---|
[68470] | 1977 | /** @interface_method_impl{PDMDEVHLPR3,pfnIoApicSendMsi} */
|
---|
| 1978 | static DECLCALLBACK(void) pdmR3DevHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue)
|
---|
| 1979 | {
|
---|
| 1980 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 1981 | LogFlow(("pdmR3DevHlp_IoApicSendMsi: caller='%s'/%d: GCPhys=%RGp uValue=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, uValue));
|
---|
| 1982 |
|
---|
| 1983 | /*
|
---|
| 1984 | * Validate input.
|
---|
| 1985 | */
|
---|
| 1986 | Assert(GCPhys != 0);
|
---|
| 1987 | Assert(uValue != 0);
|
---|
| 1988 |
|
---|
| 1989 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 1990 |
|
---|
| 1991 | /*
|
---|
| 1992 | * Do the job.
|
---|
| 1993 | */
|
---|
| 1994 | pdmLock(pVM);
|
---|
| 1995 | uint32_t uTagSrc;
|
---|
| 1996 | pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
|
---|
| 1997 | VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
|
---|
| 1998 |
|
---|
| 1999 | PDMIoApicSendMsi(pVM, GCPhys, uValue, uTagSrc); /* (The API takes the lock recursively.) */
|
---|
| 2000 |
|
---|
| 2001 | pdmUnlock(pVM);
|
---|
| 2002 |
|
---|
| 2003 | LogFlow(("pdmR3DevHlp_IoApicSendMsi: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
| 2004 | }
|
---|
| 2005 |
|
---|
| 2006 |
|
---|
[26152] | 2007 | /** @interface_method_impl{PDMDEVHLPR3,pfnDriverAttach} */
|
---|
[39136] | 2008 | static DECLCALLBACK(int) pdmR3DevHlp_DriverAttach(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)
|
---|
[1] | 2009 | {
|
---|
| 2010 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 2011 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[1] | 2012 | VM_ASSERT_EMT(pVM);
|
---|
| 2013 | LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: iLun=%d pBaseInterface=%p ppBaseInterface=%p pszDesc=%p:{%s}\n",
|
---|
[26165] | 2014 | pDevIns->pReg->szName, pDevIns->iInstance, iLun, pBaseInterface, ppBaseInterface, pszDesc, pszDesc));
|
---|
[1] | 2015 |
|
---|
| 2016 | /*
|
---|
| 2017 | * Lookup the LUN, it might already be registered.
|
---|
| 2018 | */
|
---|
| 2019 | PPDMLUN pLunPrev = NULL;
|
---|
[12970] | 2020 | PPDMLUN pLun = pDevIns->Internal.s.pLunsR3;
|
---|
[1] | 2021 | for (; pLun; pLunPrev = pLun, pLun = pLun->pNext)
|
---|
| 2022 | if (pLun->iLun == iLun)
|
---|
| 2023 | break;
|
---|
| 2024 |
|
---|
| 2025 | /*
|
---|
| 2026 | * Create the LUN if if wasn't found, else check if driver is already attached to it.
|
---|
| 2027 | */
|
---|
| 2028 | if (!pLun)
|
---|
| 2029 | {
|
---|
| 2030 | if ( !pBaseInterface
|
---|
| 2031 | || !pszDesc
|
---|
| 2032 | || !*pszDesc)
|
---|
| 2033 | {
|
---|
| 2034 | Assert(pBaseInterface);
|
---|
| 2035 | Assert(pszDesc || *pszDesc);
|
---|
| 2036 | return VERR_INVALID_PARAMETER;
|
---|
| 2037 | }
|
---|
| 2038 |
|
---|
| 2039 | pLun = (PPDMLUN)MMR3HeapAlloc(pVM, MM_TAG_PDM_LUN, sizeof(*pLun));
|
---|
| 2040 | if (!pLun)
|
---|
| 2041 | return VERR_NO_MEMORY;
|
---|
| 2042 |
|
---|
| 2043 | pLun->iLun = iLun;
|
---|
| 2044 | pLun->pNext = pLunPrev ? pLunPrev->pNext : NULL;
|
---|
| 2045 | pLun->pTop = NULL;
|
---|
[5722] | 2046 | pLun->pBottom = NULL;
|
---|
[1] | 2047 | pLun->pDevIns = pDevIns;
|
---|
[26112] | 2048 | pLun->pUsbIns = NULL;
|
---|
[1] | 2049 | pLun->pszDesc = pszDesc;
|
---|
| 2050 | pLun->pBase = pBaseInterface;
|
---|
| 2051 | if (!pLunPrev)
|
---|
[12970] | 2052 | pDevIns->Internal.s.pLunsR3 = pLun;
|
---|
[1] | 2053 | else
|
---|
| 2054 | pLunPrev->pNext = pLun;
|
---|
| 2055 | Log(("pdmR3DevHlp_DriverAttach: Registered LUN#%d '%s' with device '%s'/%d.\n",
|
---|
[26165] | 2056 | iLun, pszDesc, pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[1] | 2057 | }
|
---|
| 2058 | else if (pLun->pTop)
|
---|
| 2059 | {
|
---|
| 2060 | AssertMsgFailed(("Already attached! The device should keep track of such things!\n"));
|
---|
[26165] | 2061 | LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_DRIVER_ALREADY_ATTACHED));
|
---|
[1] | 2062 | return VERR_PDM_DRIVER_ALREADY_ATTACHED;
|
---|
| 2063 | }
|
---|
| 2064 | Assert(pLun->pBase == pBaseInterface);
|
---|
| 2065 |
|
---|
| 2066 |
|
---|
| 2067 | /*
|
---|
| 2068 | * Get the attached driver configuration.
|
---|
| 2069 | */
|
---|
| 2070 | int rc;
|
---|
[24282] | 2071 | PCFGMNODE pNode = CFGMR3GetChildF(pDevIns->Internal.s.pCfgHandle, "LUN#%u", iLun);
|
---|
[1] | 2072 | if (pNode)
|
---|
[25891] | 2073 | rc = pdmR3DrvInstantiate(pVM, pNode, pBaseInterface, NULL /*pDrvAbove*/, pLun, ppBaseInterface);
|
---|
[1] | 2074 | else
|
---|
| 2075 | rc = VERR_PDM_NO_ATTACHED_DRIVER;
|
---|
| 2076 |
|
---|
[26165] | 2077 | LogFlow(("pdmR3DevHlp_DriverAttach: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 2078 | return rc;
|
---|
| 2079 | }
|
---|
| 2080 |
|
---|
| 2081 |
|
---|
[59348] | 2082 | /** @interface_method_impl{PDMDEVHLPR3,pfnDriverDetach} */
|
---|
| 2083 | static DECLCALLBACK(int) pdmR3DevHlp_DriverDetach(PPDMDEVINS pDevIns, PPDMDRVINS pDrvIns, uint32_t fFlags)
|
---|
| 2084 | {
|
---|
[62643] | 2085 | PDMDEV_ASSERT_DEVINS(pDevIns); RT_NOREF_PV(pDevIns);
|
---|
[59348] | 2086 | LogFlow(("pdmR3DevHlp_DriverDetach: caller='%s'/%d: pDrvIns=%p\n",
|
---|
| 2087 | pDevIns->pReg->szName, pDevIns->iInstance, pDrvIns));
|
---|
| 2088 |
|
---|
[62643] | 2089 | #ifdef VBOX_STRICT
|
---|
[59348] | 2090 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 2091 | VM_ASSERT_EMT(pVM);
|
---|
[62643] | 2092 | #endif
|
---|
[59348] | 2093 |
|
---|
| 2094 | int rc = pdmR3DrvDetach(pDrvIns, fFlags);
|
---|
| 2095 |
|
---|
| 2096 | LogFlow(("pdmR3DevHlp_DriverDetach: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 2097 | return rc;
|
---|
| 2098 | }
|
---|
| 2099 |
|
---|
| 2100 |
|
---|
[26157] | 2101 | /** @interface_method_impl{PDMDEVHLPR3,pfnQueueCreate} */
|
---|
[39136] | 2102 | static DECLCALLBACK(int) pdmR3DevHlp_QueueCreate(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
|
---|
[58126] | 2103 | PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PPDMQUEUE *ppQueue)
|
---|
[1] | 2104 | {
|
---|
| 2105 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[58126] | 2106 | LogFlow(("pdmR3DevHlp_QueueCreate: caller='%s'/%d: cbItem=%#x cItems=%#x cMilliesInterval=%u pfnCallback=%p fRZEnabled=%RTbool pszName=%p:{%s} ppQueue=%p\n",
|
---|
| 2107 | pDevIns->pReg->szName, pDevIns->iInstance, cbItem, cItems, cMilliesInterval, pfnCallback, fRZEnabled, pszName, pszName, ppQueue));
|
---|
[1] | 2108 |
|
---|
[26157] | 2109 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 2110 | VM_ASSERT_EMT(pVM);
|
---|
[1] | 2111 |
|
---|
[26157] | 2112 | if (pDevIns->iInstance > 0)
|
---|
| 2113 | {
|
---|
| 2114 | pszName = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_DESC, "%s_%u", pszName, pDevIns->iInstance);
|
---|
| 2115 | AssertLogRelReturn(pszName, VERR_NO_MEMORY);
|
---|
| 2116 | }
|
---|
[1] | 2117 |
|
---|
[58126] | 2118 | int rc = PDMR3QueueCreateDevice(pVM, pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fRZEnabled, pszName, ppQueue);
|
---|
[1] | 2119 |
|
---|
[26165] | 2120 | LogFlow(("pdmR3DevHlp_QueueCreate: caller='%s'/%d: returns %Rrc *ppQueue=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *ppQueue));
|
---|
[1] | 2121 | return rc;
|
---|
| 2122 | }
|
---|
| 2123 |
|
---|
| 2124 |
|
---|
[26157] | 2125 | /** @interface_method_impl{PDMDEVHLPR3,pfnCritSectInit} */
|
---|
| 2126 | static DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
|
---|
| 2127 | const char *pszNameFmt, va_list va)
|
---|
[1] | 2128 | {
|
---|
| 2129 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26157] | 2130 | LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: pCritSect=%p pszNameFmt=%p:{%s}\n",
|
---|
[26165] | 2131 | pDevIns->pReg->szName, pDevIns->iInstance, pCritSect, pszNameFmt, pszNameFmt));
|
---|
[1] | 2132 |
|
---|
[12970] | 2133 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[1] | 2134 | VM_ASSERT_EMT(pVM);
|
---|
[26780] | 2135 | int rc = pdmR3CritSectInitDevice(pVM, pDevIns, pCritSect, RT_SRC_POS_ARGS, pszNameFmt, va);
|
---|
[1] | 2136 |
|
---|
[26165] | 2137 | LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 2138 | return rc;
|
---|
| 2139 | }
|
---|
| 2140 |
|
---|
| 2141 |
|
---|
[37443] | 2142 | /** @interface_method_impl{PDMDEVHLPR3,pfnCritSectGetNop} */
|
---|
| 2143 | static DECLCALLBACK(PPDMCRITSECT) pdmR3DevHlp_CritSectGetNop(PPDMDEVINS pDevIns)
|
---|
| 2144 | {
|
---|
| 2145 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2146 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 2147 | VM_ASSERT_EMT(pVM);
|
---|
| 2148 |
|
---|
| 2149 | PPDMCRITSECT pCritSect = PDMR3CritSectGetNop(pVM);
|
---|
| 2150 | LogFlow(("pdmR3DevHlp_CritSectGetNop: caller='%s'/%d: return %p\n",
|
---|
| 2151 | pDevIns->pReg->szName, pDevIns->iInstance, pCritSect));
|
---|
| 2152 | return pCritSect;
|
---|
| 2153 | }
|
---|
| 2154 |
|
---|
| 2155 |
|
---|
| 2156 | /** @interface_method_impl{PDMDEVHLPR3,pfnCritSectGetNopR0} */
|
---|
| 2157 | static DECLCALLBACK(R0PTRTYPE(PPDMCRITSECT)) pdmR3DevHlp_CritSectGetNopR0(PPDMDEVINS pDevIns)
|
---|
| 2158 | {
|
---|
| 2159 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2160 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 2161 | VM_ASSERT_EMT(pVM);
|
---|
| 2162 |
|
---|
| 2163 | R0PTRTYPE(PPDMCRITSECT) pCritSect = PDMR3CritSectGetNopR0(pVM);
|
---|
| 2164 | LogFlow(("pdmR3DevHlp_CritSectGetNopR0: caller='%s'/%d: return %RHv\n",
|
---|
| 2165 | pDevIns->pReg->szName, pDevIns->iInstance, pCritSect));
|
---|
| 2166 | return pCritSect;
|
---|
| 2167 | }
|
---|
| 2168 |
|
---|
| 2169 |
|
---|
| 2170 | /** @interface_method_impl{PDMDEVHLPR3,pfnCritSectGetNopRC} */
|
---|
| 2171 | static DECLCALLBACK(RCPTRTYPE(PPDMCRITSECT)) pdmR3DevHlp_CritSectGetNopRC(PPDMDEVINS pDevIns)
|
---|
| 2172 | {
|
---|
| 2173 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2174 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 2175 | VM_ASSERT_EMT(pVM);
|
---|
| 2176 |
|
---|
| 2177 | RCPTRTYPE(PPDMCRITSECT) pCritSect = PDMR3CritSectGetNopRC(pVM);
|
---|
| 2178 | LogFlow(("pdmR3DevHlp_CritSectGetNopRC: caller='%s'/%d: return %RRv\n",
|
---|
| 2179 | pDevIns->pReg->szName, pDevIns->iInstance, pCritSect));
|
---|
| 2180 | return pCritSect;
|
---|
| 2181 | }
|
---|
| 2182 |
|
---|
| 2183 |
|
---|
[37466] | 2184 | /** @interface_method_impl{PDMDEVHLPR3,pfnSetDeviceCritSect} */
|
---|
| 2185 | static DECLCALLBACK(int) pdmR3DevHlp_SetDeviceCritSect(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
|
---|
| 2186 | {
|
---|
| 2187 | /*
|
---|
| 2188 | * Validate input.
|
---|
| 2189 | *
|
---|
| 2190 | * Note! We only allow the automatically created default critical section
|
---|
| 2191 | * to be replaced by this API.
|
---|
| 2192 | */
|
---|
| 2193 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2194 | AssertPtrReturn(pCritSect, VERR_INVALID_POINTER);
|
---|
| 2195 | LogFlow(("pdmR3DevHlp_SetDeviceCritSect: caller='%s'/%d: pCritSect=%p (%s)\n",
|
---|
| 2196 | pDevIns->pReg->szName, pDevIns->iInstance, pCritSect, pCritSect->s.pszName));
|
---|
| 2197 | AssertReturn(PDMCritSectIsInitialized(pCritSect), VERR_INVALID_PARAMETER);
|
---|
| 2198 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 2199 | AssertReturn(pCritSect->s.pVMR3 == pVM, VERR_INVALID_PARAMETER);
|
---|
| 2200 |
|
---|
| 2201 | VM_ASSERT_EMT(pVM);
|
---|
| 2202 | VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
|
---|
| 2203 |
|
---|
[39402] | 2204 | AssertReturn(pDevIns->pCritSectRoR3, VERR_PDM_DEV_IPE_1);
|
---|
[37466] | 2205 | AssertReturn(pDevIns->pCritSectRoR3->s.fAutomaticDefaultCritsect, VERR_WRONG_ORDER);
|
---|
| 2206 | AssertReturn(!pDevIns->pCritSectRoR3->s.fUsedByTimerOrSimilar, VERR_WRONG_ORDER);
|
---|
| 2207 | AssertReturn(pDevIns->pCritSectRoR3 != pCritSect, VERR_INVALID_PARAMETER);
|
---|
| 2208 |
|
---|
| 2209 | /*
|
---|
| 2210 | * Replace the critical section and destroy the automatic default section.
|
---|
| 2211 | */
|
---|
| 2212 | PPDMCRITSECT pOldCritSect = pDevIns->pCritSectRoR3;
|
---|
| 2213 | pDevIns->pCritSectRoR3 = pCritSect;
|
---|
| 2214 | if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
|
---|
| 2215 | pDevIns->pCritSectRoR0 = MMHyperCCToR0(pVM, pDevIns->pCritSectRoR3);
|
---|
| 2216 | else
|
---|
| 2217 | Assert(pDevIns->pCritSectRoR0 == NIL_RTRCPTR);
|
---|
| 2218 |
|
---|
| 2219 | if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
|
---|
| 2220 | pDevIns->pCritSectRoRC = MMHyperCCToRC(pVM, pDevIns->pCritSectRoR3);
|
---|
| 2221 | else
|
---|
| 2222 | Assert(pDevIns->pCritSectRoRC == NIL_RTRCPTR);
|
---|
| 2223 |
|
---|
| 2224 | PDMR3CritSectDelete(pOldCritSect);
|
---|
| 2225 | if (pDevIns->pReg->fFlags & (PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0))
|
---|
| 2226 | MMHyperFree(pVM, pOldCritSect);
|
---|
| 2227 | else
|
---|
| 2228 | MMR3HeapFree(pOldCritSect);
|
---|
| 2229 |
|
---|
| 2230 | LogFlow(("pdmR3DevHlp_SetDeviceCritSect: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
|
---|
| 2231 | return VINF_SUCCESS;
|
---|
| 2232 | }
|
---|
| 2233 |
|
---|
| 2234 |
|
---|
[26157] | 2235 | /** @interface_method_impl{PDMDEVHLPR3,pfnThreadCreate} */
|
---|
| 2236 | static DECLCALLBACK(int) pdmR3DevHlp_ThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
|
---|
| 2237 | PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
|
---|
[1] | 2238 | {
|
---|
| 2239 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26157] | 2240 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
| 2241 | LogFlow(("pdmR3DevHlp_ThreadCreate: caller='%s'/%d: ppThread=%p pvUser=%p pfnThread=%p pfnWakeup=%p cbStack=%#zx enmType=%d pszName=%p:{%s}\n",
|
---|
[26165] | 2242 | pDevIns->pReg->szName, pDevIns->iInstance, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName, pszName));
|
---|
[1] | 2243 |
|
---|
[26157] | 2244 | int rc = pdmR3ThreadCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
|
---|
[1] | 2245 |
|
---|
[26165] | 2246 | LogFlow(("pdmR3DevHlp_ThreadCreate: caller='%s'/%d: returns %Rrc *ppThread=%RTthrd\n", pDevIns->pReg->szName, pDevIns->iInstance,
|
---|
[26157] | 2247 | rc, *ppThread));
|
---|
[1] | 2248 | return rc;
|
---|
| 2249 | }
|
---|
| 2250 |
|
---|
| 2251 |
|
---|
[26157] | 2252 | /** @interface_method_impl{PDMDEVHLPR3,pfnSetAsyncNotification} */
|
---|
| 2253 | static DECLCALLBACK(int) pdmR3DevHlp_SetAsyncNotification(PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify)
|
---|
[1] | 2254 | {
|
---|
| 2255 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26157] | 2256 | VM_ASSERT_EMT0(pDevIns->Internal.s.pVMR3);
|
---|
[26165] | 2257 | LogFlow(("pdmR3DevHlp_SetAsyncNotification: caller='%s'/%d: pfnAsyncNotify=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pfnAsyncNotify));
|
---|
[1] | 2258 |
|
---|
[26157] | 2259 | int rc = VINF_SUCCESS;
|
---|
| 2260 | AssertStmt(pfnAsyncNotify, rc = VERR_INVALID_PARAMETER);
|
---|
| 2261 | AssertStmt(!pDevIns->Internal.s.pfnAsyncNotify, rc = VERR_WRONG_ORDER);
|
---|
| 2262 | AssertStmt(pDevIns->Internal.s.fIntFlags & (PDMDEVINSINT_FLAGS_SUSPENDED | PDMDEVINSINT_FLAGS_RESET), rc = VERR_WRONG_ORDER);
|
---|
| 2263 | VMSTATE enmVMState = VMR3GetState(pDevIns->Internal.s.pVMR3);
|
---|
| 2264 | AssertStmt( enmVMState == VMSTATE_SUSPENDING
|
---|
| 2265 | || enmVMState == VMSTATE_SUSPENDING_EXT_LS
|
---|
| 2266 | || enmVMState == VMSTATE_SUSPENDING_LS
|
---|
| 2267 | || enmVMState == VMSTATE_RESETTING
|
---|
| 2268 | || enmVMState == VMSTATE_RESETTING_LS
|
---|
| 2269 | || enmVMState == VMSTATE_POWERING_OFF
|
---|
| 2270 | || enmVMState == VMSTATE_POWERING_OFF_LS,
|
---|
| 2271 | rc = VERR_INVALID_STATE);
|
---|
[1] | 2272 |
|
---|
[26157] | 2273 | if (RT_SUCCESS(rc))
|
---|
| 2274 | pDevIns->Internal.s.pfnAsyncNotify = pfnAsyncNotify;
|
---|
[1] | 2275 |
|
---|
[26165] | 2276 | LogFlow(("pdmR3DevHlp_SetAsyncNotification: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 2277 | return rc;
|
---|
[1] | 2278 | }
|
---|
| 2279 |
|
---|
| 2280 |
|
---|
[26157] | 2281 | /** @interface_method_impl{PDMDEVHLPR3,pfnAsyncNotificationCompleted} */
|
---|
| 2282 | static DECLCALLBACK(void) pdmR3DevHlp_AsyncNotificationCompleted(PPDMDEVINS pDevIns)
|
---|
[1] | 2283 | {
|
---|
| 2284 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 2285 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[1] | 2286 |
|
---|
[26157] | 2287 | VMSTATE enmVMState = VMR3GetState(pVM);
|
---|
| 2288 | if ( enmVMState == VMSTATE_SUSPENDING
|
---|
| 2289 | || enmVMState == VMSTATE_SUSPENDING_EXT_LS
|
---|
| 2290 | || enmVMState == VMSTATE_SUSPENDING_LS
|
---|
| 2291 | || enmVMState == VMSTATE_RESETTING
|
---|
| 2292 | || enmVMState == VMSTATE_RESETTING_LS
|
---|
| 2293 | || enmVMState == VMSTATE_POWERING_OFF
|
---|
| 2294 | || enmVMState == VMSTATE_POWERING_OFF_LS)
|
---|
| 2295 | {
|
---|
[26165] | 2296 | LogFlow(("pdmR3DevHlp_AsyncNotificationCompleted: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[26157] | 2297 | VMR3AsyncPdmNotificationWakeupU(pVM->pUVM);
|
---|
| 2298 | }
|
---|
| 2299 | else
|
---|
[26165] | 2300 | LogFlow(("pdmR3DevHlp_AsyncNotificationCompleted: caller='%s'/%d: enmVMState=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, enmVMState));
|
---|
[1] | 2301 | }
|
---|
| 2302 |
|
---|
| 2303 |
|
---|
[26152] | 2304 | /** @interface_method_impl{PDMDEVHLPR3,pfnRTCRegister} */
|
---|
[1] | 2305 | static DECLCALLBACK(int) pdmR3DevHlp_RTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp)
|
---|
| 2306 | {
|
---|
| 2307 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 2308 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[1] | 2309 | LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: pRtcReg=%p:{.u32Version=%#x, .pfnWrite=%p, .pfnRead=%p} ppRtcHlp=%p\n",
|
---|
[26165] | 2310 | pDevIns->pReg->szName, pDevIns->iInstance, pRtcReg, pRtcReg->u32Version, pRtcReg->pfnWrite,
|
---|
[1] | 2311 | pRtcReg->pfnWrite, ppRtcHlp));
|
---|
| 2312 |
|
---|
| 2313 | /*
|
---|
| 2314 | * Validate input.
|
---|
| 2315 | */
|
---|
| 2316 | if (pRtcReg->u32Version != PDM_RTCREG_VERSION)
|
---|
| 2317 | {
|
---|
| 2318 | AssertMsgFailed(("u32Version=%#x expected %#x\n", pRtcReg->u32Version,
|
---|
| 2319 | PDM_RTCREG_VERSION));
|
---|
[13818] | 2320 | LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc (version)\n",
|
---|
[26165] | 2321 | pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2322 | return VERR_INVALID_PARAMETER;
|
---|
| 2323 | }
|
---|
| 2324 | if ( !pRtcReg->pfnWrite
|
---|
| 2325 | || !pRtcReg->pfnRead)
|
---|
| 2326 | {
|
---|
| 2327 | Assert(pRtcReg->pfnWrite);
|
---|
| 2328 | Assert(pRtcReg->pfnRead);
|
---|
[13818] | 2329 | LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc (callbacks)\n",
|
---|
[26165] | 2330 | pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2331 | return VERR_INVALID_PARAMETER;
|
---|
| 2332 | }
|
---|
| 2333 |
|
---|
| 2334 | if (!ppRtcHlp)
|
---|
| 2335 | {
|
---|
| 2336 | Assert(ppRtcHlp);
|
---|
[13818] | 2337 | LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc (ppRtcHlp)\n",
|
---|
[26165] | 2338 | pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2339 | return VERR_INVALID_PARAMETER;
|
---|
| 2340 | }
|
---|
| 2341 |
|
---|
| 2342 | /*
|
---|
| 2343 | * Only one DMA device.
|
---|
| 2344 | */
|
---|
[12970] | 2345 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[1] | 2346 | if (pVM->pdm.s.pRtc)
|
---|
| 2347 | {
|
---|
| 2348 | AssertMsgFailed(("Only one RTC device is supported!\n"));
|
---|
[13818] | 2349 | LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc\n",
|
---|
[26165] | 2350 | pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2351 | return VERR_INVALID_PARAMETER;
|
---|
| 2352 | }
|
---|
| 2353 |
|
---|
| 2354 | /*
|
---|
| 2355 | * Allocate and initialize pci bus structure.
|
---|
| 2356 | */
|
---|
| 2357 | int rc = VINF_SUCCESS;
|
---|
[12970] | 2358 | PPDMRTC pRtc = (PPDMRTC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pRtc));
|
---|
[1] | 2359 | if (pRtc)
|
---|
| 2360 | {
|
---|
| 2361 | pRtc->pDevIns = pDevIns;
|
---|
| 2362 | pRtc->Reg = *pRtcReg;
|
---|
| 2363 | pVM->pdm.s.pRtc = pRtc;
|
---|
| 2364 |
|
---|
| 2365 | /* set the helper pointer. */
|
---|
| 2366 | *ppRtcHlp = &g_pdmR3DevRtcHlp;
|
---|
| 2367 | Log(("PDM: Registered RTC device '%s'/%d pDevIns=%p\n",
|
---|
[26165] | 2368 | pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
|
---|
[1] | 2369 | }
|
---|
| 2370 | else
|
---|
| 2371 | rc = VERR_NO_MEMORY;
|
---|
| 2372 |
|
---|
[13818] | 2373 | LogFlow(("pdmR3DevHlp_RTCRegister: caller='%s'/%d: returns %Rrc\n",
|
---|
[26165] | 2374 | pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 2375 | return rc;
|
---|
| 2376 | }
|
---|
| 2377 |
|
---|
| 2378 |
|
---|
[26157] | 2379 | /** @interface_method_impl{PDMDEVHLPR3,pfnDMARegister} */
|
---|
| 2380 | static DECLCALLBACK(int) pdmR3DevHlp_DMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
|
---|
[1] | 2381 | {
|
---|
| 2382 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26157] | 2383 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 2384 | VM_ASSERT_EMT(pVM);
|
---|
| 2385 | LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: uChannel=%d pfnTransferHandler=%p pvUser=%p\n",
|
---|
[26165] | 2386 | pDevIns->pReg->szName, pDevIns->iInstance, uChannel, pfnTransferHandler, pvUser));
|
---|
[26157] | 2387 | int rc = VINF_SUCCESS;
|
---|
| 2388 | if (pVM->pdm.s.pDmac)
|
---|
| 2389 | pVM->pdm.s.pDmac->Reg.pfnRegister(pVM->pdm.s.pDmac->pDevIns, uChannel, pfnTransferHandler, pvUser);
|
---|
| 2390 | else
|
---|
| 2391 | {
|
---|
| 2392 | AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
|
---|
| 2393 | rc = VERR_PDM_NO_DMAC_INSTANCE;
|
---|
| 2394 | }
|
---|
| 2395 | LogFlow(("pdmR3DevHlp_DMARegister: caller='%s'/%d: returns %Rrc\n",
|
---|
[26165] | 2396 | pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 2397 | return rc;
|
---|
| 2398 | }
|
---|
[1] | 2399 |
|
---|
[26157] | 2400 |
|
---|
| 2401 | /** @interface_method_impl{PDMDEVHLPR3,pfnDMAReadMemory} */
|
---|
| 2402 | static DECLCALLBACK(int) pdmR3DevHlp_DMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)
|
---|
| 2403 | {
|
---|
| 2404 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 2405 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[1] | 2406 | VM_ASSERT_EMT(pVM);
|
---|
[26157] | 2407 | LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbRead=%p\n",
|
---|
[26165] | 2408 | pDevIns->pReg->szName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbRead));
|
---|
[26157] | 2409 | int rc = VINF_SUCCESS;
|
---|
| 2410 | if (pVM->pdm.s.pDmac)
|
---|
| 2411 | {
|
---|
| 2412 | uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnReadMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock);
|
---|
| 2413 | if (pcbRead)
|
---|
| 2414 | *pcbRead = cb;
|
---|
| 2415 | }
|
---|
| 2416 | else
|
---|
| 2417 | {
|
---|
| 2418 | AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
|
---|
| 2419 | rc = VERR_PDM_NO_DMAC_INSTANCE;
|
---|
| 2420 | }
|
---|
| 2421 | LogFlow(("pdmR3DevHlp_DMAReadMemory: caller='%s'/%d: returns %Rrc\n",
|
---|
[26165] | 2422 | pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 2423 | return rc;
|
---|
| 2424 | }
|
---|
[1] | 2425 |
|
---|
[26157] | 2426 |
|
---|
| 2427 | /** @interface_method_impl{PDMDEVHLPR3,pfnDMAWriteMemory} */
|
---|
| 2428 | static DECLCALLBACK(int) pdmR3DevHlp_DMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)
|
---|
| 2429 | {
|
---|
| 2430 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2431 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 2432 | VM_ASSERT_EMT(pVM);
|
---|
| 2433 | LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: uChannel=%d pvBuffer=%p off=%#x cbBlock=%#x pcbWritten=%p\n",
|
---|
[26165] | 2434 | pDevIns->pReg->szName, pDevIns->iInstance, uChannel, pvBuffer, off, cbBlock, pcbWritten));
|
---|
[26157] | 2435 | int rc = VINF_SUCCESS;
|
---|
| 2436 | if (pVM->pdm.s.pDmac)
|
---|
[21363] | 2437 | {
|
---|
[26157] | 2438 | uint32_t cb = pVM->pdm.s.pDmac->Reg.pfnWriteMemory(pVM->pdm.s.pDmac->pDevIns, uChannel, pvBuffer, off, cbBlock);
|
---|
| 2439 | if (pcbWritten)
|
---|
| 2440 | *pcbWritten = cb;
|
---|
[21363] | 2441 | }
|
---|
[26157] | 2442 | else
|
---|
| 2443 | {
|
---|
| 2444 | AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
|
---|
| 2445 | rc = VERR_PDM_NO_DMAC_INSTANCE;
|
---|
| 2446 | }
|
---|
| 2447 | LogFlow(("pdmR3DevHlp_DMAWriteMemory: caller='%s'/%d: returns %Rrc\n",
|
---|
[26165] | 2448 | pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 2449 | return rc;
|
---|
| 2450 | }
|
---|
[21363] | 2451 |
|
---|
| 2452 |
|
---|
[26157] | 2453 | /** @interface_method_impl{PDMDEVHLPR3,pfnDMASetDREQ} */
|
---|
| 2454 | static DECLCALLBACK(int) pdmR3DevHlp_DMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)
|
---|
| 2455 | {
|
---|
| 2456 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2457 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 2458 | VM_ASSERT_EMT(pVM);
|
---|
| 2459 | LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: uChannel=%d uLevel=%d\n",
|
---|
[26165] | 2460 | pDevIns->pReg->szName, pDevIns->iInstance, uChannel, uLevel));
|
---|
[26157] | 2461 | int rc = VINF_SUCCESS;
|
---|
| 2462 | if (pVM->pdm.s.pDmac)
|
---|
| 2463 | pVM->pdm.s.pDmac->Reg.pfnSetDREQ(pVM->pdm.s.pDmac->pDevIns, uChannel, uLevel);
|
---|
| 2464 | else
|
---|
| 2465 | {
|
---|
| 2466 | AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
|
---|
| 2467 | rc = VERR_PDM_NO_DMAC_INSTANCE;
|
---|
| 2468 | }
|
---|
| 2469 | LogFlow(("pdmR3DevHlp_DMASetDREQ: caller='%s'/%d: returns %Rrc\n",
|
---|
[26165] | 2470 | pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 2471 | return rc;
|
---|
| 2472 | }
|
---|
| 2473 |
|
---|
[26157] | 2474 | /** @interface_method_impl{PDMDEVHLPR3,pfnDMAGetChannelMode} */
|
---|
| 2475 | static DECLCALLBACK(uint8_t) pdmR3DevHlp_DMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)
|
---|
| 2476 | {
|
---|
| 2477 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2478 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 2479 | VM_ASSERT_EMT(pVM);
|
---|
| 2480 | LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: uChannel=%d\n",
|
---|
[26165] | 2481 | pDevIns->pReg->szName, pDevIns->iInstance, uChannel));
|
---|
[26157] | 2482 | uint8_t u8Mode;
|
---|
| 2483 | if (pVM->pdm.s.pDmac)
|
---|
| 2484 | u8Mode = pVM->pdm.s.pDmac->Reg.pfnGetChannelMode(pVM->pdm.s.pDmac->pDevIns, uChannel);
|
---|
| 2485 | else
|
---|
| 2486 | {
|
---|
| 2487 | AssertMsgFailed(("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
|
---|
| 2488 | u8Mode = 3 << 2 /* illegal mode type */;
|
---|
| 2489 | }
|
---|
| 2490 | LogFlow(("pdmR3DevHlp_DMAGetChannelMode: caller='%s'/%d: returns %#04x\n",
|
---|
[26165] | 2491 | pDevIns->pReg->szName, pDevIns->iInstance, u8Mode));
|
---|
[26157] | 2492 | return u8Mode;
|
---|
| 2493 | }
|
---|
[1] | 2494 |
|
---|
[26157] | 2495 | /** @interface_method_impl{PDMDEVHLPR3,pfnDMASchedule} */
|
---|
| 2496 | static DECLCALLBACK(void) pdmR3DevHlp_DMASchedule(PPDMDEVINS pDevIns)
|
---|
[1] | 2497 | {
|
---|
| 2498 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26157] | 2499 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 2500 | VM_ASSERT_EMT(pVM);
|
---|
| 2501 | LogFlow(("pdmR3DevHlp_DMASchedule: caller='%s'/%d: VM_FF_PDM_DMA %d -> 1\n",
|
---|
[46420] | 2502 | pDevIns->pReg->szName, pDevIns->iInstance, VM_FF_IS_SET(pVM, VM_FF_PDM_DMA)));
|
---|
[1] | 2503 |
|
---|
[26157] | 2504 | AssertMsg(pVM->pdm.s.pDmac, ("Configuration error: No DMAC controller available. This could be related to init order too!\n"));
|
---|
| 2505 | VM_FF_SET(pVM, VM_FF_PDM_DMA);
|
---|
[40274] | 2506 | #ifdef VBOX_WITH_REM
|
---|
[26157] | 2507 | REMR3NotifyDmaPending(pVM);
|
---|
[40274] | 2508 | #endif
|
---|
[26157] | 2509 | VMR3NotifyGlobalFFU(pVM->pUVM, VMNOTIFYFF_FLAGS_DONE_REM);
|
---|
| 2510 | }
|
---|
| 2511 |
|
---|
| 2512 |
|
---|
| 2513 | /** @interface_method_impl{PDMDEVHLPR3,pfnCMOSWrite} */
|
---|
| 2514 | static DECLCALLBACK(int) pdmR3DevHlp_CMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
|
---|
| 2515 | {
|
---|
| 2516 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 2517 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[1] | 2518 | VM_ASSERT_EMT(pVM);
|
---|
| 2519 |
|
---|
[26157] | 2520 | LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x u8Value=%#04x\n",
|
---|
[26165] | 2521 | pDevIns->pReg->szName, pDevIns->iInstance, iReg, u8Value));
|
---|
[26157] | 2522 | int rc;
|
---|
| 2523 | if (pVM->pdm.s.pRtc)
|
---|
[44510] | 2524 | {
|
---|
| 2525 | PPDMDEVINS pDevInsRtc = pVM->pdm.s.pRtc->pDevIns;
|
---|
| 2526 | rc = PDMCritSectEnter(pDevInsRtc->pCritSectRoR3, VERR_IGNORED);
|
---|
| 2527 | if (RT_SUCCESS(rc))
|
---|
| 2528 | {
|
---|
| 2529 | rc = pVM->pdm.s.pRtc->Reg.pfnWrite(pDevInsRtc, iReg, u8Value);
|
---|
| 2530 | PDMCritSectLeave(pDevInsRtc->pCritSectRoR3);
|
---|
| 2531 | }
|
---|
| 2532 | }
|
---|
[26157] | 2533 | else
|
---|
| 2534 | rc = VERR_PDM_NO_RTC_INSTANCE;
|
---|
| 2535 |
|
---|
| 2536 | LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Rrc\n",
|
---|
[26165] | 2537 | pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 2538 | return rc;
|
---|
| 2539 | }
|
---|
| 2540 |
|
---|
| 2541 |
|
---|
[26157] | 2542 | /** @interface_method_impl{PDMDEVHLPR3,pfnCMOSRead} */
|
---|
| 2543 | static DECLCALLBACK(int) pdmR3DevHlp_CMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
|
---|
[2464] | 2544 | {
|
---|
| 2545 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26157] | 2546 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 2547 | VM_ASSERT_EMT(pVM);
|
---|
[2464] | 2548 |
|
---|
[26157] | 2549 | LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: iReg=%#04x pu8Value=%p\n",
|
---|
[26165] | 2550 | pDevIns->pReg->szName, pDevIns->iInstance, iReg, pu8Value));
|
---|
[26157] | 2551 | int rc;
|
---|
| 2552 | if (pVM->pdm.s.pRtc)
|
---|
[44510] | 2553 | {
|
---|
| 2554 | PPDMDEVINS pDevInsRtc = pVM->pdm.s.pRtc->pDevIns;
|
---|
| 2555 | rc = PDMCritSectEnter(pDevInsRtc->pCritSectRoR3, VERR_IGNORED);
|
---|
| 2556 | if (RT_SUCCESS(rc))
|
---|
| 2557 | {
|
---|
| 2558 | rc = pVM->pdm.s.pRtc->Reg.pfnRead(pDevInsRtc, iReg, pu8Value);
|
---|
| 2559 | PDMCritSectLeave(pDevInsRtc->pCritSectRoR3);
|
---|
| 2560 | }
|
---|
| 2561 | }
|
---|
[26157] | 2562 | else
|
---|
| 2563 | rc = VERR_PDM_NO_RTC_INSTANCE;
|
---|
[2464] | 2564 |
|
---|
[26157] | 2565 | LogFlow(("pdmR3DevHlp_CMOSWrite: caller='%s'/%d: return %Rrc\n",
|
---|
[26165] | 2566 | pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[26157] | 2567 | return rc;
|
---|
[2464] | 2568 | }
|
---|
| 2569 |
|
---|
| 2570 |
|
---|
[26157] | 2571 | /** @interface_method_impl{PDMDEVHLPR3,pfnAssertEMT} */
|
---|
| 2572 | static DECLCALLBACK(bool) pdmR3DevHlp_AssertEMT(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)
|
---|
[4012] | 2573 | {
|
---|
| 2574 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26157] | 2575 | if (VM_IS_EMT(pDevIns->Internal.s.pVMR3))
|
---|
| 2576 | return true;
|
---|
[4012] | 2577 |
|
---|
[26157] | 2578 | char szMsg[100];
|
---|
[26165] | 2579 | RTStrPrintf(szMsg, sizeof(szMsg), "AssertEMT '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance);
|
---|
[26157] | 2580 | RTAssertMsg1Weak(szMsg, iLine, pszFile, pszFunction);
|
---|
| 2581 | AssertBreakpoint();
|
---|
| 2582 | return false;
|
---|
| 2583 | }
|
---|
[4012] | 2584 |
|
---|
[26157] | 2585 |
|
---|
| 2586 | /** @interface_method_impl{PDMDEVHLPR3,pfnAssertOther} */
|
---|
| 2587 | static DECLCALLBACK(bool) pdmR3DevHlp_AssertOther(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction)
|
---|
| 2588 | {
|
---|
| 2589 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2590 | if (!VM_IS_EMT(pDevIns->Internal.s.pVMR3))
|
---|
| 2591 | return true;
|
---|
| 2592 |
|
---|
| 2593 | char szMsg[100];
|
---|
[26165] | 2594 | RTStrPrintf(szMsg, sizeof(szMsg), "AssertOther '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance);
|
---|
[26157] | 2595 | RTAssertMsg1Weak(szMsg, iLine, pszFile, pszFunction);
|
---|
| 2596 | AssertBreakpoint();
|
---|
| 2597 | return false;
|
---|
[4012] | 2598 | }
|
---|
| 2599 |
|
---|
| 2600 |
|
---|
[58116] | 2601 | /** @interface_method_impl{PDMDEVHLPR3,pfnLdrGetRCInterfaceSymbols} */
|
---|
[26159] | 2602 | static DECLCALLBACK(int) pdmR3DevHlp_LdrGetRCInterfaceSymbols(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
|
---|
| 2603 | const char *pszSymPrefix, const char *pszSymList)
|
---|
| 2604 | {
|
---|
| 2605 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2606 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
| 2607 | LogFlow(("pdmR3DevHlp_PDMLdrGetRCInterfaceSymbols: caller='%s'/%d: pvInterface=%p cbInterface=%zu pszSymPrefix=%p:{%s} pszSymList=%p:{%s}\n",
|
---|
[26165] | 2608 | pDevIns->pReg->szName, pDevIns->iInstance, pvInterface, cbInterface, pszSymPrefix, pszSymPrefix, pszSymList, pszSymList));
|
---|
[26159] | 2609 |
|
---|
| 2610 | int rc;
|
---|
| 2611 | if ( strncmp(pszSymPrefix, "dev", 3) == 0
|
---|
[26165] | 2612 | && RTStrIStr(pszSymPrefix + 3, pDevIns->pReg->szName) != NULL)
|
---|
[26159] | 2613 | {
|
---|
[26160] | 2614 | if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
|
---|
[34241] | 2615 | rc = PDMR3LdrGetInterfaceSymbols(pDevIns->Internal.s.pVMR3,
|
---|
| 2616 | pvInterface, cbInterface,
|
---|
| 2617 | pDevIns->pReg->szRCMod, pDevIns->Internal.s.pDevR3->pszRCSearchPath,
|
---|
| 2618 | pszSymPrefix, pszSymList,
|
---|
[26159] | 2619 | false /*fRing0OrRC*/);
|
---|
| 2620 | else
|
---|
| 2621 | {
|
---|
| 2622 | AssertMsgFailed(("Not a raw-mode enabled driver\n"));
|
---|
| 2623 | rc = VERR_PERMISSION_DENIED;
|
---|
| 2624 | }
|
---|
| 2625 | }
|
---|
| 2626 | else
|
---|
| 2627 | {
|
---|
| 2628 | AssertMsgFailed(("Invalid prefix '%s' for '%s'; must start with 'dev' and contain the driver name!\n",
|
---|
[26165] | 2629 | pszSymPrefix, pDevIns->pReg->szName));
|
---|
[26159] | 2630 | rc = VERR_INVALID_NAME;
|
---|
| 2631 | }
|
---|
| 2632 |
|
---|
[26165] | 2633 | LogFlow(("pdmR3DevHlp_PDMLdrGetRCInterfaceSymbols: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName,
|
---|
[26159] | 2634 | pDevIns->iInstance, rc));
|
---|
| 2635 | return rc;
|
---|
| 2636 | }
|
---|
| 2637 |
|
---|
| 2638 |
|
---|
[58116] | 2639 | /** @interface_method_impl{PDMDEVHLPR3,pfnLdrGetR0InterfaceSymbols} */
|
---|
[26159] | 2640 | static DECLCALLBACK(int) pdmR3DevHlp_LdrGetR0InterfaceSymbols(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
|
---|
| 2641 | const char *pszSymPrefix, const char *pszSymList)
|
---|
| 2642 | {
|
---|
| 2643 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2644 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
| 2645 | LogFlow(("pdmR3DevHlp_PDMLdrGetR0InterfaceSymbols: caller='%s'/%d: pvInterface=%p cbInterface=%zu pszSymPrefix=%p:{%s} pszSymList=%p:{%s}\n",
|
---|
[26165] | 2646 | pDevIns->pReg->szName, pDevIns->iInstance, pvInterface, cbInterface, pszSymPrefix, pszSymPrefix, pszSymList, pszSymList));
|
---|
[26159] | 2647 |
|
---|
| 2648 | int rc;
|
---|
| 2649 | if ( strncmp(pszSymPrefix, "dev", 3) == 0
|
---|
[26165] | 2650 | && RTStrIStr(pszSymPrefix + 3, pDevIns->pReg->szName) != NULL)
|
---|
[26159] | 2651 | {
|
---|
[26160] | 2652 | if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
|
---|
[34241] | 2653 | rc = PDMR3LdrGetInterfaceSymbols(pDevIns->Internal.s.pVMR3,
|
---|
| 2654 | pvInterface, cbInterface,
|
---|
| 2655 | pDevIns->pReg->szR0Mod, pDevIns->Internal.s.pDevR3->pszR0SearchPath,
|
---|
| 2656 | pszSymPrefix, pszSymList,
|
---|
[26159] | 2657 | true /*fRing0OrRC*/);
|
---|
| 2658 | else
|
---|
| 2659 | {
|
---|
| 2660 | AssertMsgFailed(("Not a ring-0 enabled driver\n"));
|
---|
| 2661 | rc = VERR_PERMISSION_DENIED;
|
---|
| 2662 | }
|
---|
| 2663 | }
|
---|
| 2664 | else
|
---|
| 2665 | {
|
---|
| 2666 | AssertMsgFailed(("Invalid prefix '%s' for '%s'; must start with 'dev' and contain the driver name!\n",
|
---|
[26165] | 2667 | pszSymPrefix, pDevIns->pReg->szName));
|
---|
[26159] | 2668 | rc = VERR_INVALID_NAME;
|
---|
| 2669 | }
|
---|
| 2670 |
|
---|
[26165] | 2671 | LogFlow(("pdmR3DevHlp_PDMLdrGetR0InterfaceSymbols: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName,
|
---|
[26159] | 2672 | pDevIns->iInstance, rc));
|
---|
| 2673 | return rc;
|
---|
| 2674 | }
|
---|
| 2675 |
|
---|
| 2676 |
|
---|
[58116] | 2677 | /** @interface_method_impl{PDMDEVHLPR3,pfnCallR0} */
|
---|
[29521] | 2678 | static DECLCALLBACK(int) pdmR3DevHlp_CallR0(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg)
|
---|
| 2679 | {
|
---|
| 2680 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2681 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[46788] | 2682 | VM_ASSERT_EMT(pVM);
|
---|
[29521] | 2683 | LogFlow(("pdmR3DevHlp_CallR0: caller='%s'/%d: uOperation=%#x u64Arg=%#RX64\n",
|
---|
| 2684 | pDevIns->pReg->szName, pDevIns->iInstance, uOperation, u64Arg));
|
---|
| 2685 |
|
---|
| 2686 | /*
|
---|
| 2687 | * Resolve the ring-0 entry point. There is not need to remember this like
|
---|
| 2688 | * we do for drivers since this is mainly for construction time hacks and
|
---|
| 2689 | * other things that aren't performance critical.
|
---|
| 2690 | */
|
---|
| 2691 | int rc;
|
---|
| 2692 | if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
|
---|
| 2693 | {
|
---|
| 2694 | char szSymbol[ sizeof("devR0") + sizeof(pDevIns->pReg->szName) + sizeof("ReqHandler")];
|
---|
| 2695 | strcat(strcat(strcpy(szSymbol, "devR0"), pDevIns->pReg->szName), "ReqHandler");
|
---|
| 2696 | szSymbol[sizeof("devR0") - 1] = RT_C_TO_UPPER(szSymbol[sizeof("devR0") - 1]);
|
---|
| 2697 |
|
---|
| 2698 | PFNPDMDRVREQHANDLERR0 pfnReqHandlerR0;
|
---|
[34241] | 2699 | rc = pdmR3DevGetSymbolR0Lazy(pDevIns, szSymbol, &pfnReqHandlerR0);
|
---|
[29521] | 2700 | if (RT_SUCCESS(rc))
|
---|
| 2701 | {
|
---|
| 2702 | /*
|
---|
| 2703 | * Make the ring-0 call.
|
---|
| 2704 | */
|
---|
| 2705 | PDMDEVICECALLREQHANDLERREQ Req;
|
---|
| 2706 | Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
|
---|
| 2707 | Req.Hdr.cbReq = sizeof(Req);
|
---|
| 2708 | Req.pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
|
---|
| 2709 | Req.pfnReqHandlerR0 = pfnReqHandlerR0;
|
---|
| 2710 | Req.uOperation = uOperation;
|
---|
| 2711 | Req.u32Alignment = 0;
|
---|
| 2712 | Req.u64Arg = u64Arg;
|
---|
| 2713 | rc = SUPR3CallVMMR0Ex(pVM->pVMR0, NIL_VMCPUID, VMMR0_DO_PDM_DEVICE_CALL_REQ_HANDLER, 0, &Req.Hdr);
|
---|
| 2714 | }
|
---|
| 2715 | else
|
---|
| 2716 | pfnReqHandlerR0 = NIL_RTR0PTR;
|
---|
| 2717 | }
|
---|
| 2718 | else
|
---|
| 2719 | rc = VERR_ACCESS_DENIED;
|
---|
| 2720 | LogFlow(("pdmR3DevHlp_CallR0: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName,
|
---|
| 2721 | pDevIns->iInstance, rc));
|
---|
| 2722 | return rc;
|
---|
| 2723 | }
|
---|
| 2724 |
|
---|
| 2725 |
|
---|
[58116] | 2726 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMGetSuspendReason} */
|
---|
[46788] | 2727 | static DECLCALLBACK(VMSUSPENDREASON) pdmR3DevHlp_VMGetSuspendReason(PPDMDEVINS pDevIns)
|
---|
| 2728 | {
|
---|
| 2729 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2730 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 2731 | VM_ASSERT_EMT(pVM);
|
---|
| 2732 | VMSUSPENDREASON enmReason = VMR3GetSuspendReason(pVM->pUVM);
|
---|
| 2733 | LogFlow(("pdmR3DevHlp_VMGetSuspendReason: caller='%s'/%d: returns %d\n",
|
---|
| 2734 | pDevIns->pReg->szName, pDevIns->iInstance, enmReason));
|
---|
| 2735 | return enmReason;
|
---|
| 2736 | }
|
---|
| 2737 |
|
---|
| 2738 |
|
---|
[58116] | 2739 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMGetResumeReason} */
|
---|
[46788] | 2740 | static DECLCALLBACK(VMRESUMEREASON) pdmR3DevHlp_VMGetResumeReason(PPDMDEVINS pDevIns)
|
---|
| 2741 | {
|
---|
| 2742 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2743 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 2744 | VM_ASSERT_EMT(pVM);
|
---|
| 2745 | VMRESUMEREASON enmReason = VMR3GetResumeReason(pVM->pUVM);
|
---|
| 2746 | LogFlow(("pdmR3DevHlp_VMGetResumeReason: caller='%s'/%d: returns %d\n",
|
---|
| 2747 | pDevIns->pReg->szName, pDevIns->iInstance, enmReason));
|
---|
| 2748 | return enmReason;
|
---|
| 2749 | }
|
---|
| 2750 |
|
---|
| 2751 |
|
---|
[44351] | 2752 | /** @interface_method_impl{PDMDEVHLPR3,pfnGetUVM} */
|
---|
| 2753 | static DECLCALLBACK(PUVM) pdmR3DevHlp_GetUVM(PPDMDEVINS pDevIns)
|
---|
| 2754 | {
|
---|
| 2755 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2756 | LogFlow(("pdmR3DevHlp_GetUVM: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns->Internal.s.pVMR3));
|
---|
| 2757 | return pDevIns->Internal.s.pVMR3->pUVM;
|
---|
| 2758 | }
|
---|
| 2759 |
|
---|
| 2760 |
|
---|
[26152] | 2761 | /** @interface_method_impl{PDMDEVHLPR3,pfnGetVM} */
|
---|
[1] | 2762 | static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns)
|
---|
| 2763 | {
|
---|
| 2764 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 2765 | LogFlow(("pdmR3DevHlp_GetVM: caller='%s'/%d: returns %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns->Internal.s.pVMR3));
|
---|
[12970] | 2766 | return pDevIns->Internal.s.pVMR3;
|
---|
[1] | 2767 | }
|
---|
| 2768 |
|
---|
[19041] | 2769 |
|
---|
[26152] | 2770 | /** @interface_method_impl{PDMDEVHLPR3,pfnGetVMCPU} */
|
---|
[18927] | 2771 | static DECLCALLBACK(PVMCPU) pdmR3DevHlp_GetVMCPU(PPDMDEVINS pDevIns)
|
---|
| 2772 | {
|
---|
| 2773 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[19293] | 2774 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[26165] | 2775 | LogFlow(("pdmR3DevHlp_GetVMCPU: caller='%s'/%d for CPU %u\n", pDevIns->pReg->szName, pDevIns->iInstance, VMMGetCpuId(pDevIns->Internal.s.pVMR3)));
|
---|
[18927] | 2776 | return VMMGetCpu(pDevIns->Internal.s.pVMR3);
|
---|
| 2777 | }
|
---|
[1] | 2778 |
|
---|
[19041] | 2779 |
|
---|
[53797] | 2780 | /** @interface_method_impl{PDMDEVHLPR3,pfnGetCurrentCpuId} */
|
---|
| 2781 | static DECLCALLBACK(VMCPUID) pdmR3DevHlp_GetCurrentCpuId(PPDMDEVINS pDevIns)
|
---|
| 2782 | {
|
---|
| 2783 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 2784 | VMCPUID idCpu = VMMGetCpuId(pDevIns->Internal.s.pVMR3);
|
---|
| 2785 | LogFlow(("pdmR3DevHlp_GetCurrentCpuId: caller='%s'/%d for CPU %u\n", pDevIns->pReg->szName, pDevIns->iInstance, idCpu));
|
---|
| 2786 | return idCpu;
|
---|
| 2787 | }
|
---|
| 2788 |
|
---|
| 2789 |
|
---|
[26152] | 2790 | /** @interface_method_impl{PDMDEVHLPR3,pfnPCIBusRegister} */
|
---|
[64696] | 2791 | static DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg,
|
---|
| 2792 | PCPDMPCIHLPR3 *ppPciHlpR3, uint32_t *piBus)
|
---|
[1] | 2793 | {
|
---|
| 2794 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 2795 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[1] | 2796 | VM_ASSERT_EMT(pVM);
|
---|
[44508] | 2797 | LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: pPciBusReg=%p:{.u32Version=%#x, .pfnRegisterR3=%p, .pfnIORegionRegisterR3=%p, "
|
---|
[67668] | 2798 | ".pfnSetIrqR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppPciHlpR3=%p piBus=%p\n",
|
---|
[64696] | 2799 | pDevIns->pReg->szName, pDevIns->iInstance, pPciBusReg, pPciBusReg->u32Version, pPciBusReg->pfnRegisterR3,
|
---|
[67668] | 2800 | pPciBusReg->pfnIORegionRegisterR3, pPciBusReg->pfnSetIrqR3, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqRC,
|
---|
| 2801 | pPciBusReg->pszSetIrqR0, pPciBusReg->pszSetIrqR0, ppPciHlpR3, piBus));
|
---|
[1] | 2802 |
|
---|
| 2803 | /*
|
---|
| 2804 | * Validate the structure.
|
---|
| 2805 | */
|
---|
| 2806 | if (pPciBusReg->u32Version != PDM_PCIBUSREG_VERSION)
|
---|
| 2807 | {
|
---|
| 2808 | AssertMsgFailed(("u32Version=%#x expected %#x\n", pPciBusReg->u32Version, PDM_PCIBUSREG_VERSION));
|
---|
[26165] | 2809 | LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Rrc (version)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2810 | return VERR_INVALID_PARAMETER;
|
---|
| 2811 | }
|
---|
[11224] | 2812 | if ( !pPciBusReg->pfnRegisterR3
|
---|
| 2813 | || !pPciBusReg->pfnIORegionRegisterR3
|
---|
[67668] | 2814 | || !pPciBusReg->pfnSetIrqR3)
|
---|
[1] | 2815 | {
|
---|
[11224] | 2816 | Assert(pPciBusReg->pfnRegisterR3);
|
---|
| 2817 | Assert(pPciBusReg->pfnIORegionRegisterR3);
|
---|
| 2818 | Assert(pPciBusReg->pfnSetIrqR3);
|
---|
[26165] | 2819 | LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Rrc (R3 callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2820 | return VERR_INVALID_PARAMETER;
|
---|
| 2821 | }
|
---|
[11224] | 2822 | if ( pPciBusReg->pszSetIrqRC
|
---|
| 2823 | && !VALID_PTR(pPciBusReg->pszSetIrqRC))
|
---|
[1] | 2824 | {
|
---|
[11224] | 2825 | Assert(VALID_PTR(pPciBusReg->pszSetIrqRC));
|
---|
[26165] | 2826 | LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2827 | return VERR_INVALID_PARAMETER;
|
---|
| 2828 | }
|
---|
| 2829 | if ( pPciBusReg->pszSetIrqR0
|
---|
| 2830 | && !VALID_PTR(pPciBusReg->pszSetIrqR0))
|
---|
| 2831 | {
|
---|
| 2832 | Assert(VALID_PTR(pPciBusReg->pszSetIrqR0));
|
---|
[26165] | 2833 | LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2834 | return VERR_INVALID_PARAMETER;
|
---|
| 2835 | }
|
---|
[64696] | 2836 | if (!ppPciHlpR3)
|
---|
[1] | 2837 | {
|
---|
| 2838 | Assert(ppPciHlpR3);
|
---|
[26165] | 2839 | LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Rrc (ppPciHlpR3)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2840 | return VERR_INVALID_PARAMETER;
|
---|
| 2841 | }
|
---|
[64696] | 2842 | AssertLogRelMsgReturn(RT_VALID_PTR(piBus) || !piBus,
|
---|
| 2843 | ("caller='%s'/%d: piBus=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, piBus),
|
---|
| 2844 | VERR_INVALID_POINTER);
|
---|
[1] | 2845 |
|
---|
| 2846 | /*
|
---|
| 2847 | * Find free PCI bus entry.
|
---|
| 2848 | */
|
---|
| 2849 | unsigned iBus = 0;
|
---|
[11311] | 2850 | for (iBus = 0; iBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses); iBus++)
|
---|
[1] | 2851 | if (!pVM->pdm.s.aPciBuses[iBus].pDevInsR3)
|
---|
| 2852 | break;
|
---|
[11311] | 2853 | if (iBus >= RT_ELEMENTS(pVM->pdm.s.aPciBuses))
|
---|
[1] | 2854 | {
|
---|
[11311] | 2855 | AssertMsgFailed(("Too many PCI buses. Max=%u\n", RT_ELEMENTS(pVM->pdm.s.aPciBuses)));
|
---|
[26165] | 2856 | LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Rrc (pci bus)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2857 | return VERR_INVALID_PARAMETER;
|
---|
| 2858 | }
|
---|
| 2859 | PPDMPCIBUS pPciBus = &pVM->pdm.s.aPciBuses[iBus];
|
---|
| 2860 |
|
---|
| 2861 | /*
|
---|
[11224] | 2862 | * Resolve and init the RC bits.
|
---|
[1] | 2863 | */
|
---|
[11224] | 2864 | if (pPciBusReg->pszSetIrqRC)
|
---|
[1] | 2865 | {
|
---|
[34241] | 2866 | int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pPciBusReg->pszSetIrqRC, &pPciBus->pfnSetIrqRC);
|
---|
[26160] | 2867 | AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pPciBusReg->pszSetIrqRC, rc));
|
---|
[13816] | 2868 | if (RT_FAILURE(rc))
|
---|
[1] | 2869 | {
|
---|
[26165] | 2870 | LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 2871 | return rc;
|
---|
| 2872 | }
|
---|
[11224] | 2873 | pPciBus->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
|
---|
[1] | 2874 | }
|
---|
| 2875 | else
|
---|
| 2876 | {
|
---|
[32935] | 2877 | pPciBus->pfnSetIrqRC = 0;
|
---|
| 2878 | pPciBus->pDevInsRC = 0;
|
---|
[1] | 2879 | }
|
---|
| 2880 |
|
---|
| 2881 | /*
|
---|
| 2882 | * Resolve and init the R0 bits.
|
---|
| 2883 | */
|
---|
[7523] | 2884 | if (pPciBusReg->pszSetIrqR0)
|
---|
[1] | 2885 | {
|
---|
[34241] | 2886 | int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pPciBusReg->pszSetIrqR0, &pPciBus->pfnSetIrqR0);
|
---|
[26160] | 2887 | AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pPciBusReg->pszSetIrqR0, rc));
|
---|
[13816] | 2888 | if (RT_FAILURE(rc))
|
---|
[1] | 2889 | {
|
---|
[26165] | 2890 | LogFlow(("pdmR3DevHlp_PCIRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 2891 | return rc;
|
---|
| 2892 | }
|
---|
[12981] | 2893 | pPciBus->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
|
---|
[1] | 2894 | }
|
---|
| 2895 | else
|
---|
| 2896 | {
|
---|
| 2897 | pPciBus->pfnSetIrqR0 = 0;
|
---|
| 2898 | pPciBus->pDevInsR0 = 0;
|
---|
| 2899 | }
|
---|
| 2900 |
|
---|
| 2901 | /*
|
---|
[11224] | 2902 | * Init the R3 bits.
|
---|
[1] | 2903 | */
|
---|
[2597] | 2904 | pPciBus->iBus = iBus;
|
---|
| 2905 | pPciBus->pDevInsR3 = pDevIns;
|
---|
[11224] | 2906 | pPciBus->pfnRegisterR3 = pPciBusReg->pfnRegisterR3;
|
---|
[32820] | 2907 | pPciBus->pfnRegisterMsiR3 = pPciBusReg->pfnRegisterMsiR3;
|
---|
[11224] | 2908 | pPciBus->pfnIORegionRegisterR3 = pPciBusReg->pfnIORegionRegisterR3;
|
---|
| 2909 | pPciBus->pfnSetConfigCallbacksR3 = pPciBusReg->pfnSetConfigCallbacksR3;
|
---|
| 2910 | pPciBus->pfnSetIrqR3 = pPciBusReg->pfnSetIrqR3;
|
---|
[1] | 2911 |
|
---|
[26165] | 2912 | Log(("PDM: Registered PCI bus device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
|
---|
[1] | 2913 |
|
---|
| 2914 | /* set the helper pointer and return. */
|
---|
| 2915 | *ppPciHlpR3 = &g_pdmR3DevPciHlp;
|
---|
[64696] | 2916 | if (piBus)
|
---|
| 2917 | *piBus = iBus;
|
---|
| 2918 | LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Rrc *piBus=%u\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS, iBus));
|
---|
[1] | 2919 | return VINF_SUCCESS;
|
---|
| 2920 | }
|
---|
| 2921 |
|
---|
| 2922 |
|
---|
[26152] | 2923 | /** @interface_method_impl{PDMDEVHLPR3,pfnPICRegister} */
|
---|
[1] | 2924 | static DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3)
|
---|
| 2925 | {
|
---|
| 2926 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 2927 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[11261] | 2928 | LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: pPicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pfnGetInterruptR3=%p, .pszGetIrqRC=%p:{%s}, .pszGetInterruptRC=%p:{%s}, .pszGetIrqR0=%p:{%s}, .pszGetInterruptR0=%p:{%s} } ppPicHlpR3=%p\n",
|
---|
[26165] | 2929 | pDevIns->pReg->szName, pDevIns->iInstance, pPicReg, pPicReg->u32Version, pPicReg->pfnSetIrqR3, pPicReg->pfnGetInterruptR3,
|
---|
[11261] | 2930 | pPicReg->pszSetIrqRC, pPicReg->pszSetIrqRC, pPicReg->pszGetInterruptRC, pPicReg->pszGetInterruptRC,
|
---|
| 2931 | pPicReg->pszSetIrqR0, pPicReg->pszSetIrqR0, pPicReg->pszGetInterruptR0, pPicReg->pszGetInterruptR0,
|
---|
| 2932 | ppPicHlpR3));
|
---|
[1] | 2933 |
|
---|
| 2934 | /*
|
---|
| 2935 | * Validate input.
|
---|
| 2936 | */
|
---|
| 2937 | if (pPicReg->u32Version != PDM_PICREG_VERSION)
|
---|
| 2938 | {
|
---|
| 2939 | AssertMsgFailed(("u32Version=%#x expected %#x\n", pPicReg->u32Version, PDM_PICREG_VERSION));
|
---|
[26165] | 2940 | LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc (version)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2941 | return VERR_INVALID_PARAMETER;
|
---|
| 2942 | }
|
---|
[11261] | 2943 | if ( !pPicReg->pfnSetIrqR3
|
---|
| 2944 | || !pPicReg->pfnGetInterruptR3)
|
---|
[1] | 2945 | {
|
---|
[11261] | 2946 | Assert(pPicReg->pfnSetIrqR3);
|
---|
| 2947 | Assert(pPicReg->pfnGetInterruptR3);
|
---|
[26165] | 2948 | LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc (R3 callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2949 | return VERR_INVALID_PARAMETER;
|
---|
| 2950 | }
|
---|
[11261] | 2951 | if ( ( pPicReg->pszSetIrqRC
|
---|
| 2952 | || pPicReg->pszGetInterruptRC)
|
---|
| 2953 | && ( !VALID_PTR(pPicReg->pszSetIrqRC)
|
---|
| 2954 | || !VALID_PTR(pPicReg->pszGetInterruptRC))
|
---|
[1] | 2955 | )
|
---|
| 2956 | {
|
---|
[11261] | 2957 | Assert(VALID_PTR(pPicReg->pszSetIrqRC));
|
---|
| 2958 | Assert(VALID_PTR(pPicReg->pszGetInterruptRC));
|
---|
[26165] | 2959 | LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc (RC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2960 | return VERR_INVALID_PARAMETER;
|
---|
| 2961 | }
|
---|
[11261] | 2962 | if ( pPicReg->pszSetIrqRC
|
---|
[26160] | 2963 | && !(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC))
|
---|
[1] | 2964 | {
|
---|
[26160] | 2965 | Assert(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC);
|
---|
[26165] | 2966 | LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc (RC flag)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2967 | return VERR_INVALID_PARAMETER;
|
---|
| 2968 | }
|
---|
| 2969 | if ( pPicReg->pszSetIrqR0
|
---|
[26160] | 2970 | && !(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0))
|
---|
[1] | 2971 | {
|
---|
[26160] | 2972 | Assert(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0);
|
---|
[26165] | 2973 | LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc (R0 flag)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2974 | return VERR_INVALID_PARAMETER;
|
---|
| 2975 | }
|
---|
| 2976 | if (!ppPicHlpR3)
|
---|
| 2977 | {
|
---|
| 2978 | Assert(ppPicHlpR3);
|
---|
[26165] | 2979 | LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc (ppPicHlpR3)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2980 | return VERR_INVALID_PARAMETER;
|
---|
| 2981 | }
|
---|
| 2982 |
|
---|
| 2983 | /*
|
---|
| 2984 | * Only one PIC device.
|
---|
| 2985 | */
|
---|
[12970] | 2986 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[1] | 2987 | if (pVM->pdm.s.Pic.pDevInsR3)
|
---|
| 2988 | {
|
---|
| 2989 | AssertMsgFailed(("Only one pic device is supported!\n"));
|
---|
[26165] | 2990 | LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 2991 | return VERR_INVALID_PARAMETER;
|
---|
| 2992 | }
|
---|
| 2993 |
|
---|
| 2994 | /*
|
---|
[11261] | 2995 | * RC stuff.
|
---|
[1] | 2996 | */
|
---|
[11261] | 2997 | if (pPicReg->pszSetIrqRC)
|
---|
[1] | 2998 | {
|
---|
[34241] | 2999 | int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pPicReg->pszSetIrqRC, &pVM->pdm.s.Pic.pfnSetIrqRC);
|
---|
[26160] | 3000 | AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pPicReg->pszSetIrqRC, rc));
|
---|
[13816] | 3001 | if (RT_SUCCESS(rc))
|
---|
[1] | 3002 | {
|
---|
[34241] | 3003 | rc = pdmR3DevGetSymbolRCLazy(pDevIns, pPicReg->pszGetInterruptRC, &pVM->pdm.s.Pic.pfnGetInterruptRC);
|
---|
[26160] | 3004 | AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pPicReg->pszGetInterruptRC, rc));
|
---|
[1] | 3005 | }
|
---|
[13816] | 3006 | if (RT_FAILURE(rc))
|
---|
[1] | 3007 | {
|
---|
[26165] | 3008 | LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 3009 | return rc;
|
---|
| 3010 | }
|
---|
[11261] | 3011 | pVM->pdm.s.Pic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
|
---|
[1] | 3012 | }
|
---|
| 3013 | else
|
---|
| 3014 | {
|
---|
[11261] | 3015 | pVM->pdm.s.Pic.pDevInsRC = 0;
|
---|
| 3016 | pVM->pdm.s.Pic.pfnSetIrqRC = 0;
|
---|
| 3017 | pVM->pdm.s.Pic.pfnGetInterruptRC = 0;
|
---|
[1] | 3018 | }
|
---|
| 3019 |
|
---|
| 3020 | /*
|
---|
| 3021 | * R0 stuff.
|
---|
| 3022 | */
|
---|
[7523] | 3023 | if (pPicReg->pszSetIrqR0)
|
---|
[1] | 3024 | {
|
---|
[34241] | 3025 | int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pPicReg->pszSetIrqR0, &pVM->pdm.s.Pic.pfnSetIrqR0);
|
---|
[26160] | 3026 | AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pPicReg->pszSetIrqR0, rc));
|
---|
[13816] | 3027 | if (RT_SUCCESS(rc))
|
---|
[1] | 3028 | {
|
---|
[34241] | 3029 | rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pPicReg->pszGetInterruptR0, &pVM->pdm.s.Pic.pfnGetInterruptR0);
|
---|
[26160] | 3030 | AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pPicReg->pszGetInterruptR0, rc));
|
---|
[1] | 3031 | }
|
---|
[13816] | 3032 | if (RT_FAILURE(rc))
|
---|
[1] | 3033 | {
|
---|
[26165] | 3034 | LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 3035 | return rc;
|
---|
| 3036 | }
|
---|
[12981] | 3037 | pVM->pdm.s.Pic.pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
|
---|
[1] | 3038 | Assert(pVM->pdm.s.Pic.pDevInsR0);
|
---|
| 3039 | }
|
---|
| 3040 | else
|
---|
| 3041 | {
|
---|
| 3042 | pVM->pdm.s.Pic.pfnSetIrqR0 = 0;
|
---|
| 3043 | pVM->pdm.s.Pic.pfnGetInterruptR0 = 0;
|
---|
| 3044 | pVM->pdm.s.Pic.pDevInsR0 = 0;
|
---|
| 3045 | }
|
---|
| 3046 |
|
---|
| 3047 | /*
|
---|
[11261] | 3048 | * R3 stuff.
|
---|
[1] | 3049 | */
|
---|
| 3050 | pVM->pdm.s.Pic.pDevInsR3 = pDevIns;
|
---|
[11261] | 3051 | pVM->pdm.s.Pic.pfnSetIrqR3 = pPicReg->pfnSetIrqR3;
|
---|
| 3052 | pVM->pdm.s.Pic.pfnGetInterruptR3 = pPicReg->pfnGetInterruptR3;
|
---|
[26165] | 3053 | Log(("PDM: Registered PIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
|
---|
[1] | 3054 |
|
---|
| 3055 | /* set the helper pointer and return. */
|
---|
| 3056 | *ppPicHlpR3 = &g_pdmR3DevPicHlp;
|
---|
[26165] | 3057 | LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
|
---|
[1] | 3058 | return VINF_SUCCESS;
|
---|
| 3059 | }
|
---|
| 3060 |
|
---|
| 3061 |
|
---|
[26152] | 3062 | /** @interface_method_impl{PDMDEVHLPR3,pfnAPICRegister} */
|
---|
[64655] | 3063 | static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns)
|
---|
[1] | 3064 | {
|
---|
| 3065 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 3066 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[1] | 3067 |
|
---|
| 3068 | /*
|
---|
[13013] | 3069 | * Only one APIC device. On SMP we have single logical device covering all LAPICs,
|
---|
| 3070 | * as they need to communicate and share state easily.
|
---|
[1] | 3071 | */
|
---|
[12970] | 3072 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[1] | 3073 | if (pVM->pdm.s.Apic.pDevInsR3)
|
---|
| 3074 | {
|
---|
[64655] | 3075 | AssertMsgFailed(("Only one APIC device is supported!\n"));
|
---|
[26165] | 3076 | LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 3077 | return VERR_INVALID_PARAMETER;
|
---|
| 3078 | }
|
---|
| 3079 |
|
---|
| 3080 | /*
|
---|
[64655] | 3081 | * Initialize the RC, R0 and HC bits.
|
---|
[1] | 3082 | */
|
---|
[64655] | 3083 | pVM->pdm.s.Apic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
|
---|
| 3084 | Assert(pVM->pdm.s.Apic.pDevInsRC);
|
---|
[1] | 3085 |
|
---|
[64655] | 3086 | pVM->pdm.s.Apic.pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
|
---|
| 3087 | Assert(pVM->pdm.s.Apic.pDevInsR0);
|
---|
[1] | 3088 |
|
---|
[64655] | 3089 | pVM->pdm.s.Apic.pDevInsR3 = pDevIns;
|
---|
[26165] | 3090 | LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
|
---|
[1] | 3091 | return VINF_SUCCESS;
|
---|
| 3092 | }
|
---|
| 3093 |
|
---|
| 3094 |
|
---|
[26152] | 3095 | /** @interface_method_impl{PDMDEVHLPR3,pfnIOAPICRegister} */
|
---|
[1] | 3096 | static DECLCALLBACK(int) pdmR3DevHlp_IOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3)
|
---|
| 3097 | {
|
---|
| 3098 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 3099 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[11219] | 3100 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: pIoApicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppIoApicHlpR3=%p\n",
|
---|
[26165] | 3101 | pDevIns->pReg->szName, pDevIns->iInstance, pIoApicReg, pIoApicReg->u32Version, pIoApicReg->pfnSetIrqR3,
|
---|
[11219] | 3102 | pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqRC, pIoApicReg->pszSetIrqR0, pIoApicReg->pszSetIrqR0, ppIoApicHlpR3));
|
---|
[1] | 3103 |
|
---|
| 3104 | /*
|
---|
| 3105 | * Validate input.
|
---|
| 3106 | */
|
---|
| 3107 | if (pIoApicReg->u32Version != PDM_IOAPICREG_VERSION)
|
---|
| 3108 | {
|
---|
| 3109 | AssertMsgFailed(("u32Version=%#x expected %#x\n", pIoApicReg->u32Version, PDM_IOAPICREG_VERSION));
|
---|
[26165] | 3110 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (version)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 3111 | return VERR_INVALID_PARAMETER;
|
---|
| 3112 | }
|
---|
[65338] | 3113 | if (!pIoApicReg->pfnSetIrqR3 || !pIoApicReg->pfnSendMsiR3 || !pIoApicReg->pfnSetEoiR3)
|
---|
[1] | 3114 | {
|
---|
[11219] | 3115 | Assert(pIoApicReg->pfnSetIrqR3);
|
---|
[26165] | 3116 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (R3 callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 3117 | return VERR_INVALID_PARAMETER;
|
---|
| 3118 | }
|
---|
[11219] | 3119 | if ( pIoApicReg->pszSetIrqRC
|
---|
| 3120 | && !VALID_PTR(pIoApicReg->pszSetIrqRC))
|
---|
[1] | 3121 | {
|
---|
[11219] | 3122 | Assert(VALID_PTR(pIoApicReg->pszSetIrqRC));
|
---|
[26165] | 3123 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 3124 | return VERR_INVALID_PARAMETER;
|
---|
| 3125 | }
|
---|
[32935] | 3126 | if ( pIoApicReg->pszSendMsiRC
|
---|
| 3127 | && !VALID_PTR(pIoApicReg->pszSendMsiRC))
|
---|
| 3128 | {
|
---|
| 3129 | Assert(VALID_PTR(pIoApicReg->pszSendMsiRC));
|
---|
| 3130 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
| 3131 | return VERR_INVALID_PARAMETER;
|
---|
| 3132 | }
|
---|
[61339] | 3133 | if ( pIoApicReg->pszSetEoiRC
|
---|
| 3134 | && !VALID_PTR(pIoApicReg->pszSetEoiRC))
|
---|
| 3135 | {
|
---|
| 3136 | Assert(VALID_PTR(pIoApicReg->pszSetEoiRC));
|
---|
| 3137 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
| 3138 | return VERR_INVALID_PARAMETER;
|
---|
| 3139 | }
|
---|
[1] | 3140 | if ( pIoApicReg->pszSetIrqR0
|
---|
| 3141 | && !VALID_PTR(pIoApicReg->pszSetIrqR0))
|
---|
| 3142 | {
|
---|
| 3143 | Assert(VALID_PTR(pIoApicReg->pszSetIrqR0));
|
---|
[26165] | 3144 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 3145 | return VERR_INVALID_PARAMETER;
|
---|
| 3146 | }
|
---|
[32935] | 3147 | if ( pIoApicReg->pszSendMsiR0
|
---|
| 3148 | && !VALID_PTR(pIoApicReg->pszSendMsiR0))
|
---|
| 3149 | {
|
---|
| 3150 | Assert(VALID_PTR(pIoApicReg->pszSendMsiR0));
|
---|
| 3151 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
| 3152 | return VERR_INVALID_PARAMETER;
|
---|
| 3153 | }
|
---|
[61339] | 3154 | if ( pIoApicReg->pszSetEoiR0
|
---|
| 3155 | && !VALID_PTR(pIoApicReg->pszSetEoiR0))
|
---|
| 3156 | {
|
---|
| 3157 | Assert(VALID_PTR(pIoApicReg->pszSetEoiR0));
|
---|
| 3158 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (GC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
| 3159 | return VERR_INVALID_PARAMETER;
|
---|
| 3160 | }
|
---|
[1] | 3161 | if (!ppIoApicHlpR3)
|
---|
| 3162 | {
|
---|
| 3163 | Assert(ppIoApicHlpR3);
|
---|
[26165] | 3164 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (ppApicHlp)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 3165 | return VERR_INVALID_PARAMETER;
|
---|
| 3166 | }
|
---|
| 3167 |
|
---|
| 3168 | /*
|
---|
| 3169 | * The I/O APIC requires the APIC to be present (hacks++).
|
---|
| 3170 | * If the I/O APIC does GC stuff so must the APIC.
|
---|
| 3171 | */
|
---|
[12970] | 3172 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[1] | 3173 | if (!pVM->pdm.s.Apic.pDevInsR3)
|
---|
| 3174 | {
|
---|
| 3175 | AssertMsgFailed(("Configuration error / Init order error! No APIC!\n"));
|
---|
[26165] | 3176 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (no APIC)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 3177 | return VERR_INVALID_PARAMETER;
|
---|
| 3178 | }
|
---|
[11219] | 3179 | if ( pIoApicReg->pszSetIrqRC
|
---|
| 3180 | && !pVM->pdm.s.Apic.pDevInsRC)
|
---|
[1] | 3181 | {
|
---|
| 3182 | AssertMsgFailed(("Configuration error! APIC doesn't do GC, I/O APIC does!\n"));
|
---|
[26165] | 3183 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (no GC APIC)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 3184 | return VERR_INVALID_PARAMETER;
|
---|
| 3185 | }
|
---|
| 3186 |
|
---|
| 3187 | /*
|
---|
| 3188 | * Only one I/O APIC device.
|
---|
| 3189 | */
|
---|
| 3190 | if (pVM->pdm.s.IoApic.pDevInsR3)
|
---|
| 3191 | {
|
---|
| 3192 | AssertMsgFailed(("Only one ioapic device is supported!\n"));
|
---|
[26165] | 3193 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc (only one)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 3194 | return VERR_INVALID_PARAMETER;
|
---|
| 3195 | }
|
---|
| 3196 |
|
---|
| 3197 | /*
|
---|
| 3198 | * Resolve & initialize the GC bits.
|
---|
| 3199 | */
|
---|
[11219] | 3200 | if (pIoApicReg->pszSetIrqRC)
|
---|
[1] | 3201 | {
|
---|
[34241] | 3202 | int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pIoApicReg->pszSetIrqRC, &pVM->pdm.s.IoApic.pfnSetIrqRC);
|
---|
[26160] | 3203 | AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pIoApicReg->pszSetIrqRC, rc));
|
---|
[13816] | 3204 | if (RT_FAILURE(rc))
|
---|
[1] | 3205 | {
|
---|
[26165] | 3206 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 3207 | return rc;
|
---|
| 3208 | }
|
---|
[11219] | 3209 | pVM->pdm.s.IoApic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
|
---|
[1] | 3210 | }
|
---|
| 3211 | else
|
---|
| 3212 | {
|
---|
[11219] | 3213 | pVM->pdm.s.IoApic.pDevInsRC = 0;
|
---|
| 3214 | pVM->pdm.s.IoApic.pfnSetIrqRC = 0;
|
---|
[1] | 3215 | }
|
---|
| 3216 |
|
---|
[32935] | 3217 | if (pIoApicReg->pszSendMsiRC)
|
---|
| 3218 | {
|
---|
[61339] | 3219 | int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pIoApicReg->pszSendMsiRC, &pVM->pdm.s.IoApic.pfnSendMsiRC);
|
---|
[32935] | 3220 | AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pIoApicReg->pszSendMsiRC, rc));
|
---|
| 3221 | if (RT_FAILURE(rc))
|
---|
| 3222 | {
|
---|
| 3223 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 3224 | return rc;
|
---|
| 3225 | }
|
---|
| 3226 | }
|
---|
| 3227 | else
|
---|
| 3228 | {
|
---|
| 3229 | pVM->pdm.s.IoApic.pfnSendMsiRC = 0;
|
---|
| 3230 | }
|
---|
| 3231 |
|
---|
[61339] | 3232 | if (pIoApicReg->pszSetEoiRC)
|
---|
| 3233 | {
|
---|
| 3234 | int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pIoApicReg->pszSetEoiRC, &pVM->pdm.s.IoApic.pfnSetEoiRC);
|
---|
| 3235 | AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pIoApicReg->pszSetEoiRC, rc));
|
---|
| 3236 | if (RT_FAILURE(rc))
|
---|
| 3237 | {
|
---|
| 3238 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 3239 | return rc;
|
---|
| 3240 | }
|
---|
| 3241 | }
|
---|
| 3242 | else
|
---|
| 3243 | {
|
---|
| 3244 | pVM->pdm.s.IoApic.pfnSetEoiRC = 0;
|
---|
| 3245 | }
|
---|
| 3246 |
|
---|
[1] | 3247 | /*
|
---|
| 3248 | * Resolve & initialize the R0 bits.
|
---|
| 3249 | */
|
---|
[7523] | 3250 | if (pIoApicReg->pszSetIrqR0)
|
---|
[1] | 3251 | {
|
---|
[34241] | 3252 | int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pIoApicReg->pszSetIrqR0, &pVM->pdm.s.IoApic.pfnSetIrqR0);
|
---|
[26160] | 3253 | AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pIoApicReg->pszSetIrqR0, rc));
|
---|
[13816] | 3254 | if (RT_FAILURE(rc))
|
---|
[1] | 3255 | {
|
---|
[26165] | 3256 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 3257 | return rc;
|
---|
| 3258 | }
|
---|
[12981] | 3259 | pVM->pdm.s.IoApic.pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
|
---|
[1] | 3260 | Assert(pVM->pdm.s.IoApic.pDevInsR0);
|
---|
| 3261 | }
|
---|
| 3262 | else
|
---|
| 3263 | {
|
---|
| 3264 | pVM->pdm.s.IoApic.pfnSetIrqR0 = 0;
|
---|
| 3265 | pVM->pdm.s.IoApic.pDevInsR0 = 0;
|
---|
| 3266 | }
|
---|
| 3267 |
|
---|
[32935] | 3268 | if (pIoApicReg->pszSendMsiR0)
|
---|
| 3269 | {
|
---|
[51376] | 3270 | int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pIoApicReg->pszSendMsiR0, &pVM->pdm.s.IoApic.pfnSendMsiR0);
|
---|
[32935] | 3271 | AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pIoApicReg->pszSendMsiR0, rc));
|
---|
| 3272 | if (RT_FAILURE(rc))
|
---|
| 3273 | {
|
---|
| 3274 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 3275 | return rc;
|
---|
| 3276 | }
|
---|
| 3277 | }
|
---|
| 3278 | else
|
---|
| 3279 | {
|
---|
| 3280 | pVM->pdm.s.IoApic.pfnSendMsiR0 = 0;
|
---|
| 3281 | }
|
---|
| 3282 |
|
---|
[61339] | 3283 | if (pIoApicReg->pszSetEoiR0)
|
---|
| 3284 | {
|
---|
| 3285 | int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pIoApicReg->pszSetEoiR0, &pVM->pdm.s.IoApic.pfnSetEoiR0);
|
---|
| 3286 | AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pIoApicReg->pszSetEoiR0, rc));
|
---|
| 3287 | if (RT_FAILURE(rc))
|
---|
| 3288 | {
|
---|
| 3289 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 3290 | return rc;
|
---|
| 3291 | }
|
---|
| 3292 | }
|
---|
| 3293 | else
|
---|
| 3294 | {
|
---|
| 3295 | pVM->pdm.s.IoApic.pfnSetEoiR0 = 0;
|
---|
| 3296 | }
|
---|
[32935] | 3297 |
|
---|
[61339] | 3298 |
|
---|
[1] | 3299 | /*
|
---|
[11219] | 3300 | * Initialize the R3 bits.
|
---|
[1] | 3301 | */
|
---|
| 3302 | pVM->pdm.s.IoApic.pDevInsR3 = pDevIns;
|
---|
[61339] | 3303 | pVM->pdm.s.IoApic.pfnSetIrqR3 = pIoApicReg->pfnSetIrqR3;
|
---|
[32935] | 3304 | pVM->pdm.s.IoApic.pfnSendMsiR3 = pIoApicReg->pfnSendMsiR3;
|
---|
[61339] | 3305 | pVM->pdm.s.IoApic.pfnSetEoiR3 = pIoApicReg->pfnSetEoiR3;
|
---|
[26165] | 3306 | Log(("PDM: Registered I/O APIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
|
---|
[1] | 3307 |
|
---|
| 3308 | /* set the helper pointer and return. */
|
---|
| 3309 | *ppIoApicHlpR3 = &g_pdmR3DevIoApicHlp;
|
---|
[26165] | 3310 | LogFlow(("pdmR3DevHlp_IOAPICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
|
---|
[1] | 3311 | return VINF_SUCCESS;
|
---|
| 3312 | }
|
---|
[26001] | 3313 |
|
---|
| 3314 |
|
---|
[26152] | 3315 | /** @interface_method_impl{PDMDEVHLPR3,pfnHPETRegister} */
|
---|
[25995] | 3316 | static DECLCALLBACK(int) pdmR3DevHlp_HPETRegister(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3)
|
---|
| 3317 | {
|
---|
[62643] | 3318 | PDMDEV_ASSERT_DEVINS(pDevIns); RT_NOREF_PV(pDevIns);
|
---|
[25995] | 3319 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[56985] | 3320 | LogFlow(("pdmR3DevHlp_HPETRegister: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[1] | 3321 |
|
---|
[25995] | 3322 | /*
|
---|
| 3323 | * Validate input.
|
---|
| 3324 | */
|
---|
| 3325 | if (pHpetReg->u32Version != PDM_HPETREG_VERSION)
|
---|
| 3326 | {
|
---|
| 3327 | AssertMsgFailed(("u32Version=%#x expected %#x\n", pHpetReg->u32Version, PDM_HPETREG_VERSION));
|
---|
[26165] | 3328 | LogFlow(("pdmR3DevHlp_HPETRegister: caller='%s'/%d: returns %Rrc (version)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[25995] | 3329 | return VERR_INVALID_PARAMETER;
|
---|
| 3330 | }
|
---|
[1] | 3331 |
|
---|
[25995] | 3332 | if (!ppHpetHlpR3)
|
---|
| 3333 | {
|
---|
| 3334 | Assert(ppHpetHlpR3);
|
---|
[26165] | 3335 | LogFlow(("pdmR3DevHlp_HPETRegister: caller='%s'/%d: returns %Rrc (ppApicHlpR3)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[25995] | 3336 | return VERR_INVALID_PARAMETER;
|
---|
| 3337 | }
|
---|
| 3338 |
|
---|
| 3339 | /* set the helper pointer and return. */
|
---|
| 3340 | *ppHpetHlpR3 = &g_pdmR3DevHpetHlp;
|
---|
[26165] | 3341 | LogFlow(("pdmR3DevHlp_HPETRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
|
---|
[25995] | 3342 | return VINF_SUCCESS;
|
---|
| 3343 | }
|
---|
| 3344 |
|
---|
[35738] | 3345 |
|
---|
[35676] | 3346 | /** @interface_method_impl{PDMDEVHLPR3,pfnPciRawRegister} */
|
---|
| 3347 | static DECLCALLBACK(int) pdmR3DevHlp_PciRawRegister(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3)
|
---|
| 3348 | {
|
---|
[62643] | 3349 | PDMDEV_ASSERT_DEVINS(pDevIns); RT_NOREF_PV(pDevIns);
|
---|
[35676] | 3350 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[56985] | 3351 | LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[26001] | 3352 |
|
---|
[35676] | 3353 | /*
|
---|
| 3354 | * Validate input.
|
---|
| 3355 | */
|
---|
| 3356 | if (pPciRawReg->u32Version != PDM_PCIRAWREG_VERSION)
|
---|
| 3357 | {
|
---|
| 3358 | AssertMsgFailed(("u32Version=%#x expected %#x\n", pPciRawReg->u32Version, PDM_PCIRAWREG_VERSION));
|
---|
| 3359 | LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc (version)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
| 3360 | return VERR_INVALID_PARAMETER;
|
---|
| 3361 | }
|
---|
| 3362 |
|
---|
| 3363 | if (!ppPciRawHlpR3)
|
---|
| 3364 | {
|
---|
| 3365 | Assert(ppPciRawHlpR3);
|
---|
[64596] | 3366 | LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc (ppPciRawHlpR3)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[35676] | 3367 | return VERR_INVALID_PARAMETER;
|
---|
| 3368 | }
|
---|
| 3369 |
|
---|
| 3370 | /* set the helper pointer and return. */
|
---|
| 3371 | *ppPciRawHlpR3 = &g_pdmR3DevPciRawHlp;
|
---|
| 3372 | LogFlow(("pdmR3DevHlp_PciRawRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
|
---|
| 3373 | return VINF_SUCCESS;
|
---|
| 3374 | }
|
---|
| 3375 |
|
---|
[35738] | 3376 |
|
---|
[26152] | 3377 | /** @interface_method_impl{PDMDEVHLPR3,pfnDMACRegister} */
|
---|
[1] | 3378 | static DECLCALLBACK(int) pdmR3DevHlp_DMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)
|
---|
| 3379 | {
|
---|
| 3380 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 3381 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[1] | 3382 | LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: pDmacReg=%p:{.u32Version=%#x, .pfnRun=%p, .pfnRegister=%p, .pfnReadMemory=%p, .pfnWriteMemory=%p, .pfnSetDREQ=%p, .pfnGetChannelMode=%p} ppDmacHlp=%p\n",
|
---|
[26165] | 3383 | pDevIns->pReg->szName, pDevIns->iInstance, pDmacReg, pDmacReg->u32Version, pDmacReg->pfnRun, pDmacReg->pfnRegister,
|
---|
[1] | 3384 | pDmacReg->pfnReadMemory, pDmacReg->pfnWriteMemory, pDmacReg->pfnSetDREQ, pDmacReg->pfnGetChannelMode, ppDmacHlp));
|
---|
| 3385 |
|
---|
| 3386 | /*
|
---|
| 3387 | * Validate input.
|
---|
| 3388 | */
|
---|
| 3389 | if (pDmacReg->u32Version != PDM_DMACREG_VERSION)
|
---|
| 3390 | {
|
---|
| 3391 | AssertMsgFailed(("u32Version=%#x expected %#x\n", pDmacReg->u32Version,
|
---|
| 3392 | PDM_DMACREG_VERSION));
|
---|
[13818] | 3393 | LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc (version)\n",
|
---|
[26165] | 3394 | pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 3395 | return VERR_INVALID_PARAMETER;
|
---|
| 3396 | }
|
---|
| 3397 | if ( !pDmacReg->pfnRun
|
---|
| 3398 | || !pDmacReg->pfnRegister
|
---|
| 3399 | || !pDmacReg->pfnReadMemory
|
---|
| 3400 | || !pDmacReg->pfnWriteMemory
|
---|
| 3401 | || !pDmacReg->pfnSetDREQ
|
---|
| 3402 | || !pDmacReg->pfnGetChannelMode)
|
---|
| 3403 | {
|
---|
| 3404 | Assert(pDmacReg->pfnRun);
|
---|
| 3405 | Assert(pDmacReg->pfnRegister);
|
---|
| 3406 | Assert(pDmacReg->pfnReadMemory);
|
---|
| 3407 | Assert(pDmacReg->pfnWriteMemory);
|
---|
| 3408 | Assert(pDmacReg->pfnSetDREQ);
|
---|
| 3409 | Assert(pDmacReg->pfnGetChannelMode);
|
---|
[13818] | 3410 | LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc (callbacks)\n",
|
---|
[26165] | 3411 | pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 3412 | return VERR_INVALID_PARAMETER;
|
---|
| 3413 | }
|
---|
| 3414 |
|
---|
| 3415 | if (!ppDmacHlp)
|
---|
| 3416 | {
|
---|
| 3417 | Assert(ppDmacHlp);
|
---|
[13818] | 3418 | LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc (ppDmacHlp)\n",
|
---|
[26165] | 3419 | pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 3420 | return VERR_INVALID_PARAMETER;
|
---|
| 3421 | }
|
---|
| 3422 |
|
---|
| 3423 | /*
|
---|
| 3424 | * Only one DMA device.
|
---|
| 3425 | */
|
---|
[12970] | 3426 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[1] | 3427 | if (pVM->pdm.s.pDmac)
|
---|
| 3428 | {
|
---|
| 3429 | AssertMsgFailed(("Only one DMA device is supported!\n"));
|
---|
[13818] | 3430 | LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc\n",
|
---|
[26165] | 3431 | pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
[1] | 3432 | return VERR_INVALID_PARAMETER;
|
---|
| 3433 | }
|
---|
| 3434 |
|
---|
| 3435 | /*
|
---|
| 3436 | * Allocate and initialize pci bus structure.
|
---|
| 3437 | */
|
---|
| 3438 | int rc = VINF_SUCCESS;
|
---|
[12970] | 3439 | PPDMDMAC pDmac = (PPDMDMAC)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pDmac));
|
---|
[1] | 3440 | if (pDmac)
|
---|
| 3441 | {
|
---|
| 3442 | pDmac->pDevIns = pDevIns;
|
---|
| 3443 | pDmac->Reg = *pDmacReg;
|
---|
| 3444 | pVM->pdm.s.pDmac = pDmac;
|
---|
| 3445 |
|
---|
| 3446 | /* set the helper pointer. */
|
---|
| 3447 | *ppDmacHlp = &g_pdmR3DevDmacHlp;
|
---|
| 3448 | Log(("PDM: Registered DMAC device '%s'/%d pDevIns=%p\n",
|
---|
[26165] | 3449 | pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
|
---|
[1] | 3450 | }
|
---|
| 3451 | else
|
---|
| 3452 | rc = VERR_NO_MEMORY;
|
---|
| 3453 |
|
---|
[13818] | 3454 | LogFlow(("pdmR3DevHlp_DMACRegister: caller='%s'/%d: returns %Rrc\n",
|
---|
[26165] | 3455 | pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 3456 | return rc;
|
---|
| 3457 | }
|
---|
| 3458 |
|
---|
| 3459 |
|
---|
[26157] | 3460 | /**
|
---|
| 3461 | * @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap
|
---|
| 3462 | */
|
---|
[60396] | 3463 | static DECLCALLBACK(int) pdmR3DevHlp_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbHeap)
|
---|
[1] | 3464 | {
|
---|
| 3465 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[60396] | 3466 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 3467 | VM_ASSERT_EMT(pVM);
|
---|
| 3468 | LogFlow(("pdmR3DevHlp_RegisterVMMDevHeap: caller='%s'/%d: GCPhys=%RGp pvHeap=%p cbHeap=%#x\n",
|
---|
| 3469 | pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, pvHeap, cbHeap));
|
---|
[1] | 3470 |
|
---|
[60396] | 3471 | if (pVM->pdm.s.pvVMMDevHeap == NULL)
|
---|
| 3472 | {
|
---|
| 3473 | pVM->pdm.s.pvVMMDevHeap = pvHeap;
|
---|
| 3474 | pVM->pdm.s.GCPhysVMMDevHeap = GCPhys;
|
---|
| 3475 | pVM->pdm.s.cbVMMDevHeap = cbHeap;
|
---|
| 3476 | pVM->pdm.s.cbVMMDevHeapLeft = cbHeap;
|
---|
| 3477 | }
|
---|
| 3478 | else
|
---|
| 3479 | {
|
---|
| 3480 | Assert(pVM->pdm.s.pvVMMDevHeap == pvHeap);
|
---|
| 3481 | Assert(pVM->pdm.s.cbVMMDevHeap == cbHeap);
|
---|
| 3482 | Assert(pVM->pdm.s.GCPhysVMMDevHeap != GCPhys || GCPhys == NIL_RTGCPHYS);
|
---|
| 3483 | if (pVM->pdm.s.GCPhysVMMDevHeap != GCPhys)
|
---|
| 3484 | {
|
---|
| 3485 | pVM->pdm.s.GCPhysVMMDevHeap = GCPhys;
|
---|
| 3486 | if (pVM->pdm.s.pfnVMMDevHeapNotify)
|
---|
| 3487 | pVM->pdm.s.pfnVMMDevHeapNotify(pVM, pvHeap, GCPhys);
|
---|
| 3488 | }
|
---|
| 3489 | }
|
---|
| 3490 |
|
---|
| 3491 | LogFlow(("pdmR3DevHlp_RegisterVMMDevHeap: caller='%s'/%d: returns %Rrc\n",
|
---|
| 3492 | pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
|
---|
| 3493 | return VINF_SUCCESS;
|
---|
[1] | 3494 | }
|
---|
| 3495 |
|
---|
| 3496 |
|
---|
[26157] | 3497 | /**
|
---|
[60404] | 3498 | * @interface_method_impl{PDMDEVHLPR3,pfnFirmwareRegister}
|
---|
[26157] | 3499 | */
|
---|
[60404] | 3500 | static DECLCALLBACK(int) pdmR3DevHlp_FirmwareRegister(PPDMDEVINS pDevIns, PCPDMFWREG pFwReg, PCPDMFWHLPR3 *ppFwHlp)
|
---|
[1] | 3501 | {
|
---|
[60404] | 3502 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 3503 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
| 3504 | LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: pFWReg=%p:{.u32Version=%#x, .pfnIsHardReset=%p, .u32TheEnd=%#x} ppFwHlp=%p\n",
|
---|
| 3505 | pDevIns->pReg->szName, pDevIns->iInstance, pFwReg, pFwReg->u32Version, pFwReg->pfnIsHardReset, pFwReg->u32TheEnd, ppFwHlp));
|
---|
| 3506 |
|
---|
| 3507 | /*
|
---|
| 3508 | * Validate input.
|
---|
| 3509 | */
|
---|
| 3510 | if (pFwReg->u32Version != PDM_FWREG_VERSION)
|
---|
| 3511 | {
|
---|
| 3512 | AssertMsgFailed(("u32Version=%#x expected %#x\n", pFwReg->u32Version, PDM_FWREG_VERSION));
|
---|
| 3513 | LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc (version)\n",
|
---|
| 3514 | pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
| 3515 | return VERR_INVALID_PARAMETER;
|
---|
| 3516 | }
|
---|
| 3517 | if (!pFwReg->pfnIsHardReset)
|
---|
| 3518 | {
|
---|
| 3519 | Assert(pFwReg->pfnIsHardReset);
|
---|
| 3520 | LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc (callbacks)\n",
|
---|
| 3521 | pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
| 3522 | return VERR_INVALID_PARAMETER;
|
---|
| 3523 | }
|
---|
| 3524 |
|
---|
| 3525 | if (!ppFwHlp)
|
---|
| 3526 | {
|
---|
| 3527 | Assert(ppFwHlp);
|
---|
| 3528 | LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc (ppFwHlp)\n",
|
---|
| 3529 | pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
| 3530 | return VERR_INVALID_PARAMETER;
|
---|
| 3531 | }
|
---|
| 3532 |
|
---|
| 3533 | /*
|
---|
| 3534 | * Only one DMA device.
|
---|
| 3535 | */
|
---|
| 3536 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 3537 | if (pVM->pdm.s.pFirmware)
|
---|
| 3538 | {
|
---|
| 3539 | AssertMsgFailed(("Only one firmware device is supported!\n"));
|
---|
| 3540 | LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc\n",
|
---|
| 3541 | pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
|
---|
| 3542 | return VERR_INVALID_PARAMETER;
|
---|
| 3543 | }
|
---|
| 3544 |
|
---|
| 3545 | /*
|
---|
| 3546 | * Allocate and initialize pci bus structure.
|
---|
| 3547 | */
|
---|
| 3548 | int rc = VINF_SUCCESS;
|
---|
| 3549 | PPDMFW pFirmware = (PPDMFW)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pFirmware));
|
---|
| 3550 | if (pFirmware)
|
---|
| 3551 | {
|
---|
| 3552 | pFirmware->pDevIns = pDevIns;
|
---|
| 3553 | pFirmware->Reg = *pFwReg;
|
---|
| 3554 | pVM->pdm.s.pFirmware = pFirmware;
|
---|
| 3555 |
|
---|
| 3556 | /* set the helper pointer. */
|
---|
| 3557 | *ppFwHlp = &g_pdmR3DevFirmwareHlp;
|
---|
| 3558 | Log(("PDM: Registered firmware device '%s'/%d pDevIns=%p\n",
|
---|
| 3559 | pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
|
---|
| 3560 | }
|
---|
| 3561 | else
|
---|
| 3562 | rc = VERR_NO_MEMORY;
|
---|
| 3563 |
|
---|
| 3564 | LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc\n",
|
---|
| 3565 | pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 3566 | return rc;
|
---|
[1] | 3567 | }
|
---|
| 3568 |
|
---|
| 3569 |
|
---|
[26152] | 3570 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMReset} */
|
---|
[60404] | 3571 | static DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns, uint32_t fFlags)
|
---|
[1] | 3572 | {
|
---|
| 3573 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[12970] | 3574 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
[1] | 3575 | VM_ASSERT_EMT(pVM);
|
---|
[60404] | 3576 | LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: fFlags=%#x VM_FF_RESET %d -> 1\n",
|
---|
| 3577 | pDevIns->pReg->szName, pDevIns->iInstance, fFlags, VM_FF_IS_SET(pVM, VM_FF_RESET)));
|
---|
[1] | 3578 |
|
---|
| 3579 | /*
|
---|
| 3580 | * We postpone this operation because we're likely to be inside a I/O instruction
|
---|
| 3581 | * and the EIP will be updated when we return.
|
---|
| 3582 | * We still return VINF_EM_RESET to break out of any execution loops and force FF evaluation.
|
---|
| 3583 | */
|
---|
| 3584 | bool fHaltOnReset;
|
---|
| 3585 | int rc = CFGMR3QueryBool(CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM"), "HaltOnReset", &fHaltOnReset);
|
---|
[13816] | 3586 | if (RT_SUCCESS(rc) && fHaltOnReset)
|
---|
[1] | 3587 | {
|
---|
| 3588 | Log(("pdmR3DevHlp_VMReset: Halt On Reset!\n"));
|
---|
| 3589 | rc = VINF_EM_HALT;
|
---|
| 3590 | }
|
---|
| 3591 | else
|
---|
| 3592 | {
|
---|
[60404] | 3593 | pVM->pdm.s.fResetFlags = fFlags;
|
---|
[1] | 3594 | VM_FF_SET(pVM, VM_FF_RESET);
|
---|
| 3595 | rc = VINF_EM_RESET;
|
---|
| 3596 | }
|
---|
| 3597 |
|
---|
[26165] | 3598 | LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 3599 | return rc;
|
---|
| 3600 | }
|
---|
| 3601 |
|
---|
| 3602 |
|
---|
[26152] | 3603 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMSuspend} */
|
---|
[1] | 3604 | static DECLCALLBACK(int) pdmR3DevHlp_VMSuspend(PPDMDEVINS pDevIns)
|
---|
| 3605 | {
|
---|
[20881] | 3606 | int rc;
|
---|
[1] | 3607 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[20880] | 3608 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 3609 | VM_ASSERT_EMT(pVM);
|
---|
[1] | 3610 | LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d:\n",
|
---|
[26165] | 3611 | pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[1] | 3612 |
|
---|
[32190] | 3613 | /** @todo Always take the SMP path - fewer code paths. */
|
---|
[22890] | 3614 | if (pVM->cCpus > 1)
|
---|
[20880] | 3615 | {
|
---|
| 3616 | /* We own the IOM lock here and could cause a deadlock by waiting for a VCPU that is blocking on the IOM lock. */
|
---|
[46788] | 3617 | rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)VMR3Suspend, 2, pVM->pUVM, VMSUSPENDREASON_VM);
|
---|
[20880] | 3618 | AssertRC(rc);
|
---|
| 3619 | rc = VINF_EM_SUSPEND;
|
---|
| 3620 | }
|
---|
| 3621 | else
|
---|
[46788] | 3622 | rc = VMR3Suspend(pVM->pUVM, VMSUSPENDREASON_VM);
|
---|
[1] | 3623 |
|
---|
[26165] | 3624 | LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 3625 | return rc;
|
---|
| 3626 | }
|
---|
| 3627 |
|
---|
| 3628 |
|
---|
[32190] | 3629 | /**
|
---|
| 3630 | * Worker for pdmR3DevHlp_VMSuspendSaveAndPowerOff that is invoked via a queued
|
---|
| 3631 | * EMT request to avoid deadlocks.
|
---|
| 3632 | *
|
---|
| 3633 | * @returns VBox status code fit for scheduling.
|
---|
[58122] | 3634 | * @param pVM The cross context VM structure.
|
---|
[32190] | 3635 | * @param pDevIns The device that triggered this action.
|
---|
| 3636 | */
|
---|
| 3637 | static DECLCALLBACK(int) pdmR3DevHlp_VMSuspendSaveAndPowerOffWorker(PVM pVM, PPDMDEVINS pDevIns)
|
---|
| 3638 | {
|
---|
| 3639 | /*
|
---|
| 3640 | * Suspend the VM first then do the saving.
|
---|
| 3641 | */
|
---|
[46788] | 3642 | int rc = VMR3Suspend(pVM->pUVM, VMSUSPENDREASON_VM);
|
---|
[32190] | 3643 | if (RT_SUCCESS(rc))
|
---|
| 3644 | {
|
---|
[36437] | 3645 | PUVM pUVM = pVM->pUVM;
|
---|
| 3646 | rc = pUVM->pVmm2UserMethods->pfnSaveState(pVM->pUVM->pVmm2UserMethods, pUVM);
|
---|
[32190] | 3647 |
|
---|
| 3648 | /*
|
---|
| 3649 | * On success, power off the VM, on failure we'll leave it suspended.
|
---|
| 3650 | */
|
---|
| 3651 | if (RT_SUCCESS(rc))
|
---|
| 3652 | {
|
---|
[44340] | 3653 | rc = VMR3PowerOff(pVM->pUVM);
|
---|
[32190] | 3654 | if (RT_FAILURE(rc))
|
---|
| 3655 | LogRel(("%s/SSP: VMR3PowerOff failed: %Rrc\n", pDevIns->pReg->szName, rc));
|
---|
| 3656 | }
|
---|
| 3657 | else
|
---|
| 3658 | LogRel(("%s/SSP: pfnSaveState failed: %Rrc\n", pDevIns->pReg->szName, rc));
|
---|
| 3659 | }
|
---|
| 3660 | else
|
---|
| 3661 | LogRel(("%s/SSP: Suspend failed: %Rrc\n", pDevIns->pReg->szName, rc));
|
---|
| 3662 | return rc;
|
---|
| 3663 | }
|
---|
| 3664 |
|
---|
| 3665 |
|
---|
[32189] | 3666 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMSuspendSaveAndPowerOff} */
|
---|
| 3667 | static DECLCALLBACK(int) pdmR3DevHlp_VMSuspendSaveAndPowerOff(PPDMDEVINS pDevIns)
|
---|
| 3668 | {
|
---|
| 3669 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 3670 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 3671 | VM_ASSERT_EMT(pVM);
|
---|
| 3672 | LogFlow(("pdmR3DevHlp_VMSuspendSaveAndPowerOff: caller='%s'/%d:\n",
|
---|
| 3673 | pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
| 3674 |
|
---|
[32190] | 3675 | int rc;
|
---|
| 3676 | if ( pVM->pUVM->pVmm2UserMethods
|
---|
| 3677 | && pVM->pUVM->pVmm2UserMethods->pfnSaveState)
|
---|
| 3678 | {
|
---|
[38838] | 3679 | rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)pdmR3DevHlp_VMSuspendSaveAndPowerOffWorker, 2, pVM, pDevIns);
|
---|
[32190] | 3680 | if (RT_SUCCESS(rc))
|
---|
| 3681 | {
|
---|
| 3682 | LogRel(("%s: Suspending, Saving and Powering Off the VM\n", pDevIns->pReg->szName));
|
---|
| 3683 | rc = VINF_EM_SUSPEND;
|
---|
| 3684 | }
|
---|
| 3685 | }
|
---|
| 3686 | else
|
---|
| 3687 | rc = VERR_NOT_SUPPORTED;
|
---|
[32189] | 3688 |
|
---|
| 3689 | LogFlow(("pdmR3DevHlp_VMSuspendSaveAndPowerOff: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
| 3690 | return rc;
|
---|
| 3691 | }
|
---|
| 3692 |
|
---|
| 3693 |
|
---|
[26152] | 3694 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMPowerOff} */
|
---|
[1] | 3695 | static DECLCALLBACK(int) pdmR3DevHlp_VMPowerOff(PPDMDEVINS pDevIns)
|
---|
| 3696 | {
|
---|
[20881] | 3697 | int rc;
|
---|
[1] | 3698 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[20880] | 3699 | PVM pVM = pDevIns->Internal.s.pVMR3;
|
---|
| 3700 | VM_ASSERT_EMT(pVM);
|
---|
[1] | 3701 | LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d:\n",
|
---|
[26165] | 3702 | pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[1] | 3703 |
|
---|
[32190] | 3704 | /** @todo Always take the SMP path - fewer code paths. */
|
---|
[22890] | 3705 | if (pVM->cCpus > 1)
|
---|
[20880] | 3706 | {
|
---|
[45749] | 3707 | /* We might be holding locks here and could cause a deadlock since
|
---|
| 3708 | VMR3PowerOff rendezvous with the other CPUs. */
|
---|
[44340] | 3709 | rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)VMR3PowerOff, 1, pVM->pUVM);
|
---|
[20880] | 3710 | AssertRC(rc);
|
---|
[20927] | 3711 | /* Set the VCPU state to stopped here as well to make sure no
|
---|
[45749] | 3712 | inconsistency with the EM state occurs. */
|
---|
[20927] | 3713 | VMCPU_SET_STATE(VMMGetCpu(pVM), VMCPUSTATE_STOPPED);
|
---|
[20880] | 3714 | rc = VINF_EM_OFF;
|
---|
| 3715 | }
|
---|
| 3716 | else
|
---|
[44340] | 3717 | rc = VMR3PowerOff(pVM->pUVM);
|
---|
[1] | 3718 |
|
---|
[26165] | 3719 | LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
|
---|
[1] | 3720 | return rc;
|
---|
| 3721 | }
|
---|
| 3722 |
|
---|
| 3723 |
|
---|
[26157] | 3724 | /** @interface_method_impl{PDMDEVHLPR3,pfnA20IsEnabled} */
|
---|
| 3725 | static DECLCALLBACK(bool) pdmR3DevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
|
---|
[1] | 3726 | {
|
---|
| 3727 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26157] | 3728 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[1] | 3729 |
|
---|
[26157] | 3730 | bool fRc = PGMPhysIsA20Enabled(VMMGetCpu(pDevIns->Internal.s.pVMR3));
|
---|
[1] | 3731 |
|
---|
[26165] | 3732 | LogFlow(("pdmR3DevHlp_A20IsEnabled: caller='%s'/%d: returns %d\n", pDevIns->pReg->szName, pDevIns->iInstance, fRc));
|
---|
[26157] | 3733 | return fRc;
|
---|
[1] | 3734 | }
|
---|
| 3735 |
|
---|
| 3736 |
|
---|
[26157] | 3737 | /** @interface_method_impl{PDMDEVHLPR3,pfnA20Set} */
|
---|
| 3738 | static DECLCALLBACK(void) pdmR3DevHlp_A20Set(PPDMDEVINS pDevIns, bool fEnable)
|
---|
[1] | 3739 | {
|
---|
| 3740 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26157] | 3741 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
[26165] | 3742 | LogFlow(("pdmR3DevHlp_A20Set: caller='%s'/%d: fEnable=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, fEnable));
|
---|
[26157] | 3743 | PGMR3PhysSetA20(VMMGetCpu(pDevIns->Internal.s.pVMR3), fEnable);
|
---|
[1] | 3744 | }
|
---|
| 3745 |
|
---|
| 3746 |
|
---|
[26152] | 3747 | /** @interface_method_impl{PDMDEVHLPR3,pfnGetCpuId} */
|
---|
[2749] | 3748 | static DECLCALLBACK(void) pdmR3DevHlp_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,
|
---|
| 3749 | uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
|
---|
[2633] | 3750 | {
|
---|
| 3751 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[19293] | 3752 | VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
|
---|
| 3753 |
|
---|
[2749] | 3754 | LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: iLeaf=%d pEax=%p pEbx=%p pEcx=%p pEdx=%p\n",
|
---|
[26165] | 3755 | pDevIns->pReg->szName, pDevIns->iInstance, iLeaf, pEax, pEbx, pEcx, pEdx));
|
---|
[2749] | 3756 | AssertPtr(pEax); AssertPtr(pEbx); AssertPtr(pEcx); AssertPtr(pEdx);
|
---|
| 3757 |
|
---|
[54737] | 3758 | CPUMGetGuestCpuId(VMMGetCpu(pDevIns->Internal.s.pVMR3), iLeaf, 0 /*iSubLeaf*/, pEax, pEbx, pEcx, pEdx);
|
---|
[2749] | 3759 |
|
---|
| 3760 | LogFlow(("pdmR3DevHlp_GetCpuId: caller='%s'/%d: returns void - *pEax=%#x *pEbx=%#x *pEcx=%#x *pEdx=%#x\n",
|
---|
[26165] | 3761 | pDevIns->pReg->szName, pDevIns->iInstance, *pEax, *pEbx, *pEcx, *pEdx));
|
---|
[2633] | 3762 | }
|
---|
[1] | 3763 |
|
---|
| 3764 |
|
---|
[7635] | 3765 | /**
|
---|
[12980] | 3766 | * The device helper structure for trusted devices.
|
---|
| 3767 | */
|
---|
| 3768 | const PDMDEVHLPR3 g_pdmR3DevHlpTrusted =
|
---|
| 3769 | {
|
---|
[26157] | 3770 | PDM_DEVHLPR3_VERSION,
|
---|
[12980] | 3771 | pdmR3DevHlp_IOPortRegister,
|
---|
[26157] | 3772 | pdmR3DevHlp_IOPortRegisterRC,
|
---|
[12980] | 3773 | pdmR3DevHlp_IOPortRegisterR0,
|
---|
| 3774 | pdmR3DevHlp_IOPortDeregister,
|
---|
| 3775 | pdmR3DevHlp_MMIORegister,
|
---|
[26157] | 3776 | pdmR3DevHlp_MMIORegisterRC,
|
---|
[12980] | 3777 | pdmR3DevHlp_MMIORegisterR0,
|
---|
| 3778 | pdmR3DevHlp_MMIODeregister,
|
---|
[26157] | 3779 | pdmR3DevHlp_MMIO2Register,
|
---|
[64373] | 3780 | pdmR3DevHlp_MMIOExPreRegister,
|
---|
[64115] | 3781 | pdmR3DevHlp_MMIOExDeregister,
|
---|
| 3782 | pdmR3DevHlp_MMIOExMap,
|
---|
| 3783 | pdmR3DevHlp_MMIOExUnmap,
|
---|
[68594] | 3784 | pdmR3DevHlp_MMIOExReduce,
|
---|
[26157] | 3785 | pdmR3DevHlp_MMHyperMapMMIO2,
|
---|
| 3786 | pdmR3DevHlp_MMIO2MapKernel,
|
---|
[12980] | 3787 | pdmR3DevHlp_ROMRegister,
|
---|
[26157] | 3788 | pdmR3DevHlp_ROMProtectShadow,
|
---|
[12980] | 3789 | pdmR3DevHlp_SSMRegister,
|
---|
| 3790 | pdmR3DevHlp_TMTimerCreate,
|
---|
[26158] | 3791 | pdmR3DevHlp_TMUtcNow,
|
---|
[26157] | 3792 | pdmR3DevHlp_PhysRead,
|
---|
| 3793 | pdmR3DevHlp_PhysWrite,
|
---|
| 3794 | pdmR3DevHlp_PhysGCPhys2CCPtr,
|
---|
| 3795 | pdmR3DevHlp_PhysGCPhys2CCPtrReadOnly,
|
---|
| 3796 | pdmR3DevHlp_PhysReleasePageMappingLock,
|
---|
| 3797 | pdmR3DevHlp_PhysReadGCVirt,
|
---|
| 3798 | pdmR3DevHlp_PhysWriteGCVirt,
|
---|
| 3799 | pdmR3DevHlp_PhysGCPtr2GCPhys,
|
---|
[12980] | 3800 | pdmR3DevHlp_MMHeapAlloc,
|
---|
| 3801 | pdmR3DevHlp_MMHeapAllocZ,
|
---|
| 3802 | pdmR3DevHlp_MMHeapFree,
|
---|
[26157] | 3803 | pdmR3DevHlp_VMState,
|
---|
| 3804 | pdmR3DevHlp_VMTeleportedAndNotFullyResumedYet,
|
---|
[12980] | 3805 | pdmR3DevHlp_VMSetError,
|
---|
| 3806 | pdmR3DevHlp_VMSetErrorV,
|
---|
| 3807 | pdmR3DevHlp_VMSetRuntimeError,
|
---|
| 3808 | pdmR3DevHlp_VMSetRuntimeErrorV,
|
---|
| 3809 | pdmR3DevHlp_DBGFStopV,
|
---|
| 3810 | pdmR3DevHlp_DBGFInfoRegister,
|
---|
[80154] | 3811 | pdmR3DevHlp_DBGFInfoRegisterArgv,
|
---|
[44691] | 3812 | pdmR3DevHlp_DBGFRegRegister,
|
---|
[37410] | 3813 | pdmR3DevHlp_DBGFTraceBuf,
|
---|
[12980] | 3814 | pdmR3DevHlp_STAMRegister,
|
---|
| 3815 | pdmR3DevHlp_STAMRegisterF,
|
---|
| 3816 | pdmR3DevHlp_STAMRegisterV,
|
---|
[26157] | 3817 | pdmR3DevHlp_PCIRegister,
|
---|
[32820] | 3818 | pdmR3DevHlp_PCIRegisterMsi,
|
---|
[26157] | 3819 | pdmR3DevHlp_PCIIORegionRegister,
|
---|
| 3820 | pdmR3DevHlp_PCISetConfigCallbacks,
|
---|
[44897] | 3821 | pdmR3DevHlp_PCIPhysRead,
|
---|
| 3822 | pdmR3DevHlp_PCIPhysWrite,
|
---|
[26157] | 3823 | pdmR3DevHlp_PCISetIrq,
|
---|
| 3824 | pdmR3DevHlp_PCISetIrqNoWait,
|
---|
| 3825 | pdmR3DevHlp_ISASetIrq,
|
---|
| 3826 | pdmR3DevHlp_ISASetIrqNoWait,
|
---|
[68594] | 3827 | pdmR3DevHlp_IoApicSendMsi,
|
---|
[26157] | 3828 | pdmR3DevHlp_DriverAttach,
|
---|
[59348] | 3829 | pdmR3DevHlp_DriverDetach,
|
---|
[26157] | 3830 | pdmR3DevHlp_QueueCreate,
|
---|
[12980] | 3831 | pdmR3DevHlp_CritSectInit,
|
---|
[37443] | 3832 | pdmR3DevHlp_CritSectGetNop,
|
---|
| 3833 | pdmR3DevHlp_CritSectGetNopR0,
|
---|
| 3834 | pdmR3DevHlp_CritSectGetNopRC,
|
---|
[37466] | 3835 | pdmR3DevHlp_SetDeviceCritSect,
|
---|
[26157] | 3836 | pdmR3DevHlp_ThreadCreate,
|
---|
[24730] | 3837 | pdmR3DevHlp_SetAsyncNotification,
|
---|
[24740] | 3838 | pdmR3DevHlp_AsyncNotificationCompleted,
|
---|
[26157] | 3839 | pdmR3DevHlp_RTCRegister,
|
---|
[12980] | 3840 | pdmR3DevHlp_PCIBusRegister,
|
---|
| 3841 | pdmR3DevHlp_PICRegister,
|
---|
| 3842 | pdmR3DevHlp_APICRegister,
|
---|
| 3843 | pdmR3DevHlp_IOAPICRegister,
|
---|
[25995] | 3844 | pdmR3DevHlp_HPETRegister,
|
---|
[35676] | 3845 | pdmR3DevHlp_PciRawRegister,
|
---|
[12980] | 3846 | pdmR3DevHlp_DMACRegister,
|
---|
| 3847 | pdmR3DevHlp_DMARegister,
|
---|
| 3848 | pdmR3DevHlp_DMAReadMemory,
|
---|
| 3849 | pdmR3DevHlp_DMAWriteMemory,
|
---|
| 3850 | pdmR3DevHlp_DMASetDREQ,
|
---|
| 3851 | pdmR3DevHlp_DMAGetChannelMode,
|
---|
| 3852 | pdmR3DevHlp_DMASchedule,
|
---|
| 3853 | pdmR3DevHlp_CMOSWrite,
|
---|
| 3854 | pdmR3DevHlp_CMOSRead,
|
---|
[26157] | 3855 | pdmR3DevHlp_AssertEMT,
|
---|
| 3856 | pdmR3DevHlp_AssertOther,
|
---|
[26159] | 3857 | pdmR3DevHlp_LdrGetRCInterfaceSymbols,
|
---|
| 3858 | pdmR3DevHlp_LdrGetR0InterfaceSymbols,
|
---|
[29521] | 3859 | pdmR3DevHlp_CallR0,
|
---|
[46788] | 3860 | pdmR3DevHlp_VMGetSuspendReason,
|
---|
| 3861 | pdmR3DevHlp_VMGetResumeReason,
|
---|
[77241] | 3862 | pdmR3DevHlp_PhysBulkGCPhys2CCPtr,
|
---|
| 3863 | pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly,
|
---|
| 3864 | pdmR3DevHlp_PhysBulkReleasePageMappingLocks,
|
---|
[77299] | 3865 | pdmR3DevHlp_MMIOExChangeRegionNo,
|
---|
[26157] | 3866 | 0,
|
---|
| 3867 | 0,
|
---|
| 3868 | 0,
|
---|
| 3869 | 0,
|
---|
| 3870 | 0,
|
---|
| 3871 | 0,
|
---|
[80154] | 3872 | 0,
|
---|
| 3873 | 0,
|
---|
| 3874 | 0,
|
---|
| 3875 | 0,
|
---|
[44351] | 3876 | pdmR3DevHlp_GetUVM,
|
---|
[26157] | 3877 | pdmR3DevHlp_GetVM,
|
---|
| 3878 | pdmR3DevHlp_GetVMCPU,
|
---|
[53797] | 3879 | pdmR3DevHlp_GetCurrentCpuId,
|
---|
[12980] | 3880 | pdmR3DevHlp_RegisterVMMDevHeap,
|
---|
[60404] | 3881 | pdmR3DevHlp_FirmwareRegister,
|
---|
[26157] | 3882 | pdmR3DevHlp_VMReset,
|
---|
| 3883 | pdmR3DevHlp_VMSuspend,
|
---|
[32189] | 3884 | pdmR3DevHlp_VMSuspendSaveAndPowerOff,
|
---|
[26157] | 3885 | pdmR3DevHlp_VMPowerOff,
|
---|
| 3886 | pdmR3DevHlp_A20IsEnabled,
|
---|
| 3887 | pdmR3DevHlp_A20Set,
|
---|
| 3888 | pdmR3DevHlp_GetCpuId,
|
---|
[33799] | 3889 | pdmR3DevHlp_TMTimeVirtGet,
|
---|
| 3890 | pdmR3DevHlp_TMTimeVirtGetFreq,
|
---|
| 3891 | pdmR3DevHlp_TMTimeVirtGetNano,
|
---|
[45645] | 3892 | pdmR3DevHlp_GetSupDrvSession,
|
---|
[68986] | 3893 | pdmR3DevHlp_QueryGenericUserObject,
|
---|
[26157] | 3894 | PDM_DEVHLPR3_VERSION /* the end */
|
---|
[12980] | 3895 | };
|
---|
[12807] | 3896 |
|
---|
| 3897 |
|
---|
| 3898 |
|
---|
[12980] | 3899 |
|
---|
[44351] | 3900 | /** @interface_method_impl{PDMDEVHLPR3,pfnGetUVM} */
|
---|
| 3901 | static DECLCALLBACK(PUVM) pdmR3DevHlp_Untrusted_GetUVM(PPDMDEVINS pDevIns)
|
---|
| 3902 | {
|
---|
| 3903 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 3904 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
| 3905 | return NULL;
|
---|
| 3906 | }
|
---|
| 3907 |
|
---|
| 3908 |
|
---|
[26152] | 3909 | /** @interface_method_impl{PDMDEVHLPR3,pfnGetVM} */
|
---|
[1] | 3910 | static DECLCALLBACK(PVM) pdmR3DevHlp_Untrusted_GetVM(PPDMDEVINS pDevIns)
|
---|
| 3911 | {
|
---|
| 3912 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 3913 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[1] | 3914 | return NULL;
|
---|
| 3915 | }
|
---|
| 3916 |
|
---|
| 3917 |
|
---|
[26157] | 3918 | /** @interface_method_impl{PDMDEVHLPR3,pfnGetVMCPU} */
|
---|
| 3919 | static DECLCALLBACK(PVMCPU) pdmR3DevHlp_Untrusted_GetVMCPU(PPDMDEVINS pDevIns)
|
---|
[1] | 3920 | {
|
---|
| 3921 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 3922 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[26157] | 3923 | return NULL;
|
---|
[1] | 3924 | }
|
---|
| 3925 |
|
---|
| 3926 |
|
---|
[53797] | 3927 | /** @interface_method_impl{PDMDEVHLPR3,pfnGetCurrentCpuId} */
|
---|
| 3928 | static DECLCALLBACK(VMCPUID) pdmR3DevHlp_Untrusted_GetCurrentCpuId(PPDMDEVINS pDevIns)
|
---|
| 3929 | {
|
---|
| 3930 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 3931 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
| 3932 | return NIL_VMCPUID;
|
---|
| 3933 | }
|
---|
| 3934 |
|
---|
| 3935 |
|
---|
[26157] | 3936 | /** @interface_method_impl{PDMDEVHLPR3,pfnRegisterVMMDevHeap} */
|
---|
[60407] | 3937 | static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_RegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys,
|
---|
| 3938 | RTR3PTR pvHeap, unsigned cbHeap)
|
---|
[1] | 3939 | {
|
---|
| 3940 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[60407] | 3941 | NOREF(GCPhys); NOREF(pvHeap); NOREF(cbHeap);
|
---|
[26165] | 3942 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[1] | 3943 | return VERR_ACCESS_DENIED;
|
---|
| 3944 | }
|
---|
| 3945 |
|
---|
| 3946 |
|
---|
[60404] | 3947 | /** @interface_method_impl{PDMDEVHLPR3,pfnFirmwareRegister} */
|
---|
[60407] | 3948 | static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_FirmwareRegister(PPDMDEVINS pDevIns, PCPDMFWREG pFwReg, PCPDMFWHLPR3 *ppFwHlp)
|
---|
[1] | 3949 | {
|
---|
| 3950 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[60407] | 3951 | NOREF(pFwReg); NOREF(ppFwHlp);
|
---|
[26165] | 3952 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[1] | 3953 | return VERR_ACCESS_DENIED;
|
---|
| 3954 | }
|
---|
| 3955 |
|
---|
| 3956 |
|
---|
[26157] | 3957 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMReset} */
|
---|
[60404] | 3958 | static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns, uint32_t fFlags)
|
---|
[1] | 3959 | {
|
---|
[60404] | 3960 | PDMDEV_ASSERT_DEVINS(pDevIns); NOREF(fFlags);
|
---|
[26165] | 3961 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[1] | 3962 | return VERR_ACCESS_DENIED;
|
---|
| 3963 | }
|
---|
| 3964 |
|
---|
[26001] | 3965 |
|
---|
[26157] | 3966 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMSuspend} */
|
---|
| 3967 | static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspend(PPDMDEVINS pDevIns)
|
---|
[25995] | 3968 | {
|
---|
| 3969 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 3970 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[25995] | 3971 | return VERR_ACCESS_DENIED;
|
---|
| 3972 | }
|
---|
[1] | 3973 |
|
---|
[26001] | 3974 |
|
---|
[32189] | 3975 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMSuspendSaveAndPowerOff} */
|
---|
| 3976 | static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMSuspendSaveAndPowerOff(PPDMDEVINS pDevIns)
|
---|
| 3977 | {
|
---|
| 3978 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 3979 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
| 3980 | return VERR_ACCESS_DENIED;
|
---|
| 3981 | }
|
---|
| 3982 |
|
---|
| 3983 |
|
---|
[26157] | 3984 | /** @interface_method_impl{PDMDEVHLPR3,pfnVMPowerOff} */
|
---|
| 3985 | static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMPowerOff(PPDMDEVINS pDevIns)
|
---|
[1] | 3986 | {
|
---|
| 3987 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 3988 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[1] | 3989 | return VERR_ACCESS_DENIED;
|
---|
| 3990 | }
|
---|
| 3991 |
|
---|
| 3992 |
|
---|
[26152] | 3993 | /** @interface_method_impl{PDMDEVHLPR3,pfnA20IsEnabled} */
|
---|
[1] | 3994 | static DECLCALLBACK(bool) pdmR3DevHlp_Untrusted_A20IsEnabled(PPDMDEVINS pDevIns)
|
---|
| 3995 | {
|
---|
| 3996 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 3997 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[1] | 3998 | return false;
|
---|
| 3999 | }
|
---|
| 4000 |
|
---|
| 4001 |
|
---|
[26152] | 4002 | /** @interface_method_impl{PDMDEVHLPR3,pfnA20Set} */
|
---|
[1] | 4003 | static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_A20Set(PPDMDEVINS pDevIns, bool fEnable)
|
---|
| 4004 | {
|
---|
| 4005 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[26165] | 4006 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[1] | 4007 | NOREF(fEnable);
|
---|
| 4008 | }
|
---|
| 4009 |
|
---|
| 4010 |
|
---|
[26152] | 4011 | /** @interface_method_impl{PDMDEVHLPR3,pfnGetCpuId} */
|
---|
[12653] | 4012 | static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,
|
---|
| 4013 | uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
|
---|
[2633] | 4014 | {
|
---|
| 4015 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
[39078] | 4016 | NOREF(iLeaf); NOREF(pEax); NOREF(pEbx); NOREF(pEcx); NOREF(pEdx);
|
---|
[26165] | 4017 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
[2633] | 4018 | }
|
---|
[1] | 4019 |
|
---|
| 4020 |
|
---|
[45645] | 4021 | /** @interface_method_impl{PDMDEVHLPR3,pfnGetSupDrvSession} */
|
---|
| 4022 | static DECLCALLBACK(PSUPDRVSESSION) pdmR3DevHlp_Untrusted_GetSupDrvSession(PPDMDEVINS pDevIns)
|
---|
| 4023 | {
|
---|
| 4024 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 4025 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
|
---|
| 4026 | return (PSUPDRVSESSION)0;
|
---|
| 4027 | }
|
---|
| 4028 |
|
---|
| 4029 |
|
---|
[68986] | 4030 | /** @interface_method_impl{PDMDEVHLPR3,pfnQueryGenericUserObject} */
|
---|
| 4031 | static DECLCALLBACK(void *) pdmR3DevHlp_Untrusted_QueryGenericUserObject(PPDMDEVINS pDevIns, PCRTUUID pUuid)
|
---|
| 4032 | {
|
---|
| 4033 | PDMDEV_ASSERT_DEVINS(pDevIns);
|
---|
| 4034 | AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d %RTuuid\n",
|
---|
| 4035 | pDevIns->pReg->szName, pDevIns->iInstance, pUuid));
|
---|
| 4036 | return NULL;
|
---|
| 4037 | }
|
---|
| 4038 |
|
---|
| 4039 |
|
---|
[12980] | 4040 | /**
|
---|
| 4041 | * The device helper structure for non-trusted devices.
|
---|
| 4042 | */
|
---|
| 4043 | const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted =
|
---|
[1] | 4044 | {
|
---|
[26157] | 4045 | PDM_DEVHLPR3_VERSION,
|
---|
[12980] | 4046 | pdmR3DevHlp_IOPortRegister,
|
---|
[26157] | 4047 | pdmR3DevHlp_IOPortRegisterRC,
|
---|
[12980] | 4048 | pdmR3DevHlp_IOPortRegisterR0,
|
---|
| 4049 | pdmR3DevHlp_IOPortDeregister,
|
---|
| 4050 | pdmR3DevHlp_MMIORegister,
|
---|
[26157] | 4051 | pdmR3DevHlp_MMIORegisterRC,
|
---|
[12980] | 4052 | pdmR3DevHlp_MMIORegisterR0,
|
---|
| 4053 | pdmR3DevHlp_MMIODeregister,
|
---|
[26157] | 4054 | pdmR3DevHlp_MMIO2Register,
|
---|
[64373] | 4055 | pdmR3DevHlp_MMIOExPreRegister,
|
---|
[64115] | 4056 | pdmR3DevHlp_MMIOExDeregister,
|
---|
| 4057 | pdmR3DevHlp_MMIOExMap,
|
---|
| 4058 | pdmR3DevHlp_MMIOExUnmap,
|
---|
[68594] | 4059 | pdmR3DevHlp_MMIOExReduce,
|
---|
[26157] | 4060 | pdmR3DevHlp_MMHyperMapMMIO2,
|
---|
| 4061 | pdmR3DevHlp_MMIO2MapKernel,
|
---|
[12980] | 4062 | pdmR3DevHlp_ROMRegister,
|
---|
[26157] | 4063 | pdmR3DevHlp_ROMProtectShadow,
|
---|
[12980] | 4064 | pdmR3DevHlp_SSMRegister,
|
---|
| 4065 | pdmR3DevHlp_TMTimerCreate,
|
---|
[26158] | 4066 | pdmR3DevHlp_TMUtcNow,
|
---|
[26157] | 4067 | pdmR3DevHlp_PhysRead,
|
---|
| 4068 | pdmR3DevHlp_PhysWrite,
|
---|
| 4069 | pdmR3DevHlp_PhysGCPhys2CCPtr,
|
---|
| 4070 | pdmR3DevHlp_PhysGCPhys2CCPtrReadOnly,
|
---|
| 4071 | pdmR3DevHlp_PhysReleasePageMappingLock,
|
---|
| 4072 | pdmR3DevHlp_PhysReadGCVirt,
|
---|
| 4073 | pdmR3DevHlp_PhysWriteGCVirt,
|
---|
| 4074 | pdmR3DevHlp_PhysGCPtr2GCPhys,
|
---|
[12980] | 4075 | pdmR3DevHlp_MMHeapAlloc,
|
---|
| 4076 | pdmR3DevHlp_MMHeapAllocZ,
|
---|
| 4077 | pdmR3DevHlp_MMHeapFree,
|
---|
[26157] | 4078 | pdmR3DevHlp_VMState,
|
---|
| 4079 | pdmR3DevHlp_VMTeleportedAndNotFullyResumedYet,
|
---|
[12980] | 4080 | pdmR3DevHlp_VMSetError,
|
---|
| 4081 | pdmR3DevHlp_VMSetErrorV,
|
---|
| 4082 | pdmR3DevHlp_VMSetRuntimeError,
|
---|
| 4083 | pdmR3DevHlp_VMSetRuntimeErrorV,
|
---|
| 4084 | pdmR3DevHlp_DBGFStopV,
|
---|
| 4085 | pdmR3DevHlp_DBGFInfoRegister,
|
---|
[80154] | 4086 | pdmR3DevHlp_DBGFInfoRegisterArgv,
|
---|
[44691] | 4087 | pdmR3DevHlp_DBGFRegRegister,
|
---|
[37410] | 4088 | pdmR3DevHlp_DBGFTraceBuf,
|
---|
[12980] | 4089 | pdmR3DevHlp_STAMRegister,
|
---|
| 4090 | pdmR3DevHlp_STAMRegisterF,
|
---|
| 4091 | pdmR3DevHlp_STAMRegisterV,
|
---|
[26157] | 4092 | pdmR3DevHlp_PCIRegister,
|
---|
[32820] | 4093 | pdmR3DevHlp_PCIRegisterMsi,
|
---|
[26157] | 4094 | pdmR3DevHlp_PCIIORegionRegister,
|
---|
| 4095 | pdmR3DevHlp_PCISetConfigCallbacks,
|
---|
[44897] | 4096 | pdmR3DevHlp_PCIPhysRead,
|
---|
| 4097 | pdmR3DevHlp_PCIPhysWrite,
|
---|
[26157] | 4098 | pdmR3DevHlp_PCISetIrq,
|
---|
| 4099 | pdmR3DevHlp_PCISetIrqNoWait,
|
---|
| 4100 | pdmR3DevHlp_ISASetIrq,
|
---|
| 4101 | pdmR3DevHlp_ISASetIrqNoWait,
|
---|
[68594] | 4102 | pdmR3DevHlp_IoApicSendMsi,
|
---|
[26157] | 4103 | pdmR3DevHlp_DriverAttach,
|
---|
[59348] | 4104 | pdmR3DevHlp_DriverDetach,
|
---|
[26157] | 4105 | pdmR3DevHlp_QueueCreate,
|
---|
[12980] | 4106 | pdmR3DevHlp_CritSectInit,
|
---|
[37443] | 4107 | pdmR3DevHlp_CritSectGetNop,
|
---|
| 4108 | pdmR3DevHlp_CritSectGetNopR0,
|
---|
| 4109 | pdmR3DevHlp_CritSectGetNopRC,
|
---|
[37466] | 4110 | pdmR3DevHlp_SetDeviceCritSect,
|
---|
[26157] | 4111 | pdmR3DevHlp_ThreadCreate,
|
---|
[24730] | 4112 | pdmR3DevHlp_SetAsyncNotification,
|
---|
[24740] | 4113 | pdmR3DevHlp_AsyncNotificationCompleted,
|
---|
[26157] | 4114 | pdmR3DevHlp_RTCRegister,
|
---|
| 4115 | pdmR3DevHlp_PCIBusRegister,
|
---|
| 4116 | pdmR3DevHlp_PICRegister,
|
---|
| 4117 | pdmR3DevHlp_APICRegister,
|
---|
| 4118 | pdmR3DevHlp_IOAPICRegister,
|
---|
| 4119 | pdmR3DevHlp_HPETRegister,
|
---|
[35676] | 4120 | pdmR3DevHlp_PciRawRegister,
|
---|
[26157] | 4121 | pdmR3DevHlp_DMACRegister,
|
---|
| 4122 | pdmR3DevHlp_DMARegister,
|
---|
| 4123 | pdmR3DevHlp_DMAReadMemory,
|
---|
| 4124 | pdmR3DevHlp_DMAWriteMemory,
|
---|
| 4125 | pdmR3DevHlp_DMASetDREQ,
|
---|
| 4126 | pdmR3DevHlp_DMAGetChannelMode,
|
---|
| 4127 | pdmR3DevHlp_DMASchedule,
|
---|
| 4128 | pdmR3DevHlp_CMOSWrite,
|
---|
| 4129 | pdmR3DevHlp_CMOSRead,
|
---|
| 4130 | pdmR3DevHlp_AssertEMT,
|
---|
| 4131 | pdmR3DevHlp_AssertOther,
|
---|
[26159] | 4132 | pdmR3DevHlp_LdrGetRCInterfaceSymbols,
|
---|
| 4133 | pdmR3DevHlp_LdrGetR0InterfaceSymbols,
|
---|
[29521] | 4134 | pdmR3DevHlp_CallR0,
|
---|
[46788] | 4135 | pdmR3DevHlp_VMGetSuspendReason,
|
---|
| 4136 | pdmR3DevHlp_VMGetResumeReason,
|
---|
[77241] | 4137 | pdmR3DevHlp_PhysBulkGCPhys2CCPtr,
|
---|
| 4138 | pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly,
|
---|
| 4139 | pdmR3DevHlp_PhysBulkReleasePageMappingLocks,
|
---|
[77299] | 4140 | pdmR3DevHlp_MMIOExChangeRegionNo,
|
---|
[12980] | 4141 | 0,
|
---|
| 4142 | 0,
|
---|
| 4143 | 0,
|
---|
| 4144 | 0,
|
---|
| 4145 | 0,
|
---|
| 4146 | 0,
|
---|
[80154] | 4147 | 0,
|
---|
| 4148 | 0,
|
---|
| 4149 | 0,
|
---|
| 4150 | 0,
|
---|
[44351] | 4151 | pdmR3DevHlp_Untrusted_GetUVM,
|
---|
[12980] | 4152 | pdmR3DevHlp_Untrusted_GetVM,
|
---|
[26157] | 4153 | pdmR3DevHlp_Untrusted_GetVMCPU,
|
---|
[53797] | 4154 | pdmR3DevHlp_Untrusted_GetCurrentCpuId,
|
---|
[26157] | 4155 | pdmR3DevHlp_Untrusted_RegisterVMMDevHeap,
|
---|
[60404] | 4156 | pdmR3DevHlp_Untrusted_FirmwareRegister,
|
---|
[12980] | 4157 | pdmR3DevHlp_Untrusted_VMReset,
|
---|
| 4158 | pdmR3DevHlp_Untrusted_VMSuspend,
|
---|
[32189] | 4159 | pdmR3DevHlp_Untrusted_VMSuspendSaveAndPowerOff,
|
---|
[12980] | 4160 | pdmR3DevHlp_Untrusted_VMPowerOff,
|
---|
[26157] | 4161 | pdmR3DevHlp_Untrusted_A20IsEnabled,
|
---|
| 4162 | pdmR3DevHlp_Untrusted_A20Set,
|
---|
[12980] | 4163 | pdmR3DevHlp_Untrusted_GetCpuId,
|
---|
[33799] | 4164 | pdmR3DevHlp_TMTimeVirtGet,
|
---|
| 4165 | pdmR3DevHlp_TMTimeVirtGetFreq,
|
---|
| 4166 | pdmR3DevHlp_TMTimeVirtGetNano,
|
---|
[45645] | 4167 | pdmR3DevHlp_Untrusted_GetSupDrvSession,
|
---|
[68986] | 4168 | pdmR3DevHlp_Untrusted_QueryGenericUserObject,
|
---|
[26157] | 4169 | PDM_DEVHLPR3_VERSION /* the end */
|
---|
[12980] | 4170 | };
|
---|
[1] | 4171 |
|
---|
| 4172 |
|
---|
| 4173 |
|
---|
| 4174 | /**
|
---|
[12980] | 4175 | * Queue consumer callback for internal component.
|
---|
[1] | 4176 | *
|
---|
[12980] | 4177 | * @returns Success indicator.
|
---|
| 4178 | * If false the item will not be removed and the flushing will stop.
|
---|
[58122] | 4179 | * @param pVM The cross context VM structure.
|
---|
[12980] | 4180 | * @param pItem The item to consume. Upon return this item will be freed.
|
---|
[1] | 4181 | */
|
---|
[12980] | 4182 | DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem)
|
---|
[1] | 4183 | {
|
---|
[12980] | 4184 | PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)pItem;
|
---|
[12984] | 4185 | LogFlow(("pdmR3DevHlpQueueConsumer: enmOp=%d pDevIns=%p\n", pTask->enmOp, pTask->pDevInsR3));
|
---|
[12980] | 4186 | switch (pTask->enmOp)
|
---|
[1] | 4187 | {
|
---|
[12980] | 4188 | case PDMDEVHLPTASKOP_ISA_SET_IRQ:
|
---|
[64373] | 4189 | PDMIsaSetIrq(pVM, pTask->u.IsaSetIRQ.iIrq, pTask->u.IsaSetIRQ.iLevel, pTask->u.IsaSetIRQ.uTagSrc);
|
---|
[12980] | 4190 | break;
|
---|
[1] | 4191 |
|
---|
[12980] | 4192 | case PDMDEVHLPTASKOP_PCI_SET_IRQ:
|
---|
[40907] | 4193 | {
|
---|
| 4194 | /* Same as pdmR3DevHlp_PCISetIrq, except we've got a tag already. */
|
---|
[64387] | 4195 | PPDMPCIDEV pPciDev = pTask->u.PciSetIRQ.pPciDevR3;
|
---|
[40907] | 4196 | if (pPciDev)
|
---|
| 4197 | {
|
---|
[64373] | 4198 | PPDMPCIBUS pBus = pPciDev->Int.s.pPdmBusR3;
|
---|
[40907] | 4199 | Assert(pBus);
|
---|
| 4200 |
|
---|
| 4201 | pdmLock(pVM);
|
---|
[64373] | 4202 | pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, pTask->u.PciSetIRQ.iIrq,
|
---|
| 4203 | pTask->u.PciSetIRQ.iLevel, pTask->u.PciSetIRQ.uTagSrc);
|
---|
[40907] | 4204 | pdmUnlock(pVM);
|
---|
| 4205 | }
|
---|
| 4206 | else
|
---|
| 4207 | AssertReleaseMsgFailed(("No PCI device registered!\n"));
|
---|
[12980] | 4208 | break;
|
---|
[40907] | 4209 | }
|
---|
[1] | 4210 |
|
---|
[12980] | 4211 | case PDMDEVHLPTASKOP_IOAPIC_SET_IRQ:
|
---|
[64373] | 4212 | PDMIoApicSetIrq(pVM, pTask->u.IoApicSetIRQ.iIrq, pTask->u.IoApicSetIRQ.iLevel, pTask->u.IoApicSetIRQ.uTagSrc);
|
---|
[12980] | 4213 | break;
|
---|
[1] | 4214 |
|
---|
[12980] | 4215 | default:
|
---|
| 4216 | AssertReleaseMsgFailed(("Invalid operation %d\n", pTask->enmOp));
|
---|
| 4217 | break;
|
---|
[1] | 4218 | }
|
---|
[12980] | 4219 | return true;
|
---|
[1] | 4220 | }
|
---|
| 4221 |
|
---|
[12980] | 4222 | /** @} */
|
---|
[35738] | 4223 |
|
---|