1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2013-7-14 Peng Fan sep6200 implementation
9 */
10
11 #include <rtthread.h>
12 #include <rthw.h>
13 #include <sep6200.h>
14
15 #define MAX_HANDLERS 64
16
17
18 #define SEP6200_IRQ_TYPE 0
19 #define SEP6200_FIQ_TYPE 1
20
21 #define int_enable_all() \
22 do { \
23 *(volatile unsigned long*)SEP6200_VIC_INT_EN_L = ~0x0;\
24 *(volatile unsigned long*)SEP6200_VIC_INT_EN_H = ~0x0;\
25 }while(0)
26 #define int_disable_all() \
27 do { \
28 *(volatile unsigned long*)SEP6200_VIC_INT_EN_L = 0x0;\
29 *(volatile unsigned long*)SEP6200_VIC_INT_EN_H = 0x0;\
30 }while(0)
31 #define mask_all_int(int_type) \
32 do { \
33 if (int_type == SEP6200_IRQ_TYPE){ \
34 *(volatile unsigned long*)SEP6200_VIC_INT_MSK_ALL = 0x1;\
35 } else if (int_type == SEP6200_FIQ_TYPE) {\
36 *(volatile unsigned long*)SEP6200_VIC_INT_MSK_ALL = 0x2;\
37 }\
38 }while(0)
39 #define unmask_all_int(int_type)\
40 do { \
41 if (int_type == SEP6200_IRQ_TYPE){ \
42 *(volatile unsigned long*)SEP6200_VIC_INT_MSK_ALL = ~0x1;\
43 } else if (int_type == SEP6200_FIQ_TYPE) {\
44 *(volatile unsigned long*)SEP6200_VIC_INT_MSK_ALL = ~0x2;\
45 }\
46 }while(0)
47
48 #define SEP6200_INT_SET(intnum) \
49 do{ \
50 if(intnum < 32) \
51 *(volatile unsigned long*)SEP6200_VIC_SFT_INT_L |= (1 << intnum); \
52 else \
53 *(volatile unsigned long*)SEP6200_VIC_SFT_INT_H |= (1 << (intnum - 32)); \
54 }while(0)
55
56 #define SEP6200_INT_CLR(intnum) \
57 do{ \
58 if(intnum < 32) \
59 *(volatile unsigned long*)SEP6200_VIC_SFT_INT_L &= ~(1 << intnum);\
60 else \
61 *(volatile unsigned long*)SEP6200_VIC_SFT_INT_H &= ~(1 << (intnum - 32)); \
62 }while(0)
63
64 #define SEP6200_INT_ENABLE(intnum)\
65 do{ \
66 if(intnum < 32) \
67 *(volatile unsigned long*)SEP6200_VIC_INT_EN_L |= (1 << intnum); \
68 else \
69 *(volatile unsigned long*)SEP6200_VIC_INT_EN_H |= (1 << (intnum - 32)); \
70 }while(0)
71
72 #define SEP6200_INT_DISABLE(intnum) \
73 do{ \
74 if(intnum < 32) \
75 *(volatile unsigned long*)SEP6200_VIC_INT_EN_L &= ~(1 << intnum); \
76 else \
77 *(volatile unsigned long*)SEP6200_VIC_INT_EN_H &= ~(1 << (intnum - 32)); \
78 }while(0)
79
80
81 extern rt_atomic_t rt_interrupt_nest;
82 /* exception and interrupt handler table */
83 struct rt_irq_desc isr_table[MAX_HANDLERS];
84 rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
85 rt_uint32_t rt_thread_switch_interrupt_flag;
86
87
88 /* --------------------------------------------------------------------
89 * Interrupt initialization
90 * -------------------------------------------------------------------- */
91
92 /**
93 * @addtogroup sep6200
94 */
95 /*@{*/
96
97 void rt_hw_interrupt_mask(int irq);
98 void rt_hw_interrupt_umask(int irq);
99
sep6200_irq_enable(rt_uint32_t irq)100 rt_inline void sep6200_irq_enable(rt_uint32_t irq)
101 {
102 SEP6200_INT_ENABLE(irq);
103 }
104
sep6200_irq_disable(rt_uint32_t irq)105 rt_inline void sep6200_irq_disable(rt_uint32_t irq)
106 {
107 SEP6200_INT_DISABLE(irq);
108 }
109
sep6200_irq_unmask(rt_uint32_t irq)110 rt_inline void sep6200_irq_unmask(rt_uint32_t irq)
111 {
112 SEP6200_INT_ENABLE(irq);
113 }
114
sep6200_irq_mask(rt_uint32_t irq)115 rt_inline void sep6200_irq_mask(rt_uint32_t irq)
116 {
117 SEP6200_INT_DISABLE(irq);
118 }
rt_hw_interrupt_handle(rt_uint32_t vector)119 rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector)
120 {
121 rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
122 return RT_NULL;
123 }
124
125 /**
126 * This function will initialize hardware interrupt
127 */
rt_hw_interrupt_init(void)128 void rt_hw_interrupt_init(void)
129 {
130 rt_int32_t i;
131 register rt_uint32_t idx;
132
133
134 /* init exceptions table */
135 for(idx=0; idx < MAX_HANDLERS; idx++)
136 {
137 isr_table[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
138 }
139 int_disable_all();
140 mask_all_int(SEP6200_FIQ_TYPE);
141
142 //int_enable_all();
143 unmask_all_int(SEP6200_IRQ_TYPE);
144
145 /* init interrupt nest, and context in thread sp */
146 rt_interrupt_nest = 0;
147 rt_interrupt_from_thread = 0;
148 rt_interrupt_to_thread = 0;
149 rt_thread_switch_interrupt_flag = 0;
150 }
151
152
153
154 /**
155 * This function will mask a interrupt.
156 * @param vector the interrupt number
157 */
rt_hw_interrupt_mask(int irq)158 void rt_hw_interrupt_mask(int irq)
159 {
160 if (irq >= MAX_HANDLERS) {
161 rt_kprintf("Wrong irq num to mask\n");
162 } else {
163 sep6200_irq_mask(irq);
164 }
165
166 }
167
168 /**
169 * This function will un-mask a interrupt.
170 * @param vector the interrupt number
171 */
rt_hw_interrupt_umask(int irq)172 void rt_hw_interrupt_umask(int irq)
173 {
174 if (irq >= MAX_HANDLERS) {
175 rt_kprintf("Wrong irq num to unmask\n");
176 } else {
177 sep6200_irq_unmask(irq);
178 }
179 }
180
181 /**
182 * This function will install a interrupt service routine to a interrupt.
183 * @param vector the interrupt number
184 * @param new_handler the interrupt service routine to be installed
185 * @param old_handler the old interrupt service routine
186 */
rt_hw_interrupt_install(int vector,rt_isr_handler_t handler,void * param,const char * name)187 rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
188 void *param, const char *name)
189 {
190 rt_isr_handler_t old_handler = RT_NULL;
191
192 if(vector < MAX_HANDLERS)
193 {
194 old_handler = isr_table[vector].handler;
195
196 if (handler != RT_NULL)
197 {
198 #ifdef RT_USING_INTERRUPT_INFO
199 rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
200 #endif /* RT_USING_INTERRUPT_INFO */
201 isr_table[vector].handler = handler;
202 isr_table[vector].param = param;
203 }
204 }
205
206 return old_handler;
207 }
208
209 /*@}*/
210