rt-thread/libcpu/risc-v/nuclei/cpuport.c

260 lines
8.0 KiB
C
Raw Normal View History

[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: commit b7368bc2ed725c42f9adc297d0e9cf3ed706a520 Author: 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> commit 2c42a997f7b5d8aa53bdaf19ccb30596091a112d Author: 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> commit 915ad4c076ff3d7cebda896537605e7f7939b7af Author: 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> commit fe43869c79675a25669447d57ea5d77385e07ca5 Author: 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> commit 8fd31727bc7ff51c83a3c47840cff1bfb100c0ba Author: 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> commit b432308b20cdf24dfcc1398511d1d83bce6a9df2 Author: 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> commit 7366173d749d8a51ed8d48eca09007d27aee8ad8 Author: 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> commit 8c2cd4745b7279a6721946d119441bbf7fd1a9c2 Author: 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> commit fa8a2f24ea5e4dbce714ffda16c1ce558e5b5ddb Author: 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> commit 1be40bc50be43dfcdd105291bd24355498f9fef3 Author: 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> commit 4c8beb204b7ee3e38c04e1f23a1f7e4ce48aa196 Author: 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> commit da2bcf5c56ef32b611405a8e591ecd3f1e598b11 Author: 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> commit 0b932c677a7934d60e70da141744790aec202ef6 Author: 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> commit 0431f6f01f6efab2900de552abede83639415431 Author: 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> commit 0e1f502edfddff93a4a66c041be68560ef4828eb Author: 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> commit 1131f6e6483d8f2fbafe07f4e598fc8f802ee85d Author: 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> commit ad81c1d3bf9d80d2b561c94e903e7ce4ca2c68c6 Author: 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> commit d780138a1abf5da5097cc89e6a428ebeae06f284 Author: 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> commit 60320d34b1d88315efe1b566fd6bc75c69851f06 Author: 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> commit a042b806efe0ea3bc9dba80ebc7696e5941ba35f Author: 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> commit 2a9603adcb584b29886a2b93ded2473f4e8bffb1 Author: 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> commit 34aaf6aebae75c3ee9d38cc17e6bdb826ed9e357 Author: 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> commit 3451466e9d8da3c3c8a631be69f3c7a5e6220c21 Author: 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>
2020-04-17 21:07:29 +08:00
/*
* 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);
}