Browse Source

hw/riscv: Set IOMMU PAS via property

Replaces the only remaining use of TARGET_PHYS_ADDR_SPACE_BITS for RISCV
with a property RISCVIOMMUState::pas_bits that gets written to the
capabilities field upon device realization.  This write needs to happen
at realize-time to ensure the property has been set.

For the virt machine and sysbus device, pas_bits is set by
virt_machine_init() to either 34 or 56 bits, retaining previous behaviour.
However, for the PCI device we do not have access to the CPU state, and
instead use the maximum riscv64 value of 56 bits.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Anton Johansson <anjo@rev.ng>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Message-ID: <20260218-phys_addr-v6-6-a603bf363218@rev.ng>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
master
Anton Johansson 6 months ago
committed by Philippe Mathieu-Daudé
parent
commit
3a3cfcb29f
  1. 3
      hw/riscv/riscv-iommu-pci.c
  2. 8
      hw/riscv/riscv-iommu.c
  3. 1
      hw/riscv/riscv-iommu.h
  4. 7
      hw/riscv/virt.c

3
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[] = {

8
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),

1
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 */

7
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);
}

Loading…
Cancel
Save