Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/powerpc/ibm4xx Fix hard freeze in pic_handle_intr()...
details: https://anonhg.NetBSD.org/src/rev/d5aef7a29aab
branches: trunk
changeset: 960003:d5aef7a29aab
user: rin <rin%NetBSD.org@localhost>
date: Fri Mar 05 05:35:50 2021 +0000
description:
Fix hard freeze in pic_handle_intr() for PPC_IBM403.
Not clearly documented in reference manual, but DCR_EXISR register is
not updated immediately after some bits are cleared by mtdcr, no matter
whether sync (= eieio) and/or isync are issued.
Therefore, we have to manage our own status mask in the interrupt handler.
This is what we did in obsoleted powerpc/ibm4xx/intr.c.
With this change, my Explora 451 works just fine with serial console!
Fix for framebuffer console will be committed soon.
diffstat:
sys/arch/powerpc/ibm4xx/pic_uic.c | 30 +++++++++++++++++++++++++++---
1 files changed, 27 insertions(+), 3 deletions(-)
diffs (66 lines):
diff -r 340b2a622690 -r d5aef7a29aab sys/arch/powerpc/ibm4xx/pic_uic.c
--- a/sys/arch/powerpc/ibm4xx/pic_uic.c Fri Mar 05 02:58:13 2021 +0000
+++ b/sys/arch/powerpc/ibm4xx/pic_uic.c Fri Mar 05 05:35:50 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pic_uic.c,v 1.8 2021/02/27 20:43:58 rin Exp $ */
+/* $NetBSD: pic_uic.c,v 1.9 2021/03/05 05:35:50 rin Exp $ */
/*
* Copyright 2002 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pic_uic.c,v 1.8 2021/02/27 20:43:58 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pic_uic.c,v 1.9 2021/03/05 05:35:50 rin Exp $");
#ifdef _KERNEL_OPT
#include "opt_ppcarch.h"
@@ -73,6 +73,19 @@
struct uic {
uint32_t uic_intr_enable; /* cached intr enable mask */
+#ifdef PPC_IBM403
+ /*
+ * Not clearly documented in reference manual, but DCR_EXISR
+ * register is not updated immediately after some bits are
+ * cleared by mtdcr, no matter whether sync (= eieio) and/or
+ * isync are issued.
+ *
+ * Therefore, we have to manage our own status mask in the
+ * interrupt handler; see uic_{ack,get}_irq() for more details.
+ * This is what we did in obsoleted powerpc/ibm4xx/intr.c.
+ */
+ uint32_t uic_intr_status;
+#endif
uint32_t (*uic_mf_intr_status)(void);
uint32_t (*uic_mf_intr_enable)(void);
void (*uic_mt_intr_enable)(uint32_t);
@@ -356,15 +369,26 @@
struct uic * const uic = pic->pic_cookie;
const uint32_t irqmask = IRQ_TO_MASK(irq);
+#ifdef PPC_IBM403
+ uic->uic_intr_status &= ~irqmask;
+#endif
+
(*uic->uic_mt_intr_ack)(irqmask);
}
static int
-uic_get_irq(struct pic_ops *pic, int dummy)
+uic_get_irq(struct pic_ops *pic, int req)
{
struct uic * const uic = pic->pic_cookie;
+#ifdef PPC_IBM403
+ if (req == PIC_GET_IRQ)
+ uic->uic_intr_status = (*uic->uic_mf_intr_status)();
+ const uint32_t irqmask = uic->uic_intr_status;
+#else
const uint32_t irqmask = (*uic->uic_mf_intr_status)();
+#endif
+
if (irqmask == 0)
return 255;
return IRQ_OF_MASK(irqmask);
Home |
Main Index |
Thread Index |
Old Index