ref: 55a3964517fe6b57da07de12ceb7753886b8ed3a
parent: 3e65a15ae078f00f8ddf137e6d04007797702331
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed Apr 10 11:04:59 EDT 2019
bcm: move interrupt handling out of trap.c into irq.c
--- /dev/null
+++ b/sys/src/9/bcm/irq.c
@@ -1,0 +1,166 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "ureg.h"
+#include "../port/error.h"
+
+#define INTREGS (VIRTIO+0xB200)
+
+enum {
+ Fiqenable = 1<<7,
+
+ Localtimerint = 0x40,
+ Localmboxint = 0x50,
+ Localintpending = 0x60,
+};
+
+/*
+ * interrupt control registers
+ */
+typedef struct Intregs Intregs;
+struct Intregs {
+ u32int ARMpending;
+ u32int GPUpending[2];
+ u32int FIQctl;
+ u32int GPUenable[2];
+ u32int ARMenable;
+ u32int GPUdisable[2];
+ u32int ARMdisable;
+};
+
+typedef struct Vctl Vctl;
+struct Vctl {
+ Vctl *next;
+ int irq;
+ u32int *reg;
+ u32int mask;
+ void (*f)(Ureg*, void*);
+ void *a;
+};
+
+static Lock vctllock;
+static Vctl *vctl[MAXMACH], *vfiq;
+
+void
+intrcpushutdown(void)
+{
+ u32int *enable;
+
+ if(soc.armlocal == 0)
+ return;
+ enable = (u32int*)(ARMLOCAL + Localtimerint) + m->machno;
+ *enable = 0;
+ if(m->machno){
+ enable = (u32int*)(ARMLOCAL + Localmboxint) + m->machno;
+ *enable = 1;
+ }
+}
+
+void
+intrsoff(void)
+{
+ Intregs *ip;
+ int disable;
+
+ ip = (Intregs*)INTREGS;
+ disable = ~0;
+ ip->GPUdisable[0] = disable;
+ ip->GPUdisable[1] = disable;
+ ip->ARMdisable = disable;
+ ip->FIQctl = 0;
+}
+
+/*
+ * called by trap to handle irq interrupts.
+ * returns true iff a clock interrupt, thus maybe reschedule.
+ */
+int
+irq(Ureg* ureg)
+{
+ Vctl *v;
+ int clockintr;
+
+ clockintr = 0;
+ for(v = vctl[m->machno]; v != nil; v = v->next)
+ if((*v->reg & v->mask) != 0){
+ coherence();
+ v->f(ureg, v->a);
+ coherence();
+ if(v->irq == IRQclock || v->irq == IRQcntps || v->irq == IRQcntpns)
+ clockintr = 1;
+ }
+ return clockintr;
+}
+
+/*
+ * called direct from lexception.s to handle fiq interrupt.
+ */
+void
+fiq(Ureg *ureg)
+{
+ Vctl *v;
+
+ v = vfiq;
+ if(v == nil)
+ panic("cpu%d: unexpected item in bagging area", m->machno);
+ m->intr++;
+ ureg->pc -= 4;
+ coherence();
+ v->f(ureg, v->a);
+ coherence();
+}
+
+void
+irqenable(int irq, void (*f)(Ureg*, void*), void* a)
+{
+ Vctl *v;
+ Intregs *ip;
+ u32int *enable;
+ int cpu;
+
+ ip = (Intregs*)INTREGS;
+ if((v = xalloc(sizeof(Vctl))) == nil)
+ panic("irqenable: no mem");
+ cpu = 0;
+ v->irq = irq;
+ if(irq >= IRQlocal){
+ cpu = m->machno;
+ v->reg = (u32int*)(ARMLOCAL + Localintpending) + cpu;
+ if(irq >= IRQmbox0)
+ enable = (u32int*)(ARMLOCAL + Localmboxint) + cpu;
+ else
+ enable = (u32int*)(ARMLOCAL + Localtimerint) + cpu;
+ v->mask = 1 << (irq - IRQlocal);
+ }else if(irq >= IRQbasic){
+ enable = &ip->ARMenable;
+ v->reg = &ip->ARMpending;
+ v->mask = 1 << (irq - IRQbasic);
+ }else{
+ enable = &ip->GPUenable[irq/32];
+ v->reg = &ip->GPUpending[irq/32];
+ v->mask = 1 << (irq % 32);
+ }
+ v->f = f;
+ v->a = a;
+ lock(&vctllock);
+ if(irq == IRQfiq){
+ assert((ip->FIQctl & Fiqenable) == 0);
+ assert((*enable & v->mask) == 0);
+ vfiq = v;
+ ip->FIQctl = Fiqenable | irq;
+ }else{
+ v->next = vctl[cpu];
+ vctl[cpu] = v;
+ if(irq >= IRQmbox0){
+ if(irq <= IRQmbox3)
+ *enable |= 1 << (irq - IRQmbox0);
+ }else if(irq >= IRQlocal)
+ *enable |= 1 << (irq - IRQlocal);
+ else
+ *enable = v->mask;
+ }
+ unlock(&vctllock);
+}
--- a/sys/src/9/bcm/trap.c
+++ b/sys/src/9/bcm/trap.c
@@ -12,18 +12,8 @@
#include "arm.h"
-#define INTREGS (VIRTIO+0xB200)
-
-typedef struct Intregs Intregs;
-typedef struct Vctl Vctl;
-
enum {
Nvec = 8, /* # of vectors at start of lexception.s */
- Fiqenable = 1<<7,
-
- Localtimerint = 0x40,
- Localmboxint = 0x50,
- Localintpending = 0x60,
};
/*
@@ -34,31 +24,6 @@
u32int vtable[Nvec];
} Vpage0;
-/*
- * interrupt control registers
- */
-struct Intregs {
- u32int ARMpending;
- u32int GPUpending[2];
- u32int FIQctl;
- u32int GPUenable[2];
- u32int ARMenable;
- u32int GPUdisable[2];
- u32int ARMdisable;
-};
-
-struct Vctl {
- Vctl *next;
- int irq;
- u32int *reg;
- u32int mask;
- void (*f)(Ureg*, void*);
- void *a;
-};
-
-static Lock vctllock;
-static Vctl *vctl[MAXMACH], *vfiq;
-
static char *trapnames[PsrMask+1] = {
[ PsrMusr ] "user mode",
[ PsrMfiq ] "fiq interrupt",
@@ -70,6 +35,7 @@
[ PsrMsys ] "sys trap",
};
+extern int irq(Ureg*);
extern int notify(Ureg*);
/*
@@ -100,127 +66,6 @@
setr13(PsrMsys, m->ssys);
coherence();
-}
-
-void
-intrcpushutdown(void)
-{
- u32int *enable;
-
- if(soc.armlocal == 0)
- return;
- enable = (u32int*)(ARMLOCAL + Localtimerint) + m->machno;
- *enable = 0;
- if(m->machno){
- enable = (u32int*)(ARMLOCAL + Localmboxint) + m->machno;
- *enable = 1;
- }
-}
-
-void
-intrsoff(void)
-{
- Intregs *ip;
- int disable;
-
- ip = (Intregs*)INTREGS;
- disable = ~0;
- ip->GPUdisable[0] = disable;
- ip->GPUdisable[1] = disable;
- ip->ARMdisable = disable;
- ip->FIQctl = 0;
-}
-
-/*
- * called by trap to handle irq interrupts.
- * returns true iff a clock interrupt, thus maybe reschedule.
- */
-static int
-irq(Ureg* ureg)
-{
- Vctl *v;
- int clockintr;
-
- clockintr = 0;
- for(v = vctl[m->machno]; v != nil; v = v->next)
- if((*v->reg & v->mask) != 0){
- coherence();
- v->f(ureg, v->a);
- coherence();
- if(v->irq == IRQclock || v->irq == IRQcntps || v->irq == IRQcntpns)
- clockintr = 1;
- }
- return clockintr;
-}
-
-/*
- * called direct from lexception.s to handle fiq interrupt.
- */
-void
-fiq(Ureg *ureg)
-{
- Vctl *v;
-
- v = vfiq;
- if(v == nil)
- panic("cpu%d: unexpected item in bagging area", m->machno);
- m->intr++;
- ureg->pc -= 4;
- coherence();
- v->f(ureg, v->a);
- coherence();
-}
-
-void
-irqenable(int irq, void (*f)(Ureg*, void*), void* a)
-{
- Vctl *v;
- Intregs *ip;
- u32int *enable;
- int cpu;
-
- ip = (Intregs*)INTREGS;
- if((v = xalloc(sizeof(Vctl))) == nil)
- panic("irqenable: no mem");
- cpu = 0;
- v->irq = irq;
- if(irq >= IRQlocal){
- cpu = m->machno;
- v->reg = (u32int*)(ARMLOCAL + Localintpending) + cpu;
- if(irq >= IRQmbox0)
- enable = (u32int*)(ARMLOCAL + Localmboxint) + cpu;
- else
- enable = (u32int*)(ARMLOCAL + Localtimerint) + cpu;
- v->mask = 1 << (irq - IRQlocal);
- }else if(irq >= IRQbasic){
- enable = &ip->ARMenable;
- v->reg = &ip->ARMpending;
- v->mask = 1 << (irq - IRQbasic);
- }else{
- enable = &ip->GPUenable[irq/32];
- v->reg = &ip->GPUpending[irq/32];
- v->mask = 1 << (irq % 32);
- }
- v->f = f;
- v->a = a;
- lock(&vctllock);
- if(irq == IRQfiq){
- assert((ip->FIQctl & Fiqenable) == 0);
- assert((*enable & v->mask) == 0);
- vfiq = v;
- ip->FIQctl = Fiqenable | irq;
- }else{
- v->next = vctl[cpu];
- vctl[cpu] = v;
- if(irq >= IRQmbox0){
- if(irq <= IRQmbox3)
- *enable |= 1 << (irq - IRQmbox0);
- }else if(irq >= IRQlocal)
- *enable |= 1 << (irq - IRQlocal);
- else
- *enable = v->mask;
- }
- unlock(&vctllock);
}
static char *