summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYang Jialong <[email protected]>2025-08-06 11:29:24 +0800
committerAnup Patel <[email protected]>2025-09-30 17:24:13 +0530
commit944db4eced291f248724d9f662585257b4876e16 (patch)
treeb255f346111687e4b39d3ed1da40670fdd4d2128
parentd9afef57b70689f5fb6b081b64e7c4aba5ea539e (diff)
lib: utils/irqchip: fix aplic lock mechanism in xmsiaddrcfg(h)
The section 4.5.4 "Supervisor MSI address configuration (smsiaddrcfg and smsiaddrcfgh)" of the AIA specification states that: "If register mmsiaddrcfgh of the domain has bit L set to one, then smsiaddrcfg and smsiaddrcfgh are locked as read-only alongside mmsiaddrcfg and mmsiaddrcfgh." In other words, the L bit is not defined for smsiaddrcfg[h] registers so fix aplic_writel_msicfg() accordingly. Signed-off-by: Yang Jialong <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
-rw-r--r--lib/utils/irqchip/aplic.c11
1 files changed, 4 insertions, 7 deletions
diff --git a/lib/utils/irqchip/aplic.c b/lib/utils/irqchip/aplic.c
index 72906d5d..efaaf0ca 100644
--- a/lib/utils/irqchip/aplic.c
+++ b/lib/utils/irqchip/aplic.c
@@ -121,10 +121,6 @@ static void aplic_writel_msicfg(struct aplic_msicfg_data *msicfg,
u32 val;
unsigned long base_ppn;
- /* Check if MSI config is already locked */
- if (readl(msicfgaddrH) & APLIC_xMSICFGADDRH_L)
- return;
-
/* Compute the MSI base PPN */
base_ppn = msicfg->base_addr >> APLIC_xMSICFGADDR_PPN_SHIFT;
base_ppn &= ~APLIC_xMSICFGADDR_PPN_HART(msicfg->lhxs);
@@ -167,7 +163,7 @@ static int aplic_check_msicfg(struct aplic_msicfg_data *msicfg)
int aplic_cold_irqchip_init(struct aplic_data *aplic)
{
- int rc;
+ int rc, locked;
u32 i, j, tmp;
struct aplic_delegate_data *deleg;
u32 first_deleg_irq, last_deleg_irq;
@@ -247,12 +243,13 @@ int aplic_cold_irqchip_init(struct aplic_data *aplic)
}
/* MSI configuration */
- if (aplic->targets_mmode && aplic->has_msicfg_mmode) {
+ locked = readl((void *)(aplic->addr + APLIC_MMSICFGADDRH)) & APLIC_xMSICFGADDRH_L;
+ if (aplic->targets_mmode && aplic->has_msicfg_mmode && !locked) {
aplic_writel_msicfg(&aplic->msicfg_mmode,
(void *)(aplic->addr + APLIC_MMSICFGADDR),
(void *)(aplic->addr + APLIC_MMSICFGADDRH));
}
- if (aplic->targets_mmode && aplic->has_msicfg_smode) {
+ if (aplic->targets_mmode && aplic->has_msicfg_smode && !locked) {
aplic_writel_msicfg(&aplic->msicfg_smode,
(void *)(aplic->addr + APLIC_SMSICFGADDR),
(void *)(aplic->addr + APLIC_SMSICFGADDRH));