move Drivers -> drivers
[AROS.git] / arch / i386-pc / drivers / irq.hidd / servers.c
bloba2b3550a43f72a4df830647a2fe3d45b59f202ac
1 /*
2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: IRQ servers for standalone i386 AROS
6 Lang: english
7 */
9 #define DEBUG 0
10 #include <aros/debug.h>
12 #include <oop/oop.h>
13 #include <aros/asmcall.h>
14 #include <exec/types.h>
15 #include <exec/lists.h>
16 #include <exec/interrupts.h>
17 #include <exec/execbase.h>
18 #include <exec/memory.h>
19 #include <hidd/irq.h>
20 #include <utility/utility.h>
21 #include <hardware/intbits.h>
23 #include <asm/ptrace.h>
24 #include <asm/irq.h>
25 #include <asm/io.h>
27 #include <proto/exec.h>
28 #include <proto/oop.h>
30 #include "irq.h"
32 void global_server(int cpl, struct irq_staticdata *isd, struct pt_regs *);
34 struct irqServer irq5_int = { global_server, "IRQ5" , NULL};
35 struct irqServer irq7_int = { global_server, "IRQ7" , NULL};
36 struct irqServer irq9_int = { global_server, "IRQ9" , NULL};
37 struct irqServer irq10_int = { global_server, "IRQ10" , NULL};
38 struct irqServer irq11_int = { global_server, "IRQ11" , NULL};
39 struct irqServer timer_int = { global_server, "timer" , NULL};
40 struct irqServer kbd_int = { global_server, "keyboard" , NULL};
41 struct irqServer com1_int = { global_server, "serial 1" , NULL};
42 struct irqServer com2_int = { global_server, "serial 2" , NULL};
43 struct irqServer floppy_int = { global_server, "floppy" , NULL};
44 struct irqServer rtc_int = { global_server, "rtc" , NULL};
45 struct irqServer mouse_int = { global_server, "ps/2 mouse" , NULL};
46 struct irqServer ide0_int = { global_server, "ide0" , NULL};
47 struct irqServer ide1_int = { global_server, "ide1" , NULL};
49 void timer_interrupt(HIDDT_IRQ_Handler *irq, HIDDT_IRQ_HwInfo *hw);
51 /*******************************************************************************
52 Two special irq handlers. As we don't need these two interrupts we define
53 here dummy handlers.
54 *******************************************************************************/
56 void no_action(int cpl, struct irq_staticdata *isd, struct pt_regs *regs)
60 static void math_error_irq(int cpl, struct irq_staticdata *isd, struct pt_regs *regs)
62 outb(0,0xF0);
65 static struct irqServer irq13 = { math_error_irq, "fpu", NULL};
68 * IRQ2 is cascade interrupt to second interrupt controller
71 static struct irqServer irq2 = { no_action, "cascade", NULL};
73 void irqSet(int, struct irqServer *);
75 void init_Servers(struct irq_staticdata *isd)
77 HIDDT_IRQ_Handler *timer;
79 timer_int.is_UserData = isd;
80 irq2.is_UserData = isd;
81 kbd_int.is_UserData = isd;
82 com1_int.is_UserData = isd;
83 com2_int.is_UserData = isd;
84 floppy_int.is_UserData = isd;
85 rtc_int.is_UserData = isd;
86 mouse_int.is_UserData = isd;
87 irq13.is_UserData = isd;
88 ide0_int.is_UserData = isd;
89 ide1_int.is_UserData = isd;
91 irq5_int.is_UserData = isd;
92 irq7_int.is_UserData = isd;
93 irq9_int.is_UserData = isd;
94 irq10_int.is_UserData = isd;
95 irq11_int.is_UserData = isd;
97 irqSet(0, &timer_int);
98 irqSet(1, &kbd_int);
99 irqSet(2, &irq2);
100 irqSet(3, &com2_int);
101 irqSet(4, &com1_int);
102 irqSet(5, &irq5_int);
103 irqSet(6, &floppy_int);
104 irqSet(7, &irq7_int);
105 irqSet(8, &rtc_int);
106 irqSet(9, &irq9_int);
107 irqSet(10, &irq10_int);
108 irqSet(11, &irq11_int);
109 irqSet(12, &mouse_int);
110 irqSet(13, &irq13);
111 irqSet(14, &ide0_int);
112 irqSet(15, &ide1_int);
114 /* Install timer interrupt */
115 timer = AllocMem(sizeof(HIDDT_IRQ_Handler), MEMF_CLEAR|MEMF_PUBLIC);
116 if (timer)
118 timer->h_Node.ln_Name = "INTB_TIMERTICK";
119 timer->h_Node.ln_Type = NT_INTERRUPT;
120 timer->h_Node.ln_Pri = 0;
121 timer->h_Data = &SysBase->IntVects[INTB_TIMERTICK];
122 timer->h_Code = timer_interrupt;
124 Enqueue((struct List *)&isd->irqlist[0], (struct Node *)timer);
128 /*******************************************************************************
129 This timer interrupt is used to keep compatibility with old Amiga software
130 *******************************************************************************/
132 void timer_interrupt(HIDDT_IRQ_Handler *irq, HIDDT_IRQ_HwInfo *hw)
134 struct IntVector *iv = irq->h_Data;
136 if (iv->iv_Code)
138 /* Call it. I call with all these parameters for a reason.
140 In my `Amiga ROM Kernel Reference Manual: Libraries and
141 Devices' (the 1.3 version), interrupt servers are called
142 with the following 5 parameters.
144 D1 - Mask of INTENAR and INTREQR
145 A0 - 0xDFF000 (base of custom chips)
146 A1 - Interrupt Data
147 A5 - Interrupt Code vector
148 A6 - SysBase
150 It is quite possible that some code uses all of these, so
151 I must supply them here. Obviously I will dummy some of these
152 though.
154 AROS_UFC5(void, iv->iv_Code,
155 AROS_UFCA(ULONG, 0, D1),
156 AROS_UFCA(ULONG, 0, A0),
157 AROS_UFCA(APTR, iv->iv_Data, A1),
158 AROS_UFCA(APTR, iv->iv_Code, A5),
159 AROS_UFCA(struct ExecBase *, hw->sysBase, A6)
163 if (--SysBase->Elapsed == 0)
165 SysBase->SysFlags |= 0x2000;
166 SysBase->AttnResched |= 0x80;
170 /*******************************************************************************
171 Global Interrupt Handler
173 This pice of code translates real irq number to AROS specific irq id. This
174 allows us to map system-dependent irqs (audio, ethernet and so on) into well
175 defined ids.
176 *******************************************************************************/
178 void global_server(int cpl, struct irq_staticdata *isd, struct pt_regs *regs)
180 HIDDT_IRQ_Id id;
181 HIDDT_IRQ_HwInfo hwinfo;
182 HIDDT_IRQ_Handler *handler;
184 #if 0
185 switch (cpl)
187 case 0: /* Timer */
188 id = vHidd_IRQ_Timer;
189 break;
190 case 1: /* Keyboard */
191 id = vHidd_IRQ_Keyboard;
192 break;
193 case 3: /* COM2 */
194 id = vHidd_IRQ_Serial2;
195 break;
196 case 4: /* COM1 */
197 id = vHidd_IRQ_Serial1;
198 break;
199 case 6: /* Floppy */
200 id = vHidd_IRQ_Floppy;
201 break;
202 case 8: /* RTC */
203 id = vHidd_IRQ_RTC;
204 break;
205 case 12: /* PS/2 mouse */
206 id = vHidd_IRQ_Mouse;
207 break;
208 case 14: /* HDD1 */
209 id = vHidd_IRQ_HDD1;
210 break;
211 case 15: /* HDD2 */
212 id = vHidd_IRQ_HDD2;
213 break;
214 default:
215 #warning TODO: Write mapping for Global Interrupt Server
217 We should implement some kind of translation table built
218 while autodetecting devices
220 return;
222 #endif
224 hwinfo.Error = 0; /* No errorcode */
225 hwinfo.sysBase = SysBase;
227 if (cpl == 11) { D(bug("IRQ%02d",cpl)); }
229 /* Execute all installed handlers */
230 ForeachNode(&isd->irqlist[cpl], handler)
232 if (handler->h_Code)
233 handler->h_Code(handler, &hwinfo);
236 /* Leave the interrupt. */