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