Copyright clean-up (part 1):
[AROS.git] / arch / ppc-sam440 / kernel / uic.c
blob18d34043b290fb073b87cb3835752e41012c1fd6
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/debug.h>
7 #include <asm/amcc440.h>
8 #include <exec/lists.h>
9 #include <stddef.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
22 ULONG uic_er[4];
24 void uic_enable(int irq)
26 ULONG mask = (0x80000000 >> (irq & 0x1f));
28 uic_er[irq >> 5] |= mask;
30 switch (irq >> 5) {
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;
35 default: break;
39 void uic_disable(int irq)
41 ULONG mask = (0x80000000 >> (irq & 0x1f));
43 uic_er[irq >> 5] &= ~mask;
45 switch (irq >> 5) {
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;
50 default: break;
54 void uic_init(void)
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);
64 wrdcr(UIC0_VCR, 0);
66 uic_er[1] = 0;
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);
72 wrdcr(UIC1_VCR, 0);
74 uic_er[2] = 0;
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);
80 wrdcr(UIC2_VCR, 0);
82 uic_er[3] = 0;
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);
88 wrdcr(UIC3_VCR, 0);
89 } else {
90 wrdcr(UIC0_ER, 0);
91 wrdcr(UIC1_ER, 0);
95 void uic_handler(context_t *ctx, uint8_t exception)
97 struct KernelBase *KernelBase = getKernelBase();
99 /* Get the interrupt sources */
100 uint32_t uic_sr[4];
101 uint32_t uic_tr[4];
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;
116 } else {
117 uic_sr[2] = 0;
118 uic_sr[3] = 0;
119 uic_tr[2] = 0;
120 uic_tr[3] = 0;
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. */
133 if (KernelBase)
135 int i;
136 uint32_t irq = 0;
139 * Process the interrupt sources in the priority order.
141 for (i = 0; i < 4; i++) {
142 uint32_t mask;
144 if (uic_sr[i] == 0) {
145 irq += 32;
146 continue;
149 for (mask = 0x80000000; mask; mask >>= 1, irq++)
151 if (i == 0 && (mask & uic0_cascade))
152 continue;
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]);
170 ExitInterrupt(ctx);