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/10/01     Bernard      The first version
9  * 2018/12/27     Jesven       Change irq enable/disable to cpu0
10  */
11 #include <plic.h>
12 #include <mmu.h>
13 #include "tick.h"
14 #include "encoding.h"
15 #include "riscv.h"
16 #include "interrupt.h"
17 
18 struct rt_irq_desc irq_desc[MAX_HANDLERS];
19 
rt_hw_interrupt_handle(rt_uint32_t vector,void * param)20 static rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param)
21 {
22     rt_kprintf("UN-handled interrupt %d occurred!!!\n", vector);
23     return RT_NULL;
24 }
25 
rt_hw_plic_irq_enable(int irq_number)26 int rt_hw_plic_irq_enable(int irq_number)
27 {
28     plic_irq_enable(irq_number);
29     return 0;
30 }
31 
rt_hw_plic_irq_disable(int irq_number)32 int rt_hw_plic_irq_disable(int irq_number)
33 {
34     plic_irq_disable(irq_number);
35     return 0;
36 }
37 
38 /**
39  * This function will un-mask a interrupt.
40  * @param vector the interrupt number
41  */
rt_hw_interrupt_umask(int vector)42 void rt_hw_interrupt_umask(int vector)
43 {
44     plic_set_priority(vector, 1);
45 
46     rt_hw_plic_irq_enable(vector);
47 }
48 
49 /**
50  * This function will install a interrupt service routine to a interrupt.
51  * @param vector the interrupt number
52  * @param new_handler the interrupt service routine to be installed
53  * @param old_handler the old interrupt service routine
54  */
rt_hw_interrupt_install(int vector,rt_isr_handler_t handler,void * param,const char * name)55 rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
56         void *param, const char *name)
57 {
58     rt_isr_handler_t old_handler = RT_NULL;
59 
60     if(vector < MAX_HANDLERS)
61     {
62         old_handler = irq_desc[vector].handler;
63         if (handler != RT_NULL)
64         {
65             irq_desc[vector].handler = (rt_isr_handler_t)handler;
66             irq_desc[vector].param = param;
67 #ifdef RT_USING_INTERRUPT_INFO
68             rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name);
69             irq_desc[vector].counter = 0;
70 #endif
71         }
72     }
73 
74     return old_handler;
75 }
76 
rt_hw_interrupt_init()77 void rt_hw_interrupt_init()
78 {
79     /* Enable machine external interrupts. */
80     // set_csr(sie, SIP_SEIP);
81     int idx = 0;
82     /* init exceptions table */
83     for (idx = 0; idx < MAX_HANDLERS; idx++)
84     {
85         irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
86         irq_desc[idx].param = RT_NULL;
87 #ifdef RT_USING_INTERRUPT_INFO
88         rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default");
89         irq_desc[idx].counter = 0;
90 #endif
91     }
92 
93     plic_set_threshold(0);
94 }
95