]> git.buserror.net Git - polintos/scott/priv.git/blob - kernel/include/kern/irq.h
minor doc updates
[polintos/scott/priv.git] / kernel / include / kern / irq.h
1 #ifndef _KERN_IRQ_H
2 #define _KERN_IRQ_H
3
4 #include <kern/kernel.h>
5 #include <util/spinlock.h>
6
7 #include <System/IO/Interrupts.h>
8
9 namespace IRQ {
10         using namespace Lock;
11
12         typedef System::IO::Interrupts::Interrupt IInterrupt;
13         typedef System::IO::Interrupts::UserInterrupt IUserInterrupt;
14         typedef System::IO::Interrupts::InterruptController IInterruptController;
15         using System::IO::Bus::Device;
16         
17         struct Interrupt;
18         class InterruptController;
19         
20         struct InterruptSlot {
21                 InterruptController *controller;
22                 Interrupt *first_int;
23                 int mask_count;
24                 
25                 static const u32 Pending = 0x00000001;
26                 static const u32 Running = 0x00000002;
27                 
28                 u32 flags;
29         };
30
31         class InterruptController {
32                 // When this function returns, any irq instances that were running
33                 // when the function was entered will have completed.  If not
34                 // masked, though, there could be new instances of the IRQ running
35                 // when this function exits.
36                 
37                 void wait_for_irq(InterruptSlot *slot);
38         
39         protected:
40                 SpinLock lock;
41         
42                 // The derived constructor must initialize these.
43                 InterruptSlot *irqs;
44                 u32 num_irqs;
45
46                 virtual void mask_and_ack(u32 irq) = 0;
47                 virtual void mask(u32 irq) = 0;
48                 virtual void unmask(u32 irq) = 0;
49
50                 // Returns the highest-priority pending, unmasked interrupt, or
51                 // negative if no pending unmasked interrupts.
52                 
53                 virtual int get_pending_irq() = 0;
54                         
55         public:
56 //              #include "core/irq-server/IRQ/InterruptController.h"
57                 
58                 virtual ~InterruptController()
59                 {
60                 }
61                 
62                 void request_int(InterruptSlot *slot, Interrupt *irq);
63                 void free_int(Interrupt *irq);
64         
65                 // If irq is non-negative, then the given IRQ number is the IRQ
66                 // source (this is a hack for x86 and x64, which provide this
67                 // information via the entry point used).  Otherwise,
68                 // get_pending_irq() will be called repeatedly (after handling
69                 // whatever interrupt was returned on the previous iteration) until
70                 // it returns negative.  This returns true if any of the handlers
71                 // called returned true.
72         
73                 bool handle_irq(int irq);
74                 
75                 // Recursively request masking/unmasking of an interrupt.
76
77                 void rec_mask(InterruptSlot *slot);
78                 void rec_unmask(InterruptSlot *slot);
79
80                 // Like rec_mask, but does not wait for the completion of any pending
81                 // or running handlers.
82                 
83                 void rec_mask_nowait(InterruptSlot *slot);
84                 
85                 InterruptSlot *get_slot(u32 irq)
86                 {
87                         assert(irq < num_irqs);
88                         return &irqs[irq];
89                 }
90                 
91                 u32 get_irqnum(InterruptSlot *slot)
92                 {
93                         assert(slot - irqs >= 0 && slot - irqs < (int)num_irqs);
94                         return slot - irqs;
95                 }
96         };
97         
98         struct Interrupt {
99                 Interrupt *next;
100                 InterruptController *controller;
101                 InterruptSlot *slot;
102                 Device device;
103                 
104                 virtual ~Interrupt()
105                 {
106                 }
107                 
108                 // Returns true if there was an interrupt condition present
109                 // on the device; false otherwise.  This is used to detect
110                 // stuck interrupts.
111                 
112                 virtual bool action() = 0;
113
114 #if 0   
115                 #include "core/irq-server/IRQ/Interrupt.h"
116                 
117                 Interrupt()
118                 {
119                         init_iface();
120                 }
121 #endif
122                 
123                 void get_device(Device *dev)
124                 {
125                         if (dev)
126                                 *dev = device;
127                 }
128                 
129                 void get_controller(IInterruptController *con)
130                 {
131 //                      if (con)
132 //                              *con = parent;
133                 }
134                 
135                 void get_num(u32 *irqnum)
136                 {
137                         if (irqnum)
138                                 *irqnum = controller->get_irqnum(slot);
139                 }
140         };
141         
142         // FIXME: per-CPU
143         extern bool in_irq;
144 }
145
146 #endif