added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / arch / .unmaintained / generic / hidd / irq / servers.c
blob69eeb6700000a0bed31ae769c12383c541a2d23f
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: IRQ servers for standalone i386 AROS
6 Lang: english
7 */
9 #include <oop/oop.h>
10 #include <aros/asmcall.h>
11 #include <exec/types.h>
12 #include <exec/lists.h>
13 #include <exec/interrupts.h>
14 #include <exec/execbase.h>
15 #include <exec/memory.h>
16 #include <hidd/irq.h>
17 #include <utility/utility.h>
18 #include <hardware/intbits.h>
20 #include <asm/ptrace.h>
21 #include <asm/irq.h>
23 #include <proto/exec.h>
24 #include <proto/oop.h>
26 #include "irq.h"
28 #ifdef SysBase
29 #undef SysBase
30 #endif /* SysBase */
32 void global_server(int cpl, struct irq_staticdata *isd, struct pt_regs *regs);
34 struct irqServer timer_int = { global_server, "timer", NULL};
35 struct irqServer kbd_int = { global_server, "keyboard", NULL};
36 struct irqServer com1_int = { global_server, "serial 1", NULL};
37 struct irqServer com2_int = { global_server, "serial 2", NULL};
38 struct irqServer floppy_int = { global_server, "floppy", NULL};
39 struct irqServer rtc_int = { global_server, "rtc", NULL};
40 struct irqServer mouse_int = { global_server, "ps/2 mouse", NULL};
41 struct irqServer ide0_int = { global_server, "ide0", NULL};
42 struct irqServer ide1_int = { global_server, "ide1", NULL};
44 void timer_interrupt(HIDDT_IRQ_Handler *irq, HIDDT_IRQ_HwInfo *hw);
46 /*******************************************************************************
47 Two special irq handlers. As we don't need these two interrupts we define
48 here dummy handlers.
49 *******************************************************************************/
51 void no_action(int cpl, void *dev_id, struct pt_regs *regs, struct irq_staticdata *isd) { }
53 static void math_error_irq(int cpl, void *dev_id, struct pt_regs *regs, struct irq_staticdata *isd)
55 outb(0,0xF0);
58 static struct irqServer irq13 = { math_error_irq, "fpu", NULL};
61 * IRQ2 is cascade interrupt to second interrupt controller
64 static struct irqServer irq2 = { no_action, "cascade", NULL};
66 #define SysBase (isd->sysbase)
68 void irqSet(int, struct irqServer *);
70 void init_Servers(struct irq_staticdata *isd)
72 HIDDT_IRQ_Handler *timer;
74 timer_int.is_UserData = isd;
75 irq2.is_UserData = isd;
76 kbd_int.is_UserData = isd;
77 com1_int.is_UserData = isd;
78 com2_int.is_UserData = isd;
79 floppy_int.is_UserData = isd;
80 rtc_int.is_UserData = isd;
81 mouse_int.is_UserData = isd;
82 irq13.is_UserData = isd;
83 ide0_int.is_UserData = isd;
84 ide1_int.is_UserData = isd;
86 irqSet(0, &timer_int);
87 irqSet(1, &kbd_int);
88 irqSet(2, &irq2);
89 irqSet(3, &com2_int);
90 irqSet(4, &com1_int);
91 irqSet(6, &floppy_int);
92 irqSet(8, &rtc_int);
93 irqSet(12, &mouse_int);
94 irqSet(13, &irq13);
95 irqSet(14, &ide0_int);
96 irqSet(15, &ide1_int);
98 /* Install timer interrupt */
99 timer = AllocMem(sizeof(HIDDT_IRQ_Handler), MEMF_CLEAR|MEMF_PUBLIC);
100 if (timer) {
101 timer->h_Node.ln_Name = "INT_VERTB emulator";
102 timer->h_Node.ln_Type = NT_INTERRUPT;
103 timer->h_Node.ln_Pri = 0;
104 timer->h_Data = &SysBase->IntVects[INTB_VERTB];
105 timer->h_Code = timer_interrupt;
107 Enqueue((struct List *)&isd->irqlist[vHidd_IRQ_Timer], (struct Node *)timer);
111 #undef SysBase
113 /*******************************************************************************
114 This timer interrupt is used to keep compatibility with old Amiga software
115 *******************************************************************************/
117 void timer_interrupt(HIDDT_IRQ_Handler *irq, HIDDT_IRQ_HwInfo *hw)
119 struct IntVector *iv = irq->h_Data;
121 if (iv->iv_Code)
123 /* Call it. I call with all these parameters for a reason.
125 In my `Amiga ROM Kernel Reference Manual: Libraries and
126 Devices' (the 1.3 version), interrupt servers are called
127 with the following 5 parameters.
129 D1 - Mask of INTENAR and INTREQR
130 A0 - 0xDFF000 (base of custom chips)
131 A1 - Interrupt Data
132 A5 - Interrupt Code vector
133 A6 - SysBase
135 It is quite possible that some code uses all of these, so
136 I must supply them here. Obviously I will dummy some of these
137 though.
139 AROS_UFC5(void, iv->iv_Code,
140 AROS_UFCA(ULONG, 0, D1),
141 AROS_UFCA(ULONG, 0, A0),
142 AROS_UFCA(APTR, iv->iv_Data, A1),
143 AROS_UFCA(APTR, iv->iv_Code, A5),
144 AROS_UFCA(struct ExecBase *, hw->sysBase, A6));
147 if (--SysBase->Elapsed == 0) {
148 SysBase->SysFlags |= 0x2000;
149 SysBase->AttnResched |= 0x80;
153 /*******************************************************************************
154 Global Interrupt Handler
156 This piece of code translates real irq number to AROS specific irq id. This
157 allows us to map system-dependent irqs (audio, ethernet and so on) into well
158 defined ids.
159 *******************************************************************************/
161 #undef SysBase
162 #define SysBase (isd->sysbase)
164 HIDDT_IRQ_Id translation_table[] = {
165 vHidd_IRQ_Timer,
166 vHidd_IRQ_Keyboard,
167 /* 2 */ -1,
168 vHidd_IRQ_Serial2,
169 vHidd_IRQ_Serial1,
170 /* 5 */ -1
171 vHidd_IRQ_Floppy,
172 /* 7 */ -1,
173 vHidd_IRQ_RTC,
174 /* 9 */ -1,
177 vHidd_IRQ_Mouse,
178 /* 13 */-1,
179 vHidd_IRQ_HDD1,
180 vHidd_IRQ_HDD2};
183 void global_server(int cpl, struct irq_staticdata *isd, struct pt_regs *regs)
185 if (cpl >= 0 && cpl <= 15) {
186 HIDDT_IRQ_Id id;
187 HIDDT_IRQ_HwInfo hwinfo;
188 HIDDT_IRQ_Handler *handler;
190 if (-1 == (id = translation_table[cpl]))
191 return;
193 hwinfo.Error = 0; /* No errorcode */
194 hwinfo.sysBase = isd->sysbase;
196 /* Execute all installed handlers */
197 ForeachNode(&isd->irqlist[id], handler) {
198 handler->h_Code(handler, &hwinfo);
201 /* Leave the interrupt. */