| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726 |
- /*
- * FreeRTOS Kernel Port For Nuclei RISC-V Processor
- * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
- #include "riscv_encoding.h"
- #ifndef __riscv_32e
- #define portRegNum 32
- #else
- #define portRegNum 14
- #endif
- #define portCONTEXT_SIZE ( portRegNum * REGBYTES )
- .section .text.entry
- .align 8
- // If you want to use SMP freertos
- // configNUMBER_OF_CORES must be defined to the number of cores in your system.
- // If you define configNUMBER_OF_CORES using -D option, you must make sure that
- // asm option must contains this macro defined
- #ifndef configNUMBER_OF_CORES
- #define configNUMBER_OF_CORES 1
- #endif
- .extern xPortTaskSwitch
- #if ( configNUMBER_OF_CORES == 1 )
- .extern pxCurrentTCB
- #else
- .extern pxCurrentTCBs
- #endif
- .global prvPortStartFirstTask
- /**
- * \brief Global interrupt disabled
- * \details
- * This function disable global interrupt.
- * \remarks
- * - All the interrupt requests will be ignored by CPU.
- */
- .macro DISABLE_MIE
- csrc CSR_MSTATUS, MSTATUS_MIE
- .endm
- /**
- * \brief Macro for context save
- * \details
- * This macro save ABI defined caller saved registers in the stack.
- * \remarks
- * - This Macro could use to save context when you enter to interrupt
- * or exception
- */
- /* Save caller registers */
- .macro SAVE_CONTEXT
- #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
- #else
- csrrw sp, CSR_MSCRATCHCSWL, sp
- /* Allocate stack space for context saving */
- #ifndef __riscv_32e
- addi sp, sp, -20*REGBYTES
- #else
- addi sp, sp, -14*REGBYTES
- #endif /* __riscv_32e */
- STORE x1, 0*REGBYTES(sp)
- STORE x4, 1*REGBYTES(sp)
- STORE x5, 2*REGBYTES(sp)
- STORE x6, 3*REGBYTES(sp)
- STORE x7, 4*REGBYTES(sp)
- STORE x10, 5*REGBYTES(sp)
- STORE x11, 6*REGBYTES(sp)
- STORE x12, 7*REGBYTES(sp)
- STORE x13, 8*REGBYTES(sp)
- STORE x14, 9*REGBYTES(sp)
- STORE x15, 10*REGBYTES(sp)
- #ifndef __riscv_32e
- STORE x16, 14*REGBYTES(sp)
- STORE x17, 15*REGBYTES(sp)
- STORE x28, 16*REGBYTES(sp)
- STORE x29, 17*REGBYTES(sp)
- STORE x30, 18*REGBYTES(sp)
- STORE x31, 19*REGBYTES(sp)
- #endif /* __riscv_32e */
- #endif
- .endm
- /**
- * \brief Macro for restore caller registers
- * \details
- * This macro restore ABI defined caller saved registers from stack.
- * \remarks
- * - You could use this macro to restore context before you want return
- * from interrupt or exeception
- */
- /* Restore caller registers */
- .macro RESTORE_CONTEXT
- #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
- #else
- LOAD x1, 0*REGBYTES(sp)
- LOAD x4, 1*REGBYTES(sp)
- LOAD x5, 2*REGBYTES(sp)
- LOAD x6, 3*REGBYTES(sp)
- LOAD x7, 4*REGBYTES(sp)
- LOAD x10, 5*REGBYTES(sp)
- LOAD x11, 6*REGBYTES(sp)
- LOAD x12, 7*REGBYTES(sp)
- LOAD x13, 8*REGBYTES(sp)
- LOAD x14, 9*REGBYTES(sp)
- LOAD x15, 10*REGBYTES(sp)
- #ifndef __riscv_32e
- LOAD x16, 14*REGBYTES(sp)
- LOAD x17, 15*REGBYTES(sp)
- LOAD x28, 16*REGBYTES(sp)
- LOAD x29, 17*REGBYTES(sp)
- LOAD x30, 18*REGBYTES(sp)
- LOAD x31, 19*REGBYTES(sp)
- /* De-allocate the stack space */
- addi sp, sp, 20*REGBYTES
- #else
- /* De-allocate the stack space */
- addi sp, sp, 14*REGBYTES
- #endif /* __riscv_32e */
- csrrw sp, CSR_MSCRATCHCSWL, sp
- #endif
- .endm
- /**
- * \brief Macro for save necessary CSRs to stack
- * \details
- * This macro store MCAUSE, MEPC, MSUBM to stack.
- */
- .macro SAVE_CSR_CONTEXT
- #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
- #else
- /* Store CSR mcause to stack using pushmcause */
- csrrwi x0, CSR_PUSHMCAUSE, 11
- /* Store CSR mepc to stack using pushmepc */
- csrrwi x0, CSR_PUSHMEPC, 12
- /* Store CSR msub to stack using pushmsub */
- csrrwi x0, CSR_PUSHMSUBM, 13
- #endif
- .endm
- /**
- * \brief Macro for restore necessary CSRs from stack
- * \details
- * This macro restore MSUBM, MEPC, MCAUSE from stack.
- */
- .macro RESTORE_CSR_CONTEXT
- #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
- #else
- LOAD x5, 13*REGBYTES(sp)
- csrw CSR_MSUBM, x5
- LOAD x5, 12*REGBYTES(sp)
- csrw CSR_MEPC, x5
- LOAD x5, 11*REGBYTES(sp)
- csrw CSR_MCAUSE, x5
- #endif
- .endm
- /**
- * \brief Exception/NMI Entry
- * \details
- * This function provide common entry functions for exception/nmi.
- * \remarks
- * This function provide a default exception/nmi entry.
- * ABI defined caller save register and some CSR registers
- * to be saved before enter interrupt handler and be restored before return.
- */
- .section .text.trap
- /* In CLIC mode, the exeception entry must be 64bytes aligned */
- .align 6
- .global exc_entry
- .type exc_entry, @function
- exc_entry:
- /* Save the caller saving registers (context) */
- SAVE_CONTEXT
- /* Save the necessary CSR registers */
- SAVE_CSR_CONTEXT
- /*
- * Set the exception handler function arguments
- * argument 1: mcause value
- * argument 2: current stack point(SP) value
- */
- csrr a0, mcause
- mv a1, sp
- /*
- * TODO: Call the exception handler function
- * By default, the function template is provided in
- * system_Device.c, you can adjust it as you want
- */
- call core_exception_handler
- /* Restore the necessary CSR registers */
- RESTORE_CSR_CONTEXT
- /* Restore the caller saving registers (context) */
- RESTORE_CONTEXT
- /* Return to regular code */
- #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
- csrrwi x0, CSR_POPXRET, 0
- #else
- mret
- #endif
- .size exc_entry, . - exc_entry
- /**
- * \brief Non-Vector Interrupt Entry
- * \details
- * This function provide common entry functions for handling
- * non-vector interrupts
- * \remarks
- * This function provide a default non-vector interrupt entry.
- * ABI defined caller save register and some CSR registers need
- * to be saved before enter interrupt handler and be restored before return.
- */
- .section .text.irq
- /* In CLIC mode, the interrupt entry must be 4bytes aligned */
- .align 2
- .global irq_entry
- .type irq_entry, @function
- /* This label will be set to MTVT2 register */
- irq_entry:
- /* Save the caller saving registers (context) */
- SAVE_CONTEXT
- /* Save the necessary CSR registers */
- SAVE_CSR_CONTEXT
- /* This special CSR read/write operation, which is actually
- * claim the CLIC to find its pending highest ID, if the ID
- * is not 0, then automatically enable the mstatus.MIE, and
- * jump to its vector-entry-label, and update the link register
- */
- csrrw ra, CSR_JALMNXTI, ra
- /* Critical section with interrupts disabled */
- DISABLE_MIE
- /* Restore the necessary CSR registers */
- RESTORE_CSR_CONTEXT
- /* Restore the caller saving registers (context) */
- RESTORE_CONTEXT
- /* Return to regular code */
- #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
- csrrwi x0, CSR_POPXRET, 0
- #else
- mret
- #endif
- .size irq_entry, . - irq_entry
- /* Default Handler for Exceptions / Interrupts */
- .global default_intexc_handler
- .type default_intexc_handler, @function
- Undef_Handler:
- default_intexc_handler:
- 1:
- j 1b
- .size default_intexc_handler, . - default_intexc_handler
- /* Start the first task. This also clears the bit that indicates the FPU is
- in use in case the FPU was used before the scheduler was started - which
- would otherwise result in the unnecessary leaving of space in the stack
- for lazy saving of FPU registers. */
- .type prvPortStartFirstTask, @function
- .align 3
- prvPortStartFirstTask:
- /* Setup Interrupt Stack using
- The stack that was used by main()
- before the scheduler is started is
- no longer required after the scheduler is started.
- Interrupt stack pointer is stored in CSR_MSCRATCH */
- #if defined(SMP_CPU_CNT) && (SMP_CPU_CNT > 1)
- /* get correct sp for each cpu
- * each stack size is __STACK_SIZE
- * defined in linker script */
- lui t1, %hi(__STACK_SIZE)
- addi t1, t1, %lo(__STACK_SIZE)
- la t0, _sp
- csrr a0, CSR_MHARTID
- andi a0, a0, 0xFF
- li a1, 0
- 1:
- beq a0, a1, 2f
- sub t0, t0, t1
- addi a1, a1, 1
- j 1b
- 2:
- #else
- la t0, _sp // TODO need to consider SMP case
- #endif
- csrw CSR_MSCRATCH, t0
- #if ( configNUMBER_OF_CORES == 1 )
- LOAD t0, pxCurrentTCB /* Load pxCurrentTCB. */
- #else
- la t0, pxCurrentTCBs /* Load pxCurrentTCBs[core] */
- csrr t1, CSR_MHARTID
- slli t1, t1, LOG_REGBYTES
- add t0, t0, t1
- LOAD t0, 0(t0)
- #endif
- LOAD sp, 0x0(t0) /* Read sp from first TCB member */
- /* Pop PC from stack and set MEPC */
- LOAD t0, 0 * REGBYTES(sp)
- csrw CSR_MEPC, t0
- /* Pop mstatus from stack and set it */
- LOAD t0, (portRegNum - 1) * REGBYTES(sp)
- csrw CSR_MSTATUS, t0
- /* Interrupt still disable here */
- /* Restore Registers from Stack */
- LOAD x1, 1 * REGBYTES(sp) /* RA */
- LOAD x5, 2 * REGBYTES(sp)
- LOAD x6, 3 * REGBYTES(sp)
- LOAD x7, 4 * REGBYTES(sp)
- LOAD x8, 5 * REGBYTES(sp)
- LOAD x9, 6 * REGBYTES(sp)
- LOAD x10, 7 * REGBYTES(sp)
- LOAD x11, 8 * REGBYTES(sp)
- LOAD x12, 9 * REGBYTES(sp)
- LOAD x13, 10 * REGBYTES(sp)
- LOAD x14, 11 * REGBYTES(sp)
- LOAD x15, 12 * REGBYTES(sp)
- #ifndef __riscv_32e
- LOAD x16, 13 * REGBYTES(sp)
- LOAD x17, 14 * REGBYTES(sp)
- LOAD x18, 15 * REGBYTES(sp)
- LOAD x19, 16 * REGBYTES(sp)
- LOAD x20, 17 * REGBYTES(sp)
- LOAD x21, 18 * REGBYTES(sp)
- LOAD x22, 19 * REGBYTES(sp)
- LOAD x23, 20 * REGBYTES(sp)
- LOAD x24, 21 * REGBYTES(sp)
- LOAD x25, 22 * REGBYTES(sp)
- LOAD x26, 23 * REGBYTES(sp)
- LOAD x27, 24 * REGBYTES(sp)
- LOAD x28, 25 * REGBYTES(sp)
- LOAD x29, 26 * REGBYTES(sp)
- LOAD x30, 27 * REGBYTES(sp)
- LOAD x31, 28 * REGBYTES(sp)
- #endif
- addi sp, sp, portCONTEXT_SIZE
- mret
- .size prvPortStartFirstTask, . - prvPortStartFirstTask
- .align 2
- .global eclic_msip_handler
- .type eclic_msip_handler, @function
- eclic_msip_handler:
- #if defined(__riscv_flen)
- addi sp, sp, -(2 * REGBYTES)
- STORE t0, 0 * REGBYTES(sp)
- STORE t1, 1 * REGBYTES(sp)
- _save_fp_stack:
- csrr t0, CSR_MSTATUS
- li t1, MSTATUS_FS_DIRTY
- and t0,t0,t1
- #if defined(__riscv_vector)
- bne t0, t1, _save_vector_stack
- #else
- bne t0, t1, _save_integer_stack
- #endif
- LOAD t0, 0 * REGBYTES(sp)
- LOAD t1, 1 * REGBYTES(sp)
- addi sp, sp, (2 * REGBYTES)
- /* Save fp registers and fcsr and 3 reserved reg space, make sure 16 bytes aligned */
- addi sp, sp, -(5 * REGBYTES)
- STORE t0, 0 * REGBYTES(sp)
- csrr t0, CSR_FCSR
- STORE t0, 1 * REGBYTES(sp)
- LOAD t0, 0 * REGBYTES(sp)
- addi sp, sp, (1 * REGBYTES)
- addi sp, sp, -(32 * FPREGBYTES)
- FPSTORE f0 , 0 * FPREGBYTES(sp)
- FPSTORE f1 , 1 * FPREGBYTES(sp)
- FPSTORE f2 , 2 * FPREGBYTES(sp)
- FPSTORE f3 , 3 * FPREGBYTES(sp)
- FPSTORE f4 , 4 * FPREGBYTES(sp)
- FPSTORE f5 , 5 * FPREGBYTES(sp)
- FPSTORE f6 , 6 * FPREGBYTES(sp)
- FPSTORE f7 , 7 * FPREGBYTES(sp)
- FPSTORE f8 , 8 * FPREGBYTES(sp)
- FPSTORE f9 , 9 * FPREGBYTES(sp)
- FPSTORE f10, 10 * FPREGBYTES(sp)
- FPSTORE f11, 11 * FPREGBYTES(sp)
- FPSTORE f12, 12 * FPREGBYTES(sp)
- FPSTORE f13, 13 * FPREGBYTES(sp)
- FPSTORE f14, 14 * FPREGBYTES(sp)
- FPSTORE f15, 15 * FPREGBYTES(sp)
- FPSTORE f16, 16 * FPREGBYTES(sp)
- FPSTORE f17, 17 * FPREGBYTES(sp)
- FPSTORE f18, 18 * FPREGBYTES(sp)
- FPSTORE f19, 19 * FPREGBYTES(sp)
- FPSTORE f20, 20 * FPREGBYTES(sp)
- FPSTORE f21, 21 * FPREGBYTES(sp)
- FPSTORE f22, 22 * FPREGBYTES(sp)
- FPSTORE f23, 23 * FPREGBYTES(sp)
- FPSTORE f24, 24 * FPREGBYTES(sp)
- FPSTORE f25, 25 * FPREGBYTES(sp)
- FPSTORE f26, 26 * FPREGBYTES(sp)
- FPSTORE f27, 27 * FPREGBYTES(sp)
- FPSTORE f28, 28 * FPREGBYTES(sp)
- FPSTORE f29, 29 * FPREGBYTES(sp)
- FPSTORE f30, 30 * FPREGBYTES(sp)
- FPSTORE f31, 31 * FPREGBYTES(sp)
- #endif
- #if defined(__riscv_vector)
- addi sp, sp, -(2 * REGBYTES)
- STORE t0, 0 * REGBYTES(sp)
- STORE t1, 1 * REGBYTES(sp)
- _save_vector_stack:
- csrr t0, CSR_MSTATUS
- li t1, MSTATUS_VS_DIRTY
- and t0,t0,t1
- bne t0, t1, _save_integer_stack
- LOAD t0, 0 * REGBYTES(sp)
- LOAD t1, 1 * REGBYTES(sp)
- addi sp, sp, (2 * REGBYTES)
- /* Save vector registers and vtype/vl/vstart/vcsr */
- addi sp, sp, -(6 * REGBYTES)
- STORE t0, 0 * REGBYTES(sp)
- STORE t1, 1 * REGBYTES(sp)
- csrr t0, CSR_VSTART
- STORE t0, 2 * REGBYTES(sp)
- csrr t0, CSR_VTYPE
- STORE t0, 3 * REGBYTES(sp)
- csrr t0, CSR_VL
- STORE t0, 4 * REGBYTES(sp)
- csrr t0, CSR_VCSR
- STORE t0, 5 * REGBYTES(sp)
- mv t1, sp
- csrr t0, CSR_VLENB
- slli t0, t0, 5
- /* t1 is the new temp stack where t0, t1 saved */
- sub t1, t1, t0
- LOAD t0, 0 * REGBYTES(sp)
- STORE t0, 0 * REGBYTES(t1)
- LOAD t0, 1 * REGBYTES(sp)
- STORE t0, 1 * REGBYTES(t1)
- mv sp, t1
- /* new sp -> t1 to save vector registers */
- addi t1, t1, (2 * REGBYTES)
- vsetvli t0, x0, e8, m8, ta, ma
- vse8.v v0, (t1)
- add t1, t1, t0
- vse8.v v8, (t1)
- add t1, t1, t0
- vse8.v v16, (t1)
- add t1, t1, t0
- vse8.v v24, (t1)
- LOAD t0, 0 * REGBYTES(sp)
- LOAD t1, 1 * REGBYTES(sp)
- addi sp, sp, (2 * REGBYTES)
- #endif
- #if defined(__riscv_flen) || defined(__riscv_vector)
- addi sp, sp, -(2 * REGBYTES)
- STORE t0, 0 * REGBYTES(sp)
- STORE t1, 1 * REGBYTES(sp)
- _save_integer_stack:
- LOAD t0, 0 * REGBYTES(sp)
- LOAD t1, 1 * REGBYTES(sp)
- addi sp, sp, (2 * REGBYTES)
- #endif
- addi sp, sp, -portCONTEXT_SIZE
- STORE x1, 1 * REGBYTES(sp) /* RA */
- STORE x5, 2 * REGBYTES(sp)
- STORE x6, 3 * REGBYTES(sp)
- STORE x7, 4 * REGBYTES(sp)
- STORE x8, 5 * REGBYTES(sp)
- STORE x9, 6 * REGBYTES(sp)
- STORE x10, 7 * REGBYTES(sp)
- STORE x11, 8 * REGBYTES(sp)
- STORE x12, 9 * REGBYTES(sp)
- STORE x13, 10 * REGBYTES(sp)
- STORE x14, 11 * REGBYTES(sp)
- STORE x15, 12 * REGBYTES(sp)
- #ifndef __riscv_32e
- STORE x16, 13 * REGBYTES(sp)
- STORE x17, 14 * REGBYTES(sp)
- STORE x18, 15 * REGBYTES(sp)
- STORE x19, 16 * REGBYTES(sp)
- STORE x20, 17 * REGBYTES(sp)
- STORE x21, 18 * REGBYTES(sp)
- STORE x22, 19 * REGBYTES(sp)
- STORE x23, 20 * REGBYTES(sp)
- STORE x24, 21 * REGBYTES(sp)
- STORE x25, 22 * REGBYTES(sp)
- STORE x26, 23 * REGBYTES(sp)
- STORE x27, 24 * REGBYTES(sp)
- STORE x28, 25 * REGBYTES(sp)
- STORE x29, 26 * REGBYTES(sp)
- STORE x30, 27 * REGBYTES(sp)
- STORE x31, 28 * REGBYTES(sp)
- #endif
- /* Push mstatus to stack */
- csrr t0, CSR_MSTATUS
- STORE t0, (portRegNum - 1) * REGBYTES(sp)
- /* Push additional registers */
- /* Store sp to task stack */
- #if ( configNUMBER_OF_CORES == 1 )
- LOAD t0, pxCurrentTCB /* Load pxCurrentTCB. */
- #else
- la t0, pxCurrentTCBs /* Load pxCurrentTCBs[core] */
- csrr t1, CSR_MHARTID
- slli t1, t1, LOG_REGBYTES
- add t0, t0, t1
- LOAD t0, 0(t0)
- #endif
- STORE sp, 0(t0)
- csrr t0, CSR_MEPC
- STORE t0, 0(sp)
- jal xPortTaskSwitch
- /* Switch task context */
- #if ( configNUMBER_OF_CORES == 1 )
- LOAD t0, pxCurrentTCB /* Load pxCurrentTCB. */
- #else
- la t0, pxCurrentTCBs /* Load pxCurrentTCBs[core] */
- csrr t1, CSR_MHARTID
- slli t1, t1, LOG_REGBYTES
- add t0, t0, t1
- LOAD t0, 0(t0)
- #endif
- LOAD sp, 0x0(t0) /* Read sp from first TCB member */
- /* Pop PC from stack and set MEPC */
- LOAD t0, 0 * REGBYTES(sp)
- csrw CSR_MEPC, t0
- /* Pop additional registers */
- /* Pop mstatus from stack and set it */
- LOAD t0, (portRegNum - 1) * REGBYTES(sp)
- csrw CSR_MSTATUS, t0
- /* Interrupt still disable here */
- /* Restore Registers from Stack */
- LOAD x1, 1 * REGBYTES(sp) /* RA */
- LOAD x5, 2 * REGBYTES(sp)
- LOAD x6, 3 * REGBYTES(sp)
- LOAD x7, 4 * REGBYTES(sp)
- LOAD x8, 5 * REGBYTES(sp)
- LOAD x9, 6 * REGBYTES(sp)
- LOAD x10, 7 * REGBYTES(sp)
- LOAD x11, 8 * REGBYTES(sp)
- LOAD x12, 9 * REGBYTES(sp)
- LOAD x13, 10 * REGBYTES(sp)
- LOAD x14, 11 * REGBYTES(sp)
- LOAD x15, 12 * REGBYTES(sp)
- #ifndef __riscv_32e
- LOAD x16, 13 * REGBYTES(sp)
- LOAD x17, 14 * REGBYTES(sp)
- LOAD x18, 15 * REGBYTES(sp)
- LOAD x19, 16 * REGBYTES(sp)
- LOAD x20, 17 * REGBYTES(sp)
- LOAD x21, 18 * REGBYTES(sp)
- LOAD x22, 19 * REGBYTES(sp)
- LOAD x23, 20 * REGBYTES(sp)
- LOAD x24, 21 * REGBYTES(sp)
- LOAD x25, 22 * REGBYTES(sp)
- LOAD x26, 23 * REGBYTES(sp)
- LOAD x27, 24 * REGBYTES(sp)
- LOAD x28, 25 * REGBYTES(sp)
- LOAD x29, 26 * REGBYTES(sp)
- LOAD x30, 27 * REGBYTES(sp)
- LOAD x31, 28 * REGBYTES(sp)
- #endif
- addi sp, sp, portCONTEXT_SIZE
- #if defined(__riscv_vector)
- /* Pop vector stack if needed */
- addi sp, sp, -(2 * REGBYTES)
- STORE t0, 0 * REGBYTES(sp)
- STORE t1, 1 * REGBYTES(sp)
- _restore_vector_stack:
- csrr t0, CSR_MSTATUS
- li t1, MSTATUS_VS_DIRTY
- and t0,t0,t1
- #if defined(__riscv_flen)
- bne t0, t1, _restore_fp_stack
- #else
- bne t0, t1, _restore_done
- #endif
- LOAD t0, 0 * REGBYTES(sp)
- LOAD t1, 1 * REGBYTES(sp)
- addi sp, sp, (2 * REGBYTES)
- /* pop vector registers and vtype/vl/vstart/vcsr */
- addi sp, sp, -(3 * REGBYTES)
- STORE t0, 0 * REGBYTES(sp)
- STORE t1, 1 * REGBYTES(sp)
- STORE t2, 2 * REGBYTES(sp)
- mv t2, sp
- /* temp regs are stored in t2 stack top */
- addi sp, sp, (3 * REGBYTES)
- vsetvli t0, x0, e8, m8, ta, ma
- vle8.v v0, (sp)
- add sp, sp, t0
- vle8.v v8, (sp)
- add sp, sp, t0
- vle8.v v16, (sp)
- add sp, sp, t0
- vle8.v v24, (sp)
- add sp, sp, t0
- LOAD t0, 2 * REGBYTES(sp)
- LOAD t1, 1 * REGBYTES(sp)
- vsetvl x0, t0, t1
- LOAD t0, 0 * REGBYTES(sp)
- csrw CSR_VSTART, t0
- LOAD t0, 3 * REGBYTES(sp)
- csrw CSR_VCSR, t0
- addi sp, sp, (4 * REGBYTES)
- LOAD t0, 0 * REGBYTES(t2)
- LOAD t1, 1 * REGBYTES(t2)
- LOAD t2, 2 * REGBYTES(t2)
- #endif
- #if defined(__riscv_flen)
- addi sp, sp, -(2 * REGBYTES)
- STORE t0, 0 * REGBYTES(sp)
- STORE t1, 1 * REGBYTES(sp)
- _restore_fp_stack:
- csrr t0, CSR_MSTATUS
- li t1, MSTATUS_FS_DIRTY
- and t0,t0,t1
- bne t0, t1, _restore_done
- LOAD t0, 0 * REGBYTES(sp)
- LOAD t1, 1 * REGBYTES(sp)
- addi sp, sp, (2 * REGBYTES)
- /* Restore fp registers and fcsr and 3 reserved reg space */
- FPLOAD f0 , 0 * FPREGBYTES(sp)
- FPLOAD f1 , 1 * FPREGBYTES(sp)
- FPLOAD f2 , 2 * FPREGBYTES(sp)
- FPLOAD f3 , 3 * FPREGBYTES(sp)
- FPLOAD f4 , 4 * FPREGBYTES(sp)
- FPLOAD f5 , 5 * FPREGBYTES(sp)
- FPLOAD f6 , 6 * FPREGBYTES(sp)
- FPLOAD f7 , 7 * FPREGBYTES(sp)
- FPLOAD f8 , 8 * FPREGBYTES(sp)
- FPLOAD f9 , 9 * FPREGBYTES(sp)
- FPLOAD f10, 10 * FPREGBYTES(sp)
- FPLOAD f11, 11 * FPREGBYTES(sp)
- FPLOAD f12, 12 * FPREGBYTES(sp)
- FPLOAD f13, 13 * FPREGBYTES(sp)
- FPLOAD f14, 14 * FPREGBYTES(sp)
- FPLOAD f15, 15 * FPREGBYTES(sp)
- FPLOAD f16, 16 * FPREGBYTES(sp)
- FPLOAD f17, 17 * FPREGBYTES(sp)
- FPLOAD f18, 18 * FPREGBYTES(sp)
- FPLOAD f19, 19 * FPREGBYTES(sp)
- FPLOAD f20, 20 * FPREGBYTES(sp)
- FPLOAD f21, 21 * FPREGBYTES(sp)
- FPLOAD f22, 22 * FPREGBYTES(sp)
- FPLOAD f23, 23 * FPREGBYTES(sp)
- FPLOAD f24, 24 * FPREGBYTES(sp)
- FPLOAD f25, 25 * FPREGBYTES(sp)
- FPLOAD f26, 26 * FPREGBYTES(sp)
- FPLOAD f27, 27 * FPREGBYTES(sp)
- FPLOAD f28, 28 * FPREGBYTES(sp)
- FPLOAD f29, 29 * FPREGBYTES(sp)
- FPLOAD f30, 30 * FPREGBYTES(sp)
- FPLOAD f31, 31 * FPREGBYTES(sp)
- addi sp, sp, (32 * FPREGBYTES)
- addi sp, sp, -(1 * REGBYTES)
- STORE t0, 0 * REGBYTES(sp)
- LOAD t0, 1 * REGBYTES(sp)
- csrw CSR_FCSR, t0
- LOAD t0, 0 * REGBYTES(sp)
- addi sp, sp, (5 * REGBYTES)
- #endif
- #if defined(__riscv_flen) || defined(__riscv_vector)
- addi sp, sp, -(2 * REGBYTES)
- STORE t0, 0 * REGBYTES(sp)
- STORE t1, 1 * REGBYTES(sp)
- _restore_done:
- LOAD t0, 0 * REGBYTES(sp)
- LOAD t1, 1 * REGBYTES(sp)
- addi sp, sp, (2 * REGBYTES)
- #endif
- mret
- .size eclic_msip_handler, . - eclic_msip_handler
|