1/* 2 * Copyright (c) 2021 Nuclei Limited. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without modification, 5 * are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, this list of 8 * conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 * of conditions and the following disclaimer in the documentation and/or other materials 12 * provided with the distribution. 13 * 14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific prior written 16 * permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#ifndef _LOS_EXC_S 32#define _LOS_EXC_S 33 34#include "riscv_encoding.h" 35 36.section .text.entry 37.align 8 38 39/** 40 * \brief Global interrupt disabled 41 * \details 42 * This function disable global interrupt. 43 * \remarks 44 * - All the interrupt requests will be ignored by CPU. 45 */ 46.macro DISABLE_MIE 47 csrc CSR_MSTATUS, MSTATUS_MIE 48.endm 49 50/** 51 * \brief Macro for context save 52 * \details 53 * This macro save ABI defined caller saved registers in the stack. 54 * \remarks 55 * - This Macro could use to save context when you enter to interrupt 56 * or exception 57*/ 58/* Save caller registers */ 59.macro SAVE_CONTEXT 60 csrrw sp, CSR_MSCRATCHCSWL, sp 61 /* Allocate stack space for context saving */ 62#ifndef __riscv_32e 63 addi sp, sp, -20*REGBYTES 64#else 65 addi sp, sp, -14*REGBYTES 66#endif /* __riscv_32e */ 67 68 STORE x1, 0*REGBYTES(sp) 69 STORE x4, 1*REGBYTES(sp) 70 STORE x5, 2*REGBYTES(sp) 71 STORE x6, 3*REGBYTES(sp) 72 STORE x7, 4*REGBYTES(sp) 73 STORE x10, 5*REGBYTES(sp) 74 STORE x11, 6*REGBYTES(sp) 75 STORE x12, 7*REGBYTES(sp) 76 STORE x13, 8*REGBYTES(sp) 77 STORE x14, 9*REGBYTES(sp) 78 STORE x15, 10*REGBYTES(sp) 79#ifndef __riscv_32e 80 STORE x16, 14*REGBYTES(sp) 81 STORE x17, 15*REGBYTES(sp) 82 STORE x28, 16*REGBYTES(sp) 83 STORE x29, 17*REGBYTES(sp) 84 STORE x30, 18*REGBYTES(sp) 85 STORE x31, 19*REGBYTES(sp) 86#endif /* __riscv_32e */ 87.endm 88 89/** 90 * \brief Macro for restore caller registers 91 * \details 92 * This macro restore ABI defined caller saved registers from stack. 93 * \remarks 94 * - You could use this macro to restore context before you want return 95 * from interrupt or exeception 96 */ 97/* Restore caller registers */ 98.macro RESTORE_CONTEXT 99 LOAD x1, 0*REGBYTES(sp) 100 LOAD x4, 1*REGBYTES(sp) 101 LOAD x5, 2*REGBYTES(sp) 102 LOAD x6, 3*REGBYTES(sp) 103 LOAD x7, 4*REGBYTES(sp) 104 LOAD x10, 5*REGBYTES(sp) 105 LOAD x11, 6*REGBYTES(sp) 106 LOAD x12, 7*REGBYTES(sp) 107 LOAD x13, 8*REGBYTES(sp) 108 LOAD x14, 9*REGBYTES(sp) 109 LOAD x15, 10*REGBYTES(sp) 110#ifndef __riscv_32e 111 LOAD x16, 14*REGBYTES(sp) 112 LOAD x17, 15*REGBYTES(sp) 113 LOAD x28, 16*REGBYTES(sp) 114 LOAD x29, 17*REGBYTES(sp) 115 LOAD x30, 18*REGBYTES(sp) 116 LOAD x31, 19*REGBYTES(sp) 117 118 /* De-allocate the stack space */ 119 addi sp, sp, 20*REGBYTES 120#else 121 /* De-allocate the stack space */ 122 addi sp, sp, 14*REGBYTES 123#endif /* __riscv_32e */ 124 csrrw sp, CSR_MSCRATCHCSWL, sp 125.endm 126 127/** 128 * \brief Macro for save necessary CSRs to stack 129 * \details 130 * This macro store MCAUSE, MEPC, MSUBM to stack. 131 */ 132.macro SAVE_CSR_CONTEXT 133 /* Store CSR mcause to stack using pushmcause */ 134 csrrwi x0, CSR_PUSHMCAUSE, 11 135 /* Store CSR mepc to stack using pushmepc */ 136 csrrwi x0, CSR_PUSHMEPC, 12 137 /* Store CSR msub to stack using pushmsub */ 138 csrrwi x0, CSR_PUSHMSUBM, 13 139.endm 140 141/** 142 * \brief Macro for restore necessary CSRs from stack 143 * \details 144 * This macro restore MSUBM, MEPC, MCAUSE from stack. 145 */ 146.macro RESTORE_CSR_CONTEXT 147 LOAD x5, 13*REGBYTES(sp) 148 csrw CSR_MSUBM, x5 149 LOAD x5, 12*REGBYTES(sp) 150 csrw CSR_MEPC, x5 151 LOAD x5, 11*REGBYTES(sp) 152 csrw CSR_MCAUSE, x5 153.endm 154 155/** 156 * \brief Exception/NMI Entry 157 * \details 158 * This function provide common entry functions for exception/nmi. 159 * \remarks 160 * This function provide a default exception/nmi entry. 161 * ABI defined caller save register and some CSR registers 162 * to be saved before enter interrupt handler and be restored before return. 163 */ 164.section .text.trap 165/* In CLIC mode, the exeception entry must be 64bytes aligned */ 166.align 6 167.global exc_entry 168exc_entry: 169 /* Save the caller saving registers (context) */ 170 SAVE_CONTEXT 171 /* Save the necessary CSR registers */ 172 SAVE_CSR_CONTEXT 173 174 /* 175 * Set the exception handler function arguments 176 * argument 1: mcause value 177 * argument 2: current stack point(SP) value 178 */ 179 csrr a0, mcause 180 mv a1, sp 181 /* 182 * By default, the function template is provided in 183 * system_Device.c, you can adjust it as you want 184 */ 185 call core_exception_handler 186 187 /* Restore the necessary CSR registers */ 188 RESTORE_CSR_CONTEXT 189 /* Restore the caller saving registers (context) */ 190 RESTORE_CONTEXT 191 192 /* Return to regular code */ 193 mret 194 195/** 196 * \brief Non-Vector Interrupt Entry 197 * \details 198 * This function provide common entry functions for handling 199 * non-vector interrupts 200 * \remarks 201 * This function provide a default non-vector interrupt entry. 202 * ABI defined caller save register and some CSR registers need 203 * to be saved before enter interrupt handler and be restored before return. 204 */ 205.section .text.irq 206/* In CLIC mode, the interrupt entry must be 4bytes aligned */ 207.align 2 208.extern g_intCount 209.global irq_entry 210/* This label will be set to MTVT2 register */ 211irq_entry: 212 /* Save the caller saving registers (context) */ 213 SAVE_CONTEXT 214 /* Save the necessary CSR registers */ 215 SAVE_CSR_CONTEXT 216 217 /* This special CSR read/write operation, which is actually 218 * claim the CLIC to find its pending highest ID, if the ID 219 * is not 0, then automatically enable the mstatus.MIE, and 220 * jump to its vector-entry-label, and update the link register 221 */ 222 la t0, g_intCount 223 lw t1, 0(t0) 224 add t1, t1, 0x1 225 sw t1, 0(t0) 226 227 csrrw ra, CSR_JALMNXTI, ra 228 229 /* Critical section with interrupts disabled */ 230 DISABLE_MIE 231 232 la t0, g_intCount 233 lw t1, 0(t0) 234 li t2, 0x1 235 sub t1, t1, t2 236 sw t1, 0(t0) 237 238 /* Restore the necessary CSR registers */ 239 RESTORE_CSR_CONTEXT 240 /* Restore the caller saving registers (context) */ 241 RESTORE_CONTEXT 242 243 /* Return to regular code */ 244 mret 245 246/* Default Handler for Exceptions / Interrupts */ 247.global default_intexc_handler 248Undef_Handler: 249default_intexc_handler: 2501: 251 j 1b 252 253#endif /* _LOS_TRAP_S */ 254 255