Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/cortex PR# port-evbarm/49468: Cortex GIC assert...
details: https://anonhg.NetBSD.org/src/rev/e1bb104f0778
branches: trunk
changeset: 359351:e1bb104f0778
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Wed Feb 07 20:42:17 2018 +0000
description:
PR# port-evbarm/49468: Cortex GIC assertion triggered on Allwinner A80 SoC
The priority level is changed by writing to GICC_PMR with interrupts
disabled. However, interrupts are enabled/disabled downstream of the GICC
at the CPU. When raising priority level, there is a window between the time
that interrupts are disabled and the GICC_PMR register is written. If an
interrupt occurs at a previously allowed priority before GICC_PMR is
changed, the CPU will receive the signal when interrupts are re-enabled.
At this time, GICC_PMR is now the new priority level, so reads of
GICC_IAR will report a spurious IRQ.
Move the "old_ipl != IPL_HIGH" test until after we have confirmed that
there is at least one pending IRQ.
diffstat:
sys/arch/arm/cortex/gic.c | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)
diffs (46 lines):
diff -r fef97c08006e -r e1bb104f0778 sys/arch/arm/cortex/gic.c
--- a/sys/arch/arm/cortex/gic.c Wed Feb 07 15:55:58 2018 +0000
+++ b/sys/arch/arm/cortex/gic.c Wed Feb 07 20:42:17 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gic.c,v 1.31 2017/07/14 06:33:26 skrll Exp $ */
+/* $NetBSD: gic.c,v 1.32 2018/02/07 20:42:17 jmcneill Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -34,7 +34,7 @@
#define _INTR_PRIVATE
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.31 2017/07/14 06:33:26 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.32 2018/02/07 20:42:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -259,9 +259,6 @@
ci->ci_data.cpu_nintr++;
- KASSERTMSG(old_ipl != IPL_HIGH, "old_ipl %d pmr %#x hppir %#x",
- old_ipl, gicc_read(sc, GICC_PMR), gicc_read(sc, GICC_HPPIR));
-
for (;;) {
uint32_t iar = gicc_read(sc, GICC_IAR);
uint32_t irq = __SHIFTOUT(iar, GICC_IAR_IRQ);
@@ -277,6 +274,9 @@
}
}
+ KASSERTMSG(old_ipl != IPL_HIGH, "old_ipl %d pmr %#x hppir %#x",
+ old_ipl, gicc_read(sc, GICC_PMR), gicc_read(sc, GICC_HPPIR));
+
//const uint32_t cpuid = __SHIFTOUT(iar, GICC_IAR_CPUID_MASK);
struct intrsource * const is = sc->sc_pic.pic_sources[irq];
KASSERT(is != &armgic_dummy_source);
@@ -318,7 +318,6 @@
/*
* Now handle any pending ints.
*/
- KASSERT(old_ipl != IPL_HIGH);
pic_do_pending_ints(I32_bit, old_ipl, tf);
KASSERTMSG(ci->ci_cpl == old_ipl, "ci_cpl %d old_ipl %d", ci->ci_cpl, old_ipl);
KASSERT(old_mtx_count == ci->ci_mtx_count);
Home |
Main Index |
Thread Index |
Old Index