diff options
Diffstat (limited to 'libcpu/risc-v/virt64/cpuport.c')
| -rw-r--r-- | libcpu/risc-v/virt64/cpuport.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/libcpu/risc-v/virt64/cpuport.c b/libcpu/risc-v/virt64/cpuport.c new file mode 100644 index 0000000000..50929125ac --- /dev/null +++ b/libcpu/risc-v/virt64/cpuport.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018/10/28 Bernard The unify RISC-V porting code. + * 2021-02-11 lizhirui add gp support + */ + +#include <rthw.h> +#include <rtthread.h> + +#include "cpuport.h" +#include "stack.h" + + +/** + * @brief from thread used interrupt context switch + * + */ +volatile rt_ubase_t rt_interrupt_from_thread = 0; +/** + * @brief to thread used interrupt context switch + * + */ +volatile rt_ubase_t rt_interrupt_to_thread = 0; +/** + * @brief flag to indicate context switch in interrupt or not + * + */ +volatile rt_ubase_t rt_thread_switch_interrupt_flag = 0; + + +/** + * This function will initialize thread stack + * + * @param tentry the entry of thread + * @param parameter the parameter of entry + * @param stack_addr the beginning stack address + * @param texit the function will be called when thread exit + * + * @return stack address + */ +rt_uint8_t *rt_hw_stack_init(void *tentry, + void *parameter, + rt_uint8_t *stack_addr, + void *texit) +{ + struct rt_hw_stack_frame *frame; + rt_uint8_t *stk; + int i; + extern int __global_pointer$; + + stk = stack_addr + sizeof(rt_ubase_t); + stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_ubase_t)stk, REGBYTES); + stk -= sizeof(struct rt_hw_stack_frame); + + frame = (struct rt_hw_stack_frame *)stk; + + for (i = 0; i < sizeof(struct rt_hw_stack_frame) / sizeof(rt_ubase_t); i++) + { + ((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 */ + frame->sstatus = 0x00040120; + + return stk; +} + +/* + * #ifdef RT_USING_SMP + * void rt_hw_context_switch_interrupt(void *context, rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread); + * #else + * void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to); + * #endif + */ +#ifndef RT_USING_SMP +void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to) +{ + if (rt_thread_switch_interrupt_flag == 0) + rt_interrupt_from_thread = from; + + rt_interrupt_to_thread = to; + rt_thread_switch_interrupt_flag = 1; + + return ; +} +#endif /* end of RT_USING_SMP */ + +/** shutdown CPU */ +void rt_hw_cpu_shutdown() +{ + rt_uint32_t level; + rt_kprintf("shutdown...\n"); + + level = rt_hw_interrupt_disable(); + while (level) + { + RT_ASSERT(0); + } +} + +rt_thread_t rt_thread_sp_to_thread(void *spmember_addr) +{ + return (rt_thread_t)(((rt_ubase_t)spmember_addr) - (offsetof(struct rt_thread,sp))); +} + +void *get_thread_kernel_stack_top(rt_thread_t thread) +{ + return (void *)(((rt_size_t)thread -> stack_addr) + ((rt_size_t)thread -> stack_size)); +} |
