From: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>
Add 'ats_do_translate' method to enable manual IOMMU address
translation.
This allows the Remote Port subsystem to resolve guest virtual
addresses to physical addresses by querying the QEMU IOMMU
translation pipeline. This is required for the Remote Port
subsystem to support translation requests from external masters
in a co-simulation environment.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
Signed-off-by: Takahiro Nakata <takahiro.nakata.wr@renesas.com>
Signed-off-by: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>
---
include/system/memory.h | 8 +++++++
system/physmem.c | 53 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/include/system/memory.h b/include/system/memory.h
index e1fb82608d..c787c544ce 100644
--- a/include/system/memory.h
+++ b/include/system/memory.h
@@ -2895,6 +2895,14 @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
addr, xlat, len, is_write, attrs);
}
+MemoryRegion *ats_do_translate(AddressSpace *as,
+ hwaddr addr,
+ hwaddr *xlat,
+ hwaddr *plen_out,
+ AddressSpace **target_as,
+ int *prot,
+ MemTxAttrs attrs);
+
/* address_space_access_valid: check for validity of accessing an address
* space range
*
diff --git a/system/physmem.c b/system/physmem.c
index 2fb0c25c93..b4c18f3a01 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -527,6 +527,59 @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
return *section;
}
+/* This function is called from RCU critical section */
+MemoryRegion *ats_do_translate(AddressSpace *as,
+ hwaddr addr,
+ hwaddr *xlat,
+ hwaddr *plen_out,
+ AddressSpace **target_as,
+ int *prot,
+ MemTxAttrs attrs)
+{
+ MemoryRegionSection *section;
+ IOMMUMemoryRegion *iommu_mr;
+ hwaddr plen = (hwaddr)(-1);
+ FlatView *fv = address_space_to_flatview(as);
+ IOMMUMemoryRegionClass *imrc;
+ IOMMUTLBEntry iotlb;
+ int iommu_idx = 0;
+
+ if (!plen_out) {
+ plen_out = &plen;
+ }
+
+ /* This can be MMIO, so setup MMIO bit. */
+ section = address_space_translate_internal(
+ flatview_to_dispatch(fv), addr, xlat,
+ plen_out, true);
+
+ /* Illegal translation */
+ if (section->mr == &io_mem_unassigned) {
+ return NULL;
+ }
+
+ iommu_mr = memory_region_get_iommu(section->mr);
+ if (!iommu_mr) {
+ return NULL;
+ }
+
+ imrc = memory_region_get_iommu_class_nocheck(iommu_mr);
+
+ if (imrc->attrs_to_index) {
+ iommu_idx = imrc->attrs_to_index(iommu_mr, attrs);
+ }
+
+ iotlb = imrc->translate(iommu_mr, addr, IOMMU_RO, iommu_idx);
+
+ *xlat = ((iotlb.translated_addr & ~iotlb.addr_mask)
+ | (addr & iotlb.addr_mask));
+ *plen_out = MIN(*plen_out, (addr | iotlb.addr_mask) - addr + 1);
+ *prot = iotlb.perm;
+ *target_as = iotlb.target_as;
+
+ return section->mr;
+}
+
/* Called from RCU critical section */
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
bool is_write, MemTxAttrs attrs)
--
2.43.0