diff --git a/hw/riscv/riscv-iommu-pci.c b/hw/riscv/riscv-iommu-pci.c index 5f7d359204..14dd5f3857 100644 --- a/hw/riscv/riscv-iommu-pci.c +++ b/hw/riscv/riscv-iommu-pci.c @@ -158,6 +158,9 @@ static void riscv_iommu_pci_init(Object *obj) iommu->icvec_avail_vectors = RISCV_IOMMU_PCI_ICVEC_VECTORS; riscv_iommu_set_cap_igs(iommu, RISCV_IOMMU_CAP_IGS_MSI); + + /* Report maximum physical address size of riscv64 */ + iommu->pas_bits = 56; } static const Property riscv_iommu_pci_properties[] = { diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c index b46b337375..98345b1280 100644 --- a/hw/riscv/riscv-iommu.c +++ b/hw/riscv/riscv-iommu.c @@ -2453,10 +2453,6 @@ static void riscv_iommu_instance_init(Object *obj) /* Enable translation debug interface */ s->cap = RISCV_IOMMU_CAP_DBG; - /* Report QEMU target physical address space limits */ - s->cap = set_field(s->cap, RISCV_IOMMU_CAP_PAS, - TARGET_PHYS_ADDR_SPACE_BITS); - /* TODO: method to report supported PID bits */ s->pid_bits = 8; /* restricted to size of MemTxAttrs.pid */ s->cap |= RISCV_IOMMU_CAP_PD8; @@ -2487,6 +2483,9 @@ static void riscv_iommu_realize(DeviceState *dev, Error **errp) { RISCVIOMMUState *s = RISCV_IOMMU(dev); + /* Report QEMU target physical address space limits. */ + s->cap = set_field(s->cap, RISCV_IOMMU_CAP_PAS, s->pas_bits); + s->cap |= s->version & RISCV_IOMMU_CAP_VERSION; if (s->enable_msi) { s->cap |= RISCV_IOMMU_CAP_MSI_FLAT | RISCV_IOMMU_CAP_MSI_MRIF; @@ -2645,6 +2644,7 @@ void riscv_iommu_reset(RISCVIOMMUState *s) static const Property riscv_iommu_properties[] = { DEFINE_PROP_UINT32("version", RISCVIOMMUState, version, RISCV_IOMMU_SPEC_DOT_VER), + DEFINE_PROP_UINT32("pas-bits", RISCVIOMMUState, pas_bits, 0), DEFINE_PROP_UINT32("bus", RISCVIOMMUState, bus, 0x0), DEFINE_PROP_UINT32("ioatc-limit", RISCVIOMMUState, iot_limit, LIMIT_CACHE_IOT), diff --git a/hw/riscv/riscv-iommu.h b/hw/riscv/riscv-iommu.h index 2dabd86941..2a9f6fccd5 100644 --- a/hw/riscv/riscv-iommu.h +++ b/hw/riscv/riscv-iommu.h @@ -34,6 +34,7 @@ struct RISCVIOMMUState { /*< public >*/ uint32_t version; /* Reported interface version number */ uint32_t pid_bits; /* process identifier width */ + uint32_t pas_bits; /* physical address bits */ uint32_t bus; /* PCI bus mapping for non-root endpoints */ uint64_t cap; /* IOMMU supported capabilities */ diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 07e66b3936..bbce2fb667 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1739,6 +1739,13 @@ static void virt_machine_init(MachineState *machine) object_property_set_link(OBJECT(iommu_sys), "irqchip", OBJECT(mmio_irqchip), &error_fatal); + /* + * For riscv64 use a physical address size of 56 bits (44 bit PPN), + * and for riscv32 use 34 bits (22 bit PPN). + */ + object_property_set_uint(OBJECT(iommu_sys), "pas-bits", + riscv_is_32bit(&s->soc[0]) ? 34 : 56, + &error_fatal); sysbus_realize_and_unref(SYS_BUS_DEVICE(iommu_sys), &error_fatal); }