4 #include <kern/kernel.h>
5 #include <util/spinlock.h>
7 #include <System/IO/Interrupts.h>
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;
18 class InterruptController;
20 struct InterruptSlot {
21 InterruptController *controller;
25 static const u32 Pending = 0x00000001;
26 static const u32 Running = 0x00000002;
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.
37 void wait_for_irq(InterruptSlot *slot);
42 // The derived constructor must initialize these.
46 virtual void mask_and_ack(u32 irq) = 0;
47 virtual void mask(u32 irq) = 0;
48 virtual void unmask(u32 irq) = 0;
50 // Returns the highest-priority pending, unmasked interrupt, or
51 // negative if no pending unmasked interrupts.
53 virtual int get_pending_irq() = 0;
56 // #include "core/irq-server/IRQ/InterruptController.h"
58 virtual ~InterruptController()
62 void request_int(InterruptSlot *slot, Interrupt *irq);
63 void free_int(Interrupt *irq);
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.
73 bool handle_irq(int irq);
75 // Recursively request masking/unmasking of an interrupt.
77 void rec_mask(InterruptSlot *slot);
78 void rec_unmask(InterruptSlot *slot);
80 // Like rec_mask, but does not wait for the completion of any pending
81 // or running handlers.
83 void rec_mask_nowait(InterruptSlot *slot);
85 InterruptSlot *get_slot(u32 irq)
87 assert(irq < num_irqs);
91 u32 get_irqnum(InterruptSlot *slot)
93 assert(slot - irqs >= 0 && slot - irqs < (int)num_irqs);
100 InterruptController *controller;
108 // Returns true if there was an interrupt condition present
109 // on the device; false otherwise. This is used to detect
112 virtual bool action() = 0;
115 #include "core/irq-server/IRQ/Interrupt.h"
123 void get_device(Device *dev)
129 void get_controller(IInterruptController *con)
135 void get_num(u32 *irqnum)
138 *irqnum = controller->get_irqnum(slot);