2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: IRQ servers for standalone i386 AROS
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>
17 #include <utility/utility.h>
18 #include <hardware/intbits.h>
20 #include <asm/ptrace.h>
23 #include <proto/exec.h>
24 #include <proto/oop.h>
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
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
)
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
);
91 irqSet(6, &floppy_int
);
93 irqSet(12, &mouse_int
);
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
);
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
);
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
;
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)
132 A5 - Interrupt Code vector
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
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
159 *******************************************************************************/
162 #define SysBase (isd->sysbase)
164 HIDDT_IRQ_Id translation_table
[] = {
183 void global_server(int cpl
, struct irq_staticdata
*isd
, struct pt_regs
*regs
)
185 if (cpl
>= 0 && cpl
<= 15) {
187 HIDDT_IRQ_HwInfo hwinfo
;
188 HIDDT_IRQ_Handler
*handler
;
190 if (-1 == (id
= translation_table
[cpl
]))
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. */