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