| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- /*
- * Copyright (c) 2019-Present Nuclei Limited. All rights reserved.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2020/03/26 Huaqi First Nuclei RISC-V porting implementation
- */
- #include "riscv_encoding.h"
- /* see https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc */
- #ifndef __riscv_32e
- /* Make sure the stack pointer is 16-byte aligned when calling c function */
- #define portRegNum 32
- #else
- /* Make sure the stack pointer is 4-byte aligned when calling c function for ilp32e */
- #define portRegNum 14
- #endif
- #define portCONTEXT_SIZE ( portRegNum * REGBYTES )
- .extern rt_interrupt_from_thread
- .extern rt_interrupt_to_thread
- .section .text
- /*
- * void rt_hw_context_switch_to(rt_ubase_t to);
- * a0 --> to_thread
- */
- .globl rt_hw_context_switch_to
- /* 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 rt_hw_context_switch_to, @function
- .align 3
- rt_hw_context_switch_to:
- /* 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_XSCRATCH */
- la t0, _sp
- csrw CSR_XSCRATCH, t0
- LOAD sp, 0x0(a0) /* Read sp from first TCB member(a0) */
- /* Pop PC from stack and set XEPC */
- LOAD t0, 0 * REGBYTES(sp)
- csrw CSR_XEPC, t0
- /* Pop xstatus from stack and set it */
- LOAD t0, (portRegNum - 1) * REGBYTES(sp)
- csrw CSR_XSTATUS, 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
- XRET
- .size rt_hw_context_switch_to, . - rt_hw_context_switch_to
- .align 2
- .global eclic_xsip_handler
- .type eclic_xsip_handler, @function
- eclic_xsip_handler:
- 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 xstatus to stack */
- csrr t0, CSR_XSTATUS
- STORE t0, (portRegNum - 1) * REGBYTES(sp)
- /* Push additional registers */
- /* Store sp to task stack */
- LOAD t0, rt_interrupt_from_thread
- STORE sp, 0(t0)
- csrr t0, CSR_XEPC
- STORE t0, 0(sp)
- jal xPortTaskSwitch
- /* Switch task context */
- LOAD t0, rt_interrupt_to_thread
- LOAD sp, 0x0(t0)
- /* Pop PC from stack and set XEPC */
- LOAD t0, 0 * REGBYTES(sp)
- csrw CSR_XEPC, t0
- /* Pop additional registers */
- /* Pop xstatus from stack and set it */
- LOAD t0, (portRegNum - 1) * REGBYTES(sp)
- csrw CSR_XSTATUS, 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
- XRET
- .size eclic_xsip_handler, . - eclic_xsip_handler
|