]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/RISC-V_IGLOO2_Creative_SoftConsole/riscv_hal/riscv_hal.c
Backup checkin of MiFive demo running in ReNode emulator.
[freertos] / FreeRTOS / Demo / RISC-V_IGLOO2_Creative_SoftConsole / riscv_hal / riscv_hal.c
1 #if 0\r
2 /*******************************************************************************\r
3  * (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.\r
4  *\r
5  * @file riscv_hal.c\r
6  * @author Microsemi SoC Products Group\r
7  * @brief Implementation of Hardware Abstraction Layer for Mi-V soft processors\r
8  *\r
9  * SVN $Revision: 9835 $\r
10  * SVN $Date: 2018-03-19 19:11:35 +0530 (Mon, 19 Mar 2018) $\r
11  */\r
12 #include <stdlib.h>\r
13 #include <stdint.h>\r
14 #include <unistd.h>\r
15 \r
16 #include "riscv_hal.h"\r
17 \r
18 #ifdef __cplusplus\r
19 extern "C" {\r
20 #endif\r
21 \r
22 #define RTC_PRESCALER 100UL\r
23 \r
24 #define SUCCESS 0U\r
25 #define ERROR   1U\r
26 \r
27 /*------------------------------------------------------------------------------\r
28  *\r
29  */\r
30 uint8_t Invalid_IRQHandler(void);\r
31 uint8_t External_1_IRQHandler(void);\r
32 uint8_t External_2_IRQHandler(void);\r
33 uint8_t External_3_IRQHandler(void);\r
34 uint8_t External_4_IRQHandler(void);\r
35 uint8_t External_5_IRQHandler(void);\r
36 uint8_t External_6_IRQHandler(void);\r
37 uint8_t External_7_IRQHandler(void);\r
38 uint8_t External_8_IRQHandler(void);\r
39 uint8_t External_9_IRQHandler(void);\r
40 uint8_t External_10_IRQHandler(void);\r
41 uint8_t External_11_IRQHandler(void);\r
42 uint8_t External_12_IRQHandler(void);\r
43 uint8_t External_13_IRQHandler(void);\r
44 uint8_t External_14_IRQHandler(void);\r
45 uint8_t External_15_IRQHandler(void);\r
46 uint8_t External_16_IRQHandler(void);\r
47 uint8_t External_17_IRQHandler(void);\r
48 uint8_t External_18_IRQHandler(void);\r
49 uint8_t External_19_IRQHandler(void);\r
50 uint8_t External_20_IRQHandler(void);\r
51 uint8_t External_21_IRQHandler(void);\r
52 uint8_t External_22_IRQHandler(void);\r
53 uint8_t External_23_IRQHandler(void);\r
54 uint8_t External_24_IRQHandler(void);\r
55 uint8_t External_25_IRQHandler(void);\r
56 uint8_t External_26_IRQHandler(void);\r
57 uint8_t External_27_IRQHandler(void);\r
58 uint8_t External_28_IRQHandler(void);\r
59 uint8_t External_29_IRQHandler(void);\r
60 uint8_t External_30_IRQHandler(void);\r
61 uint8_t External_31_IRQHandler(void);\r
62 \r
63 /*------------------------------------------------------------------------------\r
64  *\r
65  */\r
66 extern void Software_IRQHandler(void);\r
67 extern void Timer_IRQHandle( void );\r
68 \r
69 /*------------------------------------------------------------------------------\r
70  * Increment value for the mtimecmp register in order to achieve a system tick\r
71  * interrupt as specified through the SysTick_Config() function.\r
72  */\r
73 static uint64_t g_systick_increment = 0U;\r
74 \r
75 /*------------------------------------------------------------------------------\r
76  * Disable all interrupts.\r
77  */\r
78 void __disable_irq(void)\r
79 {\r
80     clear_csr(mstatus, MSTATUS_MPIE);\r
81     clear_csr(mstatus, MSTATUS_MIE);\r
82 }\r
83 \r
84 /*------------------------------------------------------------------------------\r
85  * Enabler all interrupts.\r
86  */\r
87 void __enable_irq(void)\r
88 {\r
89     set_csr(mstatus, MSTATUS_MIE);\r
90 }\r
91 \r
92 /*------------------------------------------------------------------------------\r
93  * Configure the machine timer to generate an interrupt.\r
94  */\r
95 uint32_t SysTick_Config(uint32_t ticks)\r
96 {\r
97     uint32_t ret_val = ERROR;\r
98 \r
99     g_systick_increment = (uint64_t)(ticks) / RTC_PRESCALER;\r
100 \r
101     if (g_systick_increment > 0U)\r
102     {\r
103         uint32_t mhart_id = read_csr(mhartid);\r
104 \r
105         PRCI->MTIMECMP[mhart_id] = PRCI->MTIME + g_systick_increment;\r
106 \r
107         set_csr(mie, MIP_MTIP);\r
108 \r
109         __enable_irq();\r
110 \r
111         ret_val = SUCCESS;\r
112     }\r
113 \r
114     return ret_val;\r
115 }\r
116 \r
117 /*------------------------------------------------------------------------------\r
118  * RISC-V interrupt handler for machine timer interrupts.\r
119  */\r
120 volatile uint32_t ulTimerInterrupts = 0;\r
121 extern void Timer_IRQHandler( void );\r
122 static void handle_m_timer_interrupt(void)\r
123 {\r
124 //    clear_csr(mie, MIP_MTIP);\r
125 \r
126     Timer_IRQHandler();\r
127 \r
128 //    PRCI->MTIMECMP[read_csr(mhartid)] = PRCI->MTIME + g_systick_increment;\r
129 \r
130 //    set_csr(mie, MIP_MTIP);\r
131 }\r
132 \r
133 /*------------------------------------------------------------------------------\r
134  * RISC-V interrupt handler for external interrupts.\r
135  */\r
136 uint8_t (*ext_irq_handler_table[32])(void) =\r
137 {\r
138     Invalid_IRQHandler,\r
139     External_1_IRQHandler,\r
140     External_2_IRQHandler,\r
141     External_3_IRQHandler,\r
142     External_4_IRQHandler,\r
143     External_5_IRQHandler,\r
144     External_6_IRQHandler,\r
145     External_7_IRQHandler,\r
146     External_8_IRQHandler,\r
147     External_9_IRQHandler,\r
148     External_10_IRQHandler,\r
149     External_11_IRQHandler,\r
150     External_12_IRQHandler,\r
151     External_13_IRQHandler,\r
152     External_14_IRQHandler,\r
153     External_15_IRQHandler,\r
154     External_16_IRQHandler,\r
155     External_17_IRQHandler,\r
156     External_18_IRQHandler,\r
157     External_19_IRQHandler,\r
158     External_20_IRQHandler,\r
159     External_21_IRQHandler,\r
160     External_22_IRQHandler,\r
161     External_23_IRQHandler,\r
162     External_24_IRQHandler,\r
163     External_25_IRQHandler,\r
164     External_26_IRQHandler,\r
165     External_27_IRQHandler,\r
166     External_28_IRQHandler,\r
167     External_29_IRQHandler,\r
168     External_30_IRQHandler,\r
169     External_31_IRQHandler\r
170 };\r
171 \r
172 /*------------------------------------------------------------------------------\r
173  *\r
174  */\r
175 static void handle_m_ext_interrupt(void)\r
176 {\r
177     uint32_t int_num  = PLIC_ClaimIRQ();\r
178     uint8_t disable = EXT_IRQ_KEEP_ENABLED;\r
179 \r
180     disable = ext_irq_handler_table[int_num]();\r
181 \r
182     PLIC_CompleteIRQ(int_num);\r
183 \r
184     if(EXT_IRQ_DISABLE == disable)\r
185     {\r
186         PLIC_DisableIRQ((IRQn_Type)int_num);\r
187     }\r
188 }\r
189 \r
190 static void handle_m_soft_interrupt(void)\r
191 {\r
192     Software_IRQHandler();\r
193 \r
194     /*Clear software interrupt*/\r
195     PRCI->MSIP[0] = 0x00U;\r
196 }\r
197 \r
198 /*------------------------------------------------------------------------------\r
199  * Trap/Interrupt handler\r
200  */\r
201 #define ENV_CALL_FROM_M_MODE 11\r
202 extern void vTaskSwitchContext( void );\r
203 \r
204 uintptr_t handle_trap(uintptr_t mcause, uintptr_t mepc)\r
205 {\r
206         /*_RB_*/\r
207         if( mcause == ENV_CALL_FROM_M_MODE )\r
208         {\r
209                 vTaskSwitchContext();\r
210 \r
211                 /* Ensure not to return to the instruction that generated the exception. */\r
212                 mepc += 4;\r
213         } else\r
214         /*end _RB_*/\r
215     if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE)  == IRQ_M_EXT))\r
216     {\r
217         handle_m_ext_interrupt();\r
218     }\r
219     else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE)  == IRQ_M_TIMER))\r
220     {\r
221         handle_m_timer_interrupt();\r
222     }\r
223     else if ( (mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE)  == IRQ_M_SOFT))\r
224     {\r
225         handle_m_soft_interrupt();\r
226     }\r
227     else\r
228     {\r
229 #ifndef NDEBUG\r
230         /*\r
231          Arguments supplied to this function are mcause, mepc (exception PC) and stack pointer\r
232          based onprivileged-isa specification\r
233          mcause values and meanings are:\r
234          0 Instruction address misaligned (mtval/mbadaddr is the address)\r
235          1 Instruction access fault       (mtval/mbadaddr is the address)\r
236          2 Illegal instruction            (mtval/mbadaddr contains the offending instruction opcode)\r
237          3 Breakpoint\r
238          4 Load address misaligned        (mtval/mbadaddr is the address)\r
239          5 Load address fault             (mtval/mbadaddr is the address)\r
240          6 Store/AMO address fault        (mtval/mbadaddr is the address)\r
241          7 Store/AMO access fault         (mtval/mbadaddr is the address)\r
242          8 Environment call from U-mode\r
243          9 Environment call from S-mode\r
244          A Environment call from M-mode\r
245          B Instruction page fault\r
246          C Load page fault                (mtval/mbadaddr is the address)\r
247          E Store page fault               (mtval/mbadaddr is the address)\r
248         */\r
249 \r
250          uintptr_t mip      = read_csr(mip);      /* interrupt pending */\r
251          uintptr_t mbadaddr = read_csr(mbadaddr); /* additional info and meaning depends on mcause */\r
252          uintptr_t mtvec    = read_csr(mtvec);    /* trap vector */\r
253          uintptr_t mscratch = read_csr(mscratch); /* temporary, sometimes might hold temporary value of a0 */\r
254          uintptr_t mstatus  = read_csr(mstatus);  /* status contains many smaller fields: */\r
255 \r
256                 /* breakpoint*/\r
257         __asm("ebreak");\r
258 #else\r
259         _exit(1 + mcause);\r
260 #endif\r
261     }\r
262     return mepc;\r
263 }\r
264 \r
265 #ifdef __cplusplus\r
266 }\r
267 #endif\r
268 #endif\r