2 /*******************************************************************************
\r
3 * (c) Copyright 2016-2018 Microsemi SoC Products Group. All rights reserved.
\r
6 * @author Microsemi SoC Products Group
\r
7 * @brief Implementation of Hardware Abstraction Layer for Mi-V soft processors
\r
9 * SVN $Revision: 9835 $
\r
10 * SVN $Date: 2018-03-19 19:11:35 +0530 (Mon, 19 Mar 2018) $
\r
16 #include "riscv_hal.h"
\r
22 #define RTC_PRESCALER 100UL
\r
27 /*------------------------------------------------------------------------------
\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
63 /*------------------------------------------------------------------------------
\r
66 extern void Software_IRQHandler(void);
\r
67 extern void Timer_IRQHandle( void );
\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
73 static uint64_t g_systick_increment = 0U;
\r
75 /*------------------------------------------------------------------------------
\r
76 * Disable all interrupts.
\r
78 void __disable_irq(void)
\r
80 clear_csr(mstatus, MSTATUS_MPIE);
\r
81 clear_csr(mstatus, MSTATUS_MIE);
\r
84 /*------------------------------------------------------------------------------
\r
85 * Enabler all interrupts.
\r
87 void __enable_irq(void)
\r
89 set_csr(mstatus, MSTATUS_MIE);
\r
92 /*------------------------------------------------------------------------------
\r
93 * Configure the machine timer to generate an interrupt.
\r
95 uint32_t SysTick_Config(uint32_t ticks)
\r
97 uint32_t ret_val = ERROR;
\r
99 g_systick_increment = (uint64_t)(ticks) / RTC_PRESCALER;
\r
101 if (g_systick_increment > 0U)
\r
103 uint32_t mhart_id = read_csr(mhartid);
\r
105 PRCI->MTIMECMP[mhart_id] = PRCI->MTIME + g_systick_increment;
\r
107 set_csr(mie, MIP_MTIP);
\r
117 /*------------------------------------------------------------------------------
\r
118 * RISC-V interrupt handler for machine timer interrupts.
\r
120 volatile uint32_t ulTimerInterrupts = 0;
\r
121 extern void Timer_IRQHandler( void );
\r
122 static void handle_m_timer_interrupt(void)
\r
124 // clear_csr(mie, MIP_MTIP);
\r
126 Timer_IRQHandler();
\r
128 // PRCI->MTIMECMP[read_csr(mhartid)] = PRCI->MTIME + g_systick_increment;
\r
130 // set_csr(mie, MIP_MTIP);
\r
133 /*------------------------------------------------------------------------------
\r
134 * RISC-V interrupt handler for external interrupts.
\r
136 uint8_t (*ext_irq_handler_table[32])(void) =
\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
172 /*------------------------------------------------------------------------------
\r
175 static void handle_m_ext_interrupt(void)
\r
177 uint32_t int_num = PLIC_ClaimIRQ();
\r
178 uint8_t disable = EXT_IRQ_KEEP_ENABLED;
\r
180 disable = ext_irq_handler_table[int_num]();
\r
182 PLIC_CompleteIRQ(int_num);
\r
184 if(EXT_IRQ_DISABLE == disable)
\r
186 PLIC_DisableIRQ((IRQn_Type)int_num);
\r
190 static void handle_m_soft_interrupt(void)
\r
192 Software_IRQHandler();
\r
194 /*Clear software interrupt*/
\r
195 PRCI->MSIP[0] = 0x00U;
\r
198 /*------------------------------------------------------------------------------
\r
199 * Trap/Interrupt handler
\r
201 #define ENV_CALL_FROM_M_MODE 11
\r
202 extern void vTaskSwitchContext( void );
\r
204 uintptr_t handle_trap(uintptr_t mcause, uintptr_t mepc)
\r
207 if( mcause == ENV_CALL_FROM_M_MODE )
\r
209 vTaskSwitchContext();
\r
211 /* Ensure not to return to the instruction that generated the exception. */
\r
215 if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT))
\r
217 handle_m_ext_interrupt();
\r
219 else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER))
\r
221 handle_m_timer_interrupt();
\r
223 else if ( (mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_SOFT))
\r
225 handle_m_soft_interrupt();
\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
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
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