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