GBPA register can be used to globally abort all transactions. Only UPDATE and ABORT bits are considered in this patch.
It is described in the SMMU manual in "6.3.14 SMMU_GBPA". ABORT reset value is IMPLEMENTATION DEFINED, it is chosen to be zero(Do not abort incoming transactions). Signed-off-by: Mostafa Saleh <smost...@google.com> --- hw/arm/smmuv3-internal.h | 4 ++++ hw/arm/smmuv3.c | 14 ++++++++++++++ include/hw/arm/smmuv3.h | 1 + 3 files changed, 19 insertions(+) diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h index bce161870f..71f70141e8 100644 --- a/hw/arm/smmuv3-internal.h +++ b/hw/arm/smmuv3-internal.h @@ -79,6 +79,10 @@ REG32(CR0ACK, 0x24) REG32(CR1, 0x28) REG32(CR2, 0x2c) REG32(STATUSR, 0x40) +REG32(GBPA, 0x44) + FIELD(GBPA, ABORT, 20, 1) + FIELD(GBPA, UPDATE, 31, 1) + REG32(IRQ_CTRL, 0x50) FIELD(IRQ_CTRL, GERROR_IRQEN, 0, 1) FIELD(IRQ_CTRL, PRI_IRQEN, 1, 1) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 955b89c8d5..2843bc3da9 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -285,6 +285,7 @@ static void smmuv3_init_regs(SMMUv3State *s) s->gerror = 0; s->gerrorn = 0; s->statusr = 0; + s->gbpa = 0; } static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf, @@ -663,6 +664,11 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr, goto epilogue; } + if (FIELD_EX32(s->gbpa, GBPA, ABORT)) { + status = SMMU_TRANS_ABORT; + goto epilogue; + } + cfg = smmuv3_get_config(sdev, &event); if (!cfg) { status = SMMU_TRANS_ERROR; @@ -1170,6 +1176,10 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset, case A_GERROR_IRQ_CFG2: s->gerror_irq_cfg2 = data; return MEMTX_OK; + case A_GBPA: + /* Ignore update bit as write is synchronous. */ + s->gbpa = data & ~R_GBPA_UPDATE_MASK; + return MEMTX_OK; case A_STRTAB_BASE: /* 64b */ s->strtab_base = deposit64(s->strtab_base, 0, 32, data); return MEMTX_OK; @@ -1318,6 +1328,9 @@ static MemTxResult smmu_readl(SMMUv3State *s, hwaddr offset, case A_STATUSR: *data = s->statusr; return MEMTX_OK; + case A_GBPA: + *data = s->gbpa; + return MEMTX_OK; case A_IRQ_CTRL: case A_IRQ_CTRL_ACK: *data = s->irq_ctrl; @@ -1495,6 +1508,7 @@ static const VMStateDescription vmstate_smmuv3 = { VMSTATE_UINT32_ARRAY(cr, SMMUv3State, 3), VMSTATE_UINT32(cr0ack, SMMUv3State), VMSTATE_UINT32(statusr, SMMUv3State), + VMSTATE_UINT32(gbpa, SMMUv3State), VMSTATE_UINT32(irq_ctrl, SMMUv3State), VMSTATE_UINT32(gerror, SMMUv3State), VMSTATE_UINT32(gerrorn, SMMUv3State), diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h index f1921fdf9e..9899fa1860 100644 --- a/include/hw/arm/smmuv3.h +++ b/include/hw/arm/smmuv3.h @@ -46,6 +46,7 @@ struct SMMUv3State { uint32_t cr[3]; uint32_t cr0ack; uint32_t statusr; + uint32_t gbpa; uint32_t irq_ctrl; uint32_t gerror; uint32_t gerrorn; -- 2.39.0.314.g84b9a713c41-goog