4 * Created on: Sep 4, 2008
10 #include <aros/debug.h>
12 #include <aros/kernel.h>
13 #include <aros/libcall.h>
14 #include <asm/mpc5200b.h>
19 #include <proto/exec.h>
20 #include <proto/kernel.h>
22 #include "kernel_intern.h"
26 static volatile mpc5200b_ictl_t
*ictl
;
28 void ictl_init(void *MBAR
)
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
);
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
);
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();
112 /* KernelBase set? */
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? */
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
)
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
++)
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
)
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
++)
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
)
173 in
->in_Handler(in
->in_HandlerData
, in
->in_HandlerData2
);
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
)
195 in
->in_Handler(in
->in_HandlerData
, in
->in_HandlerData2
);
200 D(bug("[KRN] Orphan peripheral interrupt %d! Disabling\n", 22));
201 outl(inl(&ictl
->ictl_pim
) | __BV32(22), &ictl
->ictl_pim
);
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
)
217 in
->in_Handler(in
->in_HandlerData
, in
->in_HandlerData2
);
224 outl(inl(&ictl
->ictl_pmce
), &ictl
->ictl_pmce
);
225 core_ExitInterrupt(ctx
);