diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index c609596def..809f6b5cdd 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -274,16 +274,20 @@ static void gicv3_enable_sre(void) isb(); } -/* Wait for completion of a distributor change */ -static void gicv3_do_wait_for_rwp(void __iomem *base) +/* Wait for completion of a distributor/redistributor change */ +static void gicv3_do_wait_for_rwp(void __iomem *base, uint32_t rwp_bit) { uint32_t val; bool timeout = false; s_time_t deadline = NOW() + MILLISECS(1000); do { + /* + * GICD_CTLR and GICR_CTLR are both at offset 0, so this is + * valid for either a distributor or redistributor base. + */ val = readl_relaxed(base + GICD_CTLR); - if ( !(val & GICD_CTLR_RWP) ) + if ( !(val & rwp_bit) ) break; if ( NOW() > deadline ) { @@ -300,12 +304,12 @@ static void gicv3_do_wait_for_rwp(void __iomem *base) static void gicv3_dist_wait_for_rwp(void) { - gicv3_do_wait_for_rwp(GICD); + gicv3_do_wait_for_rwp(GICD, GICD_CTLR_RWP); } static void gicv3_redist_wait_for_rwp(void) { - gicv3_do_wait_for_rwp(GICD_RDIST_BASE); + gicv3_do_wait_for_rwp(GICD_RDIST_BASE, GICR_CTLR_RWP); } static void gicv3_wait_for_rwp(int irq) diff --git a/xen/arch/arm/include/asm/gic_v3_defs.h b/xen/arch/arm/include/asm/gic_v3_defs.h index 2af093e774..143eceaa9d 100644 --- a/xen/arch/arm/include/asm/gic_v3_defs.h +++ b/xen/arch/arm/include/asm/gic_v3_defs.h @@ -108,6 +108,7 @@ #define GICR_NSACR (0x0E00) #define GICR_CTLR_ENABLE_LPIS (1U << 0) +#define GICR_CTLR_RWP (1U << 3) #define GICR_TYPER_PLPIS (1U << 0) #define GICR_TYPER_VLPIS (1U << 1)