* [PATCH 0/2] Add SMMUv3 Root registers
@ 2026-10-16 9:40 Jim MacArthur
2026-10-16 9:40 ` [PATCH 1/2] hw/arm/smmuv3: define " Jim MacArthur
2026-10-16 9:40 ` [PATCH 2/2] hw/arm/sbsa-ref.c: Increase SMMU space for " Jim MacArthur
0 siblings, 2 replies; 10+ messages in thread
From: Jim MacArthur @ 2026-10-16 9:40 UTC (permalink / raw)
To: qemu-devel
Cc: Eric Auger, Peter Maydell, qemu-arm, Leif Lindholm, Jim MacArthur,
Pierrick Bouvier
This is preparatory work for further SMMUv3.3 features including RME-DA.
We are adding in patches originally authored by Pierrick Bouvier
<pierrick.bouvier@linaro.org> and Gustavo Romero <gustavo.romero@linaro.org>
in a way that will avoid conflicts with Tao Tang's upcoming SMMUv3 Secure
state patches. Since Root registers do not use the banking system, this
should only conflict around the offset check near smmu_write_mmio and
smmu_read_mmio.
Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
---
Jim MacArthur (1):
hw/arm/sbsa-ref.c: Increase SMMU space for Root registers
Pierrick Bouvier (1):
hw/arm/smmuv3: define Root registers
hw/arm/sbsa-ref.c | 2 +-
hw/arm/smmuv3.c | 229 +++++++++++++++++++++++++++++++++++++++++
include/hw/arm/smmuv3-common.h | 22 ++++
include/hw/arm/smmuv3.h | 13 +++
4 files changed, 265 insertions(+), 1 deletion(-)
---
base-commit: 5acdfee7f068d88813c989c52f76bb64a06121ca
change-id: 20261015-jmac-smmu-root-registers-dc4f1e2a63b5
Best regards,
--
Jim MacArthur <jim.macarthur@linaro.org>
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 1/2] hw/arm/smmuv3: define Root registers 2026-10-16 9:40 [PATCH 0/2] Add SMMUv3 Root registers Jim MacArthur @ 2026-10-16 9:40 ` Jim MacArthur 2026-11-06 22:20 ` Gustavo Romero 2026-10-16 9:40 ` [PATCH 2/2] hw/arm/sbsa-ref.c: Increase SMMU space for " Jim MacArthur 1 sibling, 1 reply; 10+ messages in thread From: Jim MacArthur @ 2026-10-16 9:40 UTC (permalink / raw) To: qemu-devel Cc: Eric Auger, Peter Maydell, qemu-arm, Leif Lindholm, Jim MacArthur, Pierrick Bouvier From: Pierrick Bouvier <pierrick.bouvier@linaro.org> Adds all the non-optional SMMUv3.3 Root registers. These registers do nothing at the moment, but RW registers can be written and all registers can be read. Based on original work by Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org> --- hw/arm/smmuv3.c | 229 +++++++++++++++++++++++++++++++++++++++++ include/hw/arm/smmuv3-common.h | 22 ++++ include/hw/arm/smmuv3.h | 13 +++ 3 files changed, 264 insertions(+) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index ed19536a4d..9d9bc2601b 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -316,6 +316,11 @@ static void smmuv3_init_id_regs(SMMUv3State *s) s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1); s->aidr = 0x1; smmuv3_accel_idr_override(s); + + /* Initialize Root bank */ + s->root.idr0 = FIELD_DP32(s->root.idr0, ROOT_IDR0, ROOT_IMPL, 1); + /* Set this to 1 when SMMU Realms are implemented */ + s->root.idr0 = FIELD_DP32(s->root.idr0, ROOT_IDR0, REALM_IMPL, 0); } bool smmuv3_ats_enabled(SMMUv3State *s) @@ -1769,6 +1774,111 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset, return MEMTX_OK; } +/* + * Check we are from the Root PA space to read from or write to the + * SMMU Root register area. + */ +static bool smmu_check_root_access(SMMUv3State *s, MemTxAttrs attrs, + hwaddr offset, bool is_read) +{ + /* Check if the access is from Root PA */ + if (!(attrs.space == ARMSS_Root)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Non-root %s attempt at offset 0x%" PRIx64 " (%s)\n", + __func__, is_read ? "read" : "write", offset, + is_read ? "RAZ" : "WI"); + return false; + } + return true; +} + +static MemTxResult smmu_root_writel(SMMUv3State *s, hwaddr offset, + uint64_t data, MemTxAttrs attrs) +{ + switch (offset) { + case A_ROOT_IDR0: + case A_ROOT_IIDR: + case A_ROOT_CR0ACK: + /* RO registers, write ignored */ + return MEMTX_OK; + case A_ROOT_TLBI_CTRL: + /* Optional, not implemented. Present if IDR0.RGPTM == 1 */ + return MEMTX_OK; + case A_ROOT_GPT_BASE_UPDATE: + /* Unimplemented at present; has side effects */ + return MEMTX_OK; + case A_ROOT_CR0: + s->root.cr0 = data; + s->root.cr0ack = s->root.cr0; + return MEMTX_OK; + default: + qemu_log_mask(LOG_UNIMP, + "%s unhandled 32-bit access at 0x%"PRIx64" (WI)\n", + __func__, offset); + /* + * Locations not associated with a register (including registers that we + * have not implemented yet) are RES0, and will follow RAZ/WI behaviour. + */ + return MEMTX_OK; + } +} + +static MemTxResult smmu_root_writell(SMMUv3State *s, hwaddr offset, + uint64_t data, MemTxAttrs attrs) +{ + switch (offset) { + case A_ROOT_GPT_BASE: + s->root.gpt_base = data; + return MEMTX_OK; + case A_ROOT_GPT_BASE_CFG: + s->root.gpt_base_cfg = data; + return MEMTX_OK; + case A_ROOT_GPF_FAR: + s->root.gpf_far = data; + return MEMTX_OK; + case A_ROOT_GPT_CFG_FAR: + s->root.gpt_cfg_far = data; + return MEMTX_OK; + case A_ROOT_TLBI: + /* Optional, not implemented. Present if ROOT_IDR0.RGPTM == 1 */ + return MEMTX_OK; + case A_ROOT_GPT_BASE2: + s->root.gpt_base2 = data; + return MEMTX_OK; + case A_ROOT_GPCBW: + /* Optional, not implemented. Present if ROOT_IDR0.GPTS == 1 */ + return MEMTX_OK; + default: + qemu_log_mask(LOG_UNIMP, + "%s unhandled 64-bit access at 0x%"PRIx64" (WI)\n", + __func__, offset); + /* RES0; See smmu_root_writel */ + return MEMTX_OK; + } +} + +static MemTxResult smmu_write_mmio_root(SMMUv3State *s, hwaddr offset, + uint64_t data, unsigned size, + MemTxAttrs attrs) +{ + MemTxResult r; + + switch (size) { + case 8: + r = smmu_root_writell(s, offset, data, attrs); + break; + case 4: + r = smmu_root_writel(s, offset, data, attrs); + break; + default: + r = MEMTX_ERROR; + break; + } + + trace_smmuv3_write_mmio(offset, data, size, r); + return r; +} + static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data, unsigned size, MemTxAttrs attrs) { @@ -1776,6 +1886,18 @@ static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data, SMMUv3State *s = ARM_SMMUV3(sys); MemTxResult r; + if (offset >= SMMU_ROOT_REG_START) { + if (!smmu_check_root_access(s, attrs, offset, false)) { + /* + * As per 6.2.8, accesses in any PA space other + * than Root are completed as RAZ/WI. + */ + trace_smmuv3_write_mmio(offset, data, size, MEMTX_OK); + return MEMTX_OK; + } + return smmu_write_mmio_root(s, offset, data, size, attrs); + } + /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */ offset &= ~0x10000; @@ -1918,6 +2040,100 @@ static MemTxResult smmu_readl(SMMUv3State *s, hwaddr offset, } } +static MemTxResult smmu_root_readl(SMMUv3State *s, hwaddr offset, + uint64_t *data, MemTxAttrs attrs) +{ + switch (offset) { + case A_ROOT_IDR0: + *data = s->root.idr0; + return MEMTX_OK; + case A_ROOT_IIDR: + *data = s->root.iidr; + return MEMTX_OK; + case A_ROOT_TLBI_CTRL: + /* Optional, not implemented. Present if ROOT_IDR0.RGPTM == 1 */ + *data = 0; + return MEMTX_OK; + case A_ROOT_GPT_BASE_UPDATE: + /* Not a regular register; reads as 0 once update is complete */ + *data = 0; + return MEMTX_OK; + case A_ROOT_CR0: + *data = s->root.cr0; + return MEMTX_OK; + case A_ROOT_CR0ACK: + *data = s->root.cr0ack; + return MEMTX_OK; + default: + qemu_log_mask(LOG_UNIMP, + "%s unhandled 32-bit access at 0x%"PRIx64" (RAZ)\n", + __func__, offset); + *data = 0; + /* RES0; See smmu_root_writel */ + return MEMTX_OK; + } +} + +static MemTxResult smmu_root_readll(SMMUv3State *s, hwaddr offset, + uint64_t *data, MemTxAttrs attrs) +{ + switch (offset) { + case A_ROOT_GPT_BASE: + *data = s->root.gpt_base; + return MEMTX_OK; + case A_ROOT_GPT_BASE_CFG: + *data = s->root.gpt_base_cfg; + return MEMTX_OK; + case A_ROOT_GPF_FAR: + *data = s->root.gpf_far; + return MEMTX_OK; + case A_ROOT_GPT_CFG_FAR: + *data = s->root.gpt_cfg_far; + return MEMTX_OK; + case A_ROOT_TLBI: + /* Optional, not implemented. Present if ROOT_IDR0.RGPTM == 1 */ + *data = 0; + return MEMTX_OK; + case A_ROOT_GPT_BASE2: + *data = s->root.gpt_base2; + return MEMTX_OK; + case A_ROOT_GPCBW: + /* Optional, not implemented. Present if ROOT_IDR0.GPTS == 0 */ + *data = 0; + return MEMTX_OK; + default: + qemu_log_mask(LOG_UNIMP, + "%s unhandled 64-bit access at 0x%"PRIx64" (RAZ)\n", + __func__, offset); + *data = 0; + /* RES0; See smmu_root_writel */ + return MEMTX_OK; + } +} + +static MemTxResult smmu_read_mmio_root(SMMUv3State *s, hwaddr offset, + uint64_t *data, unsigned size, + MemTxAttrs attrs) +{ + MemTxResult r; + + switch (size) { + case 8: + r = smmu_root_readll(s, offset, data, attrs); + break; + case 4: + r = smmu_root_readl(s, offset, data, attrs); + break; + default: + r = MEMTX_ERROR; + break; + } + + trace_smmuv3_read_mmio(offset, *data, size, r); + return r; +} + + static MemTxResult smmu_read_mmio(void *opaque, hwaddr offset, uint64_t *data, unsigned size, MemTxAttrs attrs) { @@ -1925,6 +2141,19 @@ static MemTxResult smmu_read_mmio(void *opaque, hwaddr offset, uint64_t *data, SMMUv3State *s = ARM_SMMUV3(sys); MemTxResult r; + if (offset >= SMMU_ROOT_REG_START) { + if (!smmu_check_root_access(s, attrs, offset, true)) { + /* + * As per 6.2.8, accesses in any PA space other + * than Root are completed as RAZ/WI. + */ + trace_smmuv3_read_mmio(offset, *data, size, MEMTX_OK); + return MEMTX_OK; + } + + return smmu_read_mmio_root(s, offset, data, size, attrs); + } + /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */ offset &= ~0x10000; diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h index 4609975edf..a538334066 100644 --- a/include/hw/arm/smmuv3-common.h +++ b/include/hw/arm/smmuv3-common.h @@ -411,6 +411,28 @@ REG32(EVENTQ_IRQ_CFG2, 0xbc) #define A_IDREGS 0xfd0 +#define SMMU_ROOT_REG_START 0x20000 + +REG32(ROOT_IDR0, 0x0) + FIELD(ROOT_IDR0, ROOT_IMPL, 0, 1) + FIELD(ROOT_IDR0, BGTPM, 1, 1) + FIELD(ROOT_IDR0, RGPTM, 2, 1) + FIELD(ROOT_IDR0, REALM_IMPL, 3, 1) + FIELD(ROOT_IDR0, BA_REALM, 22, 10) + +REG32(ROOT_IIDR, 0x8) +REG32(ROOT_CR0, 0x20) +REG32(ROOT_CR0ACK, 0x24) +REG64(ROOT_GPT_BASE, 0x28) +REG64(ROOT_GPT_BASE_CFG, 0x30) +REG64(ROOT_GPF_FAR, 0x38) +REG64(ROOT_GPT_CFG_FAR, 0x40) +REG64(ROOT_TLBI, 0x50) +REG32(ROOT_TLBI_CTRL, 0x58) +REG64(ROOT_GPT_BASE2, 0x60) +REG32(ROOT_GPT_BASE_UPDATE, 0x68) +REG32(ROOT_GPCBW, 0x70) + /* Commands */ typedef enum SMMUCommandType { diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h index d39fe8850b..e2708e13fe 100644 --- a/include/hw/arm/smmuv3.h +++ b/include/hw/arm/smmuv3.h @@ -34,6 +34,18 @@ typedef struct SMMUQueue { uint8_t log2size; } SMMUQueue; +typedef struct SMMUv3RootRegBank { + uint32_t idr0; + uint32_t iidr; + uint32_t cr0; + uint32_t cr0ack; + uint64_t gpt_base; + uint64_t gpt_base_cfg; + uint64_t gpf_far; + uint64_t gpt_cfg_far; + uint64_t gpt_base2; +} SMMUv3RootRegBank; + struct SMMUv3State { SMMUState smmu_state; @@ -80,6 +92,7 @@ struct SMMUv3State { OnOffAuto cmdqv; Notifier machine_done; + SMMUv3RootRegBank root; }; typedef enum { -- 2.43.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] hw/arm/smmuv3: define Root registers 2026-10-16 9:40 ` [PATCH 1/2] hw/arm/smmuv3: define " Jim MacArthur @ 2026-11-06 22:20 ` Gustavo Romero 2026-11-10 16:21 ` Jim MacArthur 0 siblings, 1 reply; 10+ messages in thread From: Gustavo Romero @ 2026-11-06 22:20 UTC (permalink / raw) To: Jim MacArthur Cc: qemu-devel, Eric Auger, Peter Maydell, qemu-arm, Leif Lindholm, Pierrick Bouvier Hi Jim, Thanks for sending it. On Fri, Oct 16, 2026 at 10:40:51AM +0100, Jim MacArthur wrote: > From: Pierrick Bouvier <pierrick.bouvier@linaro.org> > > Adds all the non-optional SMMUv3.3 Root registers. These registers > do nothing at the moment, but RW registers can be written and all > registers can be read. > > Based on original work by Pierrick Bouvier <pierrick.bouvier@linaro.org> > > Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org> > --- > hw/arm/smmuv3.c | 229 +++++++++++++++++++++++++++++++++++++++++ > include/hw/arm/smmuv3-common.h | 22 ++++ > include/hw/arm/smmuv3.h | 13 +++ > 3 files changed, 264 insertions(+) > > diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c > index ed19536a4d..9d9bc2601b 100644 > --- a/hw/arm/smmuv3.c > +++ b/hw/arm/smmuv3.c > @@ -316,6 +316,11 @@ static void smmuv3_init_id_regs(SMMUv3State *s) > s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1); > s->aidr = 0x1; > smmuv3_accel_idr_override(s); > + > + /* Initialize Root bank */ > + s->root.idr0 = FIELD_DP32(s->root.idr0, ROOT_IDR0, ROOT_IMPL, 1); > + /* Set this to 1 when SMMU Realms are implemented */ > + s->root.idr0 = FIELD_DP32(s->root.idr0, ROOT_IDR0, REALM_IMPL, 0); > } > > bool smmuv3_ats_enabled(SMMUv3State *s) > @@ -1769,6 +1774,111 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset, > return MEMTX_OK; > } > > +/* > + * Check we are from the Root PA space to read from or write to the > + * SMMU Root register area. > + */ > +static bool smmu_check_root_access(SMMUv3State *s, MemTxAttrs attrs, > + hwaddr offset, bool is_read) Indentation is off ---------------------^ I think it makes sense also to call this function smmu_root_access(), but no strong preference here. > +{ > + /* Check if the access is from Root PA */ > + if (!(attrs.space == ARMSS_Root)) { Could we use the comparison operator (!=) instead of the logical one here? I think it's clearer than a negation. > + qemu_log_mask(LOG_GUEST_ERROR, > + "%s: Non-root %s attempt at offset 0x%" PRIx64 " (%s)\n", > + __func__, is_read ? "read" : "write", offset, > + is_read ? "RAZ" : "WI"); > + return false; > + } > + return true; > +} > + > +static MemTxResult smmu_root_writel(SMMUv3State *s, hwaddr offset, > + uint64_t data, MemTxAttrs attrs) > +{ > + switch (offset) { > + case A_ROOT_IDR0: > + case A_ROOT_IIDR: > + case A_ROOT_CR0ACK: > + /* RO registers, write ignored */ > + return MEMTX_OK; > + case A_ROOT_TLBI_CTRL: > + /* Optional, not implemented. Present if IDR0.RGPTM == 1 */ > + return MEMTX_OK; > + case A_ROOT_GPT_BASE_UPDATE: > + /* Unimplemented at present; has side effects */ > + return MEMTX_OK; > + case A_ROOT_CR0: > + s->root.cr0 = data; > + s->root.cr0ack = s->root.cr0; > + return MEMTX_OK; > + default: > + qemu_log_mask(LOG_UNIMP, > + "%s unhandled 32-bit access at 0x%"PRIx64" (WI)\n", > + __func__, offset); > + /* > + * Locations not associated with a register (including registers that we > + * have not implemented yet) are RES0, and will follow RAZ/WI behaviour. > + */ > + return MEMTX_OK; > + } > +} > + > +static MemTxResult smmu_root_writell(SMMUv3State *s, hwaddr offset, > + uint64_t data, MemTxAttrs attrs) > +{ > + switch (offset) { > + case A_ROOT_GPT_BASE: > + s->root.gpt_base = data; > + return MEMTX_OK; > + case A_ROOT_GPT_BASE_CFG: > + s->root.gpt_base_cfg = data; > + return MEMTX_OK; > + case A_ROOT_GPF_FAR: > + s->root.gpf_far = data; > + return MEMTX_OK; > + case A_ROOT_GPT_CFG_FAR: > + s->root.gpt_cfg_far = data; > + return MEMTX_OK; > + case A_ROOT_TLBI: > + /* Optional, not implemented. Present if ROOT_IDR0.RGPTM == 1 */ > + return MEMTX_OK; > + case A_ROOT_GPT_BASE2: > + s->root.gpt_base2 = data; > + return MEMTX_OK; > + case A_ROOT_GPCBW: > + /* Optional, not implemented. Present if ROOT_IDR0.GPTS == 1 */ > + return MEMTX_OK; > + default: > + qemu_log_mask(LOG_UNIMP, > + "%s unhandled 64-bit access at 0x%"PRIx64" (WI)\n", > + __func__, offset); > + /* RES0; See smmu_root_writel */ > + return MEMTX_OK; > + } > +} We might have some issues down the lane since TF-A seems to rely on the spec that says that 64b registers can be written in 32b halves, since I see in the TF-A code, drivers/arm/smmu/smmu_v3.c, in smmuv3_init(): [...] /* * TODO: SMMU_ROOT_GPT_BASE_CFG is 64b in the spec, * but SMMU model only accepts 32b access. */ mmio_write_32(smmu_base + SMMU_ROOT_GPT_BASE_CFG, gpccr_el3); But for now it's ok. We can revisit it later. > + > +static MemTxResult smmu_write_mmio_root(SMMUv3State *s, hwaddr offset, > + uint64_t data, unsigned size, > + MemTxAttrs attrs) > +{ > + MemTxResult r; > + > + switch (size) { > + case 8: > + r = smmu_root_writell(s, offset, data, attrs); > + break; > + case 4: > + r = smmu_root_writel(s, offset, data, attrs); > + break; > + default: > + r = MEMTX_ERROR; > + break; > + } > + > + trace_smmuv3_write_mmio(offset, data, size, r); > + return r; > +} > + > static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data, > unsigned size, MemTxAttrs attrs) > { > @@ -1776,6 +1886,18 @@ static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data, > SMMUv3State *s = ARM_SMMUV3(sys); > MemTxResult r; > > + if (offset >= SMMU_ROOT_REG_START) { > + if (!smmu_check_root_access(s, attrs, offset, false)) { > + /* > + * As per 6.2.8, accesses in any PA space other > + * than Root are completed as RAZ/WI. > + */ > + trace_smmuv3_write_mmio(offset, data, size, MEMTX_OK); > + return MEMTX_OK; > + } > + return smmu_write_mmio_root(s, offset, data, size, attrs); > + } > + > /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */ > offset &= ~0x10000; > > @@ -1918,6 +2040,100 @@ static MemTxResult smmu_readl(SMMUv3State *s, hwaddr offset, > } > } > > +static MemTxResult smmu_root_readl(SMMUv3State *s, hwaddr offset, > + uint64_t *data, MemTxAttrs attrs) > +{ > + switch (offset) { > + case A_ROOT_IDR0: > + *data = s->root.idr0; > + return MEMTX_OK; > + case A_ROOT_IIDR: > + *data = s->root.iidr; > + return MEMTX_OK; > + case A_ROOT_TLBI_CTRL: > + /* Optional, not implemented. Present if ROOT_IDR0.RGPTM == 1 */ > + *data = 0; > + return MEMTX_OK; > + case A_ROOT_GPT_BASE_UPDATE: > + /* Not a regular register; reads as 0 once update is complete */ > + *data = 0; > + return MEMTX_OK; > + case A_ROOT_CR0: > + *data = s->root.cr0; > + return MEMTX_OK; > + case A_ROOT_CR0ACK: > + *data = s->root.cr0ack; > + return MEMTX_OK; > + default: > + qemu_log_mask(LOG_UNIMP, > + "%s unhandled 32-bit access at 0x%"PRIx64" (RAZ)\n", > + __func__, offset); > + *data = 0; > + /* RES0; See smmu_root_writel */ > + return MEMTX_OK; > + } > +} > + > +static MemTxResult smmu_root_readll(SMMUv3State *s, hwaddr offset, > + uint64_t *data, MemTxAttrs attrs) > +{ > + switch (offset) { > + case A_ROOT_GPT_BASE: > + *data = s->root.gpt_base; > + return MEMTX_OK; > + case A_ROOT_GPT_BASE_CFG: > + *data = s->root.gpt_base_cfg; > + return MEMTX_OK; > + case A_ROOT_GPF_FAR: > + *data = s->root.gpf_far; > + return MEMTX_OK; > + case A_ROOT_GPT_CFG_FAR: > + *data = s->root.gpt_cfg_far; > + return MEMTX_OK; > + case A_ROOT_TLBI: > + /* Optional, not implemented. Present if ROOT_IDR0.RGPTM == 1 */ > + *data = 0; > + return MEMTX_OK; > + case A_ROOT_GPT_BASE2: > + *data = s->root.gpt_base2; > + return MEMTX_OK; > + case A_ROOT_GPCBW: > + /* Optional, not implemented. Present if ROOT_IDR0.GPTS == 0 */ GPTS == 1 here? -----^ > + *data = 0; > + return MEMTX_OK; > + default: > + qemu_log_mask(LOG_UNIMP, > + "%s unhandled 64-bit access at 0x%"PRIx64" (RAZ)\n", > + __func__, offset); > + *data = 0; > + /* RES0; See smmu_root_writel */ > + return MEMTX_OK; > + } > +} > + > +static MemTxResult smmu_read_mmio_root(SMMUv3State *s, hwaddr offset, > + uint64_t *data, unsigned size, > + MemTxAttrs attrs) > +{ > + MemTxResult r; > + > + switch (size) { > + case 8: > + r = smmu_root_readll(s, offset, data, attrs); > + break; > + case 4: > + r = smmu_root_readl(s, offset, data, attrs); > + break; > + default: > + r = MEMTX_ERROR; > + break; > + } > + > + trace_smmuv3_read_mmio(offset, *data, size, r); > + return r; > +} > + > + > static MemTxResult smmu_read_mmio(void *opaque, hwaddr offset, uint64_t *data, > unsigned size, MemTxAttrs attrs) > { > @@ -1925,6 +2141,19 @@ static MemTxResult smmu_read_mmio(void *opaque, hwaddr offset, uint64_t *data, > SMMUv3State *s = ARM_SMMUV3(sys); > MemTxResult r; > > + if (offset >= SMMU_ROOT_REG_START) { > + if (!smmu_check_root_access(s, attrs, offset, true)) { > + /* > + * As per 6.2.8, accesses in any PA space other > + * than Root are completed as RAZ/WI. > + */ > + trace_smmuv3_read_mmio(offset, *data, size, MEMTX_OK); > + return MEMTX_OK; > + } > + > + return smmu_read_mmio_root(s, offset, data, size, attrs); > + } > + > /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */ > offset &= ~0x10000; > > diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h > index 4609975edf..a538334066 100644 > --- a/include/hw/arm/smmuv3-common.h > +++ b/include/hw/arm/smmuv3-common.h > @@ -411,6 +411,28 @@ REG32(EVENTQ_IRQ_CFG2, 0xbc) > > #define A_IDREGS 0xfd0 > > +#define SMMU_ROOT_REG_START 0x20000 The base address for the Root Control Page is implementation defined, hence 0x20000 is not always true and depends on the machine/platform. We could add property to set it externaly but it would also complicate unnecessarily the offset math. So I think it's ok to follow what FVP is doing. Please just add a note saying it's impl. defined so it might require a tweak in the future. I think we can follow TF-A code here and rename this macro. So how about renaming it to: SMMUV3_ROOT_REG_OFFSET ? > + > +REG32(ROOT_IDR0, 0x0) > + FIELD(ROOT_IDR0, ROOT_IMPL, 0, 1) > + FIELD(ROOT_IDR0, BGTPM, 1, 1) Typo: BGPTM ------------^ > + FIELD(ROOT_IDR0, RGPTM, 2, 1) > + FIELD(ROOT_IDR0, REALM_IMPL, 3, 1) > + FIELD(ROOT_IDR0, BA_REALM, 22, 10) > + > +REG32(ROOT_IIDR, 0x8) > +REG32(ROOT_CR0, 0x20) > +REG32(ROOT_CR0ACK, 0x24) > +REG64(ROOT_GPT_BASE, 0x28) > +REG64(ROOT_GPT_BASE_CFG, 0x30) > +REG64(ROOT_GPF_FAR, 0x38) > +REG64(ROOT_GPT_CFG_FAR, 0x40) > +REG64(ROOT_TLBI, 0x50) > +REG32(ROOT_TLBI_CTRL, 0x58) > +REG64(ROOT_GPT_BASE2, 0x60) > +REG32(ROOT_GPT_BASE_UPDATE, 0x68) > +REG32(ROOT_GPCBW, 0x70) > + > /* Commands */ > > typedef enum SMMUCommandType { > diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h > index d39fe8850b..e2708e13fe 100644 > --- a/include/hw/arm/smmuv3.h > +++ b/include/hw/arm/smmuv3.h > @@ -34,6 +34,18 @@ typedef struct SMMUQueue { > uint8_t log2size; > } SMMUQueue; > > +typedef struct SMMUv3RootRegBank { How about naming this struct simply SMMUv3Root? > + uint32_t idr0; > + uint32_t iidr; > + uint32_t cr0; > + uint32_t cr0ack; > + uint64_t gpt_base; > + uint64_t gpt_base_cfg; > + uint64_t gpf_far; > + uint64_t gpt_cfg_far; > + uint64_t gpt_base2; Looking at ARM IHI 0070 H.a Non-confidential spec I don't see 0x0068 SMMU_ROOT_GPT_BASE_UPDATE 32-bit, R/W and 0x0070 SMMU_ROOT_GPCBW 64-bit, R/W as Optional like I see SMMU_ROOT_TLBI and SMMU_ROOT_TLBI_CTRL. Should they be declared as well? > +} SMMUv3RootRegBank; > + > struct SMMUv3State { > SMMUState smmu_state; > > @@ -80,6 +92,7 @@ struct SMMUv3State { > OnOffAuto cmdqv; > > Notifier machine_done; > + SMMUv3RootRegBank root; > }; > > typedef enum { > > -- > 2.43.0 > > General comments: smmu_read_mmio_root smmu_write_mmio_root I think we can drop the "mmio_" for both functions. It's ok to have "mmio_" in the "trace_smmuv3_write_mmio" trace function because afaics it has a generic use, so its use is not tied to any bank. I think we're missing to reset some registers in smmuv3_reset()? Like: s->root.cr0 = 0; s->root.cr0ack = 0; s->root.gpf_far = 0; s->root.gpt_cfg_far = 0; Cheers, Gustavo ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] hw/arm/smmuv3: define Root registers 2026-11-06 22:20 ` Gustavo Romero @ 2026-11-10 16:21 ` Jim MacArthur 0 siblings, 0 replies; 10+ messages in thread From: Jim MacArthur @ 2026-11-10 16:21 UTC (permalink / raw) To: Gustavo Romero Cc: qemu-devel, Eric Auger, Peter Maydell, qemu-arm, Leif Lindholm, Pierrick Bouvier On Fri, Nov 06, 2026 at 11:20:56PM +0100, Gustavo Romero wrote: > > +/* > > + * Check we are from the Root PA space to read from or write to the > > + * SMMU Root register area. > > + */ > > +static bool smmu_check_root_access(SMMUv3State *s, MemTxAttrs attrs, > > + hwaddr offset, bool is_read) > > Indentation is off ---------------------^ > > I think it makes sense also to call this function smmu_root_access(), but no > strong preference here. Noted indentation fault. I would prefer to have a verb in the function name, but similarly have no strong preferences on it. > > > > +{ > > + /* Check if the access is from Root PA */ > > + if (!(attrs.space == ARMSS_Root)) { > > Could we use the comparison operator (!=) instead of the logical one here? I > think it's clearer than a negation. > Good point, that is clearer. > > + case A_ROOT_GPT_BASE2: > > + *data = s->root.gpt_base2; > > + return MEMTX_OK; > > + case A_ROOT_GPCBW: > > + /* Optional, not implemented. Present if ROOT_IDR0.GPTS == 0 */ > > GPTS == 1 here? -----^ Correct, thank you. > > @@ -411,6 +411,28 @@ REG32(EVENTQ_IRQ_CFG2, 0xbc) > > > > #define A_IDREGS 0xfd0 > > > > +#define SMMU_ROOT_REG_START 0x20000 > > The base address for the Root Control Page is implementation defined, hence > 0x20000 is not always true and depends on the machine/platform. We could add > property to set it externaly but it would also complicate unnecessarily the > offset math. So I think it's ok to follow what FVP is doing. Please just add a > note saying it's impl. defined so it might require a tweak in the > future. > > I think we can follow TF-A code here and rename this macro. So how about > renaming it to: > > SMMUV3_ROOT_REG_OFFSET ? > I'll add another comment and yes, that name change makes sense. ... > > +typedef struct SMMUv3RootRegBank { > > How about naming this struct simply SMMUv3Root? I don't mind renaming it to something other than 'Bank' to avoid conflicts with another meaning of register bank (e.g. the actually banked registers), for example SMMUv3RootControlPage would be fine. If it's just to save space on punch cards, I'm less keen, but will happily follow code conventions. > > > > + uint32_t idr0; > > + uint32_t iidr; > > + uint32_t cr0; > > + uint32_t cr0ack; > > + uint64_t gpt_base; > > + uint64_t gpt_base_cfg; > > + uint64_t gpf_far; > > + uint64_t gpt_cfg_far; > > + uint64_t gpt_base2; > > Looking at ARM IHI 0070 H.a Non-confidential spec I don't see > > 0x0068 SMMU_ROOT_GPT_BASE_UPDATE 32-bit, R/W and > 0x0070 SMMU_ROOT_GPCBW 64-bit, R/W > > as Optional like I see SMMU_ROOT_TLBI and SMMU_ROOT_TLBI_CTRL. > > Should they be declared as well? GPT_BASE_UPDATE is an unusual case; it has side effects when writing hence I was reluctant to include it as a normal config register, however, it shouldn't do any harm to add it - users will just see the 'update' bit stick as 1 forever if they write it. SMMU_ROOT_GPCBW is RES0 unless ROOT_IDR0.GPTS == 1 as noted above, and we don't define that bit at the moment, so making storage for it seemed unnecessary. > > > > +} SMMUv3RootRegBank; > > + > > struct SMMUv3State { > > SMMUState smmu_state; > > > > @@ -80,6 +92,7 @@ struct SMMUv3State { > > OnOffAuto cmdqv; > > > > Notifier machine_done; > > + SMMUv3RootRegBank root; > > }; > > > > typedef enum { > > > > -- > > 2.43.0 > > > > > > General comments: > > smmu_read_mmio_root > smmu_write_mmio_root > > I think we can drop the "mmio_" for both functions. It's ok to have "mmio_" in > the "trace_smmuv3_write_mmio" trace function because afaics it has a generic use, > so its use is not tied to any bank. Yep, fine by me. > > > I think we're missing to reset some registers in smmuv3_reset()? Like: > > s->root.cr0 = 0; > s->root.cr0ack = 0; > s->root.gpf_far = 0; > s->root.gpt_cfg_far = 0; Good point, we are missing those, thanks. Thanks for the review! Jim ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/2] hw/arm/sbsa-ref.c: Increase SMMU space for Root registers 2026-10-16 9:40 [PATCH 0/2] Add SMMUv3 Root registers Jim MacArthur 2026-10-16 9:40 ` [PATCH 1/2] hw/arm/smmuv3: define " Jim MacArthur @ 2026-10-16 9:40 ` Jim MacArthur 2026-10-16 11:02 ` Leif Lindholm 2026-11-06 22:21 ` Gustavo Romero 1 sibling, 2 replies; 10+ messages in thread From: Jim MacArthur @ 2026-10-16 9:40 UTC (permalink / raw) To: qemu-devel Cc: Eric Auger, Peter Maydell, qemu-arm, Leif Lindholm, Jim MacArthur In our implementation, SMMU Root registers are directly after the non-optional SMMU registers. Realms registers will be added above the root registers later. Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org> --- hw/arm/sbsa-ref.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index 158b461eb4..0747f5ca9f 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -129,7 +129,7 @@ static const MemMapEntry sbsa_ref_memmap[] = { [SBSA_GPIO] = { 0x60020000, 0x00001000 }, [SBSA_SECURE_UART] = { 0x60030000, 0x00001000 }, [SBSA_SECURE_UART_MM] = { 0x60040000, 0x00001000 }, - [SBSA_SMMU] = { 0x60050000, 0x00020000 }, + [SBSA_SMMU] = { 0x60050000, 0x00040000 }, /* Space here reserved for more SMMUs */ [SBSA_AHCI] = { 0x60100000, 0x00010000 }, [SBSA_XHCI] = { 0x60110000, 0x00010000 }, -- 2.43.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] hw/arm/sbsa-ref.c: Increase SMMU space for Root registers 2026-10-16 9:40 ` [PATCH 2/2] hw/arm/sbsa-ref.c: Increase SMMU space for " Jim MacArthur @ 2026-10-16 11:02 ` Leif Lindholm 2026-11-06 22:21 ` Gustavo Romero 1 sibling, 0 replies; 10+ messages in thread From: Leif Lindholm @ 2026-10-16 11:02 UTC (permalink / raw) To: Jim MacArthur; +Cc: qemu-devel, Eric Auger, Peter Maydell, qemu-arm On Fri, Oct 16, 2026 at 10:40:52 +0100, Jim MacArthur wrote: > In our implementation, SMMU Root registers are directly after the > non-optional SMMU registers. Realms registers will be added above the > root registers later. > > Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org> Acked-by: Leif Lindholm <leif.lindholm@oss.qualcomm.com> > --- > hw/arm/sbsa-ref.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c > index 158b461eb4..0747f5ca9f 100644 > --- a/hw/arm/sbsa-ref.c > +++ b/hw/arm/sbsa-ref.c > @@ -129,7 +129,7 @@ static const MemMapEntry sbsa_ref_memmap[] = { > [SBSA_GPIO] = { 0x60020000, 0x00001000 }, > [SBSA_SECURE_UART] = { 0x60030000, 0x00001000 }, > [SBSA_SECURE_UART_MM] = { 0x60040000, 0x00001000 }, > - [SBSA_SMMU] = { 0x60050000, 0x00020000 }, > + [SBSA_SMMU] = { 0x60050000, 0x00040000 }, > /* Space here reserved for more SMMUs */ > [SBSA_AHCI] = { 0x60100000, 0x00010000 }, > [SBSA_XHCI] = { 0x60110000, 0x00010000 }, > > -- > 2.43.0 > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] hw/arm/sbsa-ref.c: Increase SMMU space for Root registers 2026-10-16 9:40 ` [PATCH 2/2] hw/arm/sbsa-ref.c: Increase SMMU space for " Jim MacArthur 2026-10-16 11:02 ` Leif Lindholm @ 2026-11-06 22:21 ` Gustavo Romero 2026-11-11 16:31 ` Jim MacArthur 1 sibling, 1 reply; 10+ messages in thread From: Gustavo Romero @ 2026-11-06 22:21 UTC (permalink / raw) To: Jim MacArthur Cc: qemu-devel, Eric Auger, Peter Maydell, qemu-arm, Leif Lindholm Hi Jim, On Fri, Oct 16, 2026 at 10:40:52AM +0100, Jim MacArthur wrote: > In our implementation, SMMU Root registers are directly after the > non-optional SMMU registers. Realms registers will be added above the > root registers later. nit: Root registers > > Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org> > --- > hw/arm/sbsa-ref.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c > index 158b461eb4..0747f5ca9f 100644 > --- a/hw/arm/sbsa-ref.c > +++ b/hw/arm/sbsa-ref.c > @@ -129,7 +129,7 @@ static const MemMapEntry sbsa_ref_memmap[] = { > [SBSA_GPIO] = { 0x60020000, 0x00001000 }, > [SBSA_SECURE_UART] = { 0x60030000, 0x00001000 }, > [SBSA_SECURE_UART_MM] = { 0x60040000, 0x00001000 }, > - [SBSA_SMMU] = { 0x60050000, 0x00020000 }, > + [SBSA_SMMU] = { 0x60050000, 0x00040000 }, Why +0x20000 bytes here instead of +0x10000 bytes (1 x 64K page)? Most importantly, incresing the size of the SBSA_SMMU index is not enough, we need to increase also the size of the "arm-smmuv3" container (memory region). With this change applied I still see: 0000000060050000-000000006006ffff (prio 0, i/o): arm-smmuv3 on (qemu) info mtree. 2 x 64K pages: Page 0 and Page 1. Rather we should see a range to fit 3 x 64K: 0000000060050000-000000006007ffff (prio 0, i/o): arm-smmuv3 Another issue, afaics, is that the Root register page will be added to every machine that uses the SMMUv3 device, right? Because we're not gating the addition of Root registers based on the presence of RME. So I think we should add one boolean "x-root" property (flag) to the SMMUv3 device that will be used to increase the size of the "arm-smmuv3" if it's set and let it by default set to "false". This "x-root" property would be set at the machine level, so via object_property_set_bool() in create_smmu. For example: diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index 0747f5ca9f..36b0164510 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -630,6 +630,7 @@ static void create_smmu(const SBSAMachineState *sms, PCIBus *bus, &error_abort); object_property_set_link(OBJECT(dev), "secure-memory", OBJECT(secure_sysmem), &error_abort); + object_property_set_bool(OBJECT(dev), "x-root", true, &error_abort); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); for (i = 0; i < NUM_SMMU_IRQS; i++) { diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 9d9bc2601b..9912fbf920 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -2267,6 +2267,7 @@ static void smmu_realize(DeviceState *d, Error **errp) SMMUv3Class *c = ARM_SMMUV3_GET_CLASS(s); SysBusDevice *dev = SYS_BUS_DEVICE(d); Error *local_err = NULL; + uint64_t size = SMMUV3_REGS_SIZE; if (!smmu_validate_property(s, errp)) { return; @@ -2291,8 +2292,12 @@ static void smmu_realize(DeviceState *d, Error **errp) qemu_mutex_init(&s->mutex); + if (s->has_root) { + size += SMMUV3_ROOT_PAGE_SIZE; + } + memory_region_init_io(&sys->iomem, OBJECT(s), - &smmu_mem_ops, sys, TYPE_ARM_SMMUV3, 0x20000); + &smmu_mem_ops, sys, TYPE_ARM_SMMUV3, size); sys->mrtypename = TYPE_SMMUV3_IOMMU_MEMORY_REGION; @@ -2382,6 +2387,7 @@ static const Property smmuv3_properties[] = { /* Identifier used for ACPI IORT SMMUv3 (and DSDT for CMDQV) generation */ DEFINE_PROP_UINT8("identifier", SMMUv3State, identifier, 0), DEFINE_PROP_BOOL("accel", SMMUv3State, accel, false), + DEFINE_PROP_BOOL("x-root", SMMUv3State, has_root, false), /* GPA of MSI doorbell, for SMMUv3 accel use. */ DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0), /* diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h index a538334066..5d1cb759c3 100644 --- a/include/hw/arm/smmuv3-common.h +++ b/include/hw/arm/smmuv3-common.h @@ -411,7 +411,10 @@ REG32(EVENTQ_IRQ_CFG2, 0xbc) #define A_IDREGS 0xfd0 -#define SMMU_ROOT_REG_START 0x20000 +#define SMMUV3_PAGE_SIZE 0x10000 +#define SMMUV3_REGS_SIZE (2 * SMMUV3_PAGE_SIZE) /* Page 0 and Page 1 */ +#define SMMUV3_ROOT_REG_OFFSET 0x20000 +#define SMMUV3_ROOT_PAGE_SIZE SMMUV3_PAGE_SIZE REG32(ROOT_IDR0, 0x0) FIELD(ROOT_IDR0, ROOT_IMPL, 0, 1) diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h index e2708e13fe..a8b354438c 100644 --- a/include/hw/arm/smmuv3.h +++ b/include/hw/arm/smmuv3.h @@ -92,6 +92,7 @@ struct SMMUv3State { OnOffAuto cmdqv; Notifier machine_done; + bool has_root; SMMUv3RootRegBank root; }; Cheers, Gustavo > /* Space here reserved for more SMMUs */ > [SBSA_AHCI] = { 0x60100000, 0x00010000 }, > [SBSA_XHCI] = { 0x60110000, 0x00010000 }, > > -- > 2.43.0 > > ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] hw/arm/sbsa-ref.c: Increase SMMU space for Root registers 2026-11-06 22:21 ` Gustavo Romero @ 2026-11-11 16:31 ` Jim MacArthur 2026-11-11 18:10 ` Pierrick Bouvier 0 siblings, 1 reply; 10+ messages in thread From: Jim MacArthur @ 2026-11-11 16:31 UTC (permalink / raw) To: Gustavo Romero Cc: qemu-devel, Eric Auger, Peter Maydell, qemu-arm, Leif Lindholm On Fri, Nov 06, 2026 at 11:21:12PM +0100, Gustavo Romero wrote: > Hi Jim, > > On Fri, Oct 16, 2026 at 10:40:52AM +0100, Jim MacArthur wrote: > > In our implementation, SMMU Root registers are directly after the > > non-optional SMMU registers. Realms registers will be added above the > > root registers later. > > nit: Root registers Noted. > > > > > > Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org> > > --- > > hw/arm/sbsa-ref.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c > > index 158b461eb4..0747f5ca9f 100644 > > --- a/hw/arm/sbsa-ref.c > > +++ b/hw/arm/sbsa-ref.c > > @@ -129,7 +129,7 @@ static const MemMapEntry sbsa_ref_memmap[] = { > > [SBSA_GPIO] = { 0x60020000, 0x00001000 }, > > [SBSA_SECURE_UART] = { 0x60030000, 0x00001000 }, > > [SBSA_SECURE_UART_MM] = { 0x60040000, 0x00001000 }, > > - [SBSA_SMMU] = { 0x60050000, 0x00020000 }, > > + [SBSA_SMMU] = { 0x60050000, 0x00040000 }, > > Why +0x20000 bytes here instead of +0x10000 bytes (1 x 64K page)? Ultimately the plan is to add the Realm registers in here as well, and those have to be at a 128K-aligned offset from the SMMU base, so per the original plan they would have started at 0x40000. Now that you mention it though, it makes more sense to slot the Realm registers in at offset 0x20000 and move the Root registers to 0x40000 when we do so - which means we still have space in the memory map for a second SMMU. So for now, I'll trim this back to +0x10000. > > Most importantly, incresing the size of the SBSA_SMMU index is not enough, we > need to increase also the size of the "arm-smmuv3" container (memory region). > > With this change applied I still see: > > 0000000060050000-000000006006ffff (prio 0, i/o): arm-smmuv3 Thanks, I hadn't spotted that the actual allocation was specified separately; I'll fix that in the next version. > > on (qemu) info mtree. > > 2 x 64K pages: Page 0 and Page 1. Rather we should see a range to fit 3 x 64K: > > 0000000060050000-000000006007ffff (prio 0, i/o): arm-smmuv3 > > Another issue, afaics, is that the Root register page will be added to > every machine that uses the SMMUv3 device, right? Because we're not gating the > addition of Root registers based on the presence of RME. > > So I think we should add one boolean "x-root" property (flag) to the SMMUv3 > device that will be used to increase the size of the "arm-smmuv3" if it's set > and let it by default set to "false". > > This "x-root" property would be set at the machine level, so via > object_property_set_bool() in create_smmu. For example: > > diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c > index 0747f5ca9f..36b0164510 100644 > --- a/hw/arm/sbsa-ref.c > +++ b/hw/arm/sbsa-ref.c > @@ -630,6 +630,7 @@ static void create_smmu(const SBSAMachineState *sms, PCIBus *bus, > &error_abort); > object_property_set_link(OBJECT(dev), "secure-memory", OBJECT(secure_sysmem), > &error_abort); > + object_property_set_bool(OBJECT(dev), "x-root", true, &error_abort); > sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); > sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); > for (i = 0; i < NUM_SMMU_IRQS; i++) { > diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c > index 9d9bc2601b..9912fbf920 100644 > --- a/hw/arm/smmuv3.c > +++ b/hw/arm/smmuv3.c > @@ -2267,6 +2267,7 @@ static void smmu_realize(DeviceState *d, Error **errp) > SMMUv3Class *c = ARM_SMMUV3_GET_CLASS(s); > SysBusDevice *dev = SYS_BUS_DEVICE(d); > Error *local_err = NULL; > + uint64_t size = SMMUV3_REGS_SIZE; > > if (!smmu_validate_property(s, errp)) { > return; > @@ -2291,8 +2292,12 @@ static void smmu_realize(DeviceState *d, Error **errp) > > qemu_mutex_init(&s->mutex); > > + if (s->has_root) { > + size += SMMUV3_ROOT_PAGE_SIZE; > + } > + > memory_region_init_io(&sys->iomem, OBJECT(s), > - &smmu_mem_ops, sys, TYPE_ARM_SMMUV3, 0x20000); > + &smmu_mem_ops, sys, TYPE_ARM_SMMUV3, size); > > sys->mrtypename = TYPE_SMMUV3_IOMMU_MEMORY_REGION; > > @@ -2382,6 +2387,7 @@ static const Property smmuv3_properties[] = { > /* Identifier used for ACPI IORT SMMUv3 (and DSDT for CMDQV) generation */ > DEFINE_PROP_UINT8("identifier", SMMUv3State, identifier, 0), > DEFINE_PROP_BOOL("accel", SMMUv3State, accel, false), > + DEFINE_PROP_BOOL("x-root", SMMUv3State, has_root, false), > /* GPA of MSI doorbell, for SMMUv3 accel use. */ > DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0), > /* > diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h > index a538334066..5d1cb759c3 100644 > --- a/include/hw/arm/smmuv3-common.h > +++ b/include/hw/arm/smmuv3-common.h > @@ -411,7 +411,10 @@ REG32(EVENTQ_IRQ_CFG2, 0xbc) > > #define A_IDREGS 0xfd0 > > -#define SMMU_ROOT_REG_START 0x20000 > +#define SMMUV3_PAGE_SIZE 0x10000 > +#define SMMUV3_REGS_SIZE (2 * SMMUV3_PAGE_SIZE) /* Page 0 and Page 1 */ > +#define SMMUV3_ROOT_REG_OFFSET 0x20000 > +#define SMMUV3_ROOT_PAGE_SIZE SMMUV3_PAGE_SIZE > > REG32(ROOT_IDR0, 0x0) > FIELD(ROOT_IDR0, ROOT_IMPL, 0, 1) > diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h > index e2708e13fe..a8b354438c 100644 > --- a/include/hw/arm/smmuv3.h > +++ b/include/hw/arm/smmuv3.h > @@ -92,6 +92,7 @@ struct SMMUv3State { > OnOffAuto cmdqv; > > Notifier machine_done; > + bool has_root; > SMMUv3RootRegBank root; > }; > > > Cheers, > Gustavo Thank you for doing this. The only complication is that we'll probably want an x-realms flag as well later, and if we do the rearrangement of the map as above then SMMUV3_ROOT_REG_OFFSET will have to be variable. I'll handle that when we get to the Realm part. Jim ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] hw/arm/sbsa-ref.c: Increase SMMU space for Root registers 2026-11-11 16:31 ` Jim MacArthur @ 2026-11-11 18:10 ` Pierrick Bouvier 2026-11-12 18:59 ` Gustavo Romero 0 siblings, 1 reply; 10+ messages in thread From: Pierrick Bouvier @ 2026-11-11 18:10 UTC (permalink / raw) To: Jim MacArthur, Gustavo Romero Cc: qemu-devel, Eric Auger, Peter Maydell, qemu-arm, Leif Lindholm On 11/11/2026 8:31 AM, Jim MacArthur wrote: > On Fri, Nov 06, 2026 at 11:21:12PM +0100, Gustavo Romero wrote: >> Hi Jim, >> >> On Fri, Oct 16, 2026 at 10:40:52AM +0100, Jim MacArthur wrote: >>> In our implementation, SMMU Root registers are directly after the >>> non-optional SMMU registers. Realms registers will be added above the >>> root registers later. >> >> nit: Root registers > > Noted. > >> >> >>> >>> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org> >>> --- >>> hw/arm/sbsa-ref.c | 2 +- >>> 1 file changed, 1 insertion(+), 1 deletion(-) >>> >>> diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c >>> index 158b461eb4..0747f5ca9f 100644 >>> --- a/hw/arm/sbsa-ref.c >>> +++ b/hw/arm/sbsa-ref.c >>> @@ -129,7 +129,7 @@ static const MemMapEntry sbsa_ref_memmap[] = { >>> [SBSA_GPIO] = { 0x60020000, 0x00001000 }, >>> [SBSA_SECURE_UART] = { 0x60030000, 0x00001000 }, >>> [SBSA_SECURE_UART_MM] = { 0x60040000, 0x00001000 }, >>> - [SBSA_SMMU] = { 0x60050000, 0x00020000 }, >>> + [SBSA_SMMU] = { 0x60050000, 0x00040000 }, >> >> Why +0x20000 bytes here instead of +0x10000 bytes (1 x 64K page)? > > Ultimately the plan is to add the Realm registers in here as well, and > those have to be at a 128K-aligned offset from the SMMU base, so per the > original plan they would have started at 0x40000. Now that you mention it > though, it makes more sense to slot the Realm registers in at offset 0x20000 > and move the Root registers to 0x40000 when we do so - which means we still > have space in the memory map for a second SMMU. So for now, I'll trim > this back to +0x10000. > >> >> Most importantly, incresing the size of the SBSA_SMMU index is not enough, we >> need to increase also the size of the "arm-smmuv3" container (memory region). >> >> With this change applied I still see: >> >> 0000000060050000-000000006006ffff (prio 0, i/o): arm-smmuv3 > > Thanks, I hadn't spotted that the actual allocation was specified separately; > I'll fix that in the next version. > >> >> on (qemu) info mtree. >> >> 2 x 64K pages: Page 0 and Page 1. Rather we should see a range to fit 3 x 64K: >> >> 0000000060050000-000000006007ffff (prio 0, i/o): arm-smmuv3 >> >> Another issue, afaics, is that the Root register page will be added to >> every machine that uses the SMMUv3 device, right? Because we're not gating the >> addition of Root registers based on the presence of RME. >> >> So I think we should add one boolean "x-root" property (flag) to the SMMUv3 >> device that will be used to increase the size of the "arm-smmuv3" if it's set >> and let it by default set to "false". >> >> This "x-root" property would be set at the machine level, so via >> object_property_set_bool() in create_smmu. For example: >> >> diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c >> index 0747f5ca9f..36b0164510 100644 >> --- a/hw/arm/sbsa-ref.c >> +++ b/hw/arm/sbsa-ref.c >> @@ -630,6 +630,7 @@ static void create_smmu(const SBSAMachineState *sms, PCIBus *bus, >> &error_abort); >> object_property_set_link(OBJECT(dev), "secure-memory", OBJECT(secure_sysmem), >> &error_abort); >> + object_property_set_bool(OBJECT(dev), "x-root", true, &error_abort); >> sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); >> sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); >> for (i = 0; i < NUM_SMMU_IRQS; i++) { >> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c >> index 9d9bc2601b..9912fbf920 100644 >> --- a/hw/arm/smmuv3.c >> +++ b/hw/arm/smmuv3.c >> @@ -2267,6 +2267,7 @@ static void smmu_realize(DeviceState *d, Error **errp) >> SMMUv3Class *c = ARM_SMMUV3_GET_CLASS(s); >> SysBusDevice *dev = SYS_BUS_DEVICE(d); >> Error *local_err = NULL; >> + uint64_t size = SMMUV3_REGS_SIZE; >> >> if (!smmu_validate_property(s, errp)) { >> return; >> @@ -2291,8 +2292,12 @@ static void smmu_realize(DeviceState *d, Error **errp) >> >> qemu_mutex_init(&s->mutex); >> >> + if (s->has_root) { >> + size += SMMUV3_ROOT_PAGE_SIZE; >> + } >> + >> memory_region_init_io(&sys->iomem, OBJECT(s), >> - &smmu_mem_ops, sys, TYPE_ARM_SMMUV3, 0x20000); >> + &smmu_mem_ops, sys, TYPE_ARM_SMMUV3, size); >> >> sys->mrtypename = TYPE_SMMUV3_IOMMU_MEMORY_REGION; >> >> @@ -2382,6 +2387,7 @@ static const Property smmuv3_properties[] = { >> /* Identifier used for ACPI IORT SMMUv3 (and DSDT for CMDQV) generation */ >> DEFINE_PROP_UINT8("identifier", SMMUv3State, identifier, 0), >> DEFINE_PROP_BOOL("accel", SMMUv3State, accel, false), >> + DEFINE_PROP_BOOL("x-root", SMMUv3State, has_root, false), >> /* GPA of MSI doorbell, for SMMUv3 accel use. */ >> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0), >> /* >> diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h >> index a538334066..5d1cb759c3 100644 >> --- a/include/hw/arm/smmuv3-common.h >> +++ b/include/hw/arm/smmuv3-common.h >> @@ -411,7 +411,10 @@ REG32(EVENTQ_IRQ_CFG2, 0xbc) >> >> #define A_IDREGS 0xfd0 >> >> -#define SMMU_ROOT_REG_START 0x20000 >> +#define SMMUV3_PAGE_SIZE 0x10000 >> +#define SMMUV3_REGS_SIZE (2 * SMMUV3_PAGE_SIZE) /* Page 0 and Page 1 */ >> +#define SMMUV3_ROOT_REG_OFFSET 0x20000 >> +#define SMMUV3_ROOT_PAGE_SIZE SMMUV3_PAGE_SIZE >> >> REG32(ROOT_IDR0, 0x0) >> FIELD(ROOT_IDR0, ROOT_IMPL, 0, 1) >> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h >> index e2708e13fe..a8b354438c 100644 >> --- a/include/hw/arm/smmuv3.h >> +++ b/include/hw/arm/smmuv3.h >> @@ -92,6 +92,7 @@ struct SMMUv3State { >> OnOffAuto cmdqv; >> >> Notifier machine_done; >> + bool has_root; >> SMMUv3RootRegBank root; >> }; >> >> >> Cheers, >> Gustavo > > Thank you for doing this. The only complication is that we'll probably want > an x-realms flag as well later, and if we do the rearrangement of the map > as above then SMMUV3_ROOT_REG_OFFSET will have to be variable. I'll handle > that when we get to the Realm part. > The biggest different with realms is the presence of GPC, for which the GPT has to be configured correctly to allow accesses. However, in TF-A, this is gated behind cpu support for realms, which also require setting up GPT. ``` /* drivers/arm/smmu/smmu_v3.c */ if (is_feat_rme_present()) { if ((mmio_read_32(smmu_base + SMMU_ROOT_IDR0) & SMMU_ROOT_IDR0_ROOT_IMPL) == 0U) { WARN("Skip SMMU GPC configuration.\n"); } else { uint64_t gpccr_el3 = read_gpccr_el3(); uint64_t gptbr_el3 = read_gptbr_el3(); /* SMMU_ROOT_GPT_BASE_CFG[16] is RES0. */ gpccr_el3 &= ~(1UL << 16); mmio_write_32(smmu_base +SMMU_ROOT_GPT_BASE_CFG, gpccr_el3); mmio_write_64(smmu_base + SMMU_ROOT_GPT_BASE, gptbr_el3 << 12); mmio_setbits_32(smmu_base + SMMU_ROOT_CR0, SMMU_ROOT_CR0_GPCEN); } } ``` As a result, once both will enabled (root + realm), I think we can enable both by default, as they will be automatically depend on cpu support for realms. For now, root only would have to be false by default though. At the time, I could also run all our tests successfully, without having to do any modification. > Jim > Regards, Pierrick ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] hw/arm/sbsa-ref.c: Increase SMMU space for Root registers 2026-11-11 18:10 ` Pierrick Bouvier @ 2026-11-12 18:59 ` Gustavo Romero 0 siblings, 0 replies; 10+ messages in thread From: Gustavo Romero @ 2026-11-12 18:59 UTC (permalink / raw) To: Pierrick Bouvier Cc: Jim MacArthur, qemu-devel, Eric Auger, Peter Maydell, qemu-arm, Leif Lindholm Hi Jim and Pierrick, On Wed, Nov 11, 2026 at 10:10:18AM -0800, Pierrick Bouvier wrote: > On 11/11/2026 8:31 AM, Jim MacArthur wrote: > > On Fri, Nov 06, 2026 at 11:21:12PM +0100, Gustavo Romero wrote: > >> Hi Jim, > >> > >> On Fri, Oct 16, 2026 at 10:40:52AM +0100, Jim MacArthur wrote: > >>> In our implementation, SMMU Root registers are directly after the > >>> non-optional SMMU registers. Realms registers will be added above the > >>> root registers later. > >> > >> nit: Root registers > > > > Noted. > > > >> > >> > >>> > >>> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org> > >>> --- > >>> hw/arm/sbsa-ref.c | 2 +- > >>> 1 file changed, 1 insertion(+), 1 deletion(-) > >>> > >>> diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c > >>> index 158b461eb4..0747f5ca9f 100644 > >>> --- a/hw/arm/sbsa-ref.c > >>> +++ b/hw/arm/sbsa-ref.c > >>> @@ -129,7 +129,7 @@ static const MemMapEntry sbsa_ref_memmap[] = { > >>> [SBSA_GPIO] = { 0x60020000, 0x00001000 }, > >>> [SBSA_SECURE_UART] = { 0x60030000, 0x00001000 }, > >>> [SBSA_SECURE_UART_MM] = { 0x60040000, 0x00001000 }, > >>> - [SBSA_SMMU] = { 0x60050000, 0x00020000 }, > >>> + [SBSA_SMMU] = { 0x60050000, 0x00040000 }, > >> > >> Why +0x20000 bytes here instead of +0x10000 bytes (1 x 64K page)? > > > > Ultimately the plan is to add the Realm registers in here as well, and > > those have to be at a 128K-aligned offset from the SMMU base, so per the > > original plan they would have started at 0x40000. Now that you mention it > > though, it makes more sense to slot the Realm registers in at offset 0x20000 > > and move the Root registers to 0x40000 when we do so - which means we still > > have space in the memory map for a second SMMU. So for now, I'll trim > > this back to +0x10000. > > > >> > >> Most importantly, incresing the size of the SBSA_SMMU index is not enough, we > >> need to increase also the size of the "arm-smmuv3" container (memory region). > >> > >> With this change applied I still see: > >> > >> 0000000060050000-000000006006ffff (prio 0, i/o): arm-smmuv3 > > > > Thanks, I hadn't spotted that the actual allocation was specified separately; > > I'll fix that in the next version. > > > >> > >> on (qemu) info mtree. > >> > >> 2 x 64K pages: Page 0 and Page 1. Rather we should see a range to fit 3 x 64K: > >> > >> 0000000060050000-000000006007ffff (prio 0, i/o): arm-smmuv3 > >> > >> Another issue, afaics, is that the Root register page will be added to > >> every machine that uses the SMMUv3 device, right? Because we're not gating the > >> addition of Root registers based on the presence of RME. > >> > >> So I think we should add one boolean "x-root" property (flag) to the SMMUv3 > >> device that will be used to increase the size of the "arm-smmuv3" if it's set > >> and let it by default set to "false". > >> > >> This "x-root" property would be set at the machine level, so via > >> object_property_set_bool() in create_smmu. For example: > >> > >> diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c > >> index 0747f5ca9f..36b0164510 100644 > >> --- a/hw/arm/sbsa-ref.c > >> +++ b/hw/arm/sbsa-ref.c > >> @@ -630,6 +630,7 @@ static void create_smmu(const SBSAMachineState *sms, PCIBus *bus, > >> &error_abort); > >> object_property_set_link(OBJECT(dev), "secure-memory", OBJECT(secure_sysmem), > >> &error_abort); > >> + object_property_set_bool(OBJECT(dev), "x-root", true, &error_abort); > >> sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); > >> sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); > >> for (i = 0; i < NUM_SMMU_IRQS; i++) { > >> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c > >> index 9d9bc2601b..9912fbf920 100644 > >> --- a/hw/arm/smmuv3.c > >> +++ b/hw/arm/smmuv3.c > >> @@ -2267,6 +2267,7 @@ static void smmu_realize(DeviceState *d, Error **errp) > >> SMMUv3Class *c = ARM_SMMUV3_GET_CLASS(s); > >> SysBusDevice *dev = SYS_BUS_DEVICE(d); > >> Error *local_err = NULL; > >> + uint64_t size = SMMUV3_REGS_SIZE; > >> > >> if (!smmu_validate_property(s, errp)) { > >> return; > >> @@ -2291,8 +2292,12 @@ static void smmu_realize(DeviceState *d, Error **errp) > >> > >> qemu_mutex_init(&s->mutex); > >> > >> + if (s->has_root) { > >> + size += SMMUV3_ROOT_PAGE_SIZE; > >> + } > >> + > >> memory_region_init_io(&sys->iomem, OBJECT(s), > >> - &smmu_mem_ops, sys, TYPE_ARM_SMMUV3, 0x20000); > >> + &smmu_mem_ops, sys, TYPE_ARM_SMMUV3, size); > >> > >> sys->mrtypename = TYPE_SMMUV3_IOMMU_MEMORY_REGION; > >> > >> @@ -2382,6 +2387,7 @@ static const Property smmuv3_properties[] = { > >> /* Identifier used for ACPI IORT SMMUv3 (and DSDT for CMDQV) generation */ > >> DEFINE_PROP_UINT8("identifier", SMMUv3State, identifier, 0), > >> DEFINE_PROP_BOOL("accel", SMMUv3State, accel, false), > >> + DEFINE_PROP_BOOL("x-root", SMMUv3State, has_root, false), > >> /* GPA of MSI doorbell, for SMMUv3 accel use. */ > >> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0), > >> /* > >> diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h > >> index a538334066..5d1cb759c3 100644 > >> --- a/include/hw/arm/smmuv3-common.h > >> +++ b/include/hw/arm/smmuv3-common.h > >> @@ -411,7 +411,10 @@ REG32(EVENTQ_IRQ_CFG2, 0xbc) > >> > >> #define A_IDREGS 0xfd0 > >> > >> -#define SMMU_ROOT_REG_START 0x20000 > >> +#define SMMUV3_PAGE_SIZE 0x10000 > >> +#define SMMUV3_REGS_SIZE (2 * SMMUV3_PAGE_SIZE) /* Page 0 and Page 1 */ > >> +#define SMMUV3_ROOT_REG_OFFSET 0x20000 > >> +#define SMMUV3_ROOT_PAGE_SIZE SMMUV3_PAGE_SIZE > >> > >> REG32(ROOT_IDR0, 0x0) > >> FIELD(ROOT_IDR0, ROOT_IMPL, 0, 1) > >> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h > >> index e2708e13fe..a8b354438c 100644 > >> --- a/include/hw/arm/smmuv3.h > >> +++ b/include/hw/arm/smmuv3.h > >> @@ -92,6 +92,7 @@ struct SMMUv3State { > >> OnOffAuto cmdqv; > >> > >> Notifier machine_done; > >> + bool has_root; > >> SMMUv3RootRegBank root; > >> }; > >> > >> > >> Cheers, > >> Gustavo > > > > Thank you for doing this. The only complication is that we'll probably want > > an x-realms flag as well later, and if we do the rearrangement of the map > > as above then SMMUV3_ROOT_REG_OFFSET will have to be variable. I'll handle > > that when we get to the Realm part. @Jim Why would you need to rearrange the SMMUV3_ROOT_REG_OFFSET? I was expecting the Root registers would stay still at +0x20000, i.e., at the start of the "OPTIONAL pages", just after the "SMMU Register Page 1". > > The biggest different with realms is the presence of GPC, for which the > GPT has to be configured correctly to allow accesses. > However, in TF-A, this is gated behind cpu support for realms, which > also require setting up GPT. > > ``` > /* drivers/arm/smmu/smmu_v3.c */ > if (is_feat_rme_present()) { > if ((mmio_read_32(smmu_base + SMMU_ROOT_IDR0) & > SMMU_ROOT_IDR0_ROOT_IMPL) == 0U) { > WARN("Skip SMMU GPC configuration.\n"); > } else { > uint64_t gpccr_el3 = read_gpccr_el3(); > uint64_t gptbr_el3 = read_gptbr_el3(); > > /* SMMU_ROOT_GPT_BASE_CFG[16] is RES0. */ > gpccr_el3 &= ~(1UL << 16); > mmio_write_32(smmu_base +SMMU_ROOT_GPT_BASE_CFG, > gpccr_el3); > mmio_write_64(smmu_base + SMMU_ROOT_GPT_BASE, > gptbr_el3 << 12); > mmio_setbits_32(smmu_base + SMMU_ROOT_CR0, > SMMU_ROOT_CR0_GPCEN); > } > } > ``` > > As a result, once both will enabled (root + realm), I think we can > enable both by default, as they will be automatically depend on cpu > support for realms. For now, root only would have to be false by default > though. @Pierrick Thanks a lot for the pointer. So I think we can rename "x-root" flag with the introduction of the Realm Registers to something like "x-realm" and gate both Root and Realm register banks based on it. Also, I could not find out anything in the docs that contradicts it, so the Root registers are always present on SMMUs with RME. Yes, that's what I think too, for now the Root registers would not be exposed by default. Cheers, Gustavo ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-11-12 18:59 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-10-16 9:40 [PATCH 0/2] Add SMMUv3 Root registers Jim MacArthur 2026-10-16 9:40 ` [PATCH 1/2] hw/arm/smmuv3: define " Jim MacArthur 2026-11-06 22:20 ` Gustavo Romero 2026-11-10 16:21 ` Jim MacArthur 2026-10-16 9:40 ` [PATCH 2/2] hw/arm/sbsa-ref.c: Increase SMMU space for " Jim MacArthur 2026-10-16 11:02 ` Leif Lindholm 2026-11-06 22:21 ` Gustavo Romero 2026-11-11 16:31 ` Jim MacArthur 2026-11-11 18:10 ` Pierrick Bouvier 2026-11-12 18:59 ` Gustavo Romero
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.