support T-HEAD Xuantie-E9xx Series CPU on Smart-EVB, eg. E906/F/D/P, E907/F/D/P

This commit is contained in:
chenzx 2021-07-14 20:12:55 +08:00
parent 2602f54ff4
commit 236e01bead
17 changed files with 320 additions and 63 deletions

View File

@ -26,7 +26,7 @@ extern void ioreuse_initial(void);
/**
* This function will initial smartl-evb(e906) board.
* This function will initial smart-evb board.
*/
void rt_hw_board_init(void)
{

View File

@ -290,6 +290,42 @@ typedef struct
/*@} end of group CSI_CACHE */
#define SYSMAP_SYSMAPCFG_B_Pos 0U /*!< SYSMAP SYSMAPCFG: B Position */
#define SYSMAP_SYSMAPCFG_B_Msk (0x1UL << SYSMAP_SYSMAPCFG_B_Pos) /*!< SYSMAP SYSMAPCFG: B Mask */
#define SYSMAP_SYSMAPCFG_C_Pos 1U /*!< SYSMAP SYSMAPCFG: C Position */
#define SYSMAP_SYSMAPCFG_C_Msk (0x1UL << SYSMAP_SYSMAPCFG_C_Pos) /*!< SYSMAP SYSMAPCFG: C Mask */
#define SYSMAP_SYSMAPCFG_SO_Pos 2U /*!< SYSMAP SYSMAPCFG: SO Position */
#define SYSMAP_SYSMAPCFG_SO_Msk (0x1UL << SYSMAP_SYSMAPCFG_SO_Pos) /*!< SYSMAP SYSMAPCFG: SO Mask */
/**
\ingroup CSI_core_register
\defgroup CSI_SYSMAP system map (SYSMAP)
\brief Type definitions for the SYSMAP Registers
@{
*/
typedef struct
{
__IOM uint32_t SYSMAPADDR0; /*!< Offset: 0x000 (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPCFG0; /*!< Offset: 0x004 (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPADDR1; /*!< Offset: 0x008 (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPCFG1; /*!< Offset: 0x00c (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPADDR2; /*!< Offset: 0x010 (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPCFG2; /*!< Offset: 0x014 (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPADDR3; /*!< Offset: 0x018 (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPCFG3; /*!< Offset: 0x01c (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPADDR4; /*!< Offset: 0x020 (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPCFG4; /*!< Offset: 0x024 (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPADDR5; /*!< Offset: 0x028 (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPCFG5; /*!< Offset: 0x02c (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPADDR6; /*!< Offset: 0x030 (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPCFG6; /*!< Offset: 0x034 (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPADDR7; /*!< Offset: 0x038 (R/W) SYSMAP configure register */
__IOM uint32_t SYSMAPCFG7; /*!< Offset: 0x03c (R/W) SYSMAP configure register */
} SYSMAP_Type;
/*@} end of group CSI_SYSMAP */
/**
\ingroup CSI_core_register
\defgroup CSI_SysTick System Tick Timer (CORET)
@ -383,12 +419,14 @@ typedef struct
#define TCIP_BASE (0xE000E000UL) /*!< Titly Coupled IP Base Address */
#define CORET_BASE (0xE0004000UL) /*!< CORET Base Address */
#define CLIC_BASE (0xE0800000UL) /*!< CLIC Base Address */
#define SYSMAP_BASE (0xEFFFF000UL) /*!< SYSMAP Base Address */
#define DCC_BASE (0xE4010000UL) /*!< DCC Base Address */
#define CACHE_BASE (TCIP_BASE + 0x1000UL) /*!< CACHE Base Address */
#define CORET ((CORET_Type *) CORET_BASE ) /*!< SysTick configuration struct */
#define CLIC ((CLIC_Type *) CLIC_BASE ) /*!< CLIC configuration struct */
#define DCC ((DCC_Type *) DCC_BASE ) /*!< DCC configuration struct */
#define SYSMAP ((SYSMAP_Type *) SYSMAP_BASE ) /*!< SYSMAP configuration struct */
#define CACHE ((CACHE_Type *) CACHE_BASE ) /*!< cache configuration struct */
/*@} */
@ -646,7 +684,7 @@ __STATIC_INLINE void csi_mpu_disable_region(uint32_t idx)
*/
__STATIC_INLINE uint32_t csi_coret_config(uint32_t ticks, int32_t IRQn)
{
if (CORET->MTIMECMP) {
if ((CORET->MTIMECMP != 0) && (CORET->MTIMECMP != 0xffffffffffffffff)) {
CORET->MTIMECMP = CORET->MTIMECMP + ticks;
} else {
CORET->MTIMECMP = CORET->MTIME + ticks;
@ -691,6 +729,126 @@ __STATIC_INLINE uint32_t csi_coret_get_valueh(void)
}
/*@} end of CSI_Core_SysTickFunctions */
/* ########################## SYSMAP functions #################################### */
/**
\ingroup CSI_Core_FunctionInterface
\defgroup CSI_Core_SYSMAPFunctions SYSMAP Functions
\brief Functions that manage system map attribute
@{
*/
/**
\brief Get SYSMAPCFGx Register by index
\details Returns the content of the SYSMAPxCFG Register.
\param [in] idx SYSMAP region index
\return SYSMAPxCFG Register value
*/
__STATIC_INLINE uint8_t __get_SYSMAPCFGx(uint32_t idx)
{
switch (idx)
{
case 0: return SYSMAP->SYSMAPCFG0;
case 1: return SYSMAP->SYSMAPCFG1;
case 2: return SYSMAP->SYSMAPCFG2;
case 3: return SYSMAP->SYSMAPCFG3;
case 4: return SYSMAP->SYSMAPCFG4;
case 5: return SYSMAP->SYSMAPCFG5;
case 6: return SYSMAP->SYSMAPCFG6;
case 7: return SYSMAP->SYSMAPCFG7;
default: return 0;
}
}
/**
\brief Set SYSMAPCFGx by index
\details Writes the given value to the SYSMAPxCFG Register.
\param [in] idx SYSMAPx region index
\param [in] sysmapxcfg SYSMAPxCFG Register value to set
*/
__STATIC_INLINE void __set_SYSMAPCFGx(uint32_t idx, uint32_t sysmapxcfg)
{
switch (idx)
{
case 0: SYSMAP->SYSMAPCFG0 = sysmapxcfg; break;
case 1: SYSMAP->SYSMAPCFG1 = sysmapxcfg; break;
case 2: SYSMAP->SYSMAPCFG2 = sysmapxcfg; break;
case 3: SYSMAP->SYSMAPCFG3 = sysmapxcfg; break;
case 4: SYSMAP->SYSMAPCFG4 = sysmapxcfg; break;
case 5: SYSMAP->SYSMAPCFG5 = sysmapxcfg; break;
case 6: SYSMAP->SYSMAPCFG6 = sysmapxcfg; break;
case 7: SYSMAP->SYSMAPCFG7 = sysmapxcfg; break;
default: return;
}
}
/**
\brief Get SYSMAPADDRx Register by index
\details Returns the content of the SYSMAPADDRx Register.
\param [in] idx SYSMAP region index
\return SYSMAPADDRx Register value
*/
__STATIC_INLINE uint32_t __get_SYSMAPADDRx(uint32_t idx)
{
switch(idx)
{
case 0: return SYSMAP->SYSMAPADDR0;
case 1: return SYSMAP->SYSMAPADDR1;
case 2: return SYSMAP->SYSMAPADDR2;
case 3: return SYSMAP->SYSMAPADDR3;
case 4: return SYSMAP->SYSMAPADDR4;
case 5: return SYSMAP->SYSMAPADDR5;
case 6: return SYSMAP->SYSMAPADDR6;
case 7: return SYSMAP->SYSMAPADDR7;
default: return 0;
}
}
/**
\brief Set SYSMAPADDRx by index
\details Writes the given value to the SYSMAPADDRx Register.
\param [in] idx SYSMAP region index
\param [in] sysmapaddr SYSMAPADDRx Register value to set
*/
__STATIC_INLINE void __set_SYSMAPADDRx(uint32_t idx, uint32_t sysmapxaddr)
{
switch (idx)
{
case 0: SYSMAP->SYSMAPADDR0 = sysmapxaddr; break;
case 1: SYSMAP->SYSMAPADDR1 = sysmapxaddr; break;
case 2: SYSMAP->SYSMAPADDR2 = sysmapxaddr; break;
case 3: SYSMAP->SYSMAPADDR3 = sysmapxaddr; break;
case 4: SYSMAP->SYSMAPADDR4 = sysmapxaddr; break;
case 5: SYSMAP->SYSMAPADDR5 = sysmapxaddr; break;
case 6: SYSMAP->SYSMAPADDR6 = sysmapxaddr; break;
case 7: SYSMAP->SYSMAPADDR7 = sysmapxaddr; break;
default: return;
}
}
/**
\brief configure system map attribute.
\details
\param [in] idx system map region (0, 1, 2, ..., 7).
\param [in] base_addr base address must be aligned with page size.
\param [in] enable enable or disable memory protected region.
*/
__STATIC_INLINE void csi_sysmap_config_region(uint32_t idx, uint32_t base_addr, uint32_t attr)
{
uint32_t addr = 0;
if (idx > 7) {
return;
}
addr = base_addr >> 12;
attr = attr << 2;
__set_SYSMAPADDRx(idx, addr);
__set_SYSMAPCFGx(idx, attr);
}
/*@} end of CSI_Core_SYSMAPFunctions */
/* ##################################### DCC function ########################################### */
/**
@ -986,7 +1144,7 @@ __STATIC_INLINE void csi_dcache_invalid_range (uint32_t *addr, int32_t dsize)
__STATIC_INLINE void csi_dcache_clean_range (uint32_t *addr, int32_t dsize)
{
#if (__DCACHE_PRESENT == 1)
#if (__DCACHE_PRESENT == 1U)
int32_t op_size = dsize + (uint32_t)addr % 32;
uint32_t op_addr = (uint32_t) addr & CACHE_INV_ADDR_Msk;
int32_t linesize = 32;

View File

@ -184,6 +184,29 @@ __ALWAYS_STATIC_INLINE void __set_MHCR(uint32_t mhcr)
__ASM volatile("csrw mhcr, %0" : : "r"(mhcr));
}
/**
\brief Get MHINT
\details Returns the content of the MHINT Register.
\return MHINT Register value
*/
__ALWAYS_STATIC_INLINE uint32_t __get_MHINT(void)
{
uint32_t result;
__ASM volatile("csrr %0, mhint" : "=r"(result));
return (result);
}
/**
\brief Set MHINT
\details Writes the given value to the MHINT Register.
\param [in] MHINT Register value to set
*/
__ALWAYS_STATIC_INLINE void __set_MHINT(uint32_t mhint)
{
__ASM volatile("csrw mhint, %0" : : "r"(mhint));
}
/**
\brief Get MISA Register
\details Returns the content of the MISA Register.

View File

@ -25,7 +25,7 @@ extern void systick_handler(void);
extern void xPortSysTickHandler(void);
extern void OSTimeTick(void);
#define ATTRIBUTE_ISR
#define ATTRIBUTE_ISR __attribute__ ((interrupt ("machine")))
#define readl(addr) \
({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
@ -37,7 +37,7 @@ extern void OSTimeTick(void);
#endif
void __attribute__((isr)) SysTick_Handler(void)
ATTRIBUTE_ISR void SysTick_Handler(void)
{
#if(CONFIG_KERNEL_RTTHREAD == 1)
CSI_INTRPT_ENTER();

View File

@ -24,7 +24,7 @@ __Vectors:
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_IRQHandler
.long SysTick_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
@ -35,38 +35,39 @@ __Vectors:
.long Default_Handler
/* External interrupts */
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long USART_IRQHandler
.long Default_Handler
.long TIM0_IRQHandler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.size __Vectors,.-__Vectors
.text
.align 2

View File

@ -39,6 +39,23 @@ static void _system_init_for_kernel(void)
drv_irq_enable(CORET_IRQn);
}
/**
* @brief initialize system map
* @param None
* @return None
*/
void systemmap_config(void)
{
csi_sysmap_config_region(0, 0x20000000, SYSMAP_SYSMAPCFG_B_Msk | SYSMAP_SYSMAPCFG_C_Msk);
csi_sysmap_config_region(1, 0x40000000, SYSMAP_SYSMAPCFG_B_Msk | SYSMAP_SYSMAPCFG_C_Msk);
csi_sysmap_config_region(2, 0x50000000, SYSMAP_SYSMAPCFG_SO_Msk);
csi_sysmap_config_region(3, 0x50700000, SYSMAP_SYSMAPCFG_B_Msk | SYSMAP_SYSMAPCFG_C_Msk);
csi_sysmap_config_region(4, 0x60000000, SYSMAP_SYSMAPCFG_SO_Msk);
csi_sysmap_config_region(5, 0x80000000, SYSMAP_SYSMAPCFG_B_Msk | SYSMAP_SYSMAPCFG_C_Msk);
csi_sysmap_config_region(6, 0x90000000, SYSMAP_SYSMAPCFG_B_Msk | SYSMAP_SYSMAPCFG_C_Msk);
csi_sysmap_config_region(7, 0xf0000000, SYSMAP_SYSMAPCFG_SO_Msk);
}
/**
* @brief initialize the system
* Initialize the psr and vbr.
@ -48,8 +65,9 @@ static void _system_init_for_kernel(void)
void SystemInit(void)
{
int i;
systemmap_config();
/* enable mstatus FS */
#if ((CONFIG_CPU_E906F==1) || (CONFIG_CPU_E906FD==1))
#if (__riscv_flen)
uint32_t mstatus = __get_MSTATUS();
mstatus |= (1 << 13);
__set_MSTATUS(mstatus);
@ -77,7 +95,9 @@ void SystemInit(void)
/* tspend use positive interrupt */
CLIC->CLICINT[Machine_Software_IRQn].ATTR = 0x3;
#if ((CONFIG_CPU_E902 != 1) && (CONFIG_CPU_E902M != 1))
csi_dcache_enable();
#endif
csi_icache_enable();
drv_irq_enable(Machine_Software_IRQn);

View File

@ -23,12 +23,12 @@ void trap_c(uint32_t *regs)
vec = __get_MCAUSE() & 0x3FF;
printf("CPU Exception: NO.%d", vec);
printf("CPU Exception: NO.%ld", vec);
printf("\n");
for (i = 0; i < 31; i++)
{
printf("x%d: %08x\t", i + 1, regs[i]);
printf("x%d: %08lx\t", i + 1, regs[i]);
if ((i % 4) == 3)
{
@ -37,8 +37,8 @@ void trap_c(uint32_t *regs)
}
printf("\n");
printf("mepc : %08x\n", regs[31]);
printf("mstatus: %08x\n", regs[32]);
printf("mepc : %08lx\n", regs[31]);
printf("mstatus: %08lx\n", regs[32]);
if (trap_c_callback)
{

View File

@ -10,6 +10,8 @@
#include <csi_config.h>
#include <rtconfig.h>
#include <cpuport.h>
/* Enable interrupts when returning from the handler */
#define MSTATUS_PRV1 0x1880
@ -47,7 +49,7 @@ irq_mstatus_fs_flag:
Default_IRQHandler:
ipush
#ifdef ARCH_RISCV_FPU
#ifdef __riscv_flen
csrr t1, mstatus
srli t1, t1, 13
andi t1, t1, 0x3
@ -92,7 +94,7 @@ Default_IRQHandler:
li t0, MSTATUS_PRV1
csrs mstatus, t0
#ifdef ARCH_RISCV_FPU
#ifdef __riscv_flen
la t0, irq_mstatus_fs_flag
lw t1, (t0)
li t0, 0x3
@ -135,6 +137,7 @@ Default_IRQHandler:
.type trap, %function
trap:
/* Check for interrupt */
j .
addi sp, sp, -4
sw t0, 0x0(sp)
csrr t0, mcause
@ -235,7 +238,7 @@ Default_Handler:
sw t5, 56(sp)
sw t6, 60(sp)
#ifdef ARCH_RISCV_FPU
#ifdef __riscv_flen
addi sp, sp, -(20*FREGBYTES)
FSTORE ft0, 0 * FREGBYTES(sp)
FSTORE ft1, 1 * FREGBYTES(sp)
@ -263,7 +266,7 @@ Default_Handler:
lw t0, (t0)
jalr t0
#ifdef ARCH_RISCV_FPU
#ifdef __riscv_flen
FLOAD ft0, 0 * FREGBYTES(sp)
FLOAD ft1, 1 * FREGBYTES(sp)
FLOAD ft2, 2 * FREGBYTES(sp)

View File

@ -101,6 +101,7 @@ SECTIONS
*(.rodata1)
*(.rodata*)
*(.rodata.*)
*(.srodata*)
*(.rodata.str1.4)
. = ALIGN(0x4) ;
__ctor_start__ = .;
@ -116,10 +117,10 @@ SECTIONS
} > REGION_RODATA
.data : {
. = ALIGN(0x4) ;
__sdata = . ;
__data_start__ = . ;
__sdata = . ;
data_start = . ;
KEEP(*startup.o(*.vectors*))
KEEP(*startup_gcc.o(*.vectors*))
*(.got.plt)
*(.got)
*(.gnu.linkonce.r*)

11
bsp/thead-smart/gdbinit Normal file
View File

@ -0,0 +1,11 @@
target remote 172.16.201.64:1025
set *(int *)0x0=0x6f
si
reset
set *(int *)0x40011008=0x0
set *(int *)0x4001101c=0x0
set disassemble-next-line on
show disassemble-next-line
lo

View File

@ -39,9 +39,19 @@
#define RT_CONSOLE_DEVICE_NAME "uart1"
#define RT_VER_NUM 0x40003
#define ARCH_RISCV
#define ARCH_RISCV32
#if(__riscv_flen == 64)
#define ARCH_RISCV_FPU
#define ARCH_RISCV_FPU_D
#elif(__riscv_flen == 32)
#define ARCH_RISCV_FPU
#define ARCH_RISCV_FPU_S
#define ARCH_RISCV32
#else
#endif
#ifdef __riscv_zp64
#define ARCH_RISCV_DSP
#endif
/* RT-Thread Components */

View File

@ -1,9 +1,11 @@
import os
# toolchains options
# CPUNAME = e906/e906f/e906fd/e906p/e906fp/e906fdp
# CPUNAME = e907/e907f/e907fd/e907p/e907fp/e907fdp
ARCH ='risc-v'
CPU ='e906'
CPUNAME ='e906f'
CPU ='e9xx'
CPUNAME ='e906fdp'
VENDOR ='t-head'
CROSS_TOOL ='gcc'
@ -12,9 +14,9 @@ if os.getenv('RTT_CC'):
if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc'
EXEC_PATH = r'/home/xinge/tools/riscv64-elf-x86_64-20200616-1.9.6/bin'
EXEC_PATH = r'/home/chenzx/.thead/riscv64-elf-x86_64-2.0.1/bin/'
else:
print 'Please make sure your toolchains is GNU GCC!'
print ('Please make sure your toolchains is GNU GCC!')
exit(0)
if os.getenv('RTT_EXEC_PATH'):
@ -37,16 +39,23 @@ if PLATFORM == 'gcc':
OBJCPY = PREFIX + 'objcopy'
STRIP = PREFIX + 'strip'
if CPUNAME == 'e906fd':
DEVICE = ' -march=rv32imafdcxthead -mabi=ilp32d'
if CPUNAME == 'e906f':
DEVICE = ' -march=rv32imafcxthead -mabi=ilp32f'
if CPUNAME == 'e906':
DEVICE = ' -march=rv32imacxthead -mabi=ilp32'
if CPUNAME == 'e906fdp' or CPUNAME == 'e907fdp':
DEVICE = ' -march=rv32imafdcpzp64_xtheade -mabi=ilp32d'
if CPUNAME == 'e906fp' or CPUNAME == 'e907fp':
DEVICE = ' -march=rv32imafcpzp64_xtheade -mabi=ilp32f'
if CPUNAME == 'e906p' or CPUNAME == 'e907p':
DEVICE = ' -march=rv32imacpzp64_xtheade -mabi=ilp32'
if CPUNAME == 'e906fd' or CPUNAME == 'e907fd':
DEVICE = ' -march=rv32imafdc_xtheade -mabi=ilp32d'
if CPUNAME == 'e906f' or CPUNAME == 'e907f':
DEVICE = ' -march=rv32imafc_xtheade -mabi=ilp32f'
if CPUNAME == 'e906' or CPUNAME == 'e907':
DEVICE = ' -march=rv32imac_xtheade -mabi=ilp32'
CFLAGS = DEVICE + ' -c -g -ffunction-sections -fdata-sections -Wall -mcmodel=medlow'
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
LFLAGS = DEVICE + ' -nostartfiles -Wl,--no-whole-archive -T gcc_csky.ld -lm -lc -lgcc -Wl,-gc-sections -Wl,-zmax-page-size=1024'
LFLAGS = DEVICE + ' -nostartfiles -Wl,--no-whole-archive -T gcc_csky.ld -lm -lc -lgcc -Wl,-gc-sections -Wl,-zmax-page-size=1024 -Wl,-Map=rtt.map'
CPATH = ''
LPATH = ''

View File

@ -10,7 +10,7 @@ group = []
list = os.listdir(cwd)
# add common code files
if rtconfig.CPU == "e906" :
if rtconfig.CPU == "e9xx" :
group = group
elif rtconfig.CPU == "nuclei" :
group = group
@ -20,7 +20,7 @@ else :
group = group + SConscript(os.path.join(cwd, 'common', 'SConscript'))
# cpu porting code files
if rtconfig.CPU == "e906" :
if rtconfig.CPU == "e9xx" :
group = group + SConscript(os.path.join(cwd, rtconfig.VENDOR, rtconfig.CPU, 'SConscript'))
else :
group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript'))

View File

@ -181,7 +181,11 @@ PendSV_Handler:
FSTORE f31, 31 * FREGBYTES(sp)
#endif
#ifdef ARCH_RISCV_DSP
addi sp, sp, -33 * REGBYTES
#else
addi sp, sp, -32 * REGBYTES
#endif
STORE x1, 1 * REGBYTES(sp)
csrr x1, mepc
@ -221,6 +225,10 @@ PendSV_Handler:
STORE x29, 29 * REGBYTES(sp)
STORE x30, 30 * REGBYTES(sp)
STORE x31, 31 * REGBYTES(sp)
#ifdef ARCH_RISCV_DSP
csrr t0, vxsat
STORE t0, 32 * REGBYTES(sp)
#endif
/* store from_thread sp */
la t0, rt_interrupt_from_thread
@ -237,6 +245,12 @@ PendSV_Handler:
lw t0, (t0)
LOAD sp, (t0)
#ifdef ARCH_RISCV_DSP
LOAD a1, 32 * REGBYTES(sp)
csrw vxsat, a1
#endif
/* restore ra to mepc */
LOAD a1, 0 * REGBYTES(sp)
csrw mepc, a1
@ -277,7 +291,11 @@ PendSV_Handler:
LOAD x30, 30 * REGBYTES(sp)
LOAD x31, 31 * REGBYTES(sp)
#ifdef ARCH_RISCV_DSP
addi sp, sp, 33 * REGBYTES
#else
addi sp, sp, 32 * REGBYTES
#endif
#ifdef ARCH_RISCV_FPU
FLOAD f0, 0 * FREGBYTES(sp)

View File

@ -53,6 +53,9 @@ struct rt_hw_stack_frame
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 */
#ifdef ARCH_RISCV_DSP
rt_ubase_t vxsat; /* P-ext vxsat reg */
#endif
#ifdef ARCH_RISCV_FPU
rv_floatreg_t f0; /* f0 */
rv_floatreg_t f1; /* f1 */