mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-09-20 17:44:20 +08:00
[BSP][Nuclei] Add Nuclei RISC-V Processor support
* Nuclei RISC-V Processor support is added both RV32 and RV64 * Nuclei RVSTAR BSP is added, UART driver is added * MSH works well in RVSTAR board --------------------------- Squashed commit of the following: commitb7368bc2edAuthor: Huaqi Fang <578567190@qq.com> Date: Fri Apr 17 14:38:54 2020 +0800 [BSP][Nuclei] Pretty source code Signed-off-by: Huaqi Fang <578567190@qq.com> commit2c42a997f7Author: Huaqi Fang <578567190@qq.com> Date: Thu Apr 16 15:51:03 2020 +0800 [libcpu] Remove ARCH_NUCLEI in libcpu kconfig Signed-off-by: Huaqi Fang <578567190@qq.com> commit915ad4c076Author: Huaqi Fang <578567190@qq.com> Date: Thu Apr 16 15:50:00 2020 +0800 [BSP][Nuclei] Remove ARCH_NUCLEI in bsp KConfig Signed-off-by: Huaqi Fang <578567190@qq.com> commitfe43869c79Author: Huaqi Fang <578567190@qq.com> Date: Wed Apr 15 12:43:20 2020 +0800 [BSP][NUCLEI] Simply application main.c Remove previous complicated application of gd32vf103_rvstar Signed-off-by: Huaqi Fang <578567190@qq.com> commit8fd31727bcAuthor: Huaqi Fang <578567190@qq.com> Date: Wed Apr 15 12:38:04 2020 +0800 [BSP][NUCLEI] Format application and board source code Signed-off-by: Huaqi Fang <578567190@qq.com> commitb432308b20Author: Huaqi Fang <578567190@qq.com> Date: Wed Apr 15 11:58:28 2020 +0800 [BSP][Nuclei] Format source code of drivers of gd32vf103 Signed-off-by: Huaqi Fang <578567190@qq.com> commit7366173d74Author: Huaqi Fang <578567190@qq.com> Date: Wed Apr 15 11:54:02 2020 +0800 [LIBCPU][NUCLEI] Optimize nuclei cpu portable code Signed-off-by: Huaqi Fang <578567190@qq.com> commit8c2cd4745bAuthor: Huaqi Fang <578567190@qq.com> Date: Tue Apr 14 15:45:42 2020 +0800 nuclei: Update README.md Signed-off-by: Huaqi Fang <578567190@qq.com> commitfa8a2f24eaAuthor: Huaqi Fang <578567190@qq.com> Date: Tue Apr 14 14:06:54 2020 +0800 nuclei: Add gpio driver not tested Signed-off-by: Huaqi Fang <578567190@qq.com> commit1be40bc50bAuthor: Huaqi Fang <578567190@qq.com> Date: Thu Apr 9 14:55:22 2020 +0800 Nuclei: Update README.md Signed-off-by: Huaqi Fang <578567190@qq.com> commit4c8beb204bAuthor: Huaqi Fang <578567190@qq.com> Date: Thu Apr 9 10:20:25 2020 +0800 Nuclei: Change idle stack size from 256 to 396 bytes If changed to 396 bytes, then debug optimization level changed from O2 to O0, and the application can run successfully without stack overflow issue of tidle0 task warning: tidle0 stack is close to end of stack address. Signed-off-by: Huaqi Fang <578567190@qq.com> commitda2bcf5c56Author: Huaqi Fang <578567190@qq.com> Date: Thu Apr 9 10:11:40 2020 +0800 nuclei: Remove unused kconfig Signed-off-by: Huaqi Fang <578567190@qq.com> commit0b932c677aAuthor: Huaqi Fang <578567190@qq.com> Date: Thu Apr 9 09:32:22 2020 +0800 nuclei: optimize drivers support Signed-off-by: Huaqi Fang <578567190@qq.com> commit0431f6f01fAuthor: Huaqi Fang <578567190@qq.com> Date: Wed Apr 8 19:28:02 2020 +0800 tools: Update mkdist.py for nuclei bsp Signed-off-by: Huaqi Fang <578567190@qq.com> commit0e1f502edfAuthor: Huaqi Fang <578567190@qq.com> Date: Wed Apr 8 18:46:58 2020 +0800 nuclei: optimize rvstar support directory Signed-off-by: Huaqi Fang <578567190@qq.com> commit1131f6e648Author: Huaqi Fang <578567190@qq.com> Date: Wed Apr 8 18:37:24 2020 +0800 nuclei: update kconfig Signed-off-by: Huaqi Fang <578567190@qq.com> commitad81c1d3bfAuthor: Huaqi Fang <578567190@qq.com> Date: Wed Apr 8 15:43:00 2020 +0800 nuclei: Rename board name Signed-off-by: Huaqi Fang <578567190@qq.com> commitd780138a1aAuthor: Huaqi Fang <578567190@qq.com> Date: Tue Apr 7 09:36:19 2020 +0800 libcpu: Add Nuclei arch option in KConfig Signed-off-by: Huaqi Fang <578567190@qq.com> commit60320d34b1Author: Huaqi Fang <578567190@qq.com> Date: Fri Apr 3 16:51:01 2020 +0800 nuclei: Update nuclei sdk of rt-thread support Signed-off-by: Huaqi Fang <578567190@qq.com> commita042b806efAuthor: Huaqi Fang <578567190@qq.com> Date: Fri Apr 3 11:34:09 2020 +0800 nuclei: modify application for not print anything Signed-off-by: Huaqi Fang <578567190@qq.com> commit2a9603adcbAuthor: Huaqi Fang <578567190@qq.com> Date: Fri Apr 3 11:31:01 2020 +0800 nuclei: Add .gitignore for nuclei bsp Signed-off-by: Huaqi Fang <578567190@qq.com> commit34aaf6aebaAuthor: Huaqi Fang <578567190@qq.com> Date: Fri Apr 3 11:28:06 2020 +0800 nuclei_sdk: update link script of rvstar to contain rt-thread needed sections /* section information for finsh shell */ . = ALIGN(4); __fsymtab_start = .; KEEP(*(FSymTab)) __fsymtab_end = .; . = ALIGN(4); __vsymtab_start = .; KEEP(*(VSymTab)) __vsymtab_end = .; /* section information for initial. */ . = ALIGN(4); __rt_init_start = .; KEEP(*(SORT(.rti_fn*))) __rt_init_end = .; The above code placed in rodata section Signed-off-by: Huaqi Fang <578567190@qq.com> commit3451466e9dAuthor: Huaqi Fang <578567190@qq.com> Date: Fri Apr 3 10:04:42 2020 +0800 bsp: Add initial commit of nuclei rvstar board bsp Signed-off-by: Huaqi Fang <578567190@qq.com> Signed-off-by: Huaqi Fang <578567190@qq.com>
This commit is contained in:
@@ -10,7 +10,8 @@ group = []
|
||||
list = os.listdir(cwd)
|
||||
|
||||
# add common code files
|
||||
group = group + SConscript(os.path.join('common', 'SConscript'))
|
||||
if rtconfig.CPU != "nuclei":
|
||||
group = group + SConscript(os.path.join('common', 'SConscript'))
|
||||
|
||||
# cpu porting code files
|
||||
group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript'))
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# RT-Thread building script for component
|
||||
|
||||
from building import *
|
||||
|
||||
Import('rtconfig')
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
|
||||
CPPPATH = [cwd]
|
||||
ASFLAGS = ''
|
||||
|
||||
group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS)
|
||||
|
||||
Return('group')
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (c) 2019-Present Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020/03/26 Huaqi First Nuclei RISC-V porting implementation
|
||||
*/
|
||||
|
||||
#include "riscv_encoding.h"
|
||||
|
||||
#ifndef __riscv_32e
|
||||
#define RT_SAVED_REGNUM 30
|
||||
#else
|
||||
#define RT_SAVED_REGNUM 14
|
||||
#endif
|
||||
|
||||
#define RT_CONTEXT_SIZE (RT_SAVED_REGNUM * REGBYTES)
|
||||
|
||||
.extern rt_interrupt_from_thread
|
||||
.extern rt_interrupt_to_thread
|
||||
|
||||
|
||||
.section .text
|
||||
|
||||
|
||||
/*
|
||||
* void rt_hw_context_switch_to(rt_ubase_t to);
|
||||
* a0 --> to_thread
|
||||
*/
|
||||
.globl rt_hw_context_switch_to
|
||||
|
||||
/* Start the first task. This also clears the bit that indicates the FPU is
|
||||
in use in case the FPU was used before the scheduler was started - which
|
||||
would otherwise result in the unnecessary leaving of space in the stack
|
||||
for lazy saving of FPU registers. */
|
||||
.align 3
|
||||
rt_hw_context_switch_to:
|
||||
/* Setup Interrupt Stack using
|
||||
The stack that was used by main()
|
||||
before the scheduler is started is
|
||||
no longer required after the scheduler is started.
|
||||
Interrupt stack pointer is stored in CSR_MSCRATCH */
|
||||
la t0, _sp
|
||||
csrw CSR_MSCRATCH, t0
|
||||
LOAD sp, 0x0(a0) /* Read sp from first TCB member(a0) */
|
||||
|
||||
/* Pop PC from stack and set MEPC */
|
||||
LOAD t0, 0 * REGBYTES(sp)
|
||||
csrw CSR_MEPC, t0
|
||||
/* Pop mstatus from stack and set it */
|
||||
LOAD t0, (RT_SAVED_REGNUM - 1) * REGBYTES(sp)
|
||||
csrw CSR_MSTATUS, t0
|
||||
/* Interrupt still disable here */
|
||||
/* Restore Registers from Stack */
|
||||
LOAD x1, 1 * REGBYTES(sp) /* RA */
|
||||
LOAD x5, 2 * REGBYTES(sp)
|
||||
LOAD x6, 3 * REGBYTES(sp)
|
||||
LOAD x7, 4 * REGBYTES(sp)
|
||||
LOAD x8, 5 * REGBYTES(sp)
|
||||
LOAD x9, 6 * REGBYTES(sp)
|
||||
LOAD x10, 7 * REGBYTES(sp)
|
||||
LOAD x11, 8 * REGBYTES(sp)
|
||||
LOAD x12, 9 * REGBYTES(sp)
|
||||
LOAD x13, 10 * REGBYTES(sp)
|
||||
LOAD x14, 11 * REGBYTES(sp)
|
||||
LOAD x15, 12 * REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
LOAD x16, 13 * REGBYTES(sp)
|
||||
LOAD x17, 14 * REGBYTES(sp)
|
||||
LOAD x18, 15 * REGBYTES(sp)
|
||||
LOAD x19, 16 * REGBYTES(sp)
|
||||
LOAD x20, 17 * REGBYTES(sp)
|
||||
LOAD x21, 18 * REGBYTES(sp)
|
||||
LOAD x22, 19 * REGBYTES(sp)
|
||||
LOAD x23, 20 * REGBYTES(sp)
|
||||
LOAD x24, 21 * REGBYTES(sp)
|
||||
LOAD x25, 22 * REGBYTES(sp)
|
||||
LOAD x26, 23 * REGBYTES(sp)
|
||||
LOAD x27, 24 * REGBYTES(sp)
|
||||
LOAD x28, 25 * REGBYTES(sp)
|
||||
LOAD x29, 26 * REGBYTES(sp)
|
||||
LOAD x30, 27 * REGBYTES(sp)
|
||||
LOAD x31, 28 * REGBYTES(sp)
|
||||
#endif
|
||||
|
||||
addi sp, sp, RT_CONTEXT_SIZE
|
||||
|
||||
mret
|
||||
|
||||
.align 2
|
||||
.global eclic_msip_handler
|
||||
eclic_msip_handler:
|
||||
addi sp, sp, -RT_CONTEXT_SIZE
|
||||
STORE x1, 1 * REGBYTES(sp) /* RA */
|
||||
STORE x5, 2 * REGBYTES(sp)
|
||||
STORE x6, 3 * REGBYTES(sp)
|
||||
STORE x7, 4 * REGBYTES(sp)
|
||||
STORE x8, 5 * REGBYTES(sp)
|
||||
STORE x9, 6 * REGBYTES(sp)
|
||||
STORE x10, 7 * REGBYTES(sp)
|
||||
STORE x11, 8 * REGBYTES(sp)
|
||||
STORE x12, 9 * REGBYTES(sp)
|
||||
STORE x13, 10 * REGBYTES(sp)
|
||||
STORE x14, 11 * REGBYTES(sp)
|
||||
STORE x15, 12 * REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
STORE x16, 13 * REGBYTES(sp)
|
||||
STORE x17, 14 * REGBYTES(sp)
|
||||
STORE x18, 15 * REGBYTES(sp)
|
||||
STORE x19, 16 * REGBYTES(sp)
|
||||
STORE x20, 17 * REGBYTES(sp)
|
||||
STORE x21, 18 * REGBYTES(sp)
|
||||
STORE x22, 19 * REGBYTES(sp)
|
||||
STORE x23, 20 * REGBYTES(sp)
|
||||
STORE x24, 21 * REGBYTES(sp)
|
||||
STORE x25, 22 * REGBYTES(sp)
|
||||
STORE x26, 23 * REGBYTES(sp)
|
||||
STORE x27, 24 * REGBYTES(sp)
|
||||
STORE x28, 25 * REGBYTES(sp)
|
||||
STORE x29, 26 * REGBYTES(sp)
|
||||
STORE x30, 27 * REGBYTES(sp)
|
||||
STORE x31, 28 * REGBYTES(sp)
|
||||
#endif
|
||||
/* Push mstatus to stack */
|
||||
csrr t0, CSR_MSTATUS
|
||||
STORE t0, (RT_SAVED_REGNUM - 1) * REGBYTES(sp)
|
||||
|
||||
/* Push additional registers */
|
||||
|
||||
/* Store sp to task stack */
|
||||
LOAD t0, rt_interrupt_from_thread
|
||||
STORE sp, 0(t0)
|
||||
|
||||
csrr t0, CSR_MEPC
|
||||
STORE t0, 0(sp)
|
||||
|
||||
jal rt_hw_taskswitch
|
||||
|
||||
/* Switch task context */
|
||||
LOAD t0, rt_interrupt_to_thread
|
||||
LOAD sp, 0x0(t0)
|
||||
|
||||
/* Pop PC from stack and set MEPC */
|
||||
LOAD t0, 0 * REGBYTES(sp)
|
||||
csrw CSR_MEPC, t0
|
||||
|
||||
/* Pop additional registers */
|
||||
|
||||
/* Pop mstatus from stack and set it */
|
||||
LOAD t0, (RT_SAVED_REGNUM - 1) * REGBYTES(sp)
|
||||
csrw CSR_MSTATUS, t0
|
||||
/* Interrupt still disable here */
|
||||
/* Restore Registers from Stack */
|
||||
LOAD x1, 1 * REGBYTES(sp) /* RA */
|
||||
LOAD x5, 2 * REGBYTES(sp)
|
||||
LOAD x6, 3 * REGBYTES(sp)
|
||||
LOAD x7, 4 * REGBYTES(sp)
|
||||
LOAD x8, 5 * REGBYTES(sp)
|
||||
LOAD x9, 6 * REGBYTES(sp)
|
||||
LOAD x10, 7 * REGBYTES(sp)
|
||||
LOAD x11, 8 * REGBYTES(sp)
|
||||
LOAD x12, 9 * REGBYTES(sp)
|
||||
LOAD x13, 10 * REGBYTES(sp)
|
||||
LOAD x14, 11 * REGBYTES(sp)
|
||||
LOAD x15, 12 * REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
LOAD x16, 13 * REGBYTES(sp)
|
||||
LOAD x17, 14 * REGBYTES(sp)
|
||||
LOAD x18, 15 * REGBYTES(sp)
|
||||
LOAD x19, 16 * REGBYTES(sp)
|
||||
LOAD x20, 17 * REGBYTES(sp)
|
||||
LOAD x21, 18 * REGBYTES(sp)
|
||||
LOAD x22, 19 * REGBYTES(sp)
|
||||
LOAD x23, 20 * REGBYTES(sp)
|
||||
LOAD x24, 21 * REGBYTES(sp)
|
||||
LOAD x25, 22 * REGBYTES(sp)
|
||||
LOAD x26, 23 * REGBYTES(sp)
|
||||
LOAD x27, 24 * REGBYTES(sp)
|
||||
LOAD x28, 25 * REGBYTES(sp)
|
||||
LOAD x29, 26 * REGBYTES(sp)
|
||||
LOAD x30, 27 * REGBYTES(sp)
|
||||
LOAD x31, 28 * REGBYTES(sp)
|
||||
#endif
|
||||
|
||||
addi sp, sp, RT_CONTEXT_SIZE
|
||||
mret
|
||||
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
* Copyright (c) 2019-Present Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020/03/26 Huaqi Nuclei RISC-V Core porting code.
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "cpuport.h"
|
||||
|
||||
#define SYSTICK_TICK_CONST (SOC_TIMER_FREQ / RT_TICK_PER_SECOND)
|
||||
|
||||
/* Interrupt level for kernel systimer interrupt and software timer interrupt */
|
||||
#define RT_KERNEL_INTERRUPT_LEVEL 1
|
||||
|
||||
/* Initial CSR MSTATUS value when thread created */
|
||||
#define RT_INITIAL_MSTATUS (MSTATUS_MPP | MSTATUS_MPIE | MSTATUS_FS_INITIAL)
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* @brief thread stack frame of saved context
|
||||
*
|
||||
*/
|
||||
struct rt_hw_stack_frame
|
||||
{
|
||||
rt_ubase_t epc; /*!< epc - epc - program counter */
|
||||
rt_ubase_t ra; /*!< x1 - ra - return address for jumps */
|
||||
rt_ubase_t t0; /*!< x5 - t0 - temporary register 0 */
|
||||
rt_ubase_t t1; /*!< x6 - t1 - temporary register 1 */
|
||||
rt_ubase_t t2; /*!< x7 - t2 - temporary register 2 */
|
||||
rt_ubase_t s0_fp; /*!< x8 - s0/fp - saved register 0 or frame pointer */
|
||||
rt_ubase_t s1; /*!< x9 - s1 - saved register 1 */
|
||||
rt_ubase_t a0; /*!< x10 - a0 - return value or function argument 0 */
|
||||
rt_ubase_t a1; /*!< x11 - a1 - return value or function argument 1 */
|
||||
rt_ubase_t a2; /*!< x12 - a2 - function argument 2 */
|
||||
rt_ubase_t a3; /*!< x13 - a3 - function argument 3 */
|
||||
rt_ubase_t a4; /*!< x14 - a4 - function argument 4 */
|
||||
rt_ubase_t a5; /*!< x15 - a5 - function argument 5 */
|
||||
#ifndef __riscv_32e
|
||||
rt_ubase_t a6; /*!< x16 - a6 - function argument 6 */
|
||||
rt_ubase_t a7; /*!< x17 - s7 - function argument 7 */
|
||||
rt_ubase_t s2; /*!< x18 - s2 - saved register 2 */
|
||||
rt_ubase_t s3; /*!< x19 - s3 - saved register 3 */
|
||||
rt_ubase_t s4; /*!< x20 - s4 - saved register 4 */
|
||||
rt_ubase_t s5; /*!< x21 - s5 - saved register 5 */
|
||||
rt_ubase_t s6; /*!< x22 - s6 - saved register 6 */
|
||||
rt_ubase_t s7; /*!< x23 - s7 - saved register 7 */
|
||||
rt_ubase_t s8; /*!< x24 - s8 - saved register 8 */
|
||||
rt_ubase_t s9; /*!< x25 - s9 - saved register 9 */
|
||||
rt_ubase_t s10; /*!< x26 - s10 - saved register 10 */
|
||||
rt_ubase_t s11; /*!< x27 - s11 - saved register 11 */
|
||||
rt_ubase_t t3; /*!< x28 - t3 - temporary register 3 */
|
||||
rt_ubase_t t4; /*!< x29 - t4 - temporary register 4 */
|
||||
rt_ubase_t t5; /*!< x30 - t5 - temporary register 5 */
|
||||
rt_ubase_t t6; /*!< x31 - t6 - temporary register 6 */
|
||||
#endif
|
||||
rt_ubase_t mstatus; /*!< - machine status register */
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
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->a0 = (rt_ubase_t)parameter;
|
||||
frame->epc = (rt_ubase_t)tentry;
|
||||
|
||||
frame->mstatus = RT_INITIAL_MSTATUS;
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Do rt-thread context switch in interrupt context
|
||||
*
|
||||
* @param from thread sp of from thread
|
||||
* @param to thread sp of to thread
|
||||
*/
|
||||
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;
|
||||
RT_YIELD();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Do rt-thread context switch in task context
|
||||
*
|
||||
* @param from thread sp of from thread
|
||||
* @param to thread sp of to thread
|
||||
*/
|
||||
void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to)
|
||||
{
|
||||
rt_interrupt_from_thread = from;
|
||||
rt_interrupt_to_thread = to;
|
||||
RT_YIELD();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Do extra task switch code
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* - Clear software timer interrupt request flag
|
||||
* - clear rt_thread_switch_interrupt_flag to 0
|
||||
*/
|
||||
void rt_hw_taskswitch(void)
|
||||
{
|
||||
/* Clear Software IRQ, A MUST */
|
||||
SysTimer_ClearSWIRQ();
|
||||
rt_thread_switch_interrupt_flag = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup systimer and software timer interrupt
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* - Set Systimer interrupt as NON-VECTOR interrupt with lowest interrupt level
|
||||
* - Set software timer interrupt as VECTOR interrupt with lowest interrupt level
|
||||
* - Enable these two interrupts
|
||||
*/
|
||||
void rt_hw_ticksetup(void)
|
||||
{
|
||||
uint64_t ticks = SYSTICK_TICK_CONST;
|
||||
|
||||
/* Make SWI and SysTick the lowest priority interrupts. */
|
||||
/* Stop and clear the SysTimer. SysTimer as Non-Vector Interrupt */
|
||||
SysTick_Config(ticks);
|
||||
ECLIC_DisableIRQ(SysTimer_IRQn);
|
||||
ECLIC_SetLevelIRQ(SysTimer_IRQn, RT_KERNEL_INTERRUPT_LEVEL);
|
||||
ECLIC_SetShvIRQ(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT);
|
||||
ECLIC_EnableIRQ(SysTimer_IRQn);
|
||||
|
||||
/* Set SWI interrupt level to lowest level/priority, SysTimerSW as Vector Interrupt */
|
||||
ECLIC_SetShvIRQ(SysTimerSW_IRQn, ECLIC_VECTOR_INTERRUPT);
|
||||
ECLIC_SetLevelIRQ(SysTimerSW_IRQn, RT_KERNEL_INTERRUPT_LEVEL);
|
||||
ECLIC_EnableIRQ(SysTimerSW_IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* systimer interrupt handler eclic_mtip_handler
|
||||
* is hard coded in startup_<Device>.S
|
||||
* We define SysTick_Handler as eclic_mtip_handler
|
||||
* for easy understanding
|
||||
*/
|
||||
#define SysTick_Handler eclic_mtip_handler
|
||||
|
||||
/**
|
||||
* @brief This is the timer interrupt service routine.
|
||||
*
|
||||
*/
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
/* Reload systimer */
|
||||
SysTick_Reload(SYSTICK_TICK_CONST);
|
||||
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
/* tick increase */
|
||||
rt_tick_increase();
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable cpu interrupt
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* - Disable cpu interrupt by clear MIE bit in MSTATUS
|
||||
* - Return the previous value in MSTATUS before clear MIE bit
|
||||
*
|
||||
* @return the previous value in MSTATUS before clear MIE bit
|
||||
*/
|
||||
rt_base_t rt_hw_interrupt_disable(void)
|
||||
{
|
||||
return __RV_CSR_READ_CLEAR(CSR_MSTATUS, MSTATUS_MIE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Restore previous saved interrupt status
|
||||
*
|
||||
* @param level previous saved MSTATUS value
|
||||
*/
|
||||
void rt_hw_interrupt_enable(rt_base_t level)
|
||||
{
|
||||
__RV_CSR_WRITE(CSR_MSTATUS, level);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
* Copyright (c) 2019-Present Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020/03/26 hqfang Nuclei RISC-V Core porting code.
|
||||
*/
|
||||
|
||||
#ifndef __CPUPORT_H__
|
||||
#define __CPUPORT_H__
|
||||
|
||||
#include <rtconfig.h>
|
||||
#include <nuclei_sdk_soc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Scheduler utilities. */
|
||||
#define RT_YIELD() \
|
||||
{ \
|
||||
/* Set a software interrupt(SWI) request to request a context switch. */ \
|
||||
SysTimer_SetSWIRQ(); \
|
||||
/* Barriers are normally not required but do ensure the code is completely \
|
||||
within the specified behaviour for the architecture. */ \
|
||||
__RWMB(); \
|
||||
__FENCE_I(); \
|
||||
}
|
||||
|
||||
extern void rt_hw_ticksetup(void);
|
||||
extern void rt_hw_taskswitch(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2019-Present Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020/03/26 hqfang First Nuclei RISC-V porting implementation
|
||||
*/
|
||||
|
||||
#include "riscv_encoding.h"
|
||||
|
||||
.section .text.entry
|
||||
.align 8
|
||||
|
||||
/**
|
||||
* \brief Global interrupt disabled
|
||||
* \details
|
||||
* This function disable global interrupt.
|
||||
* \remarks
|
||||
* - All the interrupt requests will be ignored by CPU.
|
||||
*/
|
||||
.macro DISABLE_MIE
|
||||
csrc CSR_MSTATUS, MSTATUS_MIE
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for context save
|
||||
* \details
|
||||
* This macro save ABI defined caller saved registers in the stack.
|
||||
* \remarks
|
||||
* - This Macro could use to save context when you enter to interrupt
|
||||
* or exception
|
||||
*/
|
||||
/* Save caller registers */
|
||||
.macro SAVE_CONTEXT
|
||||
csrrw sp, CSR_MSCRATCHCSWL, sp
|
||||
/* Allocate stack space for context saving */
|
||||
#ifndef __riscv_32e
|
||||
addi sp, sp, -20*REGBYTES
|
||||
#else
|
||||
addi sp, sp, -14*REGBYTES
|
||||
#endif /* __riscv_32e */
|
||||
|
||||
STORE x1, 0*REGBYTES(sp)
|
||||
STORE x4, 1*REGBYTES(sp)
|
||||
STORE x5, 2*REGBYTES(sp)
|
||||
STORE x6, 3*REGBYTES(sp)
|
||||
STORE x7, 4*REGBYTES(sp)
|
||||
STORE x10, 5*REGBYTES(sp)
|
||||
STORE x11, 6*REGBYTES(sp)
|
||||
STORE x12, 7*REGBYTES(sp)
|
||||
STORE x13, 8*REGBYTES(sp)
|
||||
STORE x14, 9*REGBYTES(sp)
|
||||
STORE x15, 10*REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
STORE x16, 14*REGBYTES(sp)
|
||||
STORE x17, 15*REGBYTES(sp)
|
||||
STORE x28, 16*REGBYTES(sp)
|
||||
STORE x29, 17*REGBYTES(sp)
|
||||
STORE x30, 18*REGBYTES(sp)
|
||||
STORE x31, 19*REGBYTES(sp)
|
||||
#endif /* __riscv_32e */
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for restore caller registers
|
||||
* \details
|
||||
* This macro restore ABI defined caller saved registers from stack.
|
||||
* \remarks
|
||||
* - You could use this macro to restore context before you want return
|
||||
* from interrupt or exeception
|
||||
*/
|
||||
/* Restore caller registers */
|
||||
.macro RESTORE_CONTEXT
|
||||
LOAD x1, 0*REGBYTES(sp)
|
||||
LOAD x4, 1*REGBYTES(sp)
|
||||
LOAD x5, 2*REGBYTES(sp)
|
||||
LOAD x6, 3*REGBYTES(sp)
|
||||
LOAD x7, 4*REGBYTES(sp)
|
||||
LOAD x10, 5*REGBYTES(sp)
|
||||
LOAD x11, 6*REGBYTES(sp)
|
||||
LOAD x12, 7*REGBYTES(sp)
|
||||
LOAD x13, 8*REGBYTES(sp)
|
||||
LOAD x14, 9*REGBYTES(sp)
|
||||
LOAD x15, 10*REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
LOAD x16, 14*REGBYTES(sp)
|
||||
LOAD x17, 15*REGBYTES(sp)
|
||||
LOAD x28, 16*REGBYTES(sp)
|
||||
LOAD x29, 17*REGBYTES(sp)
|
||||
LOAD x30, 18*REGBYTES(sp)
|
||||
LOAD x31, 19*REGBYTES(sp)
|
||||
|
||||
/* De-allocate the stack space */
|
||||
addi sp, sp, 20*REGBYTES
|
||||
#else
|
||||
/* De-allocate the stack space */
|
||||
addi sp, sp, 14*REGBYTES
|
||||
#endif /* __riscv_32e */
|
||||
csrrw sp, CSR_MSCRATCHCSWL, sp
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for save necessary CSRs to stack
|
||||
* \details
|
||||
* This macro store MCAUSE, MEPC, MSUBM to stack.
|
||||
*/
|
||||
.macro SAVE_CSR_CONTEXT
|
||||
/* Store CSR mcause to stack using pushmcause */
|
||||
csrrwi x0, CSR_PUSHMCAUSE, 11
|
||||
/* Store CSR mepc to stack using pushmepc */
|
||||
csrrwi x0, CSR_PUSHMEPC, 12
|
||||
/* Store CSR msub to stack using pushmsub */
|
||||
csrrwi x0, CSR_PUSHMSUBM, 13
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for restore necessary CSRs from stack
|
||||
* \details
|
||||
* This macro restore MSUBM, MEPC, MCAUSE from stack.
|
||||
*/
|
||||
.macro RESTORE_CSR_CONTEXT
|
||||
LOAD x5, 13*REGBYTES(sp)
|
||||
csrw CSR_MSUBM, x5
|
||||
LOAD x5, 12*REGBYTES(sp)
|
||||
csrw CSR_MEPC, x5
|
||||
LOAD x5, 11*REGBYTES(sp)
|
||||
csrw CSR_MCAUSE, x5
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Exception/NMI Entry
|
||||
* \details
|
||||
* This function provide common entry functions for exception/nmi.
|
||||
* \remarks
|
||||
* This function provide a default exception/nmi entry.
|
||||
* ABI defined caller save register and some CSR registers
|
||||
* to be saved before enter interrupt handler and be restored before return.
|
||||
*/
|
||||
.section .text.trap
|
||||
/* In CLIC mode, the exeception entry must be 64bytes aligned */
|
||||
.align 6
|
||||
.global exc_entry
|
||||
exc_entry:
|
||||
/* Save the caller saving registers (context) */
|
||||
SAVE_CONTEXT
|
||||
/* Save the necessary CSR registers */
|
||||
SAVE_CSR_CONTEXT
|
||||
|
||||
/*
|
||||
* Set the exception handler function arguments
|
||||
* argument 1: mcause value
|
||||
* argument 2: current stack point(SP) value
|
||||
*/
|
||||
csrr a0, mcause
|
||||
mv a1, sp
|
||||
/*
|
||||
* TODO: Call the exception handler function
|
||||
* By default, the function template is provided in
|
||||
* system_Device.c, you can adjust it as you want
|
||||
*/
|
||||
call core_exception_handler
|
||||
|
||||
/* Restore the necessary CSR registers */
|
||||
RESTORE_CSR_CONTEXT
|
||||
/* Restore the caller saving registers (context) */
|
||||
RESTORE_CONTEXT
|
||||
|
||||
/* Return to regular code */
|
||||
mret
|
||||
|
||||
/**
|
||||
* \brief Non-Vector Interrupt Entry
|
||||
* \details
|
||||
* This function provide common entry functions for handling
|
||||
* non-vector interrupts
|
||||
* \remarks
|
||||
* This function provide a default non-vector interrupt entry.
|
||||
* ABI defined caller save register and some CSR registers need
|
||||
* to be saved before enter interrupt handler and be restored before return.
|
||||
*/
|
||||
.section .text.irq
|
||||
/* In CLIC mode, the interrupt entry must be 4bytes aligned */
|
||||
.align 2
|
||||
.global irq_entry
|
||||
/* This label will be set to MTVT2 register */
|
||||
irq_entry:
|
||||
/* Save the caller saving registers (context) */
|
||||
SAVE_CONTEXT
|
||||
/* Save the necessary CSR registers */
|
||||
SAVE_CSR_CONTEXT
|
||||
|
||||
/* This special CSR read/write operation, which is actually
|
||||
* claim the CLIC to find its pending highest ID, if the ID
|
||||
* is not 0, then automatically enable the mstatus.MIE, and
|
||||
* jump to its vector-entry-label, and update the link register
|
||||
*/
|
||||
csrrw ra, CSR_JALMNXTI, ra
|
||||
|
||||
/* Critical section with interrupts disabled */
|
||||
DISABLE_MIE
|
||||
|
||||
/* Restore the necessary CSR registers */
|
||||
RESTORE_CSR_CONTEXT
|
||||
/* Restore the caller saving registers (context) */
|
||||
RESTORE_CONTEXT
|
||||
|
||||
/* Return to regular code */
|
||||
mret
|
||||
|
||||
/* Default Handler for Exceptions / Interrupts */
|
||||
.global default_intexc_handler
|
||||
Undef_Handler:
|
||||
default_intexc_handler:
|
||||
1:
|
||||
j 1b
|
||||
|
||||
Reference in New Issue
Block a user