Skip to content

Commit

Permalink
versal: iommu tbu device mapping
Browse files Browse the repository at this point in the history
The smmu-500 has a configurable number of TBUs, but defaults
to 16. From the system programmer's perspective, it does not
matter which device is connected to which TBU, it is up to
the hardware designer how various DMA capable devices are
connected to the TBUs on the SMMU. As far as I can tell from
the documentation, Xilinx does not tell us which devices are
connected to which TBU. To make things simple, this change
introduces a scheme in which each DMA device is connected to
a different TBU.

Signed-off-by: Nelson Ho <Nelson.Ho@windriver.com>
  • Loading branch information
ho28 committed Dec 19, 2024
1 parent 5cec5c3 commit a9f5848
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
25 changes: 21 additions & 4 deletions hw/arm/xlnx-versal.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,17 @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
}
}

static void versal_connect_dev_iommu(Versal *s,
DeviceState *dev,
const char *propname,
MemoryRegion *target_mr,
int tbuId)
{
object_property_set_link(OBJECT(dev), propname,
OBJECT(&s->fpd.smmu.tbu[tbuId].iommu),
&error_abort);
}

static void versal_create_canfds(Versal *s, qemu_irq *pic)
{
int i;
Expand Down Expand Up @@ -255,6 +266,7 @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
static const int irqs[] = { VERSAL_GEM0_IRQ_0, VERSAL_GEM1_IRQ_0};
static const uint64_t addrs[] = { MM_GEM0, MM_GEM1 };
static const int smmu_sids[] = {VERSAL_GEM0_TBUID, VERSAL_GEM1_TBUID };
char *name = g_strdup_printf("gem%d", i);
DeviceState *dev;
MemoryRegion *mr;
Expand All @@ -266,8 +278,7 @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
object_property_set_int(OBJECT(dev), "phy-addr", 23, &error_abort);
object_property_set_int(OBJECT(dev), "num-priority-queues", 2,
&error_abort);
object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->fpd.smmu.tbu[0].iommu),
&error_abort);
versal_connect_dev_iommu(s, dev, "dma", &s->mr_ps, smmu_sids[i]);
sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);

mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
Expand Down Expand Up @@ -824,11 +835,17 @@ static void versal_create_smmu(Versal *s, qemu_irq *pic)
{
SysBusDevice *sbd;
MemoryRegion *mr;
int i;

object_initialize_child(OBJECT(s), "mmu-500", &s->fpd.smmu,
TYPE_XILINX_SMMU500);
sbd = SYS_BUS_DEVICE(&s->fpd.smmu);
object_property_set_link(OBJECT(sbd), "mr-0", OBJECT(&s->mr_ps), &error_abort);

for (i = 0; i < VERSAL_TBUID_MAX; i++) {
char *name = g_strdup_printf("mr-%d", i);
object_property_set_link(OBJECT(sbd), name,
OBJECT(&s->mr_ps), &error_abort);
}
sysbus_realize(sbd, &error_fatal);

mr = sysbus_mmio_get_region(sbd, 0);
Expand Down Expand Up @@ -995,8 +1012,8 @@ static void versal_realize(DeviceState *dev, Error **errp)
versal_create_apu_gic(s, pic);
versal_create_rpu_cpus(s);
versal_create_uarts(s, pic);
versal_create_canfds(s, pic);
versal_create_smmu(s, pic);
versal_create_canfds(s, pic);
versal_create_usbs(s, pic);
versal_create_lpd_iou_slcr(s);
versal_create_gems(s, pic);
Expand Down
8 changes: 8 additions & 0 deletions include/hw/arm/xlnx-versal.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,4 +357,12 @@ struct Versal {
#define MM_PMC_TRNG_SIZE 0x10000

#define MM_PMC_INT_CSR 0xf1330000

/* MMU-500 TBU device mapping */
typedef enum {
VERSAL_GEM0_TBUID,
VERSAL_GEM1_TBUID,
VERSAL_TBUID_MAX,
} VersalSmmuTbuMap;

#endif

0 comments on commit a9f5848

Please sign in to comment.