diff options
author | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2023-05-11 09:59:52 +0000 |
---|---|---|
committer | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2023-05-11 09:59:52 +0000 |
commit | ca4d05988f1eb2e2e7d56789092d05ec9eec4481 (patch) | |
tree | 7cabdb11ce79210f2ae31cdd9b005a7bb573ecd6 | |
parent | a7b416cb0a29955b896e9babb46dcb69a2c34754 (diff) | |
download | VirtualBox-svn-ca4d05988f1eb2e2e7d56789092d05ec9eec4481.tar.gz |
VMM: Add full support for reading/writing I/O ports on ARMv8 in order to emulate PIO accesses to PCI devices through a dedicated MMIO region by the host to PCI bridge, bugref:10445
git-svn-id: https://www.virtualbox.org/svn/vbox/trunk@99743 cfe28804-0f27-0410-a406-dd0f0b0b656f
-rw-r--r-- | include/VBox/vmm/pdmdev.h | 42 | ||||
-rw-r--r-- | src/VBox/VMM/Makefile.kmk | 1 | ||||
-rw-r--r-- | src/VBox/VMM/VMMR3/PDMDevHlp.cpp | 56 |
3 files changed, 63 insertions, 36 deletions
diff --git a/include/VBox/vmm/pdmdev.h b/include/VBox/vmm/pdmdev.h index f895eb86f5c..8165d322876 100644 --- a/include/VBox/vmm/pdmdev.h +++ b/include/VBox/vmm/pdmdev.h @@ -2429,7 +2429,7 @@ typedef const PDMRTCHLP *PCPDMRTCHLP; /** @} */ /** Current PDMDEVHLPR3 version number. */ -#define PDM_DEVHLPR3_VERSION PDM_VERSION_MAKE_PP(0xffe7, 65, 0) +#define PDM_DEVHLPR3_VERSION PDM_VERSION_MAKE_PP(0xffe7, 66, 0) /** * PDM Device API. @@ -2515,6 +2515,26 @@ typedef struct PDMDEVHLPR3 DECLR3CALLBACKMEMBER(uint32_t, pfnIoPortGetMappingAddress,(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts)); /** + * Reads from an I/O port register. + * + * @returns Strict VBox status code. Informational status codes other than the one documented + * here are to be treated as internal failure. Use IOM_SUCCESS() to check for success. + * @retval VINF_SUCCESS Success. + * @retval VINF_EM_FIRST-VINF_EM_LAST Success with some exceptions (see IOM_SUCCESS()), the + * status code must be passed on to EM. + * + * @param pDevIns The device instance to register the ports with. + * @param Port The port to write to. + * @param u32Value The value to write. + * @param cbValue The size of the register to read in bytes. 1, 2 or 4 bytes. + * + * @thread EMT + * + * @note This is required for the ARM platform in order to emulate PIO accesses through a dedicated MMIO region. + */ + DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnIoPortRead,(PPDMDEVINS pDevIns, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue)); + + /** * Writes to an I/O port register. * * @returns Strict VBox status code. Informational status codes other than the one documented @@ -2529,8 +2549,8 @@ typedef struct PDMDEVHLPR3 * @param cbValue The size of the register to read in bytes. 1, 2 or 4 bytes. * * @thread EMT - * @todo r=aeichner This is only used by DevPCI.cpp to write the ELCR of the PIC. This shouldn't be done that way - * and removed again as soon as possible (no time right now)... + * + * @note This is required for the ARM platform in order to emulate PIO accesses through a dedicated MMIO region. */ DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnIoPortWrite,(PPDMDEVINS pDevIns, RTIOPORT Port, uint32_t u32Value, size_t cbValue)); /** @} */ @@ -6637,6 +6657,22 @@ DECLINLINE(uint32_t) PDMDevHlpIoPortGetMappingAddress(PPDMDEVINS pDevIns, IOMIOP return pDevIns->pHlpR3->pfnIoPortGetMappingAddress(pDevIns, hIoPorts); } +/** + * @copydoc PDMDEVHLPR3::pfnIoPortRead + */ +DECLINLINE(VBOXSTRICTRC) PDMDevHlpIoPortRead(PPDMDEVINS pDevIns, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue) +{ + return pDevIns->pHlpR3->pfnIoPortRead(pDevIns, Port, pu32Value, cbValue); +} + +/** + * @copydoc PDMDEVHLPR3::pfnIoPortWrite + */ +DECLINLINE(VBOXSTRICTRC) PDMDevHlpIoPortWrite(PPDMDEVINS pDevIns, RTIOPORT Port, uint32_t u32Value, size_t cbValue) +{ + return pDevIns->pHlpR3->pfnIoPortWrite(pDevIns, Port, u32Value, cbValue); +} + #endif /* IN_RING3 */ #if !defined(IN_RING3) || defined(DOXYGEN_RUNNING) diff --git a/src/VBox/VMM/Makefile.kmk b/src/VBox/VMM/Makefile.kmk index ae348d9ad31..8e2c17a70c9 100644 --- a/src/VBox/VMM/Makefile.kmk +++ b/src/VBox/VMM/Makefile.kmk @@ -378,6 +378,7 @@ ifdef VBOX_WITH_VIRT_ARMV8 VMMR3/GIM.cpp \ VMMR3/IEMR3.cpp \ VMMR3/IOM.cpp \ + VMMR3/IOMR3IoPort.cpp \ VMMR3/IOMR3Mmio.cpp \ VMMR3/GMM.cpp \ VMMR3/GVMMR3.cpp \ diff --git a/src/VBox/VMM/VMMR3/PDMDevHlp.cpp b/src/VBox/VMM/VMMR3/PDMDevHlp.cpp index 864688c35a3..d11f9d1ca77 100644 --- a/src/VBox/VMM/VMMR3/PDMDevHlp.cpp +++ b/src/VBox/VMM/VMMR3/PDMDevHlp.cpp @@ -89,13 +89,8 @@ static DECLCALLBACK(int) pdmR3DevHlp_IoPortCreateEx(PPDMDEVINS pDevIns, RTIOPORT VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT); VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE); -#if defined(VBOX_VMM_TARGET_ARMV8) - int rc = VERR_NOT_SUPPORTED; - AssertReleaseFailed(); -#else int rc = IOMR3IoPortCreate(pVM, pDevIns, cPorts, fFlags, pPciDev, iPciRegion, pfnOut, pfnIn, pfnOutStr, pfnInStr, pvUser, pszDesc, paExtDescs, phIoPorts); -#endif LogFlow(("pdmR3DevHlp_IoPortCreateEx: caller='%s'/%d: returns %Rrc (*phIoPorts=%#x)\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *phIoPorts)); @@ -111,12 +106,7 @@ static DECLCALLBACK(int) pdmR3DevHlp_IoPortMap(PPDMDEVINS pDevIns, IOMIOPORTHAND PVM pVM = pDevIns->Internal.s.pVMR3; VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT); -#if defined(VBOX_VMM_TARGET_ARMV8) - int rc = VERR_NOT_SUPPORTED; - AssertReleaseFailed(); -#else int rc = IOMR3IoPortMap(pVM, pDevIns, hIoPorts, Port); -#endif LogFlow(("pdmR3DevHlp_IoPortMap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc)); return rc; @@ -131,12 +121,7 @@ static DECLCALLBACK(int) pdmR3DevHlp_IoPortUnmap(PPDMDEVINS pDevIns, IOMIOPORTHA PVM pVM = pDevIns->Internal.s.pVMR3; VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT); -#if defined(VBOX_VMM_TARGET_ARMV8) - int rc = VERR_NOT_SUPPORTED; - AssertReleaseFailed(); -#else int rc = IOMR3IoPortUnmap(pVM, pDevIns, hIoPorts); -#endif LogFlow(("pdmR3DevHlp_IoPortMap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc)); return rc; @@ -149,18 +134,32 @@ static DECLCALLBACK(uint32_t) pdmR3DevHlp_IoPortGetMappingAddress(PPDMDEVINS pDe PDMDEV_ASSERT_DEVINS(pDevIns); LogFlow(("pdmR3DevHlp_IoPortGetMappingAddress: caller='%s'/%d: hIoPorts=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, hIoPorts)); -#if defined(VBOX_VMM_TARGET_ARMV8) - uint32_t uAddress = UINT32_MAX; - AssertReleaseFailed(); -#else uint32_t uAddress = IOMR3IoPortGetMappingAddress(pDevIns->Internal.s.pVMR3, pDevIns, hIoPorts); -#endif LogFlow(("pdmR3DevHlp_IoPortGetMappingAddress: caller='%s'/%d: returns %#RX32\n", pDevIns->pReg->szName, pDevIns->iInstance, uAddress)); return uAddress; } +/** @interface_method_impl{PDMDEVHLPR3,pfnIoPortRead} */ +static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlp_IoPortRead(PPDMDEVINS pDevIns, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue) +{ + PDMDEV_ASSERT_DEVINS(pDevIns); + LogFlow(("pdmR3DevHlp_IoPortRead: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance)); + PVM pVM = pDevIns->Internal.s.pVMR3; + VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT); + + PVMCPU pVCpu = VMMGetCpu(pVM); + AssertPtrReturn(pVCpu, VERR_ACCESS_DENIED); + + VBOXSTRICTRC rcStrict = IOMIOPortRead(pVM, pVCpu, Port, pu32Value, cbValue); + + LogFlow(("pdmR3DevHlp_IoPortRead: caller='%s'/%d: returns %Rrc\n", + pDevIns->pReg->szName, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict))); + return rcStrict; +} + + /** @interface_method_impl{PDMDEVHLPR3,pfnIoPortWrite} */ static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlp_IoPortWrite(PPDMDEVINS pDevIns, RTIOPORT Port, uint32_t u32Value, size_t cbValue) { @@ -169,16 +168,10 @@ static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlp_IoPortWrite(PPDMDEVINS pDevIns, RT PVM pVM = pDevIns->Internal.s.pVMR3; VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT); -#if defined(VBOX_VMM_TARGET_ARMV8) - RT_NOREF(Port, u32Value, cbValue); - VBOXSTRICTRC rcStrict = VERR_NOT_SUPPORTED; - AssertReleaseFailed(); -#else PVMCPU pVCpu = VMMGetCpu(pVM); AssertPtrReturn(pVCpu, VERR_ACCESS_DENIED); VBOXSTRICTRC rcStrict = IOMIOPortWrite(pVM, pVCpu, Port, u32Value, cbValue); -#endif LogFlow(("pdmR3DevHlp_IoPortWrite: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict))); @@ -2119,14 +2112,8 @@ static DECLCALLBACK(int) pdmR3DevHlp_PCIIORegionRegister(PPDMDEVINS pDevIns, PPD break; case PDMPCIDEV_IORGN_F_IOPORT_HANDLE: AssertReturn(enmType == PCI_ADDRESS_SPACE_IO, VERR_INVALID_FLAGS); -#if defined(VBOX_VMM_TARGET_ARMV8) - rc = VERR_NOT_SUPPORTED; - AssertReleaseFailed(); - AssertRCReturn(rc, rc); -#else rc = IOMR3IoPortValidateHandle(pVM, pDevIns, (IOMIOPORTHANDLE)hHandle); AssertRCReturn(rc, rc); -#endif break; case PDMPCIDEV_IORGN_F_MMIO_HANDLE: AssertReturn( (enmType & ~PCI_ADDRESS_SPACE_BAR64) == PCI_ADDRESS_SPACE_MEM @@ -4872,6 +4859,7 @@ const PDMDEVHLPR3 g_pdmR3DevHlpTrusted = pdmR3DevHlp_IoPortMap, pdmR3DevHlp_IoPortUnmap, pdmR3DevHlp_IoPortGetMappingAddress, + pdmR3DevHlp_IoPortRead, pdmR3DevHlp_IoPortWrite, pdmR3DevHlp_MmioCreateEx, pdmR3DevHlp_MmioMap, @@ -5269,7 +5257,8 @@ const PDMDEVHLPR3 g_pdmR3DevHlpTracing = pdmR3DevHlpTracing_IoPortMap, pdmR3DevHlpTracing_IoPortUnmap, pdmR3DevHlp_IoPortGetMappingAddress, - pdmR3DevHlp_IoPortWrite, + pdmR3DevHlp_IoPortRead, /** @todo Needs tracing variants for ARM now. */ + pdmR3DevHlp_IoPortWrite, /** @todo Needs tracing variants for ARM now. */ pdmR3DevHlpTracing_MmioCreateEx, pdmR3DevHlpTracing_MmioMap, pdmR3DevHlpTracing_MmioUnmap, @@ -5986,6 +5975,7 @@ const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted = pdmR3DevHlp_IoPortMap, pdmR3DevHlp_IoPortUnmap, pdmR3DevHlp_IoPortGetMappingAddress, + pdmR3DevHlp_IoPortRead, pdmR3DevHlp_IoPortWrite, pdmR3DevHlp_MmioCreateEx, pdmR3DevHlp_MmioMap, |