summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f>2023-05-11 09:59:52 +0000
committervboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f>2023-05-11 09:59:52 +0000
commitca4d05988f1eb2e2e7d56789092d05ec9eec4481 (patch)
tree7cabdb11ce79210f2ae31cdd9b005a7bb573ecd6
parenta7b416cb0a29955b896e9babb46dcb69a2c34754 (diff)
downloadVirtualBox-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.h42
-rw-r--r--src/VBox/VMM/Makefile.kmk1
-rw-r--r--src/VBox/VMM/VMMR3/PDMDevHlp.cpp56
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,