Updated PCI IDs to latest snapshot.
[tangerine.git] / arch / ppc-chrp / efika / kernel / ictl.c
blobb303928961d2fac85615d4c787ece92842f394c1
1 /*
2 * pic.c
4 * Created on: Sep 4, 2008
5 * Author: misc
6 */
8 #define DEBUG 1
10 #include <aros/debug.h>
11 #include <inttypes.h>
12 #include <aros/kernel.h>
13 #include <aros/libcall.h>
14 #include <asm/mpc5200b.h>
15 #include <asm/io.h>
16 #include <stddef.h>
17 #include <string.h>
19 #include <proto/exec.h>
20 #include <proto/kernel.h>
22 #include "kernel_intern.h"
23 #include "syscall.h"
26 static volatile mpc5200b_ictl_t *ictl;
28 void ictl_init(void *MBAR)
30 uint32_t tmp;
31 D(bug("[KRN] Entering ictl_init.\n"));
32 ictl = (mpc5200b_ictl_t *)((intptr_t)MBAR + 0x500);
34 D(bug("[KRN] Stopping all interrupt activities\n"));
36 /* Disable all peripheral interrupts */
37 outl(0xffffff00, &ictl->ictl_pim);
39 /* Disable all master interrupts */
40 outl(0x00010fff, &ictl->ictl_cpmim);
42 /* Critical interrupts should generate EE. Keep the old IRQ[0..3] config! */
43 tmp = inl(&ictl->ictl_ee);
44 tmp &= 0x00ff0000; /* Leave the IRQ configuration intact */
45 tmp |= 0x0f000000; /* Clear any pending IRQ's */
46 outl(ICTL_EE_MEE | ICTL_EE_CEB,&ictl->ictl_ee);
48 /* Set all Main priorities to 0 */
49 outl(0, &ictl->ictl_mip[0]);
50 outl(0, &ictl->ictl_mip[1]);
52 /* Set all Peripheral priorities to 0 */
53 outl(0, &ictl->ictl_ppri[0]);
54 outl(0, &ictl->ictl_ppri[1]);
55 outl(0, &ictl->ictl_ppri[2]);
58 void ictl_enable_irq(uint8_t irqnum)
60 if (irqnum <= MPC5200B_WAKEUP)
61 D(bug("[KRN] Enabling critical irq %d? Cannot. It's already enabled.\n", irqnum));
62 else if (irqnum <= MPC5200B_TMR7)
64 D(bug("[KRN] Enabling main irq %d.\n", irqnum));
66 outl(inl(&ictl->ictl_cpmim) & ~(0x00010000 >> (irqnum - MPC5200B_ST1)), &ictl->ictl_cpmim);
68 else if (irqnum <= MPC5200B_BESTCOMMLP)
70 D(bug("[KRN] Enabling peripheral irq %d.\n", irqnum));
72 outl(inl(&ictl->ictl_pim) & ~(0x80000000 >> (irqnum - MPC5200B_BESTCOMM)), &ictl->ictl_pim);
74 else
75 D(bug("[KRN] Uhh?! Someone tried to enable non-existing irq %d\n", irqnum));
77 D(bug("[KRN] CPMIM=%08x PIM=%08x\n", inl(&ictl->ictl_cpmim), inl(&ictl->ictl_pim)));
78 D(bug("[KRN] PMCE=%08x PIS=%08x\n", inl(&ictl->ictl_pmce), inl(&ictl->ictl_pis)));
81 void ictl_disable_irq(uint8_t irqnum)
83 if (irqnum <= MPC5200B_WAKEUP)
84 D(bug("[KRN] Disabling critical irq %d? Cannot.\n", irqnum));
85 else if (irqnum <= MPC5200B_TMR7)
87 D(bug("[KRN] Disabling main irq %d.\n", irqnum));
89 outl(inl(&ictl->ictl_cpmim) | (0x00010000 > irqnum - MPC5200B_ST1), &ictl->ictl_cpmim);
91 else if (irqnum <= MPC5200B_BESTCOMMLP)
93 D(bug("[KRN] Disabling peripheral irq %d.\n", irqnum));
95 outl(inl(&ictl->ictl_pim) | (0x80000000 > irqnum - MPC5200B_BESTCOMM), &ictl->ictl_pim);
97 else
98 D(bug("[KRN] Uhh?! Someone tried to disable non-existing irq %d\n", irqnum));
102 void __attribute__((noreturn)) ictl_handler(regs_t *ctx, uint8_t exception, void *self)
104 //D(bug("[KRN] ictl_handler\n"));
105 struct KernelBase *KernelBase = getKernelBase();
107 int irqnum = 0;
108 int i;
109 uint32_t bit;
110 uint32_t irqstate;
112 /* KernelBase set? */
113 if (KernelBase)
115 /* First, check the critical interrupts */
116 irqstate = inl(&ictl->ictl_cis);
117 for (i=0, bit=0x08000000; i<4; i++, bit>>=1, irqnum++)
119 /* Interrupt occurred? */
120 if (irqstate & bit)
122 /* Any handlers available? */
123 if (!IsListEmpty(&KernelBase->kb_Interrupts[irqnum]))
125 struct IntrNode *in, *in2;
127 /* Call all handlers */
128 ForeachNodeSafe(&KernelBase->kb_Interrupts[irqnum], in, in2)
130 if (in->in_Handler)
131 in->in_Handler(in->in_HandlerData, in->in_HandlerData2);
137 /* Now the main interrupts */
138 irqstate = inl(&ictl->ictl_mis);
139 for (i=0, bit=0x00010000; i < 17; i++, bit>>=1, irqnum++)
141 if (irqstate & bit)
143 /* Any handlers available? */
144 if (!IsListEmpty(&KernelBase->kb_Interrupts[irqnum]))
146 struct IntrNode *in, *in2;
148 /* Call all handlers */
149 ForeachNodeSafe(&KernelBase->kb_Interrupts[irqnum], in, in2)
151 if (in->in_Handler)
152 in->in_Handler(in->in_HandlerData, in->in_HandlerData2);
158 /* Finally the peripheral interrupts */
159 irqstate = inl(&ictl->ictl_pis);
160 for (i=0, bit=0x00200000; i < 22; i++, bit>>=1, irqnum++)
162 if (irqstate & bit)
164 /* Any handlers available? */
165 if (!IsListEmpty(&KernelBase->kb_Interrupts[irqnum]))
167 struct IntrNode *in, *in2;
169 /* Call all handlers */
170 ForeachNodeSafe(&KernelBase->kb_Interrupts[irqnum], in, in2)
172 if (in->in_Handler)
173 in->in_Handler(in->in_HandlerData, in->in_HandlerData2);
176 else
178 // D(bug("[KRN] Orphan peripheral interrupt %d! Disabling\n", i));
179 outl(inl(&ictl->ictl_pim) | __BV32(i), &ictl->ictl_pim);
184 if (irqstate & __BV32(9))
186 /* Any handlers available? */
187 if (!IsListEmpty(&KernelBase->kb_Interrupts[irqnum]))
189 struct IntrNode *in, *in2;
191 /* Call all handlers */
192 ForeachNodeSafe(&KernelBase->kb_Interrupts[irqnum], in, in2)
194 if (in->in_Handler)
195 in->in_Handler(in->in_HandlerData, in->in_HandlerData2);
198 else
200 D(bug("[KRN] Orphan peripheral interrupt %d! Disabling\n", 22));
201 outl(inl(&ictl->ictl_pim) | __BV32(22), &ictl->ictl_pim);
204 irqnum++;
206 if (irqstate & __BV32(8))
208 /* Any handlers available? */
209 if (!IsListEmpty(&KernelBase->kb_Interrupts[irqnum]))
211 struct IntrNode *in, *in2;
213 /* Call all handlers */
214 ForeachNodeSafe(&KernelBase->kb_Interrupts[irqnum], in, in2)
216 if (in->in_Handler)
217 in->in_Handler(in->in_HandlerData, in->in_HandlerData2);
221 irqnum++;
224 outl(inl(&ictl->ictl_pmce), &ictl->ictl_pmce);
225 core_ExitInterrupt(ctx);