2 Copyright © 2008-2014, The AROS Development Team. All rights reserved.
8 #include <aros/debug.h>
10 #include <aros/kernel.h>
11 #include <aros/libcall.h>
12 #include <asm/mpc5200b.h>
17 #include <proto/exec.h>
18 #include <proto/kernel.h>
20 #include "kernel_intern.h"
24 static volatile mpc5200b_ictl_t
*ictl
;
26 void ictl_init(void *MBAR
)
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
);
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
);
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();
110 /* KernelBase set? */
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? */
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
)
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
++)
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
)
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
++)
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
)
171 in
->in_Handler(in
->in_HandlerData
, in
->in_HandlerData2
);
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
)
193 in
->in_Handler(in
->in_HandlerData
, in
->in_HandlerData2
);
198 D(bug("[KRN] Orphan peripheral interrupt %d! Disabling\n", 22));
199 outl(inl(&ictl
->ictl_pim
) | __BV32(22), &ictl
->ictl_pim
);
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
)
215 in
->in_Handler(in
->in_HandlerData
, in
->in_HandlerData2
);
222 outl(inl(&ictl
->ictl_pmce
), &ictl
->ictl_pmce
);
223 core_ExitInterrupt(ctx
);