Kernel/x86 - Clean up some of the task switching code (possibly a little broken)
[tpg/acess2.git] / KernelLand / Kernel / arch / x86 / irq.c
1 /*
2  * AcessOS Microkernel Version
3  * irq.c
4  */
5 #include <acess.h>
6
7 // === CONSTANTS ===
8 #define MAX_CALLBACKS_PER_IRQ   4
9 #define TRACE_IRQS      0
10
11 // === TYPES ===
12 typedef void (*tIRQ_Callback)(int, void *);
13
14 // === PROTOTYPES ===
15 void    IRQ_Handler(tRegs *Regs);
16
17 // === GLOBALS ===
18 tIRQ_Callback   gIRQ_Handlers[16][MAX_CALLBACKS_PER_IRQ];
19 void    *gaIRQ_DataPointers[16][MAX_CALLBACKS_PER_IRQ];
20
21 // === CODE ===
22 /**
23  * \fn void IRQ_Handler(tRegs *Regs)
24  * \brief Handle an IRQ
25  */
26 void IRQ_Handler(tRegs *Regs)
27 {
28          int    irq = Regs->int_num - 0xF0;
29          int    bHandled = 0;
30
31         //Log("IRQ_Handler: (Regs={int_num:%i})", Regs->int_num);
32
33         for( int i = 0; i < MAX_CALLBACKS_PER_IRQ; i++ )
34         {
35                 if( gIRQ_Handlers[irq][i] ) {
36                         gIRQ_Handlers[irq][i](irq, gaIRQ_DataPointers[irq][i]);
37                         #if TRACE_IRQS
38                         if( irq != 8 )
39                                 Log("IRQ %i: Call %p", Regs->int_num, gIRQ_Handlers[Regs->int_num][i]);
40                         #endif
41                         bHandled = 1;
42                 }
43         }
44         
45         if( !bHandled ) {
46                 Log_Debug("IRQ", "Unhandled IRQ %i", irq);
47         }
48
49         //Log(" IRQ_Handler: Resetting");
50         if(irq >= 8)
51                 outb(0xA0, 0x20);       // ACK IRQ (Secondary PIC)
52         outb(0x20, 0x20);       // ACK IRQ
53         //Log("IRQ_Handler: RETURN");
54 }
55
56 /**
57  * \fn int IRQ_AddHandler( int Num, void (*Callback)(int) )
58  */
59 int IRQ_AddHandler( int Num, void (*Callback)(int, void*), void *Ptr )
60 {
61         for( int i = 0; i < MAX_CALLBACKS_PER_IRQ; i++ )
62         {
63                 if( gIRQ_Handlers[Num][i] == NULL )
64                 {
65                         //Log_Log("IRQ", "Added IRQ%i Cb#%i %p", Num, i, Callback);
66                         gIRQ_Handlers[Num][i] = Callback;
67                         gaIRQ_DataPointers[Num][i] = Ptr;
68                         return Num * MAX_CALLBACKS_PER_IRQ + i;
69                 }
70         }
71
72         Log_Warning("IRQ", "No free callbacks on IRQ%i", Num);
73         return -1;
74 }
75
76 void IRQ_RemHandler(int Handle)
77 {
78          int    Num = Handle / MAX_CALLBACKS_PER_IRQ;
79          int    id = Handle % MAX_CALLBACKS_PER_IRQ;
80         gIRQ_Handlers[Num][id] = NULL;
81 }

UCC git Repository :: git.ucc.asn.au