1 /* Xilink XPS interrupt controller */ 2 3 #include "include.h" 4 5 enum { 6 /* mer bits */ 7 Merme = 1<<0, /* master enable */ 8 Merhie = 1<<1, /* hw intr enable */ 9 10 Maxintrs = 8, /* from 32; size reduction */ 11 }; 12 13 typedef struct { 14 ulong isr; /* status */ 15 ulong ipr; /* pending (ro) */ 16 ulong ier; /* enable */ 17 ulong iar; /* acknowledge (wo) */ 18 ulong sieb; /* set ie bits; avoid */ 19 ulong cieb; /* clear ie bits; avoid */ 20 ulong ivr; /* vector; silly */ 21 ulong mer; /* master enable */ 22 } Intregs; 23 24 typedef struct { 25 ulong bit; 26 int (*func)(ulong); 27 } Intr; 28 29 Intregs *irp = (Intregs *)Intctlr; 30 Intr intrs[Maxintrs]; 31 Intr *nextintr; 32 33 static uvlong extintrs; 34 35 /* called from trap to poll for external interrupts */ 36 void intr(Ureg *)37intr(Ureg *) 38 { 39 int handled; 40 Intr *ip; 41 42 extintrs++; 43 dcflush(PTR2UINT(&extintrs), sizeof extintrs); /* seems needed */ 44 handled = 0; 45 for (ip = intrs; ip->bit != 0; ip++) 46 handled |= ip->func(ip->bit); 47 if (!handled) 48 print("interrupt with no handler\n"); 49 } 50 51 void intrinit(void)52intrinit(void) 53 { 54 intrack(~0); /* clear dregs */ 55 putesr(0); /* clears machine check */ 56 coherence(); 57 58 irp->mer = Merme | Merhie; 59 irp->ier = 0; /* clear any pending spurious intrs */ 60 coherence(); 61 nextintr = intrs; /* touches sram, not dram */ 62 nextintr->bit = 0; 63 coherence(); 64 65 intrack(~0); /* clear dregs */ 66 putesr(0); /* clears machine check */ 67 coherence(); 68 } 69 70 /* register func as the interrupt-service routine for bit */ 71 void intrenable(ulong bit,int (* func)(ulong))72intrenable(ulong bit, int (*func)(ulong)) 73 { 74 Intr *ip; 75 76 if (func == nil) 77 return; 78 assert(nextintr < intrs + nelem(intrs)); 79 assert(bit); 80 for (ip = intrs; ip->bit != 0; ip++) 81 if (bit == ip->bit) { 82 iprint("handler for intr bit %#lux already " 83 "registered\n", bit); 84 return; 85 } 86 nextintr->bit = bit; 87 nextintr->func = func; 88 nextintr++; 89 coherence(); 90 irp->ier |= bit; 91 coherence(); 92 } 93 94 void intrack(ulong bit)95intrack(ulong bit) 96 { 97 if (bit) { 98 irp->iar = bit; 99 coherence(); 100 } 101 } 102