xref: /nrf52832-nimble/rt-thread/libcpu/ppc/ppc405/interrupt.c (revision 104654410c56c573564690304ae786df310c91fc)
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