/** * Register a access handler for a virtual range. * * @returns VBox status code. * @param pVM Pointer to the VM. * @param enmType Handler type. Any of the PGMVIRTHANDLERTYPE_* enums. * @param GCPtr Start address. * @param GCPtrLast Last address (inclusive). * @param pfnInvalidateR3 The R3 invalidate callback (can be 0) * @param pfnHandlerR3 The R3 handler. * @param pszHandlerRC The RC handler symbol name. * @param pszModRC The RC handler module. * @param pszDesc Pointer to description string. This must not be freed. */ VMMR3DECL(int) PGMR3HandlerVirtualRegister(PVM pVM, PGMVIRTHANDLERTYPE enmType, RTGCPTR GCPtr, RTGCPTR GCPtrLast, PFNPGMR3VIRTINVALIDATE pfnInvalidateR3, PFNPGMR3VIRTHANDLER pfnHandlerR3, const char *pszHandlerRC, const char *pszModRC, const char *pszDesc) { LogFlow(("PGMR3HandlerVirtualRegisterEx: enmType=%d GCPtr=%RGv GCPtrLast=%RGv pszHandlerRC=%p:{%s} pszModRC=%p:{%s} pszDesc=%s\n", enmType, GCPtr, GCPtrLast, pszHandlerRC, pszHandlerRC, pszModRC, pszModRC, pszDesc)); /* Not supported/relevant for VT-x and AMD-V. */ if (HWACCMIsEnabled(pVM)) return VERR_NOT_IMPLEMENTED; /* * Validate input. */ if (!pszModRC) pszModRC = VMMGC_MAIN_MODULE_NAME; if (!pszModRC || !*pszModRC || !pszHandlerRC || !*pszHandlerRC) { AssertMsgFailed(("pfnHandlerGC or/and pszModRC is missing\n")); return VERR_INVALID_PARAMETER; } /* * Resolve the GC handler. */ RTRCPTR pfnHandlerRC; int rc = PDMR3LdrGetSymbolRCLazy(pVM, pszModRC, NULL /*pszSearchPath*/, pszHandlerRC, &pfnHandlerRC); if (RT_SUCCESS(rc)) return PGMR3HandlerVirtualRegisterEx(pVM, enmType, GCPtr, GCPtrLast, pfnInvalidateR3, pfnHandlerR3, pfnHandlerRC, pszDesc); AssertMsgFailed(("Failed to resolve %s.%s, rc=%Rrc.\n", pszModRC, pszHandlerRC, rc)); return rc; }
/** * Register a access handler for a physical range. * * @returns VBox status code. * @param pVM Pointer to the VM. * @param enmType Handler type. Any of the PGMPHYSHANDLERTYPE_PHYSICAL* enums. * @param GCPhys Start physical address. * @param GCPhysLast Last physical address. (inclusive) * @param pfnHandlerR3 The R3 handler. * @param pvUserR3 User argument to the R3 handler. * @param pszModR0 The R0 handler module. NULL means the default R0 module. * @param pszHandlerR0 The R0 handler symbol name. * @param pvUserR0 User argument to the R0 handler. * @param pszModRC The RC handler module. NULL means the default RC * module. * @param pszHandlerRC The RC handler symbol name. * @param pvUserRC User argument to the RC handler. Values less than * 0x10000 will not be relocated. * @param pszDesc Pointer to description string. This must not be freed. */ VMMR3DECL(int) PGMR3HandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast, PFNPGMR3PHYSHANDLER pfnHandlerR3, void *pvUserR3, const char *pszModR0, const char *pszHandlerR0, RTR0PTR pvUserR0, const char *pszModRC, const char *pszHandlerRC, RTRCPTR pvUserRC, const char *pszDesc) { LogFlow(("PGMR3HandlerPhysicalRegister: enmType=%d GCPhys=%RGp GCPhysLast=%RGp pfnHandlerR3=%RHv pvUserHC=%RHv pszModR0=%s pszHandlerR0=%s pvUserR0=%RHv pszModRC=%s pszHandlerRC=%s pvUser=%RRv pszDesc=%s\n", enmType, GCPhys, GCPhysLast, pfnHandlerR3, pvUserR3, pszModR0, pszHandlerR0, pvUserR0, pszHandlerRC, pszModRC, pvUserRC, pszDesc)); /* * Validate input. */ if (!pszModRC) pszModRC = VMMGC_MAIN_MODULE_NAME; if (!pszModR0) pszModR0 = VMMR0_MAIN_MODULE_NAME; if (!pszHandlerR0) pszHandlerR0 = "pgmPhysHandlerRedirectToHC"; if (!pszHandlerRC) pszHandlerRC = "pgmPhysHandlerRedirectToHC"; AssertPtrReturn(pfnHandlerR3, VERR_INVALID_POINTER); AssertPtrReturn(pszHandlerR0, VERR_INVALID_POINTER); AssertPtrReturn(pszHandlerRC, VERR_INVALID_POINTER); /* * Resolve the R0 handler. */ R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnHandlerR0 = NIL_RTR0PTR; int rc = VINF_SUCCESS; rc = PDMR3LdrGetSymbolR0Lazy(pVM, pszModR0, NULL /*pszSearchPath*/, pszHandlerR0, &pfnHandlerR0); if (RT_SUCCESS(rc)) { /* * Resolve the GC handler. */ RTRCPTR pfnHandlerRC = NIL_RTRCPTR; if (!HMIsEnabled(pVM)) rc = PDMR3LdrGetSymbolRCLazy(pVM, pszModRC, NULL /*pszSearchPath*/, pszHandlerRC, &pfnHandlerRC); if (RT_SUCCESS(rc)) return PGMHandlerPhysicalRegisterEx(pVM, enmType, GCPhys, GCPhysLast, pfnHandlerR3, pvUserR3, pfnHandlerR0, pvUserR0, pfnHandlerRC, pvUserRC, pszDesc); AssertMsgFailed(("Failed to resolve %s.%s, rc=%Rrc.\n", pszModRC, pszHandlerRC, rc)); } else AssertMsgFailed(("Failed to resolve %s.%s, rc=%Rrc.\n", pszModR0, pszHandlerR0, rc)); return rc; }