2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
5 Desc: IRQ servers for standalone i386 AROS
10 #include <aros/debug.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>
20 #include <utility/utility.h>
21 #include <hardware/intbits.h>
23 #include <asm/ptrace.h>
27 #include <proto/exec.h>
28 #include <proto/oop.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
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
)
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
);
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
);
106 irqSet(9, &irq9_int
);
107 irqSet(10, &irq10_int
);
108 irqSet(11, &irq11_int
);
109 irqSet(12, &mouse_int
);
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
);
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
;
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)
147 A5 - Interrupt Code vector
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
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
176 *******************************************************************************/
178 void global_server(int cpl
, struct irq_staticdata
*isd
, struct pt_regs
*regs
)
181 HIDDT_IRQ_HwInfo hwinfo
;
182 HIDDT_IRQ_Handler
*handler
;
188 id
= vHidd_IRQ_Timer
;
190 case 1: /* Keyboard */
191 id
= vHidd_IRQ_Keyboard
;
194 id
= vHidd_IRQ_Serial2
;
197 id
= vHidd_IRQ_Serial1
;
200 id
= vHidd_IRQ_Floppy
;
205 case 12: /* PS/2 mouse */
206 id
= vHidd_IRQ_Mouse
;
215 #warning TODO: Write mapping for Global Interrupt Server
217 We should implement some kind of translation table built
218 while autodetecting devices
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
)
233 handler
->h_Code(handler
, &hwinfo
);
236 /* Leave the interrupt. */