2 #include "../port/lib.h"
8 #include "../port/error.h"
10 #define INTREGS (VIRTIO+0xB200)
17 Localintpending = 0x60,
21 * interrupt control registers
23 typedef struct Intregs Intregs;
34 typedef struct Vctl Vctl;
40 void (*f)(Ureg*, void*);
45 static Vctl *vctl[MAXMACH], *vfiq;
54 enable = (u32int*)(ARMLOCAL + Localtimerint) + m->machno;
57 enable = (u32int*)(ARMLOCAL + Localmboxint) + m->machno;
68 ip = (Intregs*)INTREGS;
70 ip->GPUdisable[0] = disable;
71 ip->GPUdisable[1] = disable;
72 ip->ARMdisable = disable;
77 * called by trap to handle irq interrupts.
78 * returns true iff a clock interrupt, thus maybe reschedule.
87 for(v = vctl[m->machno]; v != nil; v = v->next)
88 if((*v->reg & v->mask) != 0){
92 if(v->irq == IRQclock || v->irq == IRQcntps || v->irq == IRQcntpns)
99 * called direct from lexception.s to handle fiq interrupt.
108 panic("cpu%d: unexpected item in bagging area", m->machno);
117 irqenable(int irq, void (*f)(Ureg*, void*), void* a)
124 ip = (Intregs*)INTREGS;
125 if((v = xalloc(sizeof(Vctl))) == nil)
126 panic("irqenable: no mem");
131 v->reg = (u32int*)(ARMLOCAL + Localintpending) + cpu;
133 enable = (u32int*)(ARMLOCAL + Localmboxint) + cpu;
135 enable = (u32int*)(ARMLOCAL + Localtimerint) + cpu;
136 v->mask = 1 << (irq - IRQlocal);
137 }else if(irq >= IRQbasic){
138 enable = &ip->ARMenable;
139 v->reg = &ip->ARMpending;
140 v->mask = 1 << (irq - IRQbasic);
142 enable = &ip->GPUenable[irq/32];
143 v->reg = &ip->GPUpending[irq/32];
144 v->mask = 1 << (irq % 32);
150 assert((ip->FIQctl & Fiqenable) == 0);
151 assert((*enable & v->mask) == 0);
153 ip->FIQctl = Fiqenable | irq;
159 *enable |= 1 << (irq - IRQmbox0);
160 }else if(irq >= IRQlocal)
161 *enable |= 1 << (irq - IRQlocal);