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 * 2018/5/3 Bernard first version
9 */
10
11 #include <rthw.h>
12 #include <rtthread.h>
13
14 #include "cp15.h"
15 #include <board.h>
16
17 #define MAX_HANDLERS 64
18
19 extern volatile rt_atomic_t rt_interrupt_nest;
20
21 /* exception and interrupt handler table */
22 struct rt_irq_desc isr_table[MAX_HANDLERS];
23
24 rt_uint32_t rt_interrupt_from_thread;
25 rt_uint32_t rt_interrupt_to_thread;
26 rt_uint32_t rt_thread_switch_interrupt_flag;
27
28 extern void rt_cpu_vector_set_base(unsigned int addr);
29 extern int system_vectors;
30
rt_hw_vector_init(void)31 void rt_hw_vector_init(void)
32 {
33 rt_cpu_vector_set_base((unsigned int)&system_vectors);
34 }
35
default_isr_handler(int vector,void * param)36 static void default_isr_handler(int vector, void *param)
37 {
38 rt_kprintf("unhandled irq: %d\n", vector);
39 }
40
41 /**
42 * This function will initialize hardware interrupt
43 */
rt_hw_interrupt_init(void)44 void rt_hw_interrupt_init(void)
45 {
46 uint32_t index;
47
48 /* mask all of interrupts */
49 IRQ_DISABLE_BASIC = 0x000000ff;
50 IRQ_DISABLE1 = 0xffffffff;
51 IRQ_DISABLE2 = 0xffffffff;
52
53 for (index = 0; index < MAX_HANDLERS; index ++)
54 {
55 isr_table[index].handler = default_isr_handler;
56 isr_table[index].param = NULL;
57 #ifdef RT_USING_INTERRUPT_INFO
58 rt_strncpy(isr_table[index].name, "unknown", RT_NAME_MAX);
59 isr_table[index].counter = 0;
60 #endif
61 }
62
63 /* init interrupt nest, and context in thread sp */
64 rt_interrupt_nest = 0;
65 rt_interrupt_from_thread = 0;
66 rt_interrupt_to_thread = 0;
67 rt_thread_switch_interrupt_flag = 0;
68 }
69
70 /**
71 * This function will mask a interrupt.
72 * @param vector the interrupt number
73 */
rt_hw_interrupt_mask(int vector)74 void rt_hw_interrupt_mask(int vector)
75 {
76 if (vector < 8)
77 {
78 IRQ_DISABLE_BASIC = (1 << vector);
79 }
80 else if (vector < 32)
81 {
82 IRQ_DISABLE1 = (1 << vector);
83 }
84 else
85 {
86 vector = vector % 32;
87 IRQ_DISABLE2 = (1 << vector);
88 }
89 }
90
91 /**
92 * This function will un-mask a interrupt.
93 * @param vector the interrupt number
94 */
rt_hw_interrupt_umask(int vector)95 void rt_hw_interrupt_umask(int vector)
96 {
97 if (vector < 8)
98 {
99 IRQ_ENABLE_BASIC = (1 << vector);
100 }
101 else if (vector < 32)
102 {
103 IRQ_ENABLE1 = (1 << vector);
104 }
105 else
106 {
107 vector = vector % 32;
108 IRQ_ENABLE2 = (1 << vector);
109 }
110 }
111
112 /**
113 * This function will install a interrupt service routine to a interrupt.
114 * @param vector the interrupt number
115 * @param new_handler the interrupt service routine to be installed
116 * @param old_handler the old interrupt service routine
117 */
rt_hw_interrupt_install(int vector,rt_isr_handler_t handler,void * param,const char * name)118 rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
119 void *param, const char *name)
120 {
121 rt_isr_handler_t old_handler = RT_NULL;
122
123 if (vector < MAX_HANDLERS)
124 {
125 old_handler = isr_table[vector].handler;
126
127 if (handler != RT_NULL)
128 {
129 #ifdef RT_USING_INTERRUPT_INFO
130 rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
131 #endif /* RT_USING_INTERRUPT_INFO */
132 isr_table[vector].handler = handler;
133 isr_table[vector].param = param;
134 }
135 }
136
137 return old_handler;
138 }
139