原始版本
This commit is contained in:
313
RT_Thread/libcpu/risc-v/common64/stackframe.h
Normal file
313
RT_Thread/libcpu/risc-v/common64/stackframe.h
Normal file
@ -0,0 +1,313 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-02-02 lizhirui first version
|
||||
* 2021-02-11 lizhirui fixed gp save/store bug
|
||||
* 2021-11-18 JasonHu add fpu registers save/restore
|
||||
* 2022-10-22 Shell Support kernel mode RVV
|
||||
*/
|
||||
|
||||
#ifndef __STACKFRAME_H__
|
||||
#define __STACKFRAME_H__
|
||||
|
||||
#include <rtconfig.h>
|
||||
#include "encoding.h"
|
||||
|
||||
/* bytes of register width */
|
||||
#ifdef ARCH_CPU_64BIT
|
||||
#define STORE sd
|
||||
#define LOAD ld
|
||||
#define FSTORE fsd
|
||||
#define FLOAD fld
|
||||
#define REGBYTES 8
|
||||
#else
|
||||
// error here, not portable
|
||||
#error "Not supported XLEN"
|
||||
#endif
|
||||
|
||||
#include "ext_context.h"
|
||||
|
||||
/* 33 general register + 1 padding */
|
||||
#define CTX_GENERAL_REG_NR 34
|
||||
|
||||
/* all context registers */
|
||||
#define CTX_REG_NR (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR + CTX_VECTOR_REG_NR)
|
||||
|
||||
#define BYTES(idx) ((idx) * REGBYTES)
|
||||
#define FRAME_OFF_SSTATUS BYTES(2)
|
||||
#define FRAME_OFF_SP BYTES(32)
|
||||
#define FRAME_OFF_GP BYTES(3)
|
||||
|
||||
/* switch frame */
|
||||
#define RT_HW_SWITCH_CONTEXT_SSTATUS 0
|
||||
#define RT_HW_SWITCH_CONTEXT_S11 1
|
||||
#define RT_HW_SWITCH_CONTEXT_S10 2
|
||||
#define RT_HW_SWITCH_CONTEXT_S9 3
|
||||
#define RT_HW_SWITCH_CONTEXT_S8 4
|
||||
#define RT_HW_SWITCH_CONTEXT_S7 5
|
||||
#define RT_HW_SWITCH_CONTEXT_S6 6
|
||||
#define RT_HW_SWITCH_CONTEXT_S5 7
|
||||
#define RT_HW_SWITCH_CONTEXT_S4 8
|
||||
#define RT_HW_SWITCH_CONTEXT_S3 9
|
||||
#define RT_HW_SWITCH_CONTEXT_S2 10
|
||||
#define RT_HW_SWITCH_CONTEXT_S1 11
|
||||
#define RT_HW_SWITCH_CONTEXT_S0 12
|
||||
#define RT_HW_SWITCH_CONTEXT_RA 13
|
||||
#define RT_HW_SWITCH_CONTEXT_TP 14
|
||||
#define RT_HW_SWITCH_CONTEXT_ALIGNMENT 15 // Padding for alignment
|
||||
#define RT_HW_SWITCH_CONTEXT_SIZE 16 // Total size of the structure
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
.macro SAVE_ALL
|
||||
|
||||
#ifdef ARCH_RISCV_FPU
|
||||
/* reserve float registers */
|
||||
addi sp, sp, -CTX_FPU_REG_NR * REGBYTES
|
||||
#endif /* ARCH_RISCV_FPU */
|
||||
#ifdef ARCH_RISCV_VECTOR
|
||||
/* reserve float registers */
|
||||
addi sp, sp, -CTX_VECTOR_REG_NR * REGBYTES
|
||||
#endif /* ARCH_RISCV_VECTOR */
|
||||
|
||||
/* save general registers */
|
||||
addi sp, sp, -CTX_GENERAL_REG_NR * REGBYTES
|
||||
STORE x1, 1 * REGBYTES(sp)
|
||||
|
||||
csrr x1, sstatus
|
||||
STORE x1, FRAME_OFF_SSTATUS(sp)
|
||||
|
||||
csrr x1, sepc
|
||||
STORE x1, 0 * REGBYTES(sp)
|
||||
|
||||
STORE x3, 3 * REGBYTES(sp)
|
||||
STORE x4, 4 * REGBYTES(sp) /* save tp */
|
||||
STORE x5, 5 * REGBYTES(sp)
|
||||
STORE x6, 6 * REGBYTES(sp)
|
||||
STORE x7, 7 * REGBYTES(sp)
|
||||
STORE x8, 8 * REGBYTES(sp)
|
||||
STORE x9, 9 * REGBYTES(sp)
|
||||
STORE x10, 10 * REGBYTES(sp)
|
||||
STORE x11, 11 * REGBYTES(sp)
|
||||
STORE x12, 12 * REGBYTES(sp)
|
||||
STORE x13, 13 * REGBYTES(sp)
|
||||
STORE x14, 14 * REGBYTES(sp)
|
||||
STORE x15, 15 * REGBYTES(sp)
|
||||
STORE x16, 16 * REGBYTES(sp)
|
||||
STORE x17, 17 * REGBYTES(sp)
|
||||
STORE x18, 18 * REGBYTES(sp)
|
||||
STORE x19, 19 * REGBYTES(sp)
|
||||
STORE x20, 20 * REGBYTES(sp)
|
||||
STORE x21, 21 * REGBYTES(sp)
|
||||
STORE x22, 22 * REGBYTES(sp)
|
||||
STORE x23, 23 * REGBYTES(sp)
|
||||
STORE x24, 24 * REGBYTES(sp)
|
||||
STORE x25, 25 * REGBYTES(sp)
|
||||
STORE x26, 26 * REGBYTES(sp)
|
||||
STORE x27, 27 * REGBYTES(sp)
|
||||
STORE x28, 28 * REGBYTES(sp)
|
||||
STORE x29, 29 * REGBYTES(sp)
|
||||
STORE x30, 30 * REGBYTES(sp)
|
||||
STORE x31, 31 * REGBYTES(sp)
|
||||
csrr t0, sscratch
|
||||
STORE t0, 32 * REGBYTES(sp)
|
||||
|
||||
#ifdef ARCH_RISCV_FPU
|
||||
/* backup sp and adjust sp to save float registers */
|
||||
mv t1, sp
|
||||
addi t1, t1, CTX_GENERAL_REG_NR * REGBYTES
|
||||
|
||||
li t0, SSTATUS_FS
|
||||
csrs sstatus, t0
|
||||
FSTORE f0, FPU_CTX_F0_OFF(t1)
|
||||
FSTORE f1, FPU_CTX_F1_OFF(t1)
|
||||
FSTORE f2, FPU_CTX_F2_OFF(t1)
|
||||
FSTORE f3, FPU_CTX_F3_OFF(t1)
|
||||
FSTORE f4, FPU_CTX_F4_OFF(t1)
|
||||
FSTORE f5, FPU_CTX_F5_OFF(t1)
|
||||
FSTORE f6, FPU_CTX_F6_OFF(t1)
|
||||
FSTORE f7, FPU_CTX_F7_OFF(t1)
|
||||
FSTORE f8, FPU_CTX_F8_OFF(t1)
|
||||
FSTORE f9, FPU_CTX_F9_OFF(t1)
|
||||
FSTORE f10, FPU_CTX_F10_OFF(t1)
|
||||
FSTORE f11, FPU_CTX_F11_OFF(t1)
|
||||
FSTORE f12, FPU_CTX_F12_OFF(t1)
|
||||
FSTORE f13, FPU_CTX_F13_OFF(t1)
|
||||
FSTORE f14, FPU_CTX_F14_OFF(t1)
|
||||
FSTORE f15, FPU_CTX_F15_OFF(t1)
|
||||
FSTORE f16, FPU_CTX_F16_OFF(t1)
|
||||
FSTORE f17, FPU_CTX_F17_OFF(t1)
|
||||
FSTORE f18, FPU_CTX_F18_OFF(t1)
|
||||
FSTORE f19, FPU_CTX_F19_OFF(t1)
|
||||
FSTORE f20, FPU_CTX_F20_OFF(t1)
|
||||
FSTORE f21, FPU_CTX_F21_OFF(t1)
|
||||
FSTORE f22, FPU_CTX_F22_OFF(t1)
|
||||
FSTORE f23, FPU_CTX_F23_OFF(t1)
|
||||
FSTORE f24, FPU_CTX_F24_OFF(t1)
|
||||
FSTORE f25, FPU_CTX_F25_OFF(t1)
|
||||
FSTORE f26, FPU_CTX_F26_OFF(t1)
|
||||
FSTORE f27, FPU_CTX_F27_OFF(t1)
|
||||
FSTORE f28, FPU_CTX_F28_OFF(t1)
|
||||
FSTORE f29, FPU_CTX_F29_OFF(t1)
|
||||
FSTORE f30, FPU_CTX_F30_OFF(t1)
|
||||
FSTORE f31, FPU_CTX_F31_OFF(t1)
|
||||
|
||||
/* clr FS domain */
|
||||
csrc sstatus, t0
|
||||
|
||||
/* clean status would clr sr_sd; */
|
||||
li t0, SSTATUS_FS_CLEAN
|
||||
csrs sstatus, t0
|
||||
|
||||
#endif /* ARCH_RISCV_FPU */
|
||||
|
||||
#ifdef ARCH_RISCV_VECTOR
|
||||
csrr t0, sstatus
|
||||
andi t0, t0, SSTATUS_VS
|
||||
beqz t0, 0f
|
||||
|
||||
/* push vector frame */
|
||||
addi t1, sp, (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR) * REGBYTES
|
||||
|
||||
SAVE_VECTOR t1
|
||||
0:
|
||||
#endif /* ARCH_RISCV_VECTOR */
|
||||
.endm
|
||||
|
||||
/**
|
||||
* @brief Restore All General Registers, for interrupt handling
|
||||
*
|
||||
*/
|
||||
.macro RESTORE_ALL
|
||||
|
||||
#ifdef ARCH_RISCV_VECTOR
|
||||
// skip on close
|
||||
ld t0, 2 * REGBYTES(sp)
|
||||
// cannot use vector on initial
|
||||
andi t0, t0, SSTATUS_VS_CLEAN
|
||||
beqz t0, 0f
|
||||
|
||||
/* push vector frame */
|
||||
addi t1, sp, (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR) * REGBYTES
|
||||
|
||||
RESTORE_VECTOR t1
|
||||
0:
|
||||
#endif /* ARCH_RISCV_VECTOR */
|
||||
|
||||
#ifdef ARCH_RISCV_FPU
|
||||
/* restore float register */
|
||||
addi t2, sp, CTX_GENERAL_REG_NR * REGBYTES
|
||||
|
||||
li t0, SSTATUS_FS
|
||||
csrs sstatus, t0
|
||||
FLOAD f0, FPU_CTX_F0_OFF(t2)
|
||||
FLOAD f1, FPU_CTX_F1_OFF(t2)
|
||||
FLOAD f2, FPU_CTX_F2_OFF(t2)
|
||||
FLOAD f3, FPU_CTX_F3_OFF(t2)
|
||||
FLOAD f4, FPU_CTX_F4_OFF(t2)
|
||||
FLOAD f5, FPU_CTX_F5_OFF(t2)
|
||||
FLOAD f6, FPU_CTX_F6_OFF(t2)
|
||||
FLOAD f7, FPU_CTX_F7_OFF(t2)
|
||||
FLOAD f8, FPU_CTX_F8_OFF(t2)
|
||||
FLOAD f9, FPU_CTX_F9_OFF(t2)
|
||||
FLOAD f10, FPU_CTX_F10_OFF(t2)
|
||||
FLOAD f11, FPU_CTX_F11_OFF(t2)
|
||||
FLOAD f12, FPU_CTX_F12_OFF(t2)
|
||||
FLOAD f13, FPU_CTX_F13_OFF(t2)
|
||||
FLOAD f14, FPU_CTX_F14_OFF(t2)
|
||||
FLOAD f15, FPU_CTX_F15_OFF(t2)
|
||||
FLOAD f16, FPU_CTX_F16_OFF(t2)
|
||||
FLOAD f17, FPU_CTX_F17_OFF(t2)
|
||||
FLOAD f18, FPU_CTX_F18_OFF(t2)
|
||||
FLOAD f19, FPU_CTX_F19_OFF(t2)
|
||||
FLOAD f20, FPU_CTX_F20_OFF(t2)
|
||||
FLOAD f21, FPU_CTX_F21_OFF(t2)
|
||||
FLOAD f22, FPU_CTX_F22_OFF(t2)
|
||||
FLOAD f23, FPU_CTX_F23_OFF(t2)
|
||||
FLOAD f24, FPU_CTX_F24_OFF(t2)
|
||||
FLOAD f25, FPU_CTX_F25_OFF(t2)
|
||||
FLOAD f26, FPU_CTX_F26_OFF(t2)
|
||||
FLOAD f27, FPU_CTX_F27_OFF(t2)
|
||||
FLOAD f28, FPU_CTX_F28_OFF(t2)
|
||||
FLOAD f29, FPU_CTX_F29_OFF(t2)
|
||||
FLOAD f30, FPU_CTX_F30_OFF(t2)
|
||||
FLOAD f31, FPU_CTX_F31_OFF(t2)
|
||||
|
||||
/* clr FS domain */
|
||||
csrc sstatus, t0
|
||||
|
||||
/* clean status would clr sr_sd; */
|
||||
li t0, SSTATUS_FS_CLEAN
|
||||
csrs sstatus, t0
|
||||
|
||||
#endif /* ARCH_RISCV_FPU */
|
||||
|
||||
/* restore general register */
|
||||
addi t0, sp, CTX_REG_NR * REGBYTES
|
||||
csrw sscratch, t0
|
||||
|
||||
/* resw ra to sepc */
|
||||
LOAD x1, 0 * REGBYTES(sp)
|
||||
csrw sepc, x1
|
||||
|
||||
LOAD x1, 2 * REGBYTES(sp)
|
||||
csrw sstatus, x1
|
||||
|
||||
LOAD x1, 1 * REGBYTES(sp)
|
||||
|
||||
LOAD x3, 3 * REGBYTES(sp)
|
||||
LOAD x4, 4 * REGBYTES(sp) /* restore tp */
|
||||
LOAD x5, 5 * REGBYTES(sp)
|
||||
LOAD x6, 6 * REGBYTES(sp)
|
||||
LOAD x7, 7 * REGBYTES(sp)
|
||||
LOAD x8, 8 * REGBYTES(sp)
|
||||
LOAD x9, 9 * REGBYTES(sp)
|
||||
LOAD x10, 10 * REGBYTES(sp)
|
||||
LOAD x11, 11 * REGBYTES(sp)
|
||||
LOAD x12, 12 * REGBYTES(sp)
|
||||
LOAD x13, 13 * REGBYTES(sp)
|
||||
LOAD x14, 14 * REGBYTES(sp)
|
||||
LOAD x15, 15 * REGBYTES(sp)
|
||||
LOAD x16, 16 * REGBYTES(sp)
|
||||
LOAD x17, 17 * REGBYTES(sp)
|
||||
LOAD x18, 18 * REGBYTES(sp)
|
||||
LOAD x19, 19 * REGBYTES(sp)
|
||||
LOAD x20, 20 * REGBYTES(sp)
|
||||
LOAD x21, 21 * REGBYTES(sp)
|
||||
LOAD x22, 22 * REGBYTES(sp)
|
||||
LOAD x23, 23 * REGBYTES(sp)
|
||||
LOAD x24, 24 * REGBYTES(sp)
|
||||
LOAD x25, 25 * REGBYTES(sp)
|
||||
LOAD x26, 26 * REGBYTES(sp)
|
||||
LOAD x27, 27 * REGBYTES(sp)
|
||||
LOAD x28, 28 * REGBYTES(sp)
|
||||
LOAD x29, 29 * REGBYTES(sp)
|
||||
LOAD x30, 30 * REGBYTES(sp)
|
||||
LOAD x31, 31 * REGBYTES(sp)
|
||||
|
||||
/* restore user sp */
|
||||
LOAD sp, 32 * REGBYTES(sp)
|
||||
.endm
|
||||
|
||||
.macro RESTORE_SYS_GP
|
||||
.option push
|
||||
.option norelax
|
||||
la gp, __global_pointer$
|
||||
.option pop
|
||||
.endm
|
||||
|
||||
.macro OPEN_INTERRUPT
|
||||
csrsi sstatus, 2
|
||||
.endm
|
||||
|
||||
.macro CLOSE_INTERRUPT
|
||||
csrci sstatus, 2
|
||||
.endm
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __STACKFRAME_H__ */
|
||||
Reference in New Issue
Block a user