revert between 56095 -> 55830 in arch
[AROS.git] / arch / ppc-chrp / efika / kernel / ictl.c
blob5599a2e518314ddb2d8cbd1d3c60203fd57b37c7
1 /*
2 Copyright © 2008-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 1
8 #include <aros/debug.h>
9 #include <inttypes.h>
10 #include <aros/kernel.h>
11 #include <aros/libcall.h>
12 #include <asm/mpc5200b.h>
13 #include <asm/io.h>
14 #include <stddef.h>
15 #include <string.h>
17 #include <proto/exec.h>
18 #include <proto/kernel.h>
20 #include "kernel_intern.h"
21 #include "syscall.h"
24 static volatile mpc5200b_ictl_t *ictl;
26 void ictl_init(void *MBAR)
28 uint32_t tmp;
29 D(bug("[KRN] Entering ictl_init.\n"));
30 ictl = (mpc5200b_ictl_t *)((intptr_t)MBAR + 0x500);
32 D(bug("[KRN] Stopping all interrupt activities\n"));
34 /* Disable all peripheral interrupts */
35 outl(0xffffff00, &ictl->ictl_pim);
37 /* Disable all master interrupts */
38 outl(0x00010fff, &ictl->ictl_cpmim);
40 /* Critical interrupts should generate EE. Keep the old IRQ[0..3] config! */
41 tmp = inl(&ictl->ictl_ee);
42 tmp &= 0x00ff0000; /* Leave the IRQ configuration intact */
43 tmp |= 0x0f000000; /* Clear any pending IRQ's */
44 outl(ICTL_EE_MEE | ICTL_EE_CEB,&ictl->ictl_ee);
46 /* Set all Main priorities to 0 */
47 outl(0, &ictl->ictl_mip[0]);
48 outl(0, &ictl->ictl_mip[1]);
50 /* Set all Peripheral priorities to 0 */
51 outl(0, &ictl->ictl_ppri[0]);
52 outl(0, &ictl->ictl_ppri[1]);
53 outl(0, &ictl->ictl_ppri[2]);
56 void ictl_enable_irq(uint8_t irqnum)
58 if (irqnum <= MPC5200B_WAKEUP)
59 D(bug("[KRN] Enabling critical irq %d? Cannot. It's already enabled.\n", irqnum));
60 else if (irqnum <= MPC5200B_TMR7)
62 D(bug("[KRN] Enabling main irq %d.\n", irqnum));
64 outl(inl(&ictl->ictl_cpmim) & ~(0x00010000 >> (irqnum - MPC5200B_ST1)), &ictl->ictl_cpmim);
66 else if (irqnum <= MPC5200B_BESTCOMMLP)
68 D(bug("[KRN] Enabling peripheral irq %d.\n", irqnum));
70 outl(inl(&ictl->ictl_pim) & ~(0x80000000 >> (irqnum - MPC5200B_BESTCOMM)), &ictl->ictl_pim);
72 else
73 D(bug("[KRN] Uhh?! Someone tried to enable non-existing irq %d\n", irqnum));
75 D(bug("[KRN] CPMIM=%08x PIM=%08x\n", inl(&ictl->ictl_cpmim), inl(&ictl->ictl_pim)));
76 D(bug("[KRN] PMCE=%08x PIS=%08x\n", inl(&ictl->ictl_pmce), inl(&ictl->ictl_pis)));
79 void ictl_disable_irq(uint8_t irqnum)
81 if (irqnum <= MPC5200B_WAKEUP)
82 D(bug("[KRN] Disabling critical irq %d? Cannot.\n", irqnum));
83 else if (irqnum <= MPC5200B_TMR7)
85 D(bug("[KRN] Disabling main irq %d.\n", irqnum));
87 outl(inl(&ictl->ictl_cpmim) | (0x00010000 > irqnum - MPC5200B_ST1), &ictl->ictl_cpmim);
89 else if (irqnum <= MPC5200B_BESTCOMMLP)
91 D(bug("[KRN] Disabling peripheral irq %d.\n", irqnum));
93 outl(inl(&ictl->ictl_pim) | (0x80000000 > irqnum - MPC5200B_BESTCOMM), &ictl->ictl_pim);
95 else
96 D(bug("[KRN] Uhh?! Someone tried to disable non-existing irq %d\n", irqnum));
100 void __attribute__((noreturn)) ictl_handler(regs_t *ctx, uint8_t exception, void *self)
102 //D(bug("[KRN] ictl_handler\n"));
103 struct KernelBase *KernelBase = getKernelBase();
105 int irqnum = 0;
106 int i;
107 uint32_t bit;
108 uint32_t irqstate;
110 /* KernelBase set? */
111 if (KernelBase)
113 /* First, check the critical interrupts */
114 irqstate = inl(&ictl->ictl_cis);
115 for (i=0, bit=0x08000000; i<4; i++, bit>>=1, irqnum++)
117 /* Interrupt occurred? */
118 if (irqstate & bit)
120 /* Any handlers available? */
121 if (!IsListEmpty(&KernelBase->kb_Interrupts[irqnum]))
123 struct IntrNode *in, *in2;
125 /* Call all handlers */
126 ForeachNodeSafe(&KernelBase->kb_Interrupts[irqnum], in, in2)
128 if (in->in_Handler)
129 in->in_Handler(in->in_HandlerData, in->in_HandlerData2);
135 /* Now the main interrupts */
136 irqstate = inl(&ictl->ictl_mis);
137 for (i=0, bit=0x00010000; i < 17; i++, bit>>=1, irqnum++)
139 if (irqstate & bit)
141 /* Any handlers available? */
142 if (!IsListEmpty(&KernelBase->kb_Interrupts[irqnum]))
144 struct IntrNode *in, *in2;
146 /* Call all handlers */
147 ForeachNodeSafe(&KernelBase->kb_Interrupts[irqnum], in, in2)
149 if (in->in_Handler)
150 in->in_Handler(in->in_HandlerData, in->in_HandlerData2);
156 /* Finally the peripheral interrupts */
157 irqstate = inl(&ictl->ictl_pis);
158 for (i=0, bit=0x00200000; i < 22; i++, bit>>=1, irqnum++)
160 if (irqstate & bit)
162 /* Any handlers available? */
163 if (!IsListEmpty(&KernelBase->kb_Interrupts[irqnum]))
165 struct IntrNode *in, *in2;
167 /* Call all handlers */
168 ForeachNodeSafe(&KernelBase->kb_Interrupts[irqnum], in, in2)
170 if (in->in_Handler)
171 in->in_Handler(in->in_HandlerData, in->in_HandlerData2);
174 else
176 // D(bug("[KRN] Orphan peripheral interrupt %d! Disabling\n", i));
177 outl(inl(&ictl->ictl_pim) | __BV32(i), &ictl->ictl_pim);
182 if (irqstate & __BV32(9))
184 /* Any handlers available? */
185 if (!IsListEmpty(&KernelBase->kb_Interrupts[irqnum]))
187 struct IntrNode *in, *in2;
189 /* Call all handlers */
190 ForeachNodeSafe(&KernelBase->kb_Interrupts[irqnum], in, in2)
192 if (in->in_Handler)
193 in->in_Handler(in->in_HandlerData, in->in_HandlerData2);
196 else
198 D(bug("[KRN] Orphan peripheral interrupt %d! Disabling\n", 22));
199 outl(inl(&ictl->ictl_pim) | __BV32(22), &ictl->ictl_pim);
202 irqnum++;
204 if (irqstate & __BV32(8))
206 /* Any handlers available? */
207 if (!IsListEmpty(&KernelBase->kb_Interrupts[irqnum]))
209 struct IntrNode *in, *in2;
211 /* Call all handlers */
212 ForeachNodeSafe(&KernelBase->kb_Interrupts[irqnum], in, in2)
214 if (in->in_Handler)
215 in->in_Handler(in->in_HandlerData, in->in_HandlerData2);
219 irqnum++;
222 outl(inl(&ictl->ictl_pmce), &ictl->ictl_pmce);
223 core_ExitInterrupt(ctx);