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