]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/zynq/intr.c
zynq: remove unused statistics fields from Mach structure
[plan9front.git] / sys / src / 9 / zynq / intr.c
1 #include "u.h"
2 #include <ureg.h>
3 #include "../port/lib.h"
4 #include "mem.h"
5 #include "dat.h"
6 #include "fns.h"
7 #include "io.h"
8 #include "../port/error.h"
9
10 enum {
11         NINTR = 96,
12         NPRIVATE = 32
13 };
14
15 static struct irq {
16         void (*f)(Ureg *, void *);
17         void *arg;
18         char *name;
19 } irqs[NINTR];
20
21 enum {
22         ICCICR = 0x100/4,
23         ICCPMR,
24         ICCBPR,
25         ICCIAR,
26         ICCEOIR,
27         ICDDCR = 0x1000/4,
28         ICDISR = 0x1080/4,
29         ICDISER = 0x1100/4,
30         ICDICER = 0x1180/4,
31         ICDICPR = 0x1280/4,
32         ICDABR  = 0x1300/4,
33         ICDIPRI = 0x1400/4,
34         ICDIPTR = 0x1800/4,
35         ICDICFR = 0x1C00/4,
36 };
37
38 void
39 intrinit(void)
40 {
41         int i;
42
43         mpcore[ICDDCR] = 3;
44         mpcore[ICCICR] = 7;
45         mpcore[ICCBPR] = 3;
46         mpcore[ICCPMR] = 255;
47
48         if(m->machno != 0)
49                 return;
50         
51         /* disable all irqs and clear any pending interrupts */
52         for(i = 0; i < NINTR/32; i++){
53                 mpcore[ICDISR + i] = -1;
54                 mpcore[ICDICER + i] = -1;
55                 mpcore[ICDICPR + i] = -1;
56                 mpcore[ICDABR + i] = 0;
57         }
58 }
59
60 void
61 intrenable(int irq, void (*f)(Ureg *, void *), void *arg, int type, char *name)
62 {
63         ulong *e, s;
64         struct irq *i;
65
66         if(f == nil)
67                 panic("intrenable: f == nil");
68         if(irq < 0 || irq >= NINTR)
69                 panic("intrenable: invalid irq %d", irq);
70         if(type != LEVEL && type != EDGE)
71                 panic("intrenable: invalid type %d", type);
72         if(irqs[irq].f != nil && irqs[irq].f != f)
73                 panic("intrenable: handler already assigned");
74         if(irq >= NPRIVATE){
75                 e = &mpcore[ICDIPTR + (irq >> 2)];
76                 s = irq << 3 & 24;
77                 *e = *e & ~(3 << s) | 1 << s;
78                 e = &mpcore[ICDICFR + (irq >> 4)];
79                 s = irq << 1 & 30 | 1;
80                 *e = *e & ~(1 << s) | type << s;
81         }
82         ((uchar*)&mpcore[ICDIPRI])[irq] = 0;
83         i = &irqs[irq];
84         i->f = f;
85         i->arg = arg;
86         i->name = name;
87         mpcore[ICDISER + (irq >> 5)] = 1 << (irq & 31);
88         mpcore[ICDABR + (irq >> 5)] |= 1 << (irq & 31);
89 }
90
91 void
92 intr(Ureg *ureg)
93 {
94         ulong v;
95         int irq;
96         struct irq *i;
97
98         v = mpcore[ICCIAR];
99         irq = v & 0x3ff;
100         if(irq == 0x3ff)
101                 return;
102                 
103         m->intr++;
104         m->lastintr = irq;
105         i = &irqs[irq];
106         if(i->f == nil)
107                 print("irq without handler %d\n", irq);
108         else
109                 i->f(ureg, i->arg);
110         mpcore[ICCEOIR] = v;
111
112         if(up != nil){
113                 if(irq == TIMERIRQ){
114                         if(up->delaysched){
115                                 splhi();
116                                 sched();
117                         }
118                 }else
119                         preempted();
120         }
121 }