2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
6 #include <aros/debug.h>
7 #include <asm/amcc440.h>
8 #include <exec/lists.h>
11 #include LC_LIBDEFS_FILE
12 #include "kernel_intern.h"
13 #include "kernel_globals.h"
14 #include "kernel_interrupts.h"
16 #include "kernel_intr.h"
19 * Interrupt controller functions
24 void uic_enable(int irq
)
26 ULONG mask
= (0x80000000 >> (irq
& 0x1f));
28 uic_er
[irq
>> 5] |= mask
;
31 case 0: wrdcr(UIC0_ER
, uic_er
[0]); break;
32 case 1: wrdcr(UIC1_ER
, uic_er
[1]); break;
33 case 2: wrdcr(UIC2_ER
, uic_er
[2]); break;
34 case 3: wrdcr(UIC3_ER
, uic_er
[3]); break;
39 void uic_disable(int irq
)
41 ULONG mask
= (0x80000000 >> (irq
& 0x1f));
43 uic_er
[irq
>> 5] &= ~mask
;
46 case 0: wrdcr(UIC0_ER
, uic_er
[0]); break;
47 case 1: wrdcr(UIC1_ER
, uic_er
[1]); break;
48 case 2: wrdcr(UIC2_ER
, uic_er
[2]); break;
49 case 3: wrdcr(UIC3_ER
, uic_er
[3]); break;
56 /* Disable external interrupts completely */
57 if (krnIsPPC460(rdspr(PVR
))) {
58 uic_er
[0] = INTR_UIC0_CASCADE
;
59 wrdcr(UIC0_ER
, uic_er
[0]);
60 wrdcr(UIC0_PR
, INTR_UIC0_POLARITY
);
61 wrdcr(UIC0_CR
, INTR_UIC0_CRITICAL
);
62 wrdcr(UIC0_TR
, INTR_UIC0_TRIGGER
);
63 wrdcr(UIC0_SR
, 0xffffffff);
67 wrdcr(UIC1_ER
, uic_er
[1]);
68 wrdcr(UIC1_PR
, INTR_UIC1_POLARITY
);
69 wrdcr(UIC1_CR
, INTR_UIC1_CRITICAL
);
70 wrdcr(UIC1_TR
, INTR_UIC1_TRIGGER
);
71 wrdcr(UIC1_SR
, 0xffffffff);
75 wrdcr(UIC2_ER
, uic_er
[2]);
76 wrdcr(UIC2_PR
, INTR_UIC2_POLARITY
);
77 wrdcr(UIC2_CR
, INTR_UIC2_CRITICAL
);
78 wrdcr(UIC2_TR
, INTR_UIC2_TRIGGER
);
79 wrdcr(UIC2_SR
, 0xffffffff);
83 wrdcr(UIC3_ER
, uic_er
[3]);
84 wrdcr(UIC3_PR
, INTR_UIC3_POLARITY
);
85 wrdcr(UIC3_CR
, INTR_UIC3_CRITICAL
);
86 wrdcr(UIC3_TR
, INTR_UIC3_TRIGGER
);
87 wrdcr(UIC3_SR
, 0xffffffff);
95 void uic_handler(context_t
*ctx
, uint8_t exception
)
97 struct KernelBase
*KernelBase
= getKernelBase();
99 /* Get the interrupt sources */
103 uint32_t uic0_cascade
;
104 uint32_t pvr
= rdspr(PVR
);
106 uic_sr
[0] = rddcr(UIC0_MSR
);
107 uic_sr
[1] = rddcr(UIC1_MSR
);
108 uic_tr
[0] = rddcr(UIC0_TR
);
109 uic_tr
[1] = rddcr(UIC1_TR
);
110 if (krnIsPPC460(pvr
)) {
111 uic_sr
[2] = rddcr(UIC2_MSR
);
112 uic_sr
[3] = rddcr(UIC3_MSR
);
113 uic_tr
[2] = rddcr(UIC2_TR
);
114 uic_tr
[3] = rddcr(UIC3_TR
);
115 uic0_cascade
= INTR_UIC0_CASCADE
;
121 uic0_cascade
= 0x00000003;
124 /* Acknowledge edge interrups now */
125 if (krnIsPPC460(pvr
)) {
126 wrdcr(UIC3_SR
, uic_sr
[3] & uic_tr
[3]);
127 wrdcr(UIC2_SR
, uic_sr
[2] & uic_tr
[2]);
129 wrdcr(UIC1_SR
, uic_sr
[1] & uic_tr
[1]);
130 wrdcr(UIC0_SR
, uic_sr
[0] & uic_tr
[0]);
132 /* kernel.resource up and running? Good. */
139 * Process the interrupt sources in the priority order.
141 for (i
= 0; i
< 4; i
++) {
144 if (uic_sr
[i
] == 0) {
149 for (mask
= 0x80000000; mask
; mask
>>= 1, irq
++)
151 if (i
== 0 && (mask
& uic0_cascade
))
154 if (mask
& uic_sr
[i
])
156 krnRunIRQHandlers(KernelBase
, irq
);
162 /* Acknowledge the level interrupts once the handlers are done. */
163 if (krnIsPPC460(pvr
)) {
164 wrdcr(UIC3_SR
, uic_sr
[3] & ~uic_tr
[3]);
165 wrdcr(UIC2_SR
, uic_sr
[2] & ~uic_tr
[2]);
167 wrdcr(UIC1_SR
, uic_sr
[1] & ~uic_tr
[1]);
168 wrdcr(UIC0_SR
, uic_sr
[0] & ~uic_tr
[0]);