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 <z_bajeer@yeah.net>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250806032924.3532975-1-z_bajeer@yeah.net
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Yang Jialong
2025-08-06 11:29:24 +08:00
committed by Anup Patel
parent d9afef57b7
commit 944db4eced

View File

@@ -121,10 +121,6 @@ static void aplic_writel_msicfg(struct aplic_msicfg_data *msicfg,
u32 val; u32 val;
unsigned long base_ppn; unsigned long base_ppn;
/* Check if MSI config is already locked */
if (readl(msicfgaddrH) & APLIC_xMSICFGADDRH_L)
return;
/* Compute the MSI base PPN */ /* Compute the MSI base PPN */
base_ppn = msicfg->base_addr >> APLIC_xMSICFGADDR_PPN_SHIFT; base_ppn = msicfg->base_addr >> APLIC_xMSICFGADDR_PPN_SHIFT;
base_ppn &= ~APLIC_xMSICFGADDR_PPN_HART(msicfg->lhxs); 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 aplic_cold_irqchip_init(struct aplic_data *aplic)
{ {
int rc; int rc, locked;
u32 i, j, tmp; u32 i, j, tmp;
struct aplic_delegate_data *deleg; struct aplic_delegate_data *deleg;
u32 first_deleg_irq, last_deleg_irq; u32 first_deleg_irq, last_deleg_irq;
@@ -247,12 +243,13 @@ int aplic_cold_irqchip_init(struct aplic_data *aplic)
} }
/* MSI configuration */ /* 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, aplic_writel_msicfg(&aplic->msicfg_mmode,
(void *)(aplic->addr + APLIC_MMSICFGADDR), (void *)(aplic->addr + APLIC_MMSICFGADDR),
(void *)(aplic->addr + APLIC_MMSICFGADDRH)); (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, aplic_writel_msicfg(&aplic->msicfg_smode,
(void *)(aplic->addr + APLIC_SMSICFGADDR), (void *)(aplic->addr + APLIC_SMSICFGADDR),
(void *)(aplic->addr + APLIC_SMSICFGADDRH)); (void *)(aplic->addr + APLIC_SMSICFGADDRH));