Repository: OP-TEE/optee_os
Pull request #7396: (STM32) drivers: Implement AHB RISAB3/4/5 illegal access due to ghost CID0 detection errata
Author: login: GseoC
Created: 2025-05-15T13:17:53Z | Merged: 2025-05-21T08:58:58Z

When an AHB busy signal is inserted during a transaction, a ghost CID0 is generated on the bus. If the
compartment filtering is enabled on RISAB3/4/5, this transient CID0 is interpreted as a fault access by
RISAB3/4/5 which aborts current access and returns an IAC.

Link to errata (section 2.3.21): [https://www.st.com/resource/en/errata_sheet/es0598-stm32mp23xx25xx-device-errata-stmicroelectronics.pdf](url)



Diff:
diff --git a/core/drivers/firewall/stm32_rifsc.c b/core/drivers/firewall/stm32_rifsc.c
index 3e0528e56ae..3b4f33f14dc 100644
--- a/core/drivers/firewall/stm32_rifsc.c
+++ b/core/drivers/firewall/stm32_rifsc.c
@@ -98,8 +98,10 @@
 
 #define RIFSC_RISC_PERx_CID_SHIFT	U(0)
 
-#define RIFSC_RIMC_MODE_MASK		BIT(2)
+#define RIFSC_RIMC_CIDSEL_MASK		BIT(2)
+#define RIFSC_RIMC_CIDSEL_SHIFT		U(2)
 #define RIFSC_RIMC_MCID_MASK		GENMASK_32(6, 4)
+#define RIFSC_RIMC_MCID_SHIFT		U(4)
 #define RIFSC_RIMC_MSEC_MASK		BIT(8)
 #define RIFSC_RIMC_MPRIV_MASK		BIT(9)
 #define RIFSC_RIMC_M_ID_MASK		GENMASK_32(23, 16)
@@ -117,6 +119,8 @@
 					  (field ## _MASK)) >>\
 					 (field ## _SHIFT))
 
+#define NO_RISUP_ID			UINT32_MAX
+
 struct risup_cfg {
 	uint32_t cid_attr;
 	uint32_t id;
@@ -128,6 +132,7 @@ struct risup_cfg {
 
 struct rimu_cfg {
 	uint32_t id;
+	uint32_t risup_id;
 	uint32_t attr;
 };
 
@@ -157,6 +162,85 @@ struct rifsc_platdata {
 	struct risal_cfg *risal;
 	unsigned int nrisal;
 	bool is_tdcid;
+	bool errata_ahbrisab;
+};
+
+/**
+ * struct rimu_risup_pairs - Association of a RISUP and RIMU ID for a peripheral
+ *
+ * @rimu_id: ID of the RIMU
+ * @risup_id: ID of the associated RISUP
+ */
+struct rimu_risup_pairs {
+	uint32_t rimu_id;
+	uint32_t risup_id;
+};
+
+static const struct rimu_risup_pairs rimu_risup[] = {
+	[0] = {
+		.rimu_id = 0,
+		.risup_id = NO_RISUP_ID,
+	},
+	[1] = {
+		.rimu_id = 1,
+		.risup_id = STM32MP25_RIFSC_SDMMC1_ID,
+	},
+	[2] = {
+		.rimu_id = 2,
+		.risup_id = STM32MP25_RIFSC_SDMMC2_ID,
+	},
+	[3] = {
+		.rimu_id = 3,
+		.risup_id = STM32MP25_RIFSC_SDMMC3_ID,
+	},
+	[4] = {
+		.rimu_id = 4,
+		.risup_id = STM32MP25_RIFSC_USB3DR_ID,
+	},
+	[5] = {
+		.rimu_id = 5,
+		.risup_id = STM32MP25_RIFSC_USBH_ID,
+	},
+	[6] = {
+		.rimu_id = 6,
+		.risup_id = STM32MP25_RIFSC_ETH1_ID,
+	},
+	[7] = {
+		.rimu_id = 7,
+		.risup_id = STM32MP25_RIFSC_ETH2_ID,
+	},
+	[8] = {
+		.rimu_id = 8,
+		.risup_id = STM32MP25_RIFSC_PCIE_ID,
+	},
+	[9] = {
+		.rimu_id = 9,
+		.risup_id = STM32MP25_RIFSC_GPU_ID,
+	},
+	[10] = {
+		.rimu_id = 10,
+		.risup_id = STM32MP25_RIFSC_DCMIPP_ID,
+	},
+	[11] = {
+		.rimu_id = 11,
+		.risup_id = NO_RISUP_ID,
+	},
+	[12] = {
+		.rimu_id = 12,
+		.risup_id = NO_RISUP_ID,
+	},
+	[13] = {
+		.rimu_id = 13,
+		.risup_id = NO_RISUP_ID,
+	},
+	[14] = {
+		.rimu_id = 14,
+		.risup_id = STM32MP25_RIFSC_VDEC_ID,
+	},
+	[15] = {
+		.rimu_id = 15,
+		.risup_id = STM32MP25_RIFSC_VENC_ID,
+	},
 };
 
 /* There is only 1 instance of the RIFSC subsystem */
@@ -286,7 +370,7 @@ static TEE_Result stm32_rifsc_dt_conf_rimu(const void *fdt, int node,
 		return TEE_ERROR_OUT_OF_MEMORY;
 
 	for (i = 0; i < pdata->nrimu; i++) {
-		uint32_t value = fdt32_to_cpu(*conf_list);
+		uint32_t value = fdt32_to_cpu(conf_list[i]);
 		struct rimu_cfg *rimu = pdata->rimu + i;
 
 		rimu->id = _RIF_FLD_GET(RIMUPROT_RIMC_M_ID, value) -
@@ -362,7 +446,10 @@ static TEE_Result stm32_rifsc_parse_fdt(const void *fdt, int node,
 		}
 	}
 
-	return stm32_rifsc_dt_conf_rimu(fdt, node, pdata);
+	rifsc_pdata.errata_ahbrisab = fdt_getprop(fdt, node,
+						  "st,errata-ahbrisab", NULL);
+
+	return TEE_SUCCESS;
 }
 
 static TEE_Result stm32_risup_cfg(struct rifsc_platdata *pdata,
@@ -424,6 +511,80 @@ static TEE_Result stm32_risup_setup(struct rifsc_platdata *pdata)
 	return TEE_SUCCESS;
 }
 
+/*
+ * Errata: When CID filtering is enabled on one of RISAB 3/4/5 instances, we
+ * forbid the use of CID0 for any initiator on the bus to handle transient CID0
+ * transactions on these RAMs.
+ */
+static void stm32_rimu_errata_ahbrisab(struct rifsc_platdata *pdata,
+				       struct rimu_cfg *rimu)
+{
+	unsigned int i = 0;
+
+	if (!pdata->errata_ahbrisab)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(rimu_risup); i++) {
+		if (rimu->id == rimu_risup[i].rimu_id) {
+			rimu->risup_id = rimu_risup[i].risup_id;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(rimu_risup))
+		panic();
+
+	if (rimu->attr & RIFSC_RIMC_CIDSEL_MASK) {
+		/* No inheritance mode for this RIMU */
+		if ((rimu->attr & RIFSC_RIMC_MCID_MASK) >>
+		    RIFSC_RIMC_MCID_SHIFT == RIF_CID0) {
+			EMSG("A CID should be set for RIMU %"PRIu32, rimu->id);
+			if (!IS_ENABLED(CFG_INSECURE))
+				panic();
+		}
+	} else {
+		struct risup_cfg *risup = NULL;
+		uint32_t risup_cidcfgr = 0;
+		unsigned int j = 0;
+
+		/* Handle RIMU with no inheritance mode */
+		if (rimu->risup_id == NO_RISUP_ID) {
+			EMSG("RIMU %"PRIu32" cannot be set in inheritance mode",
+			     rimu->id);
+			if (!IS_ENABLED(CFG_INSECURE))
+				panic();
+			return;
+		}
+
+		for (j = 0; j < pdata->nrisup; j++) {
+			if (rimu->risup_id == pdata->risup[j].id) {
+				risup = &pdata->risup[j];
+				break;
+			}
+		}
+
+		if (!risup)
+			panic();
+
+		risup_cidcfgr = io_read32(pdata->base +
+					  _RIFSC_RISC_PER0_CIDCFGR +
+					  _OFFSET_PERX_CIDCFGR * risup->id);
+
+		if (!(risup_cidcfgr & RIFSC_RISC_CIDCFGR_CFEN_MASK) ||
+		    (!(risup_cidcfgr & RIFSC_RISC_CIDCFGR_SEM_EN_MASK) &&
+		     ((risup_cidcfgr & RIFSC_RISC_CIDCFGR_SCID_MASK) >>
+		      RIFSC_RISC_CIDCFGR_SCID_SHIFT) == RIF_CID0) ||
+		    (risup_cidcfgr & RIFSC_RISC_CIDCFGR_SEM_EN_MASK &&
+		     risup_cidcfgr & BIT(RIF_CID0 +
+					 RIFSC_RISC_CIDCFGR_SEML_SHIFT))) {
+			EMSG("RIMU %"PRIu32" in inheritance mode with CID0",
+			     rimu->id);
+			if (!IS_ENABLED(CFG_INSECURE))
+				panic();
+		}
+	}
+}
+
 static TEE_Result stm32_rimu_cfg(struct rifsc_platdata *pdata,
 				 struct rimu_cfg *rimu)
 {
@@ -433,6 +594,8 @@ static TEE_Result stm32_rimu_cfg(struct rifsc_platdata *pdata,
 	if (!rimu || rimu->id >= drv_data->nb_rimu)
 		return TEE_ERROR_BAD_PARAMETERS;
 
+	stm32_rimu_errata_ahbrisab(pdata, rimu);
+
 	if (drv_data->rif_en)
 		io_write32(pdata->base + offset, rimu->attr);
 
diff --git a/core/drivers/firewall/stm32_risab.c b/core/drivers/firewall/stm32_risab.c
index 3c92250ae3e..0c37b4332c6 100644
--- a/core/drivers/firewall/stm32_risab.c
+++ b/core/drivers/firewall/stm32_risab.c
@@ -101,6 +101,7 @@ struct stm32_risab_pdata {
 	char risab_name[RISAB_NAME_LEN_MAX];
 	uint32_t pages_configured;
 	bool srwiad;
+	bool errata_ahbrisab;
 
 	SLIST_ENTRY(stm32_risab_pdata) link;
 };
@@ -239,8 +240,15 @@ static void set_read_conf(struct stm32_risab_pdata *risab_d,
 	uint32_t mask = GENMASK_32(last_page, subr_cfg->first_page);
 
 	for (i = 0; i < _RISAB_NB_MAX_CID_SUPPORTED; i++) {
-		if (subr_cfg->rlist[i])
-			io_setbits32(base + _RISAB_CIDxRDCFGR(i), mask);
+		/*
+		 * Errata: CID0 must be authorized for RISAB accesses if
+		 * CID filtering is enabled on some RISAB instances so that
+		 * transient CID0 transactions are handled.
+		 */
+		if (subr_cfg->rlist[i] ||
+		    (risab_d->errata_ahbrisab && i == RIF_CID0))
+			io_clrsetbits32(base + _RISAB_CIDxRDCFGR(i), mask,
+					mask);
 	}
 }
 
@@ -254,8 +262,15 @@ static void set_write_conf(struct stm32_risab_pdata *risab_d,
 	uint32_t mask = GENMASK_32(last_page, subr_cfg->first_page);
 
 	for (i = 0; i < _RISAB_NB_MAX_CID_SUPPORTED; i++) {
-		if (subr_cfg->wlist[i])
-			io_setbits32(base + _RISAB_CIDxWRCFGR(i), mask);
+		/*
+		 * Errata: CID0 must be authorized for RISAB accesses if
+		 * CID filtering is enabled on some RISAB instances so that
+		 * transient CID0 transactions are handled.
+		 */
+		if (subr_cfg->wlist[i] ||
+		    (risab_d->errata_ahbrisab && i == RIF_CID0))
+			io_clrsetbits32(base + _RISAB_CIDxWRCFGR(i), mask,
+					mask);
 	}
 }
 
@@ -452,6 +467,9 @@ static TEE_Result parse_dt(const void *fdt, int node,
 	if (cuint)
 		risab_d->srwiad = true;
 
+	risab_d->errata_ahbrisab = fdt_getprop(fdt, node, "st,errata-ahbrisab",
+					       NULL);
+
 	/* Get the memory region being configured */
 	cuint = fdt_getprop(fdt, node, "st,mem-map", &lenp);
 	if (!cuint)
diff --git a/core/drivers/stm32_hpdma.c b/core/drivers/stm32_hpdma.c
index a4a77c61433..e1a2ccfad9a 100644
--- a/core/drivers/stm32_hpdma.c
+++ b/core/drivers/stm32_hpdma.c
@@ -38,7 +38,9 @@
  * CIDCFGR register bitfields
  */
 #define _HPDMA_CIDCFGR_SEMWL_MASK	GENMASK_32(23, 16)
+#define _HPDMA_CIDCFGR_SEMWL_SHIFT	U(16)
 #define _HPDMA_CIDCFGR_SCID_MASK	GENMASK_32(5, 4)
+#define _HPDMA_CIDCFGR_SCID_SHIFT	U(4)
 #define _HPDMA_CIDCFGR_CONF_MASK	(_CIDCFGR_CFEN |	 \
 					 _CIDCFGR_SEMEN |	 \
 					 _HPDMA_CIDCFGR_SCID_MASK |\
@@ -79,6 +81,7 @@ struct hpdma_pdata {
 	struct rif_conf_data *conf_data;
 	unsigned int nb_channels;
 	vaddr_t base;
+	bool errata_ahbrisab;
 
 	SLIST_ENTRY(hpdma_pdata) link;
 };
@@ -168,12 +171,30 @@ static TEE_Result apply_rif_config(struct hpdma_pdata *hpdma_d, bool is_tdcid)
 		goto end;
 
 	for (i = 0; i < HPDMA_RIF_CHANNELS; i++) {
+		uint32_t cid_conf = hpdma_d->conf_data->cid_confs[i];
+
 		if (!(BIT(i) & hpdma_d->conf_data->access_mask[0]))
 			continue;
 
+		/*
+		 * Errata: When CID filtering is enabled on one of RISAB 3/4/5
+		 * instances, we forbid the use of CID0 for any initiator on the
+		 * bus to handle transient CID0 transactions on these RAMs.
+		 */
+		if (hpdma_d->errata_ahbrisab &&
+		    (!(cid_conf & _CIDCFGR_CFEN) ||
+		     (!(cid_conf & _CIDCFGR_SEMEN) &&
+		      ((cid_conf & _HPDMA_CIDCFGR_SCID_MASK) >>
+		       _HPDMA_CIDCFGR_SCID_SHIFT) == RIF_CID0) ||
+		     (cid_conf & _CIDCFGR_SEMEN &&
+		      cid_conf & BIT(RIF_CID0 + _HPDMA_CIDCFGR_SEMWL_SHIFT)))) {
+			EMSG("HPDMA channel cannot hold CID0 value");
+			if (!IS_ENABLED(CFG_INSECURE))
+				panic();
+		}
+
 		io_clrsetbits32(hpdma_d->base + _HPDMA_CIDCFGR(i),
-				_HPDMA_CIDCFGR_CONF_MASK,
-				hpdma_d->conf_data->cid_confs[i]);
+				_HPDMA_CIDCFGR_CONF_MASK, cid_conf);
 	}
 
 	/*
@@ -226,6 +247,9 @@ static TEE_Result parse_dt(const void *fdt, int node,
 	if (res)
 		return res;
 
+	hpdma_d->errata_ahbrisab = fdt_getprop(fdt, node, "st,errata-ahbrisab",
+					       NULL);
+
 	cuint = fdt_getprop(fdt, node, "st,protreg", &lenp);
 	if (!cuint) {
 		DMSG("No RIF configuration available");


Reviews:
user: login: etienne-lms
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T08:53:16Z
user: login: GseoC
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T09:07:01Z
user: login: GseoC
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T09:10:32Z
user: login: etienne-lms
body: 
`Acked-by: Etienne Carriere <etienne.carriere@foss.st.com>` for commit
"drivers: stm32_risab: implement transient CID0 on AHB errata for RISAB",
"drivers: stm32_rifsc: implement transient CID0 on AHB errata for RIMUs" and
"drivers: stm32_hpdma: implement transient CID0 on AHB errata for HPDMAs".

`Reviewed-by: Etienne Carriere <etienne.carriere@foss.st.com>` for commit
"drivers: stm32_rifsc: remove redundant and incorrect parsing of RIMU conf"

state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T15:33:31Z
user: login: GseoC
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T15:48:08Z
user: login: etienne-lms
body: `Reviewed-by: Etienne Carriere <etienne.carriere@foss.st.com>` for commit
"drivers: stm32_rifsc: fix RIMU configuration parsing".
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T15:00:43Z
user: login: etienne-lms
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T16:57:35Z

Review comments:
diff_hunk: @@ -157,6 +160,85 @@ struct rifsc_platdata {
 	struct risal_cfg *risal;
 	unsigned int nrisal;
 	bool is_tdcid;
+	bool errata_ahbrisab;
+};
+
+/**
+ * struct rimu_risup_pairs - Association of a RISUP and RIMU ID for a peripheral
+ *
+ * @rimu_id: ID of the RIMU
+ * @risup_id: ID of the associated RISUP
+ */
+struct rimu_risup_pairs {
+	uint32_t rimu_id;
+	uint32_t risup_id;
+};
+
+static const struct rimu_risup_pairs rimu_risup[] = {
+	[0] = {
+		.rimu_id = 0,
+		.risup_id = 0,
path: core/drivers/firewall/stm32_rifsc.c
user: login: etienne-lms
body: ID 0 seems a valid RIFSC ID but is used here as a magic to note the RIMU ID is not associated. It would be better to use a specific magic ID, e.g. `#define NO_RISUP_ID UINT32_MAX`.

created_at: 2025-05-19T08:39:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -157,6 +160,85 @@ struct rifsc_platdata {
 	struct risal_cfg *risal;
 	unsigned int nrisal;
 	bool is_tdcid;
+	bool errata_ahbrisab;
+};
+
+/**
+ * struct rimu_risup_pairs - Association of a RISUP and RIMU ID for a peripheral
+ *
+ * @rimu_id: ID of the RIMU
+ * @risup_id: ID of the associated RISUP
+ */
+struct rimu_risup_pairs {
+	uint32_t rimu_id;
+	uint32_t risup_id;
+};
+
+static const struct rimu_risup_pairs rimu_risup[] = {
+	[0] = {
+		.rimu_id = 0,
path: core/drivers/firewall/stm32_rifsc.c
user: login: etienne-lms
body: Field `rimu_id` seems to always be equal to the index of the related cell in `rimu_risup`. Will it be needed in the long term for specific IDs?
created_at: 2025-05-19T08:39:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -424,6 +509,75 @@ static TEE_Result stm32_risup_setup(struct rifsc_platdata *pdata)
 	return TEE_SUCCESS;
 }
 
+/*
+ * Errata: When CID filtering is enabled on one of RISAB 3/4/5 instances, we
+ * forbid the use of CID0 for any initiator on the bus to handle transient CID0
+ * transactions on these RAMs.
+ */
+static void stm32_rimu_errata_ahbrisab(struct rifsc_platdata *pdata,
+				       struct rimu_cfg *rimu)
+{
+	unsigned int i = 0;
+
+	if (!pdata->errata_ahbrisab)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(rimu_risup); i++) {
+		if (rimu->id == rimu_risup[i].rimu_id) {
+			rimu->risup_id = rimu_risup[i].risup_id;
+			break;
+		}
+	}
path: core/drivers/firewall/stm32_rifsc.c
user: login: etienne-lms
body: `assert(i < ARRAY_SIZE(rimu_risup))` or maybe `if (i == ARRAY_SIZE(rimu_risup) { panic(); }`
created_at: 2025-05-19T08:41:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -424,6 +509,75 @@ static TEE_Result stm32_risup_setup(struct rifsc_platdata *pdata)
 	return TEE_SUCCESS;
 }
 
+/*
+ * Errata: When CID filtering is enabled on one of RISAB 3/4/5 instances, we
+ * forbid the use of CID0 for any initiator on the bus to handle transient CID0
+ * transactions on these RAMs.
+ */
+static void stm32_rimu_errata_ahbrisab(struct rifsc_platdata *pdata,
+				       struct rimu_cfg *rimu)
+{
+	unsigned int i = 0;
+
+	if (!pdata->errata_ahbrisab)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(rimu_risup); i++) {
+		if (rimu->id == rimu_risup[i].rimu_id) {
+			rimu->risup_id = rimu_risup[i].risup_id;
+			break;
+		}
+	}
+
+	if (rimu->attr & RIFSC_RIMC_CIDSEL_MASK) {
+		/* No inheritance mode for this RIMU */
+		if ((rimu->attr & RIFSC_RIMC_MCID_MASK) >>
+		    RIFSC_RIMC_MCID_SHIFT == RIF_CID0) {
+			EMSG("A CID should be set for RIMU %u", rimu->id);
path: core/drivers/firewall/stm32_rifsc.c
user: login: etienne-lms
body: `PRIu32`. Ditto at lines 547 and 574.
created_at: 2025-05-19T08:43:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -424,6 +509,75 @@ static TEE_Result stm32_risup_setup(struct rifsc_platdata *pdata)
 	return TEE_SUCCESS;
 }
 
+/*
+ * Errata: When CID filtering is enabled on one of RISAB 3/4/5 instances, we
+ * forbid the use of CID0 for any initiator on the bus to handle transient CID0
+ * transactions on these RAMs.
+ */
+static void stm32_rimu_errata_ahbrisab(struct rifsc_platdata *pdata,
+				       struct rimu_cfg *rimu)
+{
+	unsigned int i = 0;
+
+	if (!pdata->errata_ahbrisab)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(rimu_risup); i++) {
+		if (rimu->id == rimu_risup[i].rimu_id) {
+			rimu->risup_id = rimu_risup[i].risup_id;
+			break;
+		}
+	}
+
+	if (rimu->attr & RIFSC_RIMC_CIDSEL_MASK) {
+		/* No inheritance mode for this RIMU */
+		if ((rimu->attr & RIFSC_RIMC_MCID_MASK) >>
+		    RIFSC_RIMC_MCID_SHIFT == RIF_CID0) {
+			EMSG("A CID should be set for RIMU %u", rimu->id);
+			if (!IS_ENABLED(CFG_INSECURE))
+				panic();
+			}
path: core/drivers/firewall/stm32_rifsc.c
user: login: etienne-lms
body: Fix `}` indentation.

created_at: 2025-05-19T08:44:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -424,6 +509,75 @@ static TEE_Result stm32_risup_setup(struct rifsc_platdata *pdata)
 	return TEE_SUCCESS;
 }
 
+/*
+ * Errata: When CID filtering is enabled on one of RISAB 3/4/5 instances, we
+ * forbid the use of CID0 for any initiator on the bus to handle transient CID0
+ * transactions on these RAMs.
+ */
+static void stm32_rimu_errata_ahbrisab(struct rifsc_platdata *pdata,
+				       struct rimu_cfg *rimu)
+{
+	unsigned int i = 0;
+
+	if (!pdata->errata_ahbrisab)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(rimu_risup); i++) {
+		if (rimu->id == rimu_risup[i].rimu_id) {
+			rimu->risup_id = rimu_risup[i].risup_id;
+			break;
+		}
+	}
+
+	if (rimu->attr & RIFSC_RIMC_CIDSEL_MASK) {
+		/* No inheritance mode for this RIMU */
+		if ((rimu->attr & RIFSC_RIMC_MCID_MASK) >>
+		    RIFSC_RIMC_MCID_SHIFT == RIF_CID0) {
+			EMSG("A CID should be set for RIMU %u", rimu->id);
+			if (!IS_ENABLED(CFG_INSECURE))
+				panic();
+			}
+	} else {
+		struct risup_cfg *risup = NULL;
+		uint32_t risup_cidcfgr = 0;
+		unsigned int j = 0;
+
+		/* Handle RIMU with no inheritance mode */
+		if (!rimu->risup_id) {
+			EMSG("RIMU%u cannot be set in inheritance mode",
+			     rimu->id);
+			if (!IS_ENABLED(CFG_INSECURE))
+				panic();
+			return;
+		}
+
+		for (j = 0; j < pdata->nrisup; j++) {
+			if (rimu->risup_id == pdata->risup[j].id) {
+				risup = &pdata->risup[j];
+				break;
+			}
+		}
+
+		if (!risup)
+			panic();
+
+		risup_cidcfgr = io_read32(pdata->base +
+					  _RIFSC_RISC_PER0_CIDCFGR +
+					  _OFFSET_PERX_CIDCFGR * risup->id);
+
+		if (!(risup_cidcfgr & RIFSC_RISC_CIDCFGR_CFEN_MASK) ||
+		    (!(risup_cidcfgr & RIFSC_RISC_CIDCFGR_SEM_EN_MASK) &&
+		     ((risup_cidcfgr & RIFSC_RISC_CIDCFGR_SCID_MASK) >>
+		      RIFSC_RISC_CIDCFGR_SCID_SHIFT) == RIF_CID0) ||
+		    (risup_cidcfgr & RIFSC_RISC_CIDCFGR_SEM_EN_MASK &&
+		     risup_cidcfgr & BIT(RIFSC_RISC_CIDCFGR_SEML_SHIFT))) {
path: core/drivers/firewall/stm32_rifsc.c
user: login: etienne-lms
body: prefer explicit mention of `RIF_CID0` here, for consistency:
```c
		     risup_cidcfgr & BIT(RIF_CID0 +
					 RIFSC_RISC_CIDCFGR_SEML_SHIFT))) {
```
created_at: 2025-05-19T08:50:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -168,12 +171,30 @@ static TEE_Result apply_rif_config(struct hpdma_pdata *hpdma_d, bool is_tdcid)
 		goto end;
 
 	for (i = 0; i < HPDMA_RIF_CHANNELS; i++) {
+		uint32_t cid_conf = hpdma_d->conf_data->cid_confs[i];
+
 		if (!(BIT(i) & hpdma_d->conf_data->access_mask[0]))
 			continue;
 
+		/*
+		 * Errata: When CID filtering is enabled on one of RISAB 3/4/5
+		 * instances, we forbid the use of CID0 for any initiator on the
+		 * bus to handle transient CID0 transactions on these RAMs.
+		 */
+		if (hpdma_d->errata_ahbrisab &&
+		    (!(cid_conf & _CIDCFGR_CFEN) ||
+		     (!(cid_conf & _CIDCFGR_SEMEN) &&
+		      ((cid_conf & _HPDMA_CIDCFGR_SCID_MASK) >>
+		       _HPDMA_CIDCFGR_SCID_SHIFT) == RIF_CID0) ||
+		     (cid_conf & _CIDCFGR_SEMEN &&
+		      cid_conf & BIT(_HPDMA_CIDCFGR_SEMWL_SHIFT)))) {
path: core/drivers/stm32_hpdma.c
user: login: etienne-lms
body: Here also, prefer with an explicit reference to  `RIF_CID0`:
`		      cid_conf & BIT(RIF_CID0 + _HPDMA_CIDCFGR_SEMWL_SHIFT)))) {`
created_at: 2025-05-19T08:52:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -157,6 +160,85 @@ struct rifsc_platdata {
 	struct risal_cfg *risal;
 	unsigned int nrisal;
 	bool is_tdcid;
+	bool errata_ahbrisab;
+};
+
+/**
+ * struct rimu_risup_pairs - Association of a RISUP and RIMU ID for a peripheral
+ *
+ * @rimu_id: ID of the RIMU
+ * @risup_id: ID of the associated RISUP
+ */
+struct rimu_risup_pairs {
+	uint32_t rimu_id;
+	uint32_t risup_id;
+};
+
+static const struct rimu_risup_pairs rimu_risup[] = {
+	[0] = {
+		.rimu_id = 0,
+		.risup_id = 0,
path: core/drivers/firewall/stm32_rifsc.c
user: login: GseoC
body: Ok, fair
created_at: 2025-05-19T09:07:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -157,6 +160,85 @@ struct rifsc_platdata {
 	struct risal_cfg *risal;
 	unsigned int nrisal;
 	bool is_tdcid;
+	bool errata_ahbrisab;
+};
+
+/**
+ * struct rimu_risup_pairs - Association of a RISUP and RIMU ID for a peripheral
+ *
+ * @rimu_id: ID of the RIMU
+ * @risup_id: ID of the associated RISUP
+ */
+struct rimu_risup_pairs {
+	uint32_t rimu_id;
+	uint32_t risup_id;
+};
+
+static const struct rimu_risup_pairs rimu_risup[] = {
+	[0] = {
+		.rimu_id = 0,
path: core/drivers/firewall/stm32_rifsc.c
user: login: GseoC
body: Yes, for the long term
created_at: 2025-05-19T09:10:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -370,7 +370,7 @@ static TEE_Result stm32_rifsc_dt_conf_rimu(const void *fdt, int node,
 		return TEE_ERROR_OUT_OF_MEMORY;
 
 	for (i = 0; i < pdata->nrimu; i++) {
-		uint32_t value = fdt32_to_cpu(*conf_list);
+		uint32_t value = fdt32_to_cpu(conf_list[i]);
path: core/drivers/firewall/stm32_rifsc.c
user: login: etienne-lms
body: I think the commit reference is wrong in the commit message, should be:
`Fixes: cd187630b280 ("drivers: add stm32 RIFSC support")`
created_at: 2025-05-19T15:24:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -370,7 +370,7 @@ static TEE_Result stm32_rifsc_dt_conf_rimu(const void *fdt, int node,
 		return TEE_ERROR_OUT_OF_MEMORY;
 
 	for (i = 0; i < pdata->nrimu; i++) {
-		uint32_t value = fdt32_to_cpu(*conf_list);
+		uint32_t value = fdt32_to_cpu(conf_list[i]);
path: core/drivers/firewall/stm32_rifsc.c
user: login: GseoC
body: ah yes, thx
created_at: 2025-05-19T15:48:08Z
author_association: CONTRIBUTOR

PR comments:
user: login: GseoC
created_at: 2025-05-15T14:47:39Z
body: Looking at the CI logs, I don't think the error is related to this P-R?
author_association: CONTRIBUTOR
user: login: GseoC
created_at: 2025-05-15T14:48:43Z
body: Ah my bad, I didn't see the (very) recently merged P-R on Qemu :)
author_association: CONTRIBUTOR
user: login: GseoC
created_at: 2025-05-19T11:35:31Z
body: Comments addressed.

I added two fixes in this P-R. I broke the RIMU conf parsing with my latest patches
author_association: CONTRIBUTOR
user: login: GseoC
created_at: 2025-05-19T15:52:30Z
body: Tags applied and comment addressed, still missing one tag on: "drivers: add stm32 RIFSC support"
author_association: CONTRIBUTOR
user: login: GseoC
created_at: 2025-05-20T15:04:56Z
body: Tag applied, thanks for the review
author_association: CONTRIBUTOR