diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-04-10 15:04:59 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-04-10 15:04:59 +0200 |
commit | 55a3964517fe6b57da07de12ceb7753886b8ed3a (patch) | |
tree | 60ff23d94e223adc344ff687c95f6edff71b0339 /sys/src | |
parent | 3e65a15ae078f00f8ddf137e6d04007797702331 (diff) |
bcm: move interrupt handling out of trap.c into irq.c
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/9/bcm/irq.c | 166 | ||||
-rw-r--r-- | sys/src/9/bcm/trap.c | 157 |
2 files changed, 167 insertions, 156 deletions
diff --git a/sys/src/9/bcm/irq.c b/sys/src/9/bcm/irq.c new file mode 100644 index 000000000..f93dcd38c --- /dev/null +++ b/sys/src/9/bcm/irq.c @@ -0,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); +} diff --git a/sys/src/9/bcm/trap.c b/sys/src/9/bcm/trap.c index ac5223324..dcab22a6d 100644 --- 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 @@ typedef struct Vpage0 { 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 @@ static char *trapnames[PsrMask+1] = { [ PsrMsys ] "sys trap", }; +extern int irq(Ureg*); extern int notify(Ureg*); /* @@ -102,127 +68,6 @@ trapinit(void) 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 * trapname(int psr) { |