1*10465441SEvalZero /*
2*10465441SEvalZero * File : interrupt.c
3*10465441SEvalZero * This file is part of RT-Thread RTOS
4*10465441SEvalZero * COPYRIGHT (C) 2009, RT-Thread Development Team
5*10465441SEvalZero *
6*10465441SEvalZero * The license and distribution terms for this file may be
7*10465441SEvalZero * found in the file LICENSE in this distribution or at
8*10465441SEvalZero * http://www.rt-thread.org/license/LICENSE
9*10465441SEvalZero *
10*10465441SEvalZero * Change Logs:
11*10465441SEvalZero * Date Author Notes
12*10465441SEvalZero * 2009-01-05 Bernard first version
13*10465441SEvalZero */
14*10465441SEvalZero
15*10465441SEvalZero #include <rthw.h>
16*10465441SEvalZero #include <asm/ppc4xx.h>
17*10465441SEvalZero #include <asm/processor.h>
18*10465441SEvalZero
19*10465441SEvalZero /* interrupt nest */
20*10465441SEvalZero extern volatile rt_uint8_t rt_interrupt_nest;
21*10465441SEvalZero
22*10465441SEvalZero /* exception and interrupt handler table */
23*10465441SEvalZero #define MAX_HANDLERS 32
24*10465441SEvalZero struct rt_irq_desc isr_table[MAX_HANDLERS];
25*10465441SEvalZero
26*10465441SEvalZero rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
27*10465441SEvalZero rt_uint32_t rt_thread_switch_interrput_flag;
28*10465441SEvalZero
rt_hw_interrupt_handler(rt_uint32_t vector,void * param)29*10465441SEvalZero rt_isr_handler_t rt_hw_interrupt_handler(rt_uint32_t vector, void* param)
30*10465441SEvalZero {
31*10465441SEvalZero rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
32*10465441SEvalZero return RT_NULL;
33*10465441SEvalZero }
34*10465441SEvalZero
uic_irq_ack(unsigned int vec)35*10465441SEvalZero void uic_irq_ack(unsigned int vec)
36*10465441SEvalZero {
37*10465441SEvalZero mtdcr(uic0sr, UIC_MASK(vec));
38*10465441SEvalZero }
39*10465441SEvalZero
uic_int_handler(unsigned int vec)40*10465441SEvalZero void uic_int_handler (unsigned int vec)
41*10465441SEvalZero {
42*10465441SEvalZero rt_interrupt_enter();
43*10465441SEvalZero
44*10465441SEvalZero /* Allow external interrupts to the CPU. */
45*10465441SEvalZero if (isr_table [vec].handler != 0)
46*10465441SEvalZero {
47*10465441SEvalZero (*isr_table[vec].handler)(vec, isr_table[vec].param);
48*10465441SEvalZero }
49*10465441SEvalZero uic_irq_ack(vec);
50*10465441SEvalZero
51*10465441SEvalZero rt_interrupt_leave();
52*10465441SEvalZero }
53*10465441SEvalZero
54*10465441SEvalZero /* handler for UIC interrupt */
uic_interrupt(rt_uint32_t uic_base,int vec_base)55*10465441SEvalZero void uic_interrupt(rt_uint32_t uic_base, int vec_base)
56*10465441SEvalZero {
57*10465441SEvalZero int vec;
58*10465441SEvalZero rt_uint32_t uic_msr;
59*10465441SEvalZero rt_uint32_t msr_shift;
60*10465441SEvalZero
61*10465441SEvalZero /*
62*10465441SEvalZero * Read masked interrupt status register to determine interrupt source
63*10465441SEvalZero */
64*10465441SEvalZero uic_msr = get_dcr(uic_base + UIC_MSR);
65*10465441SEvalZero msr_shift = uic_msr;
66*10465441SEvalZero vec = vec_base;
67*10465441SEvalZero
68*10465441SEvalZero while (msr_shift != 0)
69*10465441SEvalZero {
70*10465441SEvalZero if (msr_shift & 0x80000000)
71*10465441SEvalZero uic_int_handler(vec);
72*10465441SEvalZero
73*10465441SEvalZero /*
74*10465441SEvalZero * Shift msr to next position and increment vector
75*10465441SEvalZero */
76*10465441SEvalZero msr_shift <<= 1;
77*10465441SEvalZero vec++;
78*10465441SEvalZero }
79*10465441SEvalZero }
80*10465441SEvalZero
rt_hw_interrupt_install(int vector,rt_isr_handler_t new_handler,void * param,const char * name)81*10465441SEvalZero rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler,
82*10465441SEvalZero void* param, const char* name)
83*10465441SEvalZero {
84*10465441SEvalZero int intVal;
85*10465441SEvalZero rt_isr_handler_t old_handler;
86*10465441SEvalZero
87*10465441SEvalZero if (((int)vector < 0) || ((int) vector >= MAX_HANDLERS))
88*10465441SEvalZero {
89*10465441SEvalZero return RT_NULL; /* out of range */
90*10465441SEvalZero }
91*10465441SEvalZero
92*10465441SEvalZero /* install the handler in the system interrupt table */
93*10465441SEvalZero intVal = rt_hw_interrupt_disable (); /* lock interrupts to prevent races */
94*10465441SEvalZero
95*10465441SEvalZero old_handler = isr_table[vector].handler;
96*10465441SEvalZero isr_table[vector].handler = new_handler;
97*10465441SEvalZero isr_table[vector].param = param;
98*10465441SEvalZero
99*10465441SEvalZero rt_hw_interrupt_enable (intVal);
100*10465441SEvalZero }
101*10465441SEvalZero
rt_hw_interrupt_mask(int vector)102*10465441SEvalZero void rt_hw_interrupt_mask(int vector)
103*10465441SEvalZero {
104*10465441SEvalZero mtdcr(uic0er, mfdcr(uic0er) & ~UIC_MASK(vector));
105*10465441SEvalZero }
106*10465441SEvalZero
rt_hw_interrupt_unmask(int vector)107*10465441SEvalZero void rt_hw_interrupt_unmask(int vector)
108*10465441SEvalZero {
109*10465441SEvalZero mtdcr(uic0er, mfdcr(uic0er) | UIC_MASK(vector));
110*10465441SEvalZero }
111*10465441SEvalZero
rt_hw_interrupt_init()112*10465441SEvalZero void rt_hw_interrupt_init()
113*10465441SEvalZero {
114*10465441SEvalZero int vector;
115*10465441SEvalZero rt_uint32_t pit_value;
116*10465441SEvalZero
117*10465441SEvalZero pit_value = RT_TICK_PER_SECOND * (100000000 / RT_CPU_FREQ);
118*10465441SEvalZero
119*10465441SEvalZero /* enable pit */
120*10465441SEvalZero mtspr(SPRN_PIT, pit_value);
121*10465441SEvalZero mtspr(SPRN_TCR, 0x4400000);
122*10465441SEvalZero
123*10465441SEvalZero /* set default interrupt handler */
124*10465441SEvalZero for (vector = 0; vector < MAX_HANDLERS; vector++)
125*10465441SEvalZero {
126*10465441SEvalZero isr_table [vector].handler = (rt_isr_handler_t)rt_hw_interrupt_handler;
127*10465441SEvalZero isr_table [vector].param = RT_NULL;
128*10465441SEvalZero }
129*10465441SEvalZero
130*10465441SEvalZero /* initialize interrupt nest, and context in thread sp */
131*10465441SEvalZero rt_interrupt_nest = 0;
132*10465441SEvalZero rt_interrupt_from_thread = 0;
133*10465441SEvalZero rt_interrupt_to_thread = 0;
134*10465441SEvalZero rt_thread_switch_interrput_flag = 0;
135*10465441SEvalZero }
136*10465441SEvalZero
137*10465441SEvalZero /*@}*/
138