feat: libcpu/risc-v: unify context on c906, virt64
Changes: - added config for NEW_CTX_SWITCH - used new context on c906 sched switch routine - update _rt_hw_stack_init to fit into NEW_CTX_SWITCH - separated vector ctx from the generic Signed-off-by: Shell <smokewood@qq.com>
This commit is contained in:
parent
adbbd24ad7
commit
7528645f59
|
@ -28,6 +28,7 @@ config ENABLE_FPU
|
||||||
|
|
||||||
config ENABLE_VECTOR
|
config ENABLE_VECTOR
|
||||||
bool "Using RISC-V Vector Extension"
|
bool "Using RISC-V Vector Extension"
|
||||||
|
select ARCH_RISCV_VECTOR
|
||||||
default n
|
default n
|
||||||
|
|
||||||
if ENABLE_VECTOR
|
if ENABLE_VECTOR
|
||||||
|
|
|
@ -245,6 +245,9 @@ config ARCH_RISCV
|
||||||
config ARCH_RISCV_FPU
|
config ARCH_RISCV_FPU
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config ARCH_RISCV_VECTOR
|
||||||
|
bool
|
||||||
|
|
||||||
config ARCH_RISCV_FPU_S
|
config ARCH_RISCV_FPU_S
|
||||||
select ARCH_RISCV_FPU
|
select ARCH_RISCV_FPU
|
||||||
bool
|
bool
|
||||||
|
@ -263,10 +266,15 @@ config ARCH_RISCV64
|
||||||
bool
|
bool
|
||||||
|
|
||||||
if ARCH_RISCV64
|
if ARCH_RISCV64
|
||||||
|
config ARCH_USING_NEW_CTX_SWITCH
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config ARCH_USING_RISCV_COMMON64
|
config ARCH_USING_RISCV_COMMON64
|
||||||
bool
|
bool
|
||||||
depends on ARCH_RISCV64
|
depends on ARCH_RISCV64
|
||||||
select RT_USING_CPUTIME
|
select RT_USING_CPUTIME
|
||||||
|
select ARCH_USING_NEW_CTX_SWITCH
|
||||||
help
|
help
|
||||||
Using the common64 implementation under ./libcpu/risc-v
|
Using the common64 implementation under ./libcpu/risc-v
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -1,137 +1,127 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
|
* 2023-10-18 Shell Add backtrace support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define DBG_TAG "hw.backtrace"
|
||||||
|
#define DBG_LVL DBG_INFO
|
||||||
|
#include <rtdbg.h>
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
#include <mm_aspace.h>
|
||||||
|
#include "riscv_mmu.h"
|
||||||
|
#include "stack.h"
|
||||||
|
|
||||||
|
#define WORD sizeof(rt_base_t)
|
||||||
|
#define ARCH_CONTEXT_FETCH(pctx, id) (*(((unsigned long *)pctx) + (id)))
|
||||||
|
|
||||||
|
rt_inline rt_err_t _bt_kaddr(rt_ubase_t *fp, struct rt_hw_backtrace_frame *frame)
|
||||||
|
{
|
||||||
|
rt_err_t rc;
|
||||||
|
frame->fp = *(fp - 2);
|
||||||
|
frame->pc = *(fp - 1);
|
||||||
|
|
||||||
|
if ((rt_ubase_t)fp == frame->fp)
|
||||||
|
{
|
||||||
|
rc = -RT_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = RT_EOK;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_SMART
|
#ifdef RT_USING_SMART
|
||||||
#include <lwp_arch.h>
|
#include <lwp_arch.h>
|
||||||
|
#include <lwp_user_mm.h>
|
||||||
|
|
||||||
#define TRANCE_LEVEL 20
|
rt_inline rt_err_t _bt_uaddr(rt_lwp_t lwp, rt_ubase_t *fp, struct rt_hw_backtrace_frame *frame)
|
||||||
|
|
||||||
extern rt_ubase_t __text_start[];
|
|
||||||
extern rt_ubase_t __text_end[];
|
|
||||||
|
|
||||||
static char *_get_elf_name(size_t sepc);
|
|
||||||
|
|
||||||
void rt_hw_backtrace(rt_uint32_t *ffp, rt_ubase_t sepc)
|
|
||||||
{
|
{
|
||||||
rt_ubase_t *ra;
|
rt_err_t rc;
|
||||||
rt_ubase_t *fp;
|
if (lwp_data_get(lwp, &frame->fp, fp - 2, WORD) != WORD)
|
||||||
rt_ubase_t vas, vae;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
rt_kprintf("riscv64-unknown-linux-musl-addr2line -e %s -a -f", _get_elf_name(sepc));
|
|
||||||
|
|
||||||
fp = (rt_ubase_t *)ffp;
|
|
||||||
|
|
||||||
if (!fp)
|
|
||||||
{
|
{
|
||||||
asm volatile("mv %0, s0"
|
rc = -RT_EFAULT;
|
||||||
: "=r"(fp));
|
|
||||||
}
|
}
|
||||||
|
else if (lwp_data_get(lwp, &frame->pc, fp - 1, WORD) != WORD)
|
||||||
if (sepc)
|
|
||||||
{
|
{
|
||||||
rt_kprintf(" %p", sepc - 0x4);
|
rc = -RT_EFAULT;
|
||||||
}
|
}
|
||||||
|
else if ((rt_ubase_t)fp == frame->fp)
|
||||||
if (fp > (rt_ubase_t *)USER_VADDR_START && fp < (rt_ubase_t *)USER_VADDR_TOP)
|
|
||||||
{
|
{
|
||||||
vas = USER_VADDR_START;
|
rc = -RT_ERROR;
|
||||||
vae = USER_VADDR_TOP;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vas = (rt_ubase_t)&__text_start;
|
frame->pc -= 0;
|
||||||
vae = (rt_ubase_t)&__text_end;
|
rc = RT_EOK;
|
||||||
}
|
}
|
||||||
|
return rc;
|
||||||
for (i = j = 0; i < TRANCE_LEVEL; i++)
|
|
||||||
{
|
|
||||||
if (RT_ALIGN((rt_ubase_t)fp, sizeof(void *)) != (rt_ubase_t)fp)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ra = fp - 1;
|
|
||||||
if (!rt_kmem_v2p(ra) || *ra < vas || *ra > vae)
|
|
||||||
break;
|
|
||||||
|
|
||||||
rt_kprintf(" %p", *ra - 0x04);
|
|
||||||
|
|
||||||
fp = fp - 2;
|
|
||||||
if (!rt_kmem_v2p(fp))
|
|
||||||
break;
|
|
||||||
fp = (rt_ubase_t *)(*fp);
|
|
||||||
if (!fp)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_kputs("\r\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _assert_backtrace_cb(const char *ex, const char *func, rt_size_t line)
|
|
||||||
{
|
|
||||||
rt_hw_interrupt_disable();
|
|
||||||
rt_kprintf("(%s) assertion failed at function:%s, line number:%d \n", ex, func, line);
|
|
||||||
|
|
||||||
rt_hw_backtrace(0, 0);
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rt_hw_backtrace_init(void)
|
|
||||||
{
|
|
||||||
rt_assert_set_hook(_assert_backtrace_cb);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
INIT_BOARD_EXPORT(rt_hw_backtrace_init);
|
|
||||||
|
|
||||||
static void backtrace_test(int args, char *argv[])
|
|
||||||
{
|
|
||||||
int *p = (void *)-1;
|
|
||||||
init_fn_t ft = 0;
|
|
||||||
|
|
||||||
if (args < 2)
|
|
||||||
{
|
|
||||||
rt_kprintf("backtrace_test usage:backtrace_test a(assert)/m(invalid memory)/i(illegal instruction)\r\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rt_strcmp(argv[1], "a"))
|
|
||||||
{
|
|
||||||
rt_kprintf("Assert test:\r\n", argv[1]);
|
|
||||||
RT_ASSERT(0);
|
|
||||||
}
|
|
||||||
else if (!rt_strcmp(argv[1], "m"))
|
|
||||||
{
|
|
||||||
rt_kprintf("Access invalid memory:\r\n", argv[1]);
|
|
||||||
*p = 0;
|
|
||||||
}
|
|
||||||
else if (!rt_strcmp(argv[1], "i"))
|
|
||||||
{
|
|
||||||
rt_kprintf("Illegal instruction:\r\n", argv[1]);
|
|
||||||
ft();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rt_kprintf("Unknown cmd :%s.\r\n", argv[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MSH_CMD_EXPORT(backtrace_test, backtrace test case);
|
|
||||||
|
|
||||||
extern struct rt_thread *rt_current_thread;
|
|
||||||
|
|
||||||
#define IN_USERSPACE (sepc > USER_VADDR_START && sepc < USER_VADDR_TOP)
|
|
||||||
|
|
||||||
static char *_get_elf_name(size_t sepc)
|
|
||||||
{
|
|
||||||
return IN_USERSPACE ? rt_current_thread->parent.name : "rtthread.elf";
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* RT_USING_SMART */
|
#endif /* RT_USING_SMART */
|
||||||
|
|
||||||
|
rt_err_t rt_hw_backtrace_frame_unwind(rt_thread_t thread, struct rt_hw_backtrace_frame *frame)
|
||||||
|
{
|
||||||
|
rt_err_t rc = -RT_ERROR;
|
||||||
|
rt_uintptr_t *fp = (rt_uintptr_t *)frame->fp;
|
||||||
|
|
||||||
|
if (fp && !((long)fp & 0x7))
|
||||||
|
{
|
||||||
|
#ifdef RT_USING_SMART
|
||||||
|
if (thread->lwp)
|
||||||
|
{
|
||||||
|
void *lwp = thread->lwp;
|
||||||
|
void *this_lwp = lwp_self();
|
||||||
|
if (this_lwp == lwp && rt_hw_mmu_v2p(((rt_lwp_t)lwp)->aspace, fp) != ARCH_MAP_FAILED)
|
||||||
|
{
|
||||||
|
rc = _bt_kaddr(fp, frame);
|
||||||
|
}
|
||||||
|
else if (lwp_user_accessible_ext(lwp, (void *)fp, WORD))
|
||||||
|
{
|
||||||
|
rc = _bt_uaddr(lwp, fp, frame);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = -RT_EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if ((rt_kmem_v2p(fp) != ARCH_MAP_FAILED))
|
||||||
|
{
|
||||||
|
rc = _bt_kaddr(fp, frame);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = -RT_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = -RT_EFAULT;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t rt_hw_backtrace_frame_get(rt_thread_t thread, struct rt_hw_backtrace_frame *frame)
|
||||||
|
{
|
||||||
|
rt_err_t rc;
|
||||||
|
|
||||||
|
if (!thread || !frame)
|
||||||
|
{
|
||||||
|
rc = -RT_EINVAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_hw_switch_frame_t sframe = thread->sp;
|
||||||
|
frame->pc = sframe->regs[RT_HW_SWITCH_CONTEXT_RA];
|
||||||
|
frame->fp = sframe->regs[RT_HW_SWITCH_CONTEXT_S0];;
|
||||||
|
rc = RT_EOK;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
|
@ -8,12 +8,72 @@
|
||||||
* 2018/10/28 Bernard The unify RISC-V porting implementation
|
* 2018/10/28 Bernard The unify RISC-V porting implementation
|
||||||
* 2018/12/27 Jesven Add SMP support
|
* 2018/12/27 Jesven Add SMP support
|
||||||
* 2021/02/02 lizhirui Add userspace support
|
* 2021/02/02 lizhirui Add userspace support
|
||||||
|
* 2022/10/22 Shell Support User mode RVV;
|
||||||
|
* Trimming process switch context
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cpuport.h"
|
#include "cpuport.h"
|
||||||
#include "stackframe.h"
|
#include "stackframe.h"
|
||||||
|
#define _REG_IDX(name) RT_HW_SWITCH_CONTEXT_##name
|
||||||
|
#define REG_IDX(name) _REG_IDX(name)
|
||||||
|
|
||||||
.globl rt_hw_context_switch_to
|
.macro SAVE_REG reg, index
|
||||||
|
STORE \reg, \index*REGBYTES(sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro LOAD_REG reg, index
|
||||||
|
LOAD \reg, \index*REGBYTES(sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro RESERVE_CONTEXT
|
||||||
|
addi sp, sp, -(RT_HW_SWITCH_CONTEXT_SIZE * REGBYTES)
|
||||||
|
SAVE_REG tp, REG_IDX(TP)
|
||||||
|
SAVE_REG ra, REG_IDX(RA)
|
||||||
|
SAVE_REG s0, REG_IDX(S0)
|
||||||
|
SAVE_REG s1, REG_IDX(S1)
|
||||||
|
SAVE_REG s2, REG_IDX(S2)
|
||||||
|
SAVE_REG s3, REG_IDX(S3)
|
||||||
|
SAVE_REG s4, REG_IDX(S4)
|
||||||
|
SAVE_REG s5, REG_IDX(S5)
|
||||||
|
SAVE_REG s6, REG_IDX(S6)
|
||||||
|
SAVE_REG s7, REG_IDX(S7)
|
||||||
|
SAVE_REG s8, REG_IDX(S8)
|
||||||
|
SAVE_REG s9, REG_IDX(S9)
|
||||||
|
SAVE_REG s10, REG_IDX(S10)
|
||||||
|
SAVE_REG s11, REG_IDX(S11)
|
||||||
|
csrr s11, sstatus
|
||||||
|
li s10, (SSTATUS_SPP)
|
||||||
|
or s11, s11, s10
|
||||||
|
SAVE_REG s11, REG_IDX(SSTATUS)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro RESTORE_CONTEXT
|
||||||
|
LOAD_REG s11, REG_IDX(SSTATUS)
|
||||||
|
csrw sstatus, s11
|
||||||
|
LOAD_REG s11, REG_IDX(S11)
|
||||||
|
LOAD_REG s10, REG_IDX(S10)
|
||||||
|
LOAD_REG s9, REG_IDX(S9)
|
||||||
|
LOAD_REG s8, REG_IDX(S8)
|
||||||
|
LOAD_REG s7, REG_IDX(S7)
|
||||||
|
LOAD_REG s6, REG_IDX(S6)
|
||||||
|
LOAD_REG s5, REG_IDX(S5)
|
||||||
|
LOAD_REG s4, REG_IDX(S4)
|
||||||
|
LOAD_REG s3, REG_IDX(S3)
|
||||||
|
LOAD_REG s2, REG_IDX(S2)
|
||||||
|
LOAD_REG s1, REG_IDX(S1)
|
||||||
|
LOAD_REG s0, REG_IDX(S0)
|
||||||
|
LOAD_REG ra, REG_IDX(RA)
|
||||||
|
LOAD_REG tp, REG_IDX(TP)
|
||||||
|
addi sp, sp, RT_HW_SWITCH_CONTEXT_SIZE * REGBYTES
|
||||||
|
csrw sepc, ra
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void rt_hw_context_switch_to(rt_ubase_t to);
|
||||||
|
*
|
||||||
|
* a0 --> to SP pointer
|
||||||
|
*/
|
||||||
|
.globl rt_hw_context_switch_to
|
||||||
rt_hw_context_switch_to:
|
rt_hw_context_switch_to:
|
||||||
LOAD sp, (a0)
|
LOAD sp, (a0)
|
||||||
|
|
||||||
|
@ -24,31 +84,26 @@ rt_hw_context_switch_to:
|
||||||
jal lwp_aspace_switch
|
jal lwp_aspace_switch
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RESTORE_ALL
|
RESTORE_CONTEXT
|
||||||
sret
|
sret
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
|
* void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
|
||||||
*
|
*
|
||||||
* a0 --> from
|
* a0 --> from SP pointer
|
||||||
* a1 --> to
|
* a1 --> to SP pointer
|
||||||
|
*
|
||||||
|
* It should only be used on local interrupt disable
|
||||||
*/
|
*/
|
||||||
.globl rt_hw_context_switch
|
.globl rt_hw_context_switch
|
||||||
rt_hw_context_switch:
|
rt_hw_context_switch:
|
||||||
mv t2, sp
|
RESERVE_CONTEXT
|
||||||
li t0, 0x120//set SPIE and SPP = 1
|
|
||||||
csrs sstatus, t0//if enter here,caller must be in system thread
|
|
||||||
csrw sepc, ra//return address
|
|
||||||
//saved from thread context
|
|
||||||
SAVE_ALL
|
|
||||||
|
|
||||||
STORE t2, 32 * REGBYTES(sp)//save user_sp
|
|
||||||
|
|
||||||
STORE sp, (a0)
|
STORE sp, (a0)
|
||||||
|
|
||||||
//restore to thread context
|
// restore to thread SP
|
||||||
LOAD sp, (a1)
|
LOAD sp, (a1)
|
||||||
|
|
||||||
|
// restore Address Space
|
||||||
jal rt_thread_self
|
jal rt_thread_self
|
||||||
mv s1, a0
|
mv s1, a0
|
||||||
|
|
||||||
|
@ -56,5 +111,5 @@ rt_hw_context_switch:
|
||||||
jal lwp_aspace_switch
|
jal lwp_aspace_switch
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RESTORE_ALL
|
RESTORE_CONTEXT
|
||||||
sret
|
sret
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
|
@ -14,9 +14,15 @@
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
||||||
#include "cpuport.h"
|
#include "cpuport.h"
|
||||||
#include "sbi.h"
|
|
||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
|
#include <sbi.h>
|
||||||
|
#include <encoding.h>
|
||||||
|
|
||||||
|
#ifdef ARCH_RISCV_FPU
|
||||||
|
#define K_SSTATUS_DEFAULT (SSTATUS_SPP | SSTATUS_SPIE | SSTATUS_SUM | SSTATUS_FS)
|
||||||
|
#else
|
||||||
|
#define K_SSTATUS_DEFAULT (SSTATUS_SPP | SSTATUS_SPIE | SSTATUS_SUM)
|
||||||
|
#endif
|
||||||
#ifdef RT_USING_SMART
|
#ifdef RT_USING_SMART
|
||||||
#include <lwp_arch.h>
|
#include <lwp_arch.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,22 +31,42 @@
|
||||||
* @brief from thread used interrupt context switch
|
* @brief from thread used interrupt context switch
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
volatile rt_ubase_t rt_interrupt_from_thread = 0;
|
volatile rt_ubase_t rt_interrupt_from_thread = 0;
|
||||||
/**
|
/**
|
||||||
* @brief to thread used interrupt context switch
|
* @brief to thread used interrupt context switch
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
volatile rt_ubase_t rt_interrupt_to_thread = 0;
|
volatile rt_ubase_t rt_interrupt_to_thread = 0;
|
||||||
/**
|
/**
|
||||||
* @brief flag to indicate context switch in interrupt or not
|
* @brief flag to indicate context switch in interrupt or not
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
volatile rt_ubase_t rt_thread_switch_interrupt_flag = 0;
|
volatile rt_ubase_t rt_thread_switch_interrupt_flag = 0;
|
||||||
|
|
||||||
|
void *_rt_hw_stack_init(rt_ubase_t *sp, rt_ubase_t ra, rt_ubase_t sstatus)
|
||||||
|
{
|
||||||
|
rt_hw_switch_frame_t frame = (rt_hw_switch_frame_t)
|
||||||
|
((rt_ubase_t)sp - sizeof(struct rt_hw_switch_frame));
|
||||||
|
|
||||||
|
rt_memset(frame, 0, sizeof(struct rt_hw_switch_frame));
|
||||||
|
|
||||||
|
frame->regs[RT_HW_SWITCH_CONTEXT_RA] = ra;
|
||||||
|
frame->regs[RT_HW_SWITCH_CONTEXT_SSTATUS] = sstatus;
|
||||||
|
|
||||||
|
return (void *)frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rt_hw_cpu_id(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function will initialize thread stack
|
* This function will initialize thread stack, we assuming
|
||||||
|
* when scheduler restore this new thread, context will restore
|
||||||
|
* an entry to user first application
|
||||||
*
|
*
|
||||||
|
* s0-s11, ra, sstatus, a0
|
||||||
* @param tentry the entry of thread
|
* @param tentry the entry of thread
|
||||||
* @param parameter the parameter of entry
|
* @param parameter the parameter of entry
|
||||||
* @param stack_addr the beginning stack address
|
* @param stack_addr the beginning stack address
|
||||||
|
@ -48,41 +74,23 @@ volatile rt_ubase_t rt_thread_switch_interrupt_flag = 0;
|
||||||
*
|
*
|
||||||
* @return stack address
|
* @return stack address
|
||||||
*/
|
*/
|
||||||
rt_uint8_t *rt_hw_stack_init(void *tentry,
|
rt_uint8_t *rt_hw_stack_init(void *tentry,
|
||||||
void *parameter,
|
void *parameter,
|
||||||
rt_uint8_t *stack_addr,
|
rt_uint8_t *stack_addr,
|
||||||
void *texit)
|
void *texit)
|
||||||
{
|
{
|
||||||
struct rt_hw_stack_frame *frame;
|
rt_ubase_t *sp = (rt_ubase_t *)stack_addr;
|
||||||
rt_uint8_t *stk;
|
// we use a strict alignment requirement for Q extension
|
||||||
int i;
|
sp = (rt_ubase_t *)RT_ALIGN_DOWN((rt_ubase_t)sp, 16);
|
||||||
extern int __global_pointer$;
|
|
||||||
|
|
||||||
stk = stack_addr + sizeof(rt_ubase_t);
|
(*--sp) = (rt_ubase_t)tentry;
|
||||||
stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_ubase_t)stk, REGBYTES);
|
(*--sp) = (rt_ubase_t)parameter;
|
||||||
stk -= sizeof(struct rt_hw_stack_frame);
|
(*--sp) = (rt_ubase_t)texit;
|
||||||
|
--sp; /* alignment */
|
||||||
|
|
||||||
frame = (struct rt_hw_stack_frame *)stk;
|
/* compatible to RESTORE_CONTEXT */
|
||||||
|
extern void _rt_thread_entry(void);
|
||||||
for (i = 0; i < sizeof(struct rt_hw_stack_frame) / sizeof(rt_ubase_t); i++)
|
return (rt_uint8_t *)_rt_hw_stack_init(sp, (rt_ubase_t)_rt_thread_entry, K_SSTATUS_DEFAULT);
|
||||||
{
|
|
||||||
((rt_ubase_t *)frame)[i] = 0xdeadbeef;
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->ra = (rt_ubase_t)texit;
|
|
||||||
frame->gp = (rt_ubase_t)&__global_pointer$;
|
|
||||||
frame->a0 = (rt_ubase_t)parameter;
|
|
||||||
frame->epc = (rt_ubase_t)tentry;
|
|
||||||
frame->user_sp_exc_stack = (rt_ubase_t)(((rt_ubase_t)stk) + sizeof(struct rt_hw_stack_frame));
|
|
||||||
|
|
||||||
/* force to supervisor mode(SPP=1) and set SPIE and SUM to 1 */
|
|
||||||
#ifdef ARCH_RISCV_FPU
|
|
||||||
frame->sstatus = 0x00046120; /* enable FPU */
|
|
||||||
#else
|
|
||||||
frame->sstatus = 0x00040120;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return stk;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -101,7 +109,7 @@ void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to, rt_thread_t
|
||||||
rt_interrupt_to_thread = to;
|
rt_interrupt_to_thread = to;
|
||||||
rt_thread_switch_interrupt_flag = 1;
|
rt_thread_switch_interrupt_flag = 1;
|
||||||
|
|
||||||
return ;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* end of RT_USING_SMP */
|
#endif /* end of RT_USING_SMP */
|
||||||
|
|
||||||
|
@ -112,16 +120,14 @@ void rt_hw_cpu_shutdown(void)
|
||||||
rt_kprintf("shutdown...\n");
|
rt_kprintf("shutdown...\n");
|
||||||
|
|
||||||
level = rt_hw_interrupt_disable();
|
level = rt_hw_interrupt_disable();
|
||||||
sbi_shutdown();
|
|
||||||
while (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int rt_hw_cpu_id(void)
|
sbi_shutdown();
|
||||||
{
|
|
||||||
return 0; /* d1 has one core */
|
while (1)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rt_hw_set_process_id(int pid)
|
void rt_hw_set_process_id(int pid)
|
||||||
{
|
{
|
||||||
//TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
|
@ -14,28 +14,16 @@
|
||||||
#include <rtconfig.h>
|
#include <rtconfig.h>
|
||||||
#include <opcode.h>
|
#include <opcode.h>
|
||||||
|
|
||||||
/* bytes of register width */
|
#ifdef RT_USING_SMP
|
||||||
#ifdef ARCH_CPU_64BIT
|
typedef union {
|
||||||
#define STORE sd
|
unsigned long slock;
|
||||||
#define LOAD ld
|
struct __arch_tickets {
|
||||||
#define REGBYTES 8
|
unsigned short owner;
|
||||||
#else
|
unsigned short next;
|
||||||
// error here, not portable
|
} tickets;
|
||||||
|
} rt_hw_spinlock_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 33 general register */
|
|
||||||
#define CTX_GENERAL_REG_NR 33
|
|
||||||
|
|
||||||
#ifdef ARCH_RISCV_FPU
|
|
||||||
/* 32 fpu register */
|
|
||||||
#define CTX_FPU_REG_NR 32
|
|
||||||
#else
|
|
||||||
#define CTX_FPU_REG_NR 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* all context registers */
|
|
||||||
#define CTX_REG_NR (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR)
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
#include <rtdef.h>
|
#include <rtdef.h>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-10-19 RT-Thread the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cpuport.h"
|
||||||
|
#include "stackframe.h"
|
||||||
|
#include "asm-generic.h"
|
||||||
|
|
||||||
|
START_POINT(_rt_thread_entry)
|
||||||
|
LOAD ra, REGBYTES(sp) /* thread exit */
|
||||||
|
addi sp, sp, 2 * REGBYTES
|
||||||
|
LOAD a0, (sp) /* parameter */
|
||||||
|
LOAD t0, REGBYTES(sp) /* tentry */
|
||||||
|
addi sp, sp, 2 * REGBYTES
|
||||||
|
mv s1, ra
|
||||||
|
jalr t0
|
||||||
|
jalr s1
|
||||||
|
j . /* never here */
|
||||||
|
START_POINT_END(_rt_thread_entry)
|
|
@ -1,8 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
*/
|
||||||
// See LICENSE for license details.
|
// See LICENSE for license details.
|
||||||
|
|
||||||
#ifndef RISCV_CSR_ENCODING_H
|
#ifndef RISCV_CSR_ENCODING_H
|
||||||
#define RISCV_CSR_ENCODING_H
|
#define RISCV_CSR_ENCODING_H
|
||||||
|
|
||||||
|
#include <rtconfig.h>
|
||||||
|
|
||||||
|
#ifdef ARCH_RISCV_VECTOR
|
||||||
|
#include "vector_encoding.h"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define SSTATUS_VS 0 /* fallback */
|
||||||
|
#endif /* ARCH_RISCV_VECTOR */
|
||||||
|
|
||||||
#define MSTATUS_UIE 0x00000001
|
#define MSTATUS_UIE 0x00000001
|
||||||
#define MSTATUS_SIE 0x00000002
|
#define MSTATUS_SIE 0x00000002
|
||||||
#define MSTATUS_HIE 0x00000004
|
#define MSTATUS_HIE 0x00000004
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-10-10 RT-Thread the first version
|
||||||
|
*/
|
||||||
|
#ifndef __EXT_CONTEXT_H__
|
||||||
|
#define __EXT_CONTEXT_H__
|
||||||
|
|
||||||
|
#include <rtconfig.h>
|
||||||
|
|
||||||
|
#ifdef ARCH_RISCV_FPU
|
||||||
|
/* 32 fpu register */
|
||||||
|
#define CTX_FPU_REG_NR 32
|
||||||
|
#else
|
||||||
|
#define CTX_FPU_REG_NR 0
|
||||||
|
#endif /* ARCH_RISCV_FPU */
|
||||||
|
|
||||||
|
#ifdef __ASSEMBLY__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ==================================
|
||||||
|
* RISC-V D ISA (Floating)
|
||||||
|
* ==================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ARCH_RISCV_FPU
|
||||||
|
#define FPU_CTX_F0_OFF (REGBYTES * 0) /* offsetof(fpu_context_t, fpustatus.f[0]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F1_OFF (REGBYTES * 1) /* offsetof(fpu_context_t, fpustatus.f[1]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F2_OFF (REGBYTES * 2) /* offsetof(fpu_context_t, fpustatus.f[2]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F3_OFF (REGBYTES * 3) /* offsetof(fpu_context_t, fpustatus.f[3]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F4_OFF (REGBYTES * 4) /* offsetof(fpu_context_t, fpustatus.f[4]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F5_OFF (REGBYTES * 5) /* offsetof(fpu_context_t, fpustatus.f[5]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F6_OFF (REGBYTES * 6) /* offsetof(fpu_context_t, fpustatus.f[6]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F7_OFF (REGBYTES * 7) /* offsetof(fpu_context_t, fpustatus.f[7]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F8_OFF (REGBYTES * 8) /* offsetof(fpu_context_t, fpustatus.f[8]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F9_OFF (REGBYTES * 9) /* offsetof(fpu_context_t, fpustatus.f[9]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F10_OFF (REGBYTES * 10) /* offsetof(fpu_context_t, fpustatus.f[10]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F11_OFF (REGBYTES * 11) /* offsetof(fpu_context_t, fpustatus.f[11]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F12_OFF (REGBYTES * 12) /* offsetof(fpu_context_t, fpustatus.f[12]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F13_OFF (REGBYTES * 13) /* offsetof(fpu_context_t, fpustatus.f[13]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F14_OFF (REGBYTES * 14) /* offsetof(fpu_context_t, fpustatus.f[14]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F15_OFF (REGBYTES * 15) /* offsetof(fpu_context_t, fpustatus.f[15]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F16_OFF (REGBYTES * 16) /* offsetof(fpu_context_t, fpustatus.f[16]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F17_OFF (REGBYTES * 17) /* offsetof(fpu_context_t, fpustatus.f[17]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F18_OFF (REGBYTES * 18) /* offsetof(fpu_context_t, fpustatus.f[18]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F19_OFF (REGBYTES * 19) /* offsetof(fpu_context_t, fpustatus.f[19]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F20_OFF (REGBYTES * 20) /* offsetof(fpu_context_t, fpustatus.f[20]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F21_OFF (REGBYTES * 21) /* offsetof(fpu_context_t, fpustatus.f[21]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F22_OFF (REGBYTES * 22) /* offsetof(fpu_context_t, fpustatus.f[22]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F23_OFF (REGBYTES * 23) /* offsetof(fpu_context_t, fpustatus.f[23]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F24_OFF (REGBYTES * 24) /* offsetof(fpu_context_t, fpustatus.f[24]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F25_OFF (REGBYTES * 25) /* offsetof(fpu_context_t, fpustatus.f[25]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F26_OFF (REGBYTES * 26) /* offsetof(fpu_context_t, fpustatus.f[26]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F27_OFF (REGBYTES * 27) /* offsetof(fpu_context_t, fpustatus.f[27]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F28_OFF (REGBYTES * 28) /* offsetof(fpu_context_t, fpustatus.f[28]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F29_OFF (REGBYTES * 29) /* offsetof(fpu_context_t, fpustatus.f[29]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F30_OFF (REGBYTES * 30) /* offsetof(fpu_context_t, fpustatus.f[30]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#define FPU_CTX_F31_OFF (REGBYTES * 31) /* offsetof(fpu_context_t, fpustatus.f[31]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
#endif /* ARCH_RISCV_FPU */
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
#ifdef ARCH_RISCV_VECTOR
|
||||||
|
#include "rvv_context.h"
|
||||||
|
#else /* !ARCH_RISCV_VECTOR */
|
||||||
|
#define CTX_VECTOR_REG_NR 0
|
||||||
|
#endif /* ARCH_RISCV_VECTOR */
|
||||||
|
|
||||||
|
#endif /* __EXT_CONTEXT_H__ */
|
|
@ -9,103 +9,81 @@
|
||||||
* 2018/12/27 Jesven Add SMP schedule
|
* 2018/12/27 Jesven Add SMP schedule
|
||||||
* 2021/02/02 lizhirui Add userspace support
|
* 2021/02/02 lizhirui Add userspace support
|
||||||
* 2021/12/24 JasonHu Add user setting save/restore
|
* 2021/12/24 JasonHu Add user setting save/restore
|
||||||
|
* 2022/10/22 Shell Support kernel mode RVV;
|
||||||
|
* Rewrite trap handling routine
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cpuport.h"
|
#include "cpuport.h"
|
||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
#include "stackframe.h"
|
#include "stackframe.h"
|
||||||
|
|
||||||
.section .text.entry
|
.align 2
|
||||||
.align 2
|
.global trap_entry
|
||||||
.global trap_entry
|
.global debug_check_sp
|
||||||
.extern __stack_cpu0
|
|
||||||
.extern get_current_thread_kernel_stack_top
|
|
||||||
trap_entry:
|
trap_entry:
|
||||||
//backup sp
|
// distingush exception from kernel or user
|
||||||
csrrw sp, sscratch, sp
|
csrrw sp, sscratch, sp
|
||||||
//load interrupt stack
|
bnez sp, _save_context
|
||||||
la sp, __stack_cpu0
|
|
||||||
//backup context
|
// BE REALLY careful with sscratch,
|
||||||
|
// if it's wrong, we could looping here forever
|
||||||
|
// or accessing random memory and seeing things totally
|
||||||
|
// messy after a long time and don't even know why
|
||||||
|
_from_kernel:
|
||||||
|
csrr sp, sscratch
|
||||||
|
j _save_context
|
||||||
|
|
||||||
|
_save_context:
|
||||||
SAVE_ALL
|
SAVE_ALL
|
||||||
|
// clear sscratch to say 'now in kernel mode'
|
||||||
|
csrw sscratch, zero
|
||||||
|
|
||||||
RESTORE_SYS_GP
|
RESTORE_SYS_GP
|
||||||
|
|
||||||
|
// now we are ready to enter interrupt / excepiton handler
|
||||||
|
_distinguish_syscall:
|
||||||
|
csrr t0, scause
|
||||||
#ifdef RT_USING_SMART
|
#ifdef RT_USING_SMART
|
||||||
//check syscall
|
// TODO swap 8 with config macro name
|
||||||
csrr t0, scause
|
li t1, 8
|
||||||
li t1, 8//environment call from u-mode
|
beq t0, t1, syscall_entry
|
||||||
beq t0, t1, syscall_entry
|
// syscall never return here
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
csrr a0, scause
|
_handle_interrupt_and_exception:
|
||||||
csrrc a1, stval, zero
|
mv a0, t0
|
||||||
csrr a2, sepc
|
csrrc a1, stval, zero
|
||||||
mv a3, sp
|
csrr a2, sepc
|
||||||
|
// sp as exception frame pointer
|
||||||
|
mv a3, sp
|
||||||
|
call handle_trap
|
||||||
|
|
||||||
/* scause, stval, sepc, sp */
|
_interrupt_exit:
|
||||||
call handle_trap
|
la s0, rt_thread_switch_interrupt_flag
|
||||||
|
lw s2, 0(s0)
|
||||||
|
beqz s2, _resume_execution
|
||||||
|
sw zero, 0(s0)
|
||||||
|
|
||||||
/* need to switch new thread */
|
_context_switch:
|
||||||
la s0, rt_thread_switch_interrupt_flag
|
la t0, rt_interrupt_from_thread
|
||||||
lw s2, 0(s0)
|
LOAD a0, 0(t0)
|
||||||
beqz s2, spurious_interrupt
|
la t0, rt_interrupt_to_thread
|
||||||
sw zero, 0(s0)
|
LOAD a1, 0(t0)
|
||||||
|
csrr t0, sstatus
|
||||||
.global rt_hw_context_switch_interrupt_do
|
andi t0, t0, ~SSTATUS_SPIE
|
||||||
rt_hw_context_switch_interrupt_do:
|
csrw sstatus, t0
|
||||||
|
jal rt_hw_context_switch
|
||||||
|
|
||||||
|
_resume_execution:
|
||||||
#ifdef RT_USING_SMART
|
#ifdef RT_USING_SMART
|
||||||
//swap to thread kernel stack
|
LOAD t0, FRAME_OFF_SSTATUS(sp)
|
||||||
csrr t0, sstatus
|
andi t0, t0, SSTATUS_SPP
|
||||||
andi t0, t0, 0x100
|
beqz t0, arch_ret_to_user
|
||||||
beqz t0, __restore_sp_from_tcb_interrupt
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__restore_sp_from_sscratch_interrupt:
|
_resume_kernel:
|
||||||
csrr t0, sscratch
|
|
||||||
j __move_stack_context_interrupt
|
|
||||||
|
|
||||||
#ifdef RT_USING_SMART
|
|
||||||
__restore_sp_from_tcb_interrupt:
|
|
||||||
la s0, rt_interrupt_from_thread
|
|
||||||
LOAD a0, 0(s0)
|
|
||||||
jal rt_thread_sp_to_thread
|
|
||||||
jal get_thread_kernel_stack_top
|
|
||||||
mv t0, a0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
__move_stack_context_interrupt:
|
|
||||||
mv t1, sp//src
|
|
||||||
mv sp, t0//switch stack
|
|
||||||
addi sp, sp, -CTX_REG_NR * REGBYTES
|
|
||||||
//copy context
|
|
||||||
li s0, CTX_REG_NR//cnt
|
|
||||||
mv t2, sp//dst
|
|
||||||
|
|
||||||
copy_context_loop_interrupt:
|
|
||||||
LOAD t0, 0(t1)
|
|
||||||
STORE t0, 0(t2)
|
|
||||||
addi s0, s0, -1
|
|
||||||
addi t1, t1, 8
|
|
||||||
addi t2, t2, 8
|
|
||||||
bnez s0, copy_context_loop_interrupt
|
|
||||||
|
|
||||||
la s0, rt_interrupt_from_thread
|
|
||||||
LOAD s1, 0(s0)
|
|
||||||
STORE sp, 0(s1)
|
|
||||||
|
|
||||||
la s0, rt_interrupt_to_thread
|
|
||||||
LOAD s1, 0(s0)
|
|
||||||
LOAD sp, 0(s1)
|
|
||||||
|
|
||||||
#ifdef RT_USING_SMART
|
|
||||||
mv a0, s1
|
|
||||||
jal rt_thread_sp_to_thread
|
|
||||||
jal lwp_aspace_switch
|
|
||||||
#endif
|
|
||||||
|
|
||||||
spurious_interrupt:
|
|
||||||
RESTORE_ALL
|
RESTORE_ALL
|
||||||
|
csrw sscratch, zero
|
||||||
sret
|
sret
|
||||||
|
|
||||||
.global rt_hw_interrupt_enable
|
.global rt_hw_interrupt_enable
|
||||||
|
|
|
@ -7,13 +7,22 @@
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2021-01-30 lizhirui first version
|
* 2021-01-30 lizhirui first version
|
||||||
* 2021-11-18 JasonHu add fpu member
|
* 2021-11-18 JasonHu add fpu member
|
||||||
|
* 2022-10-22 Shell Support kernel mode RVV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __STACK_H__
|
#ifndef __STACK_H__
|
||||||
#define __STACK_H__
|
#define __STACK_H__
|
||||||
|
|
||||||
|
#include "stackframe.h"
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
typedef struct rt_hw_switch_frame
|
||||||
|
{
|
||||||
|
uint64_t regs[RT_HW_SWITCH_CONTEXT_SIZE];
|
||||||
|
} *rt_hw_switch_frame_t;
|
||||||
|
|
||||||
|
|
||||||
struct rt_hw_stack_frame
|
struct rt_hw_stack_frame
|
||||||
{
|
{
|
||||||
rt_ubase_t epc; /* epc - epc - program counter */
|
rt_ubase_t epc; /* epc - epc - program counter */
|
||||||
|
@ -49,9 +58,13 @@ struct rt_hw_stack_frame
|
||||||
rt_ubase_t t5; /* x30 - t5 - temporary register 5 */
|
rt_ubase_t t5; /* x30 - t5 - temporary register 5 */
|
||||||
rt_ubase_t t6; /* x31 - t6 - temporary register 6 */
|
rt_ubase_t t6; /* x31 - t6 - temporary register 6 */
|
||||||
rt_ubase_t user_sp_exc_stack; /* sscratch - user mode sp/exception stack */
|
rt_ubase_t user_sp_exc_stack; /* sscratch - user mode sp/exception stack */
|
||||||
|
rt_ubase_t __padding; /* align to 16bytes */
|
||||||
#ifdef ARCH_RISCV_FPU
|
#ifdef ARCH_RISCV_FPU
|
||||||
rt_ubase_t f[CTX_FPU_REG_NR]; /* f0~f31 */
|
rt_ubase_t f[CTX_FPU_REG_NR]; /* f0~f31 */
|
||||||
#endif
|
#endif /* ARCH_RISCV_FPU */
|
||||||
|
#ifdef ARCH_RISCV_VECTOR
|
||||||
|
rt_ubase_t v[CTX_VECTOR_REG_NR];
|
||||||
|
#endif /* ARCH_RISCV_VECTOR */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
|
@ -8,61 +8,59 @@
|
||||||
* 2021-02-02 lizhirui first version
|
* 2021-02-02 lizhirui first version
|
||||||
* 2021-02-11 lizhirui fixed gp save/store bug
|
* 2021-02-11 lizhirui fixed gp save/store bug
|
||||||
* 2021-11-18 JasonHu add fpu registers save/restore
|
* 2021-11-18 JasonHu add fpu registers save/restore
|
||||||
|
* 2022-10-22 Shell Support kernel mode RVV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __STACKFRAME_H__
|
#ifndef __STACKFRAME_H__
|
||||||
#define __STACKFRAME_H__
|
#define __STACKFRAME_H__
|
||||||
|
|
||||||
|
#include <rtconfig.h>
|
||||||
|
#include "encoding.h"
|
||||||
|
#include "ext_context.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
|
||||||
|
|
||||||
|
/* 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 BYTES(idx) ((idx) * REGBYTES)
|
||||||
#define FRAME_OFF_SSTATUS BYTES(2)
|
#define FRAME_OFF_SSTATUS BYTES(2)
|
||||||
#define FRAME_OFF_SP BYTES(32)
|
#define FRAME_OFF_SP BYTES(32)
|
||||||
#define FRAME_OFF_GP BYTES(3)
|
#define FRAME_OFF_GP BYTES(3)
|
||||||
|
|
||||||
#include "cpuport.h"
|
/* switch frame */
|
||||||
#include "encoding.h"
|
#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 ARCH_RISCV_FPU
|
#ifdef __ASSEMBLY__
|
||||||
#define FPU_CTX_F0_OFF 0 /* offsetof(fpu_context_t, fpustatus.f[0]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F1_OFF 8 /* offsetof(fpu_context_t, fpustatus.f[1]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F2_OFF 16 /* offsetof(fpu_context_t, fpustatus.f[2]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F3_OFF 24 /* offsetof(fpu_context_t, fpustatus.f[3]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F4_OFF 32 /* offsetof(fpu_context_t, fpustatus.f[4]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F5_OFF 40 /* offsetof(fpu_context_t, fpustatus.f[5]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F6_OFF 48 /* offsetof(fpu_context_t, fpustatus.f[6]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F7_OFF 56 /* offsetof(fpu_context_t, fpustatus.f[7]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F8_OFF 64 /* offsetof(fpu_context_t, fpustatus.f[8]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F9_OFF 72 /* offsetof(fpu_context_t, fpustatus.f[9]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F10_OFF 80 /* offsetof(fpu_context_t, fpustatus.f[10]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F11_OFF 88 /* offsetof(fpu_context_t, fpustatus.f[11]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F12_OFF 96 /* offsetof(fpu_context_t, fpustatus.f[12]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F13_OFF 104 /* offsetof(fpu_context_t, fpustatus.f[13]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F14_OFF 112 /* offsetof(fpu_context_t, fpustatus.f[14]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F15_OFF 120 /* offsetof(fpu_context_t, fpustatus.f[15]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F16_OFF 128 /* offsetof(fpu_context_t, fpustatus.f[16]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F17_OFF 136 /* offsetof(fpu_context_t, fpustatus.f[17]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F18_OFF 144 /* offsetof(fpu_context_t, fpustatus.f[18]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F19_OFF 152 /* offsetof(fpu_context_t, fpustatus.f[19]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F20_OFF 160 /* offsetof(fpu_context_t, fpustatus.f[20]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F21_OFF 168 /* offsetof(fpu_context_t, fpustatus.f[21]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F22_OFF 176 /* offsetof(fpu_context_t, fpustatus.f[22]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F23_OFF 184 /* offsetof(fpu_context_t, fpustatus.f[23]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F24_OFF 192 /* offsetof(fpu_context_t, fpustatus.f[24]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F25_OFF 200 /* offsetof(fpu_context_t, fpustatus.f[25]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F26_OFF 208 /* offsetof(fpu_context_t, fpustatus.f[26]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F27_OFF 216 /* offsetof(fpu_context_t, fpustatus.f[27]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F28_OFF 224 /* offsetof(fpu_context_t, fpustatus.f[28]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F29_OFF 232 /* offsetof(fpu_context_t, fpustatus.f[29]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F30_OFF 240 /* offsetof(fpu_context_t, fpustatus.f[30]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#define FPU_CTX_F31_OFF 248 /* offsetof(fpu_context_t, fpustatus.f[31]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
|
||||||
#endif /* ARCH_RISCV_FPU */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The register `tp` always save/restore when context switch,
|
|
||||||
* we call `lwp_user_setting_save` when syscall enter,
|
|
||||||
* call `lwp_user_setting_restore` when syscall exit
|
|
||||||
* and modify context stack after `lwp_user_setting_restore` called
|
|
||||||
* so that the `tp` can be the correct thread area value.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.macro SAVE_ALL
|
.macro SAVE_ALL
|
||||||
|
|
||||||
|
@ -70,16 +68,20 @@
|
||||||
/* reserve float registers */
|
/* reserve float registers */
|
||||||
addi sp, sp, -CTX_FPU_REG_NR * REGBYTES
|
addi sp, sp, -CTX_FPU_REG_NR * REGBYTES
|
||||||
#endif /* ARCH_RISCV_FPU */
|
#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 */
|
/* save general registers */
|
||||||
addi sp, sp, -CTX_GENERAL_REG_NR * REGBYTES
|
addi sp, sp, -CTX_GENERAL_REG_NR * REGBYTES
|
||||||
STORE x1, 1 * REGBYTES(sp)
|
STORE x1, 1 * REGBYTES(sp)
|
||||||
|
|
||||||
csrr x1, sstatus
|
csrr x1, sstatus
|
||||||
STORE x1, 2 * REGBYTES(sp)
|
STORE x1, FRAME_OFF_SSTATUS(sp)
|
||||||
|
|
||||||
csrr x1, sepc
|
csrr x1, sepc
|
||||||
STORE x1, 0 * REGBYTES(sp)
|
STORE x1, 0 * REGBYTES(sp)
|
||||||
|
|
||||||
STORE x3, 3 * REGBYTES(sp)
|
STORE x3, 3 * REGBYTES(sp)
|
||||||
STORE x4, 4 * REGBYTES(sp) /* save tp */
|
STORE x4, 4 * REGBYTES(sp) /* save tp */
|
||||||
|
@ -120,38 +122,38 @@
|
||||||
|
|
||||||
li t0, SSTATUS_FS
|
li t0, SSTATUS_FS
|
||||||
csrs sstatus, t0
|
csrs sstatus, t0
|
||||||
fsd f0, FPU_CTX_F0_OFF(t1)
|
FSTORE f0, FPU_CTX_F0_OFF(t1)
|
||||||
fsd f1, FPU_CTX_F1_OFF(t1)
|
FSTORE f1, FPU_CTX_F1_OFF(t1)
|
||||||
fsd f2, FPU_CTX_F2_OFF(t1)
|
FSTORE f2, FPU_CTX_F2_OFF(t1)
|
||||||
fsd f3, FPU_CTX_F3_OFF(t1)
|
FSTORE f3, FPU_CTX_F3_OFF(t1)
|
||||||
fsd f4, FPU_CTX_F4_OFF(t1)
|
FSTORE f4, FPU_CTX_F4_OFF(t1)
|
||||||
fsd f5, FPU_CTX_F5_OFF(t1)
|
FSTORE f5, FPU_CTX_F5_OFF(t1)
|
||||||
fsd f6, FPU_CTX_F6_OFF(t1)
|
FSTORE f6, FPU_CTX_F6_OFF(t1)
|
||||||
fsd f7, FPU_CTX_F7_OFF(t1)
|
FSTORE f7, FPU_CTX_F7_OFF(t1)
|
||||||
fsd f8, FPU_CTX_F8_OFF(t1)
|
FSTORE f8, FPU_CTX_F8_OFF(t1)
|
||||||
fsd f9, FPU_CTX_F9_OFF(t1)
|
FSTORE f9, FPU_CTX_F9_OFF(t1)
|
||||||
fsd f10, FPU_CTX_F10_OFF(t1)
|
FSTORE f10, FPU_CTX_F10_OFF(t1)
|
||||||
fsd f11, FPU_CTX_F11_OFF(t1)
|
FSTORE f11, FPU_CTX_F11_OFF(t1)
|
||||||
fsd f12, FPU_CTX_F12_OFF(t1)
|
FSTORE f12, FPU_CTX_F12_OFF(t1)
|
||||||
fsd f13, FPU_CTX_F13_OFF(t1)
|
FSTORE f13, FPU_CTX_F13_OFF(t1)
|
||||||
fsd f14, FPU_CTX_F14_OFF(t1)
|
FSTORE f14, FPU_CTX_F14_OFF(t1)
|
||||||
fsd f15, FPU_CTX_F15_OFF(t1)
|
FSTORE f15, FPU_CTX_F15_OFF(t1)
|
||||||
fsd f16, FPU_CTX_F16_OFF(t1)
|
FSTORE f16, FPU_CTX_F16_OFF(t1)
|
||||||
fsd f17, FPU_CTX_F17_OFF(t1)
|
FSTORE f17, FPU_CTX_F17_OFF(t1)
|
||||||
fsd f18, FPU_CTX_F18_OFF(t1)
|
FSTORE f18, FPU_CTX_F18_OFF(t1)
|
||||||
fsd f19, FPU_CTX_F19_OFF(t1)
|
FSTORE f19, FPU_CTX_F19_OFF(t1)
|
||||||
fsd f20, FPU_CTX_F20_OFF(t1)
|
FSTORE f20, FPU_CTX_F20_OFF(t1)
|
||||||
fsd f21, FPU_CTX_F21_OFF(t1)
|
FSTORE f21, FPU_CTX_F21_OFF(t1)
|
||||||
fsd f22, FPU_CTX_F22_OFF(t1)
|
FSTORE f22, FPU_CTX_F22_OFF(t1)
|
||||||
fsd f23, FPU_CTX_F23_OFF(t1)
|
FSTORE f23, FPU_CTX_F23_OFF(t1)
|
||||||
fsd f24, FPU_CTX_F24_OFF(t1)
|
FSTORE f24, FPU_CTX_F24_OFF(t1)
|
||||||
fsd f25, FPU_CTX_F25_OFF(t1)
|
FSTORE f25, FPU_CTX_F25_OFF(t1)
|
||||||
fsd f26, FPU_CTX_F26_OFF(t1)
|
FSTORE f26, FPU_CTX_F26_OFF(t1)
|
||||||
fsd f27, FPU_CTX_F27_OFF(t1)
|
FSTORE f27, FPU_CTX_F27_OFF(t1)
|
||||||
fsd f28, FPU_CTX_F28_OFF(t1)
|
FSTORE f28, FPU_CTX_F28_OFF(t1)
|
||||||
fsd f29, FPU_CTX_F29_OFF(t1)
|
FSTORE f29, FPU_CTX_F29_OFF(t1)
|
||||||
fsd f30, FPU_CTX_F30_OFF(t1)
|
FSTORE f30, FPU_CTX_F30_OFF(t1)
|
||||||
fsd f31, FPU_CTX_F31_OFF(t1)
|
FSTORE f31, FPU_CTX_F31_OFF(t1)
|
||||||
|
|
||||||
/* clr FS domain */
|
/* clr FS domain */
|
||||||
csrc sstatus, t0
|
csrc sstatus, t0
|
||||||
|
@ -162,49 +164,77 @@
|
||||||
|
|
||||||
#endif /* ARCH_RISCV_FPU */
|
#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
|
.endm
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Restore All General Registers, for interrupt handling
|
||||||
|
*
|
||||||
|
*/
|
||||||
.macro RESTORE_ALL
|
.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
|
#ifdef ARCH_RISCV_FPU
|
||||||
/* restore float register */
|
/* restore float register */
|
||||||
mv t2, sp
|
addi t2, sp, CTX_GENERAL_REG_NR * REGBYTES
|
||||||
addi t2, t2, CTX_GENERAL_REG_NR * REGBYTES /* skip all normal reg */
|
|
||||||
|
|
||||||
li t0, SSTATUS_FS
|
li t0, SSTATUS_FS
|
||||||
csrs sstatus, t0
|
csrs sstatus, t0
|
||||||
fld f0, FPU_CTX_F0_OFF(t2)
|
FLOAD f0, FPU_CTX_F0_OFF(t2)
|
||||||
fld f1, FPU_CTX_F1_OFF(t2)
|
FLOAD f1, FPU_CTX_F1_OFF(t2)
|
||||||
fld f2, FPU_CTX_F2_OFF(t2)
|
FLOAD f2, FPU_CTX_F2_OFF(t2)
|
||||||
fld f3, FPU_CTX_F3_OFF(t2)
|
FLOAD f3, FPU_CTX_F3_OFF(t2)
|
||||||
fld f4, FPU_CTX_F4_OFF(t2)
|
FLOAD f4, FPU_CTX_F4_OFF(t2)
|
||||||
fld f5, FPU_CTX_F5_OFF(t2)
|
FLOAD f5, FPU_CTX_F5_OFF(t2)
|
||||||
fld f6, FPU_CTX_F6_OFF(t2)
|
FLOAD f6, FPU_CTX_F6_OFF(t2)
|
||||||
fld f7, FPU_CTX_F7_OFF(t2)
|
FLOAD f7, FPU_CTX_F7_OFF(t2)
|
||||||
fld f8, FPU_CTX_F8_OFF(t2)
|
FLOAD f8, FPU_CTX_F8_OFF(t2)
|
||||||
fld f9, FPU_CTX_F9_OFF(t2)
|
FLOAD f9, FPU_CTX_F9_OFF(t2)
|
||||||
fld f10, FPU_CTX_F10_OFF(t2)
|
FLOAD f10, FPU_CTX_F10_OFF(t2)
|
||||||
fld f11, FPU_CTX_F11_OFF(t2)
|
FLOAD f11, FPU_CTX_F11_OFF(t2)
|
||||||
fld f12, FPU_CTX_F12_OFF(t2)
|
FLOAD f12, FPU_CTX_F12_OFF(t2)
|
||||||
fld f13, FPU_CTX_F13_OFF(t2)
|
FLOAD f13, FPU_CTX_F13_OFF(t2)
|
||||||
fld f14, FPU_CTX_F14_OFF(t2)
|
FLOAD f14, FPU_CTX_F14_OFF(t2)
|
||||||
fld f15, FPU_CTX_F15_OFF(t2)
|
FLOAD f15, FPU_CTX_F15_OFF(t2)
|
||||||
fld f16, FPU_CTX_F16_OFF(t2)
|
FLOAD f16, FPU_CTX_F16_OFF(t2)
|
||||||
fld f17, FPU_CTX_F17_OFF(t2)
|
FLOAD f17, FPU_CTX_F17_OFF(t2)
|
||||||
fld f18, FPU_CTX_F18_OFF(t2)
|
FLOAD f18, FPU_CTX_F18_OFF(t2)
|
||||||
fld f19, FPU_CTX_F19_OFF(t2)
|
FLOAD f19, FPU_CTX_F19_OFF(t2)
|
||||||
fld f20, FPU_CTX_F20_OFF(t2)
|
FLOAD f20, FPU_CTX_F20_OFF(t2)
|
||||||
fld f21, FPU_CTX_F21_OFF(t2)
|
FLOAD f21, FPU_CTX_F21_OFF(t2)
|
||||||
fld f22, FPU_CTX_F22_OFF(t2)
|
FLOAD f22, FPU_CTX_F22_OFF(t2)
|
||||||
fld f23, FPU_CTX_F23_OFF(t2)
|
FLOAD f23, FPU_CTX_F23_OFF(t2)
|
||||||
fld f24, FPU_CTX_F24_OFF(t2)
|
FLOAD f24, FPU_CTX_F24_OFF(t2)
|
||||||
fld f25, FPU_CTX_F25_OFF(t2)
|
FLOAD f25, FPU_CTX_F25_OFF(t2)
|
||||||
fld f26, FPU_CTX_F26_OFF(t2)
|
FLOAD f26, FPU_CTX_F26_OFF(t2)
|
||||||
fld f27, FPU_CTX_F27_OFF(t2)
|
FLOAD f27, FPU_CTX_F27_OFF(t2)
|
||||||
fld f28, FPU_CTX_F28_OFF(t2)
|
FLOAD f28, FPU_CTX_F28_OFF(t2)
|
||||||
fld f29, FPU_CTX_F29_OFF(t2)
|
FLOAD f29, FPU_CTX_F29_OFF(t2)
|
||||||
fld f30, FPU_CTX_F30_OFF(t2)
|
FLOAD f30, FPU_CTX_F30_OFF(t2)
|
||||||
fld f31, FPU_CTX_F31_OFF(t2)
|
FLOAD f31, FPU_CTX_F31_OFF(t2)
|
||||||
|
|
||||||
/* clr FS domain */
|
/* clr FS domain */
|
||||||
csrc sstatus, t0
|
csrc sstatus, t0
|
||||||
|
@ -216,9 +246,11 @@
|
||||||
#endif /* ARCH_RISCV_FPU */
|
#endif /* ARCH_RISCV_FPU */
|
||||||
|
|
||||||
/* restore general register */
|
/* restore general register */
|
||||||
|
addi t0, sp, CTX_REG_NR * REGBYTES
|
||||||
|
csrw sscratch, t0
|
||||||
|
|
||||||
/* resw ra to sepc */
|
/* resw ra to sepc */
|
||||||
LOAD x1, 0 * REGBYTES(sp)
|
LOAD x1, 0 * REGBYTES(sp)
|
||||||
csrw sepc, x1
|
csrw sepc, x1
|
||||||
|
|
||||||
LOAD x1, 2 * REGBYTES(sp)
|
LOAD x1, 2 * REGBYTES(sp)
|
||||||
|
@ -275,4 +307,6 @@
|
||||||
csrci sstatus, 2
|
csrci sstatus, 2
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
#endif
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
#endif /* __STACKFRAME_H__ */
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
#include <mm_aspace.h>
|
#include <mm_aspace.h>
|
||||||
#include "riscv_mmu.h"
|
#include "riscv_mmu.h"
|
||||||
|
#include "stack.h"
|
||||||
|
|
||||||
#define WORD sizeof(rt_base_t)
|
#define WORD sizeof(rt_base_t)
|
||||||
#define ARCH_CONTEXT_FETCH(pctx, id) (*(((unsigned long *)pctx) + (id)))
|
#define ARCH_CONTEXT_FETCH(pctx, id) (*(((unsigned long *)pctx) + (id)))
|
||||||
|
@ -117,8 +118,9 @@ rt_err_t rt_hw_backtrace_frame_get(rt_thread_t thread, struct rt_hw_backtrace_fr
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
frame->pc = ARCH_CONTEXT_FETCH(thread->sp, 13);
|
rt_hw_switch_frame_t sframe = thread->sp;
|
||||||
frame->fp = ARCH_CONTEXT_FETCH(thread->sp, 12);
|
frame->pc = sframe->regs[RT_HW_SWITCH_CONTEXT_RA];
|
||||||
|
frame->fp = sframe->regs[RT_HW_SWITCH_CONTEXT_S0];;
|
||||||
rc = RT_EOK;
|
rc = RT_EOK;
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
|
@ -8,64 +8,64 @@
|
||||||
* 2018/10/28 Bernard The unify RISC-V porting implementation
|
* 2018/10/28 Bernard The unify RISC-V porting implementation
|
||||||
* 2018/12/27 Jesven Add SMP support
|
* 2018/12/27 Jesven Add SMP support
|
||||||
* 2021/02/02 lizhirui Add userspace support
|
* 2021/02/02 lizhirui Add userspace support
|
||||||
* 2022/10/22 WangXiaoyao Support User mode RVV;
|
* 2022/10/22 Shell Support User mode RVV;
|
||||||
* Trimming process switch context
|
* Trimming process switch context
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cpuport.h"
|
#include "cpuport.h"
|
||||||
#include "stackframe.h"
|
#include "stackframe.h"
|
||||||
|
#define _REG_IDX(name) RT_HW_SWITCH_CONTEXT_##name
|
||||||
|
#define REG_IDX(name) _REG_IDX(name)
|
||||||
|
|
||||||
.macro PUSH_REG reg
|
.macro SAVE_REG reg, index
|
||||||
addi sp, sp, -REGBYTES
|
STORE \reg, \index*REGBYTES(sp)
|
||||||
STORE \reg, (sp)
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro POP_REG reg
|
.macro LOAD_REG reg, index
|
||||||
LOAD \reg, (sp)
|
LOAD \reg, \index*REGBYTES(sp)
|
||||||
addi sp, sp, REGBYTES
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro RESERVE_CONTEXT
|
.macro RESERVE_CONTEXT
|
||||||
PUSH_REG tp
|
addi sp, sp, -(RT_HW_SWITCH_CONTEXT_SIZE * REGBYTES)
|
||||||
PUSH_REG ra
|
SAVE_REG tp, REG_IDX(TP)
|
||||||
PUSH_REG s0
|
SAVE_REG ra, REG_IDX(RA)
|
||||||
PUSH_REG s1
|
SAVE_REG s0, REG_IDX(S0)
|
||||||
PUSH_REG s2
|
SAVE_REG s1, REG_IDX(S1)
|
||||||
PUSH_REG s3
|
SAVE_REG s2, REG_IDX(S2)
|
||||||
PUSH_REG s4
|
SAVE_REG s3, REG_IDX(S3)
|
||||||
PUSH_REG s5
|
SAVE_REG s4, REG_IDX(S4)
|
||||||
PUSH_REG s6
|
SAVE_REG s5, REG_IDX(S5)
|
||||||
PUSH_REG s7
|
SAVE_REG s6, REG_IDX(S6)
|
||||||
PUSH_REG s8
|
SAVE_REG s7, REG_IDX(S7)
|
||||||
PUSH_REG s9
|
SAVE_REG s8, REG_IDX(S8)
|
||||||
PUSH_REG s10
|
SAVE_REG s9, REG_IDX(S9)
|
||||||
PUSH_REG s11
|
SAVE_REG s10, REG_IDX(S10)
|
||||||
csrr s11, sstatus
|
SAVE_REG s11, REG_IDX(S11)
|
||||||
li s10, (SSTATUS_SPP)
|
csrr s11, sstatus
|
||||||
or s11, s11, s10
|
li s10, (SSTATUS_SPP)
|
||||||
PUSH_REG s11
|
or s11, s11, s10
|
||||||
addi sp, sp, -REGBYTES
|
SAVE_REG s11, REG_IDX(SSTATUS)
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro RESTORE_CONTEXT
|
.macro RESTORE_CONTEXT
|
||||||
addi sp, sp, REGBYTES
|
LOAD_REG s11, REG_IDX(SSTATUS)
|
||||||
POP_REG s11
|
csrw sstatus, s11
|
||||||
csrw sstatus, s11
|
LOAD_REG s11, REG_IDX(S11)
|
||||||
POP_REG s11
|
LOAD_REG s10, REG_IDX(S10)
|
||||||
POP_REG s10
|
LOAD_REG s9, REG_IDX(S9)
|
||||||
POP_REG s9
|
LOAD_REG s8, REG_IDX(S8)
|
||||||
POP_REG s8
|
LOAD_REG s7, REG_IDX(S7)
|
||||||
POP_REG s7
|
LOAD_REG s6, REG_IDX(S6)
|
||||||
POP_REG s6
|
LOAD_REG s5, REG_IDX(S5)
|
||||||
POP_REG s5
|
LOAD_REG s4, REG_IDX(S4)
|
||||||
POP_REG s4
|
LOAD_REG s3, REG_IDX(S3)
|
||||||
POP_REG s3
|
LOAD_REG s2, REG_IDX(S2)
|
||||||
POP_REG s2
|
LOAD_REG s1, REG_IDX(S1)
|
||||||
POP_REG s1
|
LOAD_REG s0, REG_IDX(S0)
|
||||||
POP_REG s0
|
LOAD_REG ra, REG_IDX(RA)
|
||||||
POP_REG ra
|
LOAD_REG tp, REG_IDX(TP)
|
||||||
POP_REG tp
|
addi sp, sp, RT_HW_SWITCH_CONTEXT_SIZE * REGBYTES
|
||||||
csrw sepc, ra
|
csrw sepc, ra
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -113,33 +113,3 @@ rt_hw_context_switch:
|
||||||
|
|
||||||
RESTORE_CONTEXT
|
RESTORE_CONTEXT
|
||||||
sret
|
sret
|
||||||
|
|
||||||
#ifdef ENABLE_VECTOR
|
|
||||||
/**
|
|
||||||
* @param a0 pointer to frame bottom
|
|
||||||
*/
|
|
||||||
.global rt_hw_vector_ctx_save
|
|
||||||
rt_hw_vector_ctx_save:
|
|
||||||
SAVE_VECTOR a0
|
|
||||||
ret
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param a0 pointer to frame bottom
|
|
||||||
*/
|
|
||||||
.global rt_hw_vector_ctx_restore
|
|
||||||
rt_hw_vector_ctx_restore:
|
|
||||||
RESTORE_VECTOR a0
|
|
||||||
ret
|
|
||||||
|
|
||||||
.global rt_hw_disable_vector
|
|
||||||
rt_hw_disable_vector:
|
|
||||||
li t0, SSTATUS_VS
|
|
||||||
csrc sstatus, t0
|
|
||||||
ret
|
|
||||||
|
|
||||||
.global rt_hw_enable_vector
|
|
||||||
rt_hw_enable_vector:
|
|
||||||
li t0, SSTATUS_VS
|
|
||||||
csrs sstatus, t0
|
|
||||||
ret
|
|
||||||
#endif /* ENABLE_VECTOR */
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2018/10/28 Bernard The unify RISC-V porting code.
|
* 2018/10/28 Bernard The unify RISC-V porting code.
|
||||||
* 2021-02-11 lizhirui add gp support
|
* 2021-02-11 lizhirui add gp support
|
||||||
|
* 2021-11-19 JasonHu add fpu support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rthw.h>
|
#include <rthw.h>
|
||||||
|
@ -17,7 +18,14 @@
|
||||||
#include <sbi.h>
|
#include <sbi.h>
|
||||||
#include <encoding.h>
|
#include <encoding.h>
|
||||||
|
|
||||||
#define K_SSTATUS_DEFAULT (SSTATUS_SPP | SSTATUS_SPIE | SSTATUS_SUM | SSTATUS_FS)
|
#ifdef ARCH_RISCV_FPU
|
||||||
|
#define K_SSTATUS_DEFAULT (SSTATUS_SPP | SSTATUS_SPIE | SSTATUS_SUM | SSTATUS_FS)
|
||||||
|
#else
|
||||||
|
#define K_SSTATUS_DEFAULT (SSTATUS_SPP | SSTATUS_SPIE | SSTATUS_SUM)
|
||||||
|
#endif
|
||||||
|
#ifdef RT_USING_SMART
|
||||||
|
#include <lwp_arch.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief from thread used interrupt context switch
|
* @brief from thread used interrupt context switch
|
||||||
|
@ -37,24 +45,15 @@ volatile rt_ubase_t rt_thread_switch_interrupt_flag = 0;
|
||||||
|
|
||||||
void *_rt_hw_stack_init(rt_ubase_t *sp, rt_ubase_t ra, rt_ubase_t sstatus)
|
void *_rt_hw_stack_init(rt_ubase_t *sp, rt_ubase_t ra, rt_ubase_t sstatus)
|
||||||
{
|
{
|
||||||
(*--sp) = 0; /* tp */
|
rt_hw_switch_frame_t frame = (rt_hw_switch_frame_t)
|
||||||
(*--sp) = ra; /* ra */
|
((rt_ubase_t)sp - sizeof(struct rt_hw_switch_frame));
|
||||||
(*--sp) = 0; /* s0(fp) */
|
|
||||||
(*--sp) = 0; /* s1 */
|
|
||||||
(*--sp) = 0; /* s2 */
|
|
||||||
(*--sp) = 0; /* s3 */
|
|
||||||
(*--sp) = 0; /* s4 */
|
|
||||||
(*--sp) = 0; /* s5 */
|
|
||||||
(*--sp) = 0; /* s6 */
|
|
||||||
(*--sp) = 0; /* s7 */
|
|
||||||
(*--sp) = 0; /* s8 */
|
|
||||||
(*--sp) = 0; /* s9 */
|
|
||||||
(*--sp) = 0; /* s10 */
|
|
||||||
(*--sp) = 0; /* s11 */
|
|
||||||
(*--sp) = sstatus; /* sstatus */
|
|
||||||
--sp; /* align to 16bytes */
|
|
||||||
|
|
||||||
return (void *)sp;
|
rt_memset(frame, 0, sizeof(struct rt_hw_switch_frame));
|
||||||
|
|
||||||
|
frame->regs[RT_HW_SWITCH_CONTEXT_RA] = ra;
|
||||||
|
frame->regs[RT_HW_SWITCH_CONTEXT_SSTATUS] = sstatus;
|
||||||
|
|
||||||
|
return (void *)frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rt_hw_cpu_id(void)
|
int rt_hw_cpu_id(void)
|
||||||
|
@ -87,6 +86,7 @@ rt_uint8_t *rt_hw_stack_init(void *tentry,
|
||||||
(*--sp) = (rt_ubase_t)tentry;
|
(*--sp) = (rt_ubase_t)tentry;
|
||||||
(*--sp) = (rt_ubase_t)parameter;
|
(*--sp) = (rt_ubase_t)parameter;
|
||||||
(*--sp) = (rt_ubase_t)texit;
|
(*--sp) = (rt_ubase_t)texit;
|
||||||
|
--sp; /* alignment */
|
||||||
|
|
||||||
/* compatible to RESTORE_CONTEXT */
|
/* compatible to RESTORE_CONTEXT */
|
||||||
extern void _rt_thread_entry(void);
|
extern void _rt_thread_entry(void);
|
||||||
|
|
|
@ -12,44 +12,7 @@
|
||||||
#define CPUPORT_H__
|
#define CPUPORT_H__
|
||||||
|
|
||||||
#include <rtconfig.h>
|
#include <rtconfig.h>
|
||||||
|
#include <opcode.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
|
|
||||||
|
|
||||||
/* 33 general register + 1 padding */
|
|
||||||
#define CTX_GENERAL_REG_NR 34
|
|
||||||
|
|
||||||
#ifdef ENABLE_FPU
|
|
||||||
/* 32 fpu register */
|
|
||||||
#define CTX_FPU_REG_NR 32
|
|
||||||
#else
|
|
||||||
#define CTX_FPU_REG_NR 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_VECTOR
|
|
||||||
|
|
||||||
#if defined(ARCH_VECTOR_VLEN_128)
|
|
||||||
#define CTX_VECTOR_REGS 64
|
|
||||||
#elif defined(ARCH_VECTOR_VLEN_256)
|
|
||||||
#define CTX_VECTOR_REGS 128
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CTX_VECTOR_REG_NR (CTX_VECTOR_REGS + 4)
|
|
||||||
#else
|
|
||||||
#define CTX_VECTOR_REG_NR 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* all context registers */
|
|
||||||
#define CTX_REG_NR (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR + CTX_VECTOR_REG_NR)
|
|
||||||
|
|
||||||
#ifdef RT_USING_SMP
|
#ifdef RT_USING_SMP
|
||||||
typedef union {
|
typedef union {
|
||||||
|
@ -63,21 +26,24 @@ typedef union {
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
#include <rtdef.h>
|
#include <rtdef.h>
|
||||||
|
|
||||||
rt_inline void rt_hw_dsb(void)
|
rt_inline void rt_hw_dsb(void)
|
||||||
{
|
{
|
||||||
asm volatile("fence":::"memory");
|
__asm__ volatile("fence":::"memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_inline void rt_hw_dmb(void)
|
rt_inline void rt_hw_dmb(void)
|
||||||
{
|
{
|
||||||
asm volatile("fence":::"memory");
|
__asm__ volatile("fence":::"memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_inline void rt_hw_isb(void)
|
rt_inline void rt_hw_isb(void)
|
||||||
{
|
{
|
||||||
asm volatile(".long 0x0000100F":::"memory");
|
__asm__ volatile(OPC_FENCE_I:::"memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rt_hw_cpu_id(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,12 +13,11 @@
|
||||||
#include "asm-generic.h"
|
#include "asm-generic.h"
|
||||||
|
|
||||||
START_POINT(_rt_thread_entry)
|
START_POINT(_rt_thread_entry)
|
||||||
LOAD ra, (sp) /* thread exit */
|
LOAD ra, REGBYTES(sp) /* thread exit */
|
||||||
addi sp, sp, REGBYTES
|
addi sp, sp, 2 * REGBYTES
|
||||||
LOAD a0, (sp) /* parameter */
|
LOAD a0, (sp) /* parameter */
|
||||||
addi sp, sp, REGBYTES
|
LOAD t0, REGBYTES(sp) /* tentry */
|
||||||
LOAD t0, (sp) /* tentry */
|
addi sp, sp, 2 * REGBYTES
|
||||||
addi sp, sp, REGBYTES
|
|
||||||
mv s1, ra
|
mv s1, ra
|
||||||
jalr t0
|
jalr t0
|
||||||
jalr s1
|
jalr s1
|
||||||
|
|
|
@ -11,6 +11,15 @@
|
||||||
#ifndef RISCV_CSR_ENCODING_H
|
#ifndef RISCV_CSR_ENCODING_H
|
||||||
#define RISCV_CSR_ENCODING_H
|
#define RISCV_CSR_ENCODING_H
|
||||||
|
|
||||||
|
#include <rtconfig.h>
|
||||||
|
|
||||||
|
#ifdef ARCH_RISCV_VECTOR
|
||||||
|
#include "vector_encoding.h"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define SSTATUS_VS 0 /* fallback */
|
||||||
|
#endif /* ARCH_RISCV_VECTOR */
|
||||||
|
|
||||||
#define MSTATUS_UIE 0x00000001
|
#define MSTATUS_UIE 0x00000001
|
||||||
#define MSTATUS_SIE 0x00000002
|
#define MSTATUS_SIE 0x00000002
|
||||||
#define MSTATUS_HIE 0x00000004
|
#define MSTATUS_HIE 0x00000004
|
||||||
|
@ -23,7 +32,6 @@
|
||||||
#define MSTATUS_HPP 0x00000600
|
#define MSTATUS_HPP 0x00000600
|
||||||
#define MSTATUS_MPP 0x00001800
|
#define MSTATUS_MPP 0x00001800
|
||||||
#define MSTATUS_FS 0x00006000
|
#define MSTATUS_FS 0x00006000
|
||||||
#define MSTATUS_VS 0x00000600
|
|
||||||
#define MSTATUS_XS 0x00018000
|
#define MSTATUS_XS 0x00018000
|
||||||
#define MSTATUS_MPRV 0x00020000
|
#define MSTATUS_MPRV 0x00020000
|
||||||
#define MSTATUS_PUM 0x00040000
|
#define MSTATUS_PUM 0x00040000
|
||||||
|
@ -41,10 +49,6 @@
|
||||||
#define SSTATUS_FS_INITIAL 0x00002000
|
#define SSTATUS_FS_INITIAL 0x00002000
|
||||||
#define SSTATUS_FS_CLEAN 0x00004000
|
#define SSTATUS_FS_CLEAN 0x00004000
|
||||||
#define SSTATUS_FS_DIRTY 0x00006000
|
#define SSTATUS_FS_DIRTY 0x00006000
|
||||||
#define SSTATUS_VS 0x00000600 /* Vector Status */
|
|
||||||
#define SSTATUS_VS_INITIAL 0x00000200
|
|
||||||
#define SSTATUS_VS_CLEAN 0x00000400
|
|
||||||
#define SSTATUS_VS_DIRTY 0x00000600
|
|
||||||
#define SSTATUS_XS 0x00018000
|
#define SSTATUS_XS 0x00018000
|
||||||
#define SSTATUS_SUM 0x00040000
|
#define SSTATUS_SUM 0x00040000
|
||||||
#define SSTATUS32_SD 0x80000000
|
#define SSTATUS32_SD 0x80000000
|
||||||
|
|
|
@ -5,29 +5,29 @@
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2022-10-10 RT-Thread the first version,
|
* 2022-10-10 RT-Thread the first version
|
||||||
* compatible to riscv-v-spec-1.0
|
|
||||||
*/
|
*/
|
||||||
#ifndef __EXT_CONTEXT_H__
|
#ifndef __EXT_CONTEXT_H__
|
||||||
#define __EXT_CONTEXT_H__
|
#define __EXT_CONTEXT_H__
|
||||||
|
|
||||||
|
#include <rtconfig.h>
|
||||||
|
|
||||||
|
#ifdef ARCH_RISCV_FPU
|
||||||
|
/* 32 fpu register */
|
||||||
|
#define CTX_FPU_REG_NR 32
|
||||||
|
#else
|
||||||
|
#define CTX_FPU_REG_NR 0
|
||||||
|
#endif /* ARCH_RISCV_FPU */
|
||||||
|
|
||||||
#ifdef __ASSEMBLY__
|
#ifdef __ASSEMBLY__
|
||||||
|
|
||||||
/**
|
|
||||||
* extension context maintenance
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "cpuport.h"
|
|
||||||
#include "encoding.h"
|
|
||||||
#include "vector_encoding.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ==================================
|
* ==================================
|
||||||
* FPU EXTENSION
|
* RISC-V D ISA (Floating)
|
||||||
* ==================================
|
* ==================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef ENABLE_FPU
|
#ifdef ARCH_RISCV_FPU
|
||||||
#define FPU_CTX_F0_OFF (REGBYTES * 0) /* offsetof(fpu_context_t, fpustatus.f[0]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
#define FPU_CTX_F0_OFF (REGBYTES * 0) /* offsetof(fpu_context_t, fpustatus.f[0]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
#define FPU_CTX_F1_OFF (REGBYTES * 1) /* offsetof(fpu_context_t, fpustatus.f[1]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
#define FPU_CTX_F1_OFF (REGBYTES * 1) /* offsetof(fpu_context_t, fpustatus.f[1]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
#define FPU_CTX_F2_OFF (REGBYTES * 2) /* offsetof(fpu_context_t, fpustatus.f[2]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
#define FPU_CTX_F2_OFF (REGBYTES * 2) /* offsetof(fpu_context_t, fpustatus.f[2]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
|
@ -60,96 +60,14 @@
|
||||||
#define FPU_CTX_F29_OFF (REGBYTES * 29) /* offsetof(fpu_context_t, fpustatus.f[29]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
#define FPU_CTX_F29_OFF (REGBYTES * 29) /* offsetof(fpu_context_t, fpustatus.f[29]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
#define FPU_CTX_F30_OFF (REGBYTES * 30) /* offsetof(fpu_context_t, fpustatus.f[30]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
#define FPU_CTX_F30_OFF (REGBYTES * 30) /* offsetof(fpu_context_t, fpustatus.f[30]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
#define FPU_CTX_F31_OFF (REGBYTES * 31) /* offsetof(fpu_context_t, fpustatus.f[31]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
#define FPU_CTX_F31_OFF (REGBYTES * 31) /* offsetof(fpu_context_t, fpustatus.f[31]) - offsetof(fpu_context_t, fpustatus.f[0]) */
|
||||||
#endif /* ENABLE_FPU */
|
#endif /* ARCH_RISCV_FPU */
|
||||||
|
|
||||||
/**
|
|
||||||
* ==================================
|
|
||||||
* VECTOR EXTENSION
|
|
||||||
* ==================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef ENABLE_VECTOR
|
|
||||||
|
|
||||||
#define VEC_FRAME_VSTART (0 * REGBYTES)
|
|
||||||
#define VEC_FRAME_VTYPE (1 * REGBYTES)
|
|
||||||
#define VEC_FRAME_VL (2 * REGBYTES)
|
|
||||||
#define VEC_FRAME_VCSR (3 * REGBYTES)
|
|
||||||
#define VEC_FRAME_V0 (4 * REGBYTES)
|
|
||||||
|
|
||||||
.macro GET_VEC_FRAME_LEN, xreg
|
|
||||||
csrr \xreg, vlenb
|
|
||||||
slli \xreg, \xreg, 5
|
|
||||||
addi \xreg, \xreg, 4 * REGBYTES
|
|
||||||
.endm
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief save vector extension hardware state
|
|
||||||
*
|
|
||||||
* @param dst register storing bottom of storage block
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
.macro SAVE_VECTOR, dst
|
|
||||||
mv t1, \dst
|
|
||||||
|
|
||||||
csrr t0, vstart
|
|
||||||
STORE t0, VEC_FRAME_VSTART(t1)
|
|
||||||
csrr t0, vtype
|
|
||||||
STORE t0, VEC_FRAME_VTYPE(t1)
|
|
||||||
csrr t0, vl
|
|
||||||
STORE t0, VEC_FRAME_VL(t1)
|
|
||||||
csrr t0, vcsr
|
|
||||||
STORE t0, VEC_FRAME_VCSR(t1)
|
|
||||||
|
|
||||||
addi t1, t1, VEC_FRAME_V0
|
|
||||||
|
|
||||||
// config vector setting,
|
|
||||||
// t2 is updated to length of a vector group in bytes
|
|
||||||
VEC_CONFIG_SETVLI(t2, x0, VEC_IMM_SEW_8, VEC_IMM_LMUL_8)
|
|
||||||
|
|
||||||
vse8.v v0, (t1)
|
|
||||||
add t1, t1, t2
|
|
||||||
vse8.v v8, (t1)
|
|
||||||
add t1, t1, t2
|
|
||||||
vse8.v v16, (t1)
|
|
||||||
add t1, t1, t2
|
|
||||||
vse8.v v24, (t1)
|
|
||||||
.endm
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief restore vector extension hardware states
|
|
||||||
*
|
|
||||||
* @param dst register storing bottom of storage block
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
.macro RESTORE_VECTOR, dst
|
|
||||||
// restore vector registers first since it will modify vector states
|
|
||||||
mv t0, \dst
|
|
||||||
addi t1, t0, VEC_FRAME_V0
|
|
||||||
|
|
||||||
VEC_CONFIG_SETVLI(t2, x0, VEC_IMM_SEW_8, VEC_IMM_LMUL_8)
|
|
||||||
|
|
||||||
vle8.v v0, (t1)
|
|
||||||
add t1, t1, t2
|
|
||||||
vle8.v v8, (t1)
|
|
||||||
add t1, t1, t2
|
|
||||||
vle8.v v16, (t1)
|
|
||||||
add t1, t1, t2
|
|
||||||
vle8.v v24, (t1)
|
|
||||||
|
|
||||||
mv t1, t0
|
|
||||||
|
|
||||||
LOAD t0, VEC_FRAME_VSTART(t1)
|
|
||||||
csrw vstart, t0
|
|
||||||
LOAD t0, VEC_FRAME_VCSR(t1)
|
|
||||||
csrw vcsr, t0
|
|
||||||
|
|
||||||
LOAD t0, VEC_FRAME_VTYPE(t1)
|
|
||||||
LOAD t3, VEC_FRAME_VL(t1)
|
|
||||||
VEC_CONFIG_SET_VL_VTYPE(t3, t0)
|
|
||||||
.endm
|
|
||||||
|
|
||||||
#endif /* ENABLE_VECTOR */
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
#ifdef ARCH_RISCV_VECTOR
|
||||||
|
#include "rvv_context.h"
|
||||||
|
#else /* !ARCH_RISCV_VECTOR */
|
||||||
|
#define CTX_VECTOR_REG_NR 0
|
||||||
|
#endif /* ARCH_RISCV_VECTOR */
|
||||||
|
|
||||||
#endif /* __EXT_CONTEXT_H__ */
|
#endif /* __EXT_CONTEXT_H__ */
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
* 2018/12/27 Jesven Add SMP schedule
|
* 2018/12/27 Jesven Add SMP schedule
|
||||||
* 2021/02/02 lizhirui Add userspace support
|
* 2021/02/02 lizhirui Add userspace support
|
||||||
* 2021/12/24 JasonHu Add user setting save/restore
|
* 2021/12/24 JasonHu Add user setting save/restore
|
||||||
* 2022/10/22 WangXiaoyao Support kernel mode RVV;
|
* 2022/10/22 Shell Support kernel mode RVV;
|
||||||
* Rewrite trap handling routine
|
* Rewrite trap handling routine
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -69,6 +69,9 @@ _context_switch:
|
||||||
LOAD a0, 0(t0)
|
LOAD a0, 0(t0)
|
||||||
la t0, rt_interrupt_to_thread
|
la t0, rt_interrupt_to_thread
|
||||||
LOAD a1, 0(t0)
|
LOAD a1, 0(t0)
|
||||||
|
csrr t0, sstatus
|
||||||
|
andi t0, t0, ~SSTATUS_SPIE
|
||||||
|
csrw sstatus, t0
|
||||||
jal rt_hw_context_switch
|
jal rt_hw_context_switch
|
||||||
|
|
||||||
_resume_execution:
|
_resume_execution:
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-10-10 RT-Thread the first version,
|
||||||
|
* compatible to riscv-v-spec-1.0
|
||||||
|
*/
|
||||||
|
#ifndef __RVV_CONTEXT_H__
|
||||||
|
#define __RVV_CONTEXT_H__
|
||||||
|
|
||||||
|
#include "cpuport.h"
|
||||||
|
#include "encoding.h"
|
||||||
|
|
||||||
|
#if defined(ARCH_VECTOR_VLEN_128)
|
||||||
|
#define CTX_VECTOR_REGS 64
|
||||||
|
#elif defined(ARCH_VECTOR_VLEN_256)
|
||||||
|
#define CTX_VECTOR_REGS 128
|
||||||
|
#else
|
||||||
|
#error "No supported VLEN"
|
||||||
|
#endif /* VLEN */
|
||||||
|
|
||||||
|
#define CTX_VECTOR_REG_NR (CTX_VECTOR_REGS + 4)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ==================================
|
||||||
|
* VECTOR EXTENSION
|
||||||
|
* ==================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VEC_FRAME_VSTART (0 * REGBYTES)
|
||||||
|
#define VEC_FRAME_VTYPE (1 * REGBYTES)
|
||||||
|
#define VEC_FRAME_VL (2 * REGBYTES)
|
||||||
|
#define VEC_FRAME_VCSR (3 * REGBYTES)
|
||||||
|
#define VEC_FRAME_V0 (4 * REGBYTES)
|
||||||
|
|
||||||
|
.macro GET_VEC_FRAME_LEN, xreg
|
||||||
|
csrr \xreg, vlenb
|
||||||
|
slli \xreg, \xreg, 5
|
||||||
|
addi \xreg, \xreg, 4 * REGBYTES
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief save vector extension hardware state
|
||||||
|
*
|
||||||
|
* @param dst register storing bottom of storage block
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
.macro SAVE_VECTOR, dst
|
||||||
|
mv t1, \dst
|
||||||
|
|
||||||
|
csrr t0, vstart
|
||||||
|
STORE t0, VEC_FRAME_VSTART(t1)
|
||||||
|
csrr t0, vtype
|
||||||
|
STORE t0, VEC_FRAME_VTYPE(t1)
|
||||||
|
csrr t0, vl
|
||||||
|
STORE t0, VEC_FRAME_VL(t1)
|
||||||
|
csrr t0, vcsr
|
||||||
|
STORE t0, VEC_FRAME_VCSR(t1)
|
||||||
|
|
||||||
|
addi t1, t1, VEC_FRAME_V0
|
||||||
|
|
||||||
|
// config vector setting,
|
||||||
|
// t2 is updated to length of a vector group in bytes
|
||||||
|
VEC_CONFIG_SETVLI(t2, x0, VEC_IMM_SEW_8, VEC_IMM_LMUL_8)
|
||||||
|
|
||||||
|
vse8.v v0, (t1)
|
||||||
|
add t1, t1, t2
|
||||||
|
vse8.v v8, (t1)
|
||||||
|
add t1, t1, t2
|
||||||
|
vse8.v v16, (t1)
|
||||||
|
add t1, t1, t2
|
||||||
|
vse8.v v24, (t1)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief restore vector extension hardware states
|
||||||
|
*
|
||||||
|
* @param dst register storing bottom of storage block
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
.macro RESTORE_VECTOR, dst
|
||||||
|
// restore vector registers first since it will modify vector states
|
||||||
|
mv t0, \dst
|
||||||
|
addi t1, t0, VEC_FRAME_V0
|
||||||
|
|
||||||
|
VEC_CONFIG_SETVLI(t2, x0, VEC_IMM_SEW_8, VEC_IMM_LMUL_8)
|
||||||
|
|
||||||
|
vle8.v v0, (t1)
|
||||||
|
add t1, t1, t2
|
||||||
|
vle8.v v8, (t1)
|
||||||
|
add t1, t1, t2
|
||||||
|
vle8.v v16, (t1)
|
||||||
|
add t1, t1, t2
|
||||||
|
vle8.v v24, (t1)
|
||||||
|
|
||||||
|
mv t1, t0
|
||||||
|
|
||||||
|
LOAD t0, VEC_FRAME_VSTART(t1)
|
||||||
|
csrw vstart, t0
|
||||||
|
LOAD t0, VEC_FRAME_VCSR(t1)
|
||||||
|
csrw vcsr, t0
|
||||||
|
|
||||||
|
LOAD t0, VEC_FRAME_VTYPE(t1)
|
||||||
|
LOAD t3, VEC_FRAME_VL(t1)
|
||||||
|
VEC_CONFIG_SET_VL_VTYPE(t3, t0)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#endif /* __RVV_CONTEXT_H__ */
|
|
@ -6,12 +6,23 @@
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2021-01-30 lizhirui first version
|
* 2021-01-30 lizhirui first version
|
||||||
|
* 2021-11-18 JasonHu add fpu member
|
||||||
|
* 2022-10-22 Shell Support kernel mode RVV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __STACK_H__
|
#ifndef __STACK_H__
|
||||||
#define __STACK_H__
|
#define __STACK_H__
|
||||||
|
|
||||||
|
#include "stackframe.h"
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
typedef struct rt_hw_switch_frame
|
||||||
|
{
|
||||||
|
uint64_t regs[RT_HW_SWITCH_CONTEXT_SIZE];
|
||||||
|
} *rt_hw_switch_frame_t;
|
||||||
|
|
||||||
|
|
||||||
struct rt_hw_stack_frame
|
struct rt_hw_stack_frame
|
||||||
{
|
{
|
||||||
rt_ubase_t epc; /* epc - epc - program counter */
|
rt_ubase_t epc; /* epc - epc - program counter */
|
||||||
|
@ -47,13 +58,13 @@ struct rt_hw_stack_frame
|
||||||
rt_ubase_t t5; /* x30 - t5 - temporary register 5 */
|
rt_ubase_t t5; /* x30 - t5 - temporary register 5 */
|
||||||
rt_ubase_t t6; /* x31 - t6 - temporary register 6 */
|
rt_ubase_t t6; /* x31 - t6 - temporary register 6 */
|
||||||
rt_ubase_t user_sp_exc_stack; /* sscratch - user mode sp/exception stack */
|
rt_ubase_t user_sp_exc_stack; /* sscratch - user mode sp/exception stack */
|
||||||
rt_ubase_t __padding; /* align to 16bytes */
|
rt_ubase_t __padding; /* align to 16bytes */
|
||||||
#ifdef ENABLE_FPU
|
#ifdef ARCH_RISCV_FPU
|
||||||
rt_ubase_t f[CTX_FPU_REG_NR]; /* f0~f31 */
|
rt_ubase_t f[CTX_FPU_REG_NR]; /* f0~f31 */
|
||||||
#endif
|
#endif /* ARCH_RISCV_FPU */
|
||||||
#ifdef ENABLE_VECTOR
|
#ifdef ARCH_RISCV_VECTOR
|
||||||
rt_ubase_t v[CTX_VECTOR_REG_NR];
|
rt_ubase_t v[CTX_VECTOR_REG_NR];
|
||||||
#endif
|
#endif /* ARCH_RISCV_VECTOR */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,33 +8,70 @@
|
||||||
* 2021-02-02 lizhirui first version
|
* 2021-02-02 lizhirui first version
|
||||||
* 2021-02-11 lizhirui fixed gp save/store bug
|
* 2021-02-11 lizhirui fixed gp save/store bug
|
||||||
* 2021-11-18 JasonHu add fpu registers save/restore
|
* 2021-11-18 JasonHu add fpu registers save/restore
|
||||||
* 2022/10/22 WangXiaoyao Support kernel mode RVV;
|
* 2022-10-22 Shell Support kernel mode RVV
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __STACKFRAME_H__
|
#ifndef __STACKFRAME_H__
|
||||||
#define __STACKFRAME_H__
|
#define __STACKFRAME_H__
|
||||||
|
|
||||||
#include "cpuport.h"
|
#include <rtconfig.h>
|
||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
#include "ext_context.h"
|
#include "ext_context.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
|
||||||
|
|
||||||
|
/* 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 BYTES(idx) ((idx) * REGBYTES)
|
||||||
#define FRAME_OFF_SSTATUS BYTES(2)
|
#define FRAME_OFF_SSTATUS BYTES(2)
|
||||||
#define FRAME_OFF_SP BYTES(32)
|
#define FRAME_OFF_SP BYTES(32)
|
||||||
#define FRAME_OFF_GP BYTES(3)
|
#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__
|
#ifdef __ASSEMBLY__
|
||||||
|
|
||||||
.macro SAVE_ALL
|
.macro SAVE_ALL
|
||||||
|
|
||||||
#ifdef ENABLE_FPU
|
#ifdef ARCH_RISCV_FPU
|
||||||
/* reserve float registers */
|
/* reserve float registers */
|
||||||
addi sp, sp, -CTX_FPU_REG_NR * REGBYTES
|
addi sp, sp, -CTX_FPU_REG_NR * REGBYTES
|
||||||
#endif /* ENABLE_FPU */
|
#endif /* ARCH_RISCV_FPU */
|
||||||
#ifdef ENABLE_VECTOR
|
#ifdef ARCH_RISCV_VECTOR
|
||||||
/* reserve float registers */
|
/* reserve float registers */
|
||||||
addi sp, sp, -CTX_VECTOR_REG_NR * REGBYTES
|
addi sp, sp, -CTX_VECTOR_REG_NR * REGBYTES
|
||||||
#endif /* ENABLE_VECTOR */
|
#endif /* ARCH_RISCV_VECTOR */
|
||||||
|
|
||||||
/* save general registers */
|
/* save general registers */
|
||||||
addi sp, sp, -CTX_GENERAL_REG_NR * REGBYTES
|
addi sp, sp, -CTX_GENERAL_REG_NR * REGBYTES
|
||||||
|
@ -78,7 +115,7 @@
|
||||||
csrr t0, sscratch
|
csrr t0, sscratch
|
||||||
STORE t0, 32 * REGBYTES(sp)
|
STORE t0, 32 * REGBYTES(sp)
|
||||||
|
|
||||||
#ifdef ENABLE_FPU
|
#ifdef ARCH_RISCV_FPU
|
||||||
/* backup sp and adjust sp to save float registers */
|
/* backup sp and adjust sp to save float registers */
|
||||||
mv t1, sp
|
mv t1, sp
|
||||||
addi t1, t1, CTX_GENERAL_REG_NR * REGBYTES
|
addi t1, t1, CTX_GENERAL_REG_NR * REGBYTES
|
||||||
|
@ -125,9 +162,9 @@
|
||||||
li t0, SSTATUS_FS_CLEAN
|
li t0, SSTATUS_FS_CLEAN
|
||||||
csrs sstatus, t0
|
csrs sstatus, t0
|
||||||
|
|
||||||
#endif /* ENABLE_FPU */
|
#endif /* ARCH_RISCV_FPU */
|
||||||
|
|
||||||
#ifdef ENABLE_VECTOR
|
#ifdef ARCH_RISCV_VECTOR
|
||||||
csrr t0, sstatus
|
csrr t0, sstatus
|
||||||
andi t0, t0, SSTATUS_VS
|
andi t0, t0, SSTATUS_VS
|
||||||
beqz t0, 0f
|
beqz t0, 0f
|
||||||
|
@ -137,7 +174,7 @@
|
||||||
|
|
||||||
SAVE_VECTOR t1
|
SAVE_VECTOR t1
|
||||||
0:
|
0:
|
||||||
#endif /* ENABLE_VECTOR */
|
#endif /* ARCH_RISCV_VECTOR */
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,7 +183,7 @@
|
||||||
*/
|
*/
|
||||||
.macro RESTORE_ALL
|
.macro RESTORE_ALL
|
||||||
|
|
||||||
#ifdef ENABLE_VECTOR
|
#ifdef ARCH_RISCV_VECTOR
|
||||||
// skip on close
|
// skip on close
|
||||||
ld t0, 2 * REGBYTES(sp)
|
ld t0, 2 * REGBYTES(sp)
|
||||||
// cannot use vector on initial
|
// cannot use vector on initial
|
||||||
|
@ -158,9 +195,9 @@
|
||||||
|
|
||||||
RESTORE_VECTOR t1
|
RESTORE_VECTOR t1
|
||||||
0:
|
0:
|
||||||
#endif /* ENABLE_VECTOR */
|
#endif /* ARCH_RISCV_VECTOR */
|
||||||
|
|
||||||
#ifdef ENABLE_FPU
|
#ifdef ARCH_RISCV_FPU
|
||||||
/* restore float register */
|
/* restore float register */
|
||||||
addi t2, sp, CTX_GENERAL_REG_NR * REGBYTES
|
addi t2, sp, CTX_GENERAL_REG_NR * REGBYTES
|
||||||
|
|
||||||
|
@ -206,7 +243,7 @@
|
||||||
li t0, SSTATUS_FS_CLEAN
|
li t0, SSTATUS_FS_CLEAN
|
||||||
csrs sstatus, t0
|
csrs sstatus, t0
|
||||||
|
|
||||||
#endif /* ENABLE_FPU */
|
#endif /* ARCH_RISCV_FPU */
|
||||||
|
|
||||||
/* restore general register */
|
/* restore general register */
|
||||||
addi t0, sp, CTX_REG_NR * REGBYTES
|
addi t0, sp, CTX_REG_NR * REGBYTES
|
||||||
|
|
|
@ -12,8 +12,15 @@
|
||||||
#ifndef __VECTOR_ENCODING_H__
|
#ifndef __VECTOR_ENCODING_H__
|
||||||
#define __VECTOR_ENCODING_H__
|
#define __VECTOR_ENCODING_H__
|
||||||
|
|
||||||
|
/* mstatus/sstatus */
|
||||||
|
#define MSTATUS_VS 0x00000600
|
||||||
|
#define SSTATUS_VS 0x00000600 /* Vector Status */
|
||||||
|
#define SSTATUS_VS_INITIAL 0x00000200
|
||||||
|
#define SSTATUS_VS_CLEAN 0x00000400
|
||||||
|
#define SSTATUS_VS_DIRTY 0x00000600
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* assembler names used for vset{i}vli vtypei immediate
|
* assembler names used for vset{i}vli vtypei immediate
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VEC_IMM_SEW_8 e8
|
#define VEC_IMM_SEW_8 e8
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018/10/28 Bernard The unify RISC-V porting implementation
|
||||||
|
* 2018/12/27 Jesven Add SMP support
|
||||||
|
* 2021/02/02 lizhirui Add userspace support
|
||||||
|
* 2022/10/22 Shell Support User mode RVV;
|
||||||
|
* Trimming process switch context
|
||||||
|
* 2024/09/01 Shell Separated vector ctx from the generic
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cpuport.h"
|
||||||
|
#include "stackframe.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param a0 pointer to frame bottom
|
||||||
|
*/
|
||||||
|
.global rt_hw_vector_ctx_save
|
||||||
|
rt_hw_vector_ctx_save:
|
||||||
|
SAVE_VECTOR a0
|
||||||
|
ret
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param a0 pointer to frame bottom
|
||||||
|
*/
|
||||||
|
.global rt_hw_vector_ctx_restore
|
||||||
|
rt_hw_vector_ctx_restore:
|
||||||
|
RESTORE_VECTOR a0
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global rt_hw_disable_vector
|
||||||
|
rt_hw_disable_vector:
|
||||||
|
li t0, SSTATUS_VS
|
||||||
|
csrc sstatus, t0
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global rt_hw_enable_vector
|
||||||
|
rt_hw_enable_vector:
|
||||||
|
li t0, SSTATUS_VS
|
||||||
|
csrs sstatus, t0
|
||||||
|
ret
|
Loading…
Reference in New Issue