From 921fbfbc219f48c77d8b4296d6038bf04a8ff53b Mon Sep 17 00:00:00 2001 From: ArcherChang Date: Fri, 25 Aug 2017 10:25:33 +0800 Subject: [1] 添加Andes N1068体系; [2] 基于AE210P EVB板; [3] 详细信息参阅bsp/AE210P/readme文件夹; 《Andes工程创建和调试》文档;等。 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/nds32/context_gcc.S | 188 ++++++++++++++++++++++++++++++++++++++ libcpu/nds32/cpuport.c | 221 +++++++++++++++++++++++++++++++++++++++++++++ libcpu/nds32/os_cpu.h | 33 +++++++ 3 files changed, 442 insertions(+) create mode 100644 libcpu/nds32/context_gcc.S create mode 100644 libcpu/nds32/cpuport.c create mode 100644 libcpu/nds32/os_cpu.h (limited to 'libcpu') diff --git a/libcpu/nds32/context_gcc.S b/libcpu/nds32/context_gcc.S new file mode 100644 index 0000000000..8d5f3287e9 --- /dev/null +++ b/libcpu/nds32/context_gcc.S @@ -0,0 +1,188 @@ +#include "nds32.h" +#include "os_cpu_common.h" +#include "config.h" + + .align 4 +! void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); +! R0 --> from +! R1 --> to + .section .text + .global rt_hw_context_switch_interrupt + .global rt_hw_context_switch +rt_hw_context_switch_interrupt: +rt_hw_context_switch: + push25 $r6,#8 ! {$r6, $fp, $gp, $lp} + + la $r2, rt_thread_switch_interrupt_flag + lw $r3, [$r2] + movi $r4, #1 + beq $r3, $r4, _reswitch + sw $r4, [$r2] ! set rt_thread_switch_interrupt_flag to 1 + + la $r2, rt_interrupt_from_thread + sw $r0, [$r2] ! set rt_interrupt_from_thread +_reswitch: + la $r2, rt_interrupt_to_thread + sw $r1, [$r2] ! set rt_interrupt_to_thread + bal hal_intc_swi_trigger ! trigger the swi exception (causes context switch) + + pop25 $r6,#8 ! {$r6, $fp, $gp, $lp} + +! R0 --> switch from thread stack +! R1 --> switch to thread stack +! psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack + + .align 4 + .global OS_Trap_Interrupt_SWI +OS_Trap_Interrupt_SWI: +! pushm $r0, $r5 + setgie.d ! disable interrupt to protect context switch + dsb + + IntlDescend ! Descend interrupt level + + movi $r0, 0x0 + mtsr $r0, $INT_PEND ! clean SWI pending + + la $r0, rt_thread_switch_interrupt_flag ! get rt_thread_switch_interrupt_flag + lw $r1, [$r0] + beqz $r1, pendsv_exit ! swi has already been handled + + movi $r1, #0 + sw $r1, [$r0] ! clear rt_thread_switch_interrupt_flag to 0 + + la $r0, rt_interrupt_from_thread + lw $r1, [$r0] + beqz $r1, switch_to_thread ! skip register save at the first time(os startup phase) + + SAVE_ALL + + move $r1, $sp + la $r0, rt_interrupt_from_thread + lw $r0, [$r0] + sw $r1, [$r0] + +switch_to_thread: + la $r1, rt_interrupt_to_thread + lw $r1, [$r1] + lw $r1, [$r1] ! load thread stack pointer + move $sp, $r1 ! update stack pointer + RESTORE_ALL ! pop registers + +pendsv_exit: + setgie.e + iret + + .align 4 +! void rt_hw_context_switch_to(rt_uint32 to); +! R0 --> to + .global rt_hw_context_switch_to +rt_hw_context_switch_to: + la $r1, rt_interrupt_to_thread + sw $r0, [$r1] + + ! set from thread to 0 + la $r1, rt_interrupt_from_thread + movi $r0, #0 + sw $r0, [$r1] + + ! set interrupt flag to 1 + la $r1, rt_thread_switch_interrupt_flag + movi $r0, #1 + sw $r0, [$r1] + + ! set the SWI exception priority(must be the lowest level) + ! todo + + ! trigger the SWI exception (causes context switch) + jal hal_intc_swi_trigger + + setgie.e ! enable interrupts at processor level + +1: + b 1b ! never reach here + +#ifndef VECTOR_NUMINTRS +#define VECTOR_NUMINTRS 32 +#endif + + .global OS_Trap_Int_Common + + ! Set up Interrupt vector ISR + ! HW#IRQ_SWI_VECTOR : OS_Trap_Interrupt_SWI (SWI) + ! HW#n : OS_Trap_Int_Common + + .macro SET_HWISR num + .global OS_Trap_Interrupt_HW\num + .if \num == IRQ_SWI_VECTOR + .set OS_Trap_Interrupt_HW\num, OS_Trap_Interrupt_SWI + .else + .set OS_Trap_Interrupt_HW\num, OS_Trap_Int_Common + .endif + .endm + + .altmacro + .set irqno, 0 + .rept VECTOR_NUMINTRS + SET_HWISR %irqno + .set irqno, irqno+1 + .endr + .noaltmacro + +! .global OS_Trap_Int_Common +OS_Trap_Int_Common: +#ifdef MPU_SUPPORT + mfsr $p1, $PSW + ori $p1, $p1, (PSW_mskIT | PSW_mskDT) + mtsr $p1, $PSW ! enable IT/DT + dsb + pushm $r0, $r5 + move $r0, $p0 ! IRQ number +#endif + ! $r0 : HW Interrupt vector number + SAVE_CALLER + + IntlDescend ! Descend interrupt level + + mfsr $r1, $IPSW ! Use IPSW.CPL to check come from thread or ISR + srli45 $r1, #PSW_offCPL + fexti33 $r1, #0x2 ! IPSW.CPL + bnec $r1, #0x7, 2f ! IPSW.CPL != 7, come form ISR, reentrant + + move $fp, $sp ! save old stack pointer + la $sp, __OS_Int_Stack ! switch to interrupt stack +2: + setgie.e ! allow nested now + + ! The entire CPU state is now stashed on the stack, + ! and the stack is also 8-byte alignment. + ! We can call C program based interrupt handler now. + la $r1, OS_CPU_Vector_Table + lw $r1, [$r1+($r0<<2)] ! ISR function pointer + jral $r1 ! Call ISR + + la $r1, __OS_Int_Stack ! Check for nested interruption return + bne $r1, $sp, 3f ! $sp != __OS_Int_Stack? + + move $sp, $fp ! Move back to the thread stack +3: + RESTORE_CALLER + + iret + +! .set OS_Trap_Interrupt_HW9, OS_Trap_Interrupt_SWI +! .set OS_Trap_Interrupt_HW19, OS_Trap_Int_Common + +!********************************************* +! POINTERS TO VARIABLES +!********************************************* +#ifdef MPU_SUPPORT + .section privileged_data +#else + .section .bss +#endif + .skip IRQ_STACK_SIZE + .align 3 +__OS_Int_Stack: + + .end diff --git a/libcpu/nds32/cpuport.c b/libcpu/nds32/cpuport.c new file mode 100644 index 0000000000..17523f2430 --- /dev/null +++ b/libcpu/nds32/cpuport.c @@ -0,0 +1,221 @@ +/* + * File : cpuport.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard first version + * 2011-02-14 onelife Modify for EFM32 + * 2011-06-17 onelife Merge all of the C source code into cpuport.c + * 2012-12-23 aozima stack addr align to 8byte. + * 2012-12-29 Bernard Add exception hook. + * 2013-07-09 aozima enhancement hard fault exception handler. + */ + +#include + +#include "nds32.h" + +/* + * Initialise the stack of a task to look exactly as if a call to + * SAVE_CONTEXT had been called. + * + * See header file for description. + * + * + * Stack Layout: + * High |-----------------| + * | $R5 | + * |-----------------| + * | . | + * | . | + * |-----------------| + * | $R0 | + * |-----------------| + * | $R30 (LP) | + * |-----------------| + * | $R29 (GP) | + * |-----------------| + * | $R28 (FP) | + * |-----------------| + * | $R15 $R27 | + * |-----------------| + * | $R10 $R26 | + * |-----------------| + * | . | + * | . | + * |-----------------| + * | $R6 | + * |-----------------| + * | $IFC_LP | (Option) + * |-----------------| + * | $LC/$LE/$LB | (Option) + * | (ZOL) | + * |-----------------| + * | $IPSW | + * |-----------------| + * | $IPC | + * |-----------------| + * | Dummy word | (Option, only exist when IFC & ZOL both configured) + * |-----------------| + * | $FPU | (Option) + * |-----------------| + * Low + * + */ + +struct stack_frame +{ + rt_uint32_t topOfStack[34]; +}; + +/* flag in interrupt handling */ +rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrupt_flag; +/* exception hook */ +static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL; + +rt_base_t rt_hw_interrupt_disable(void) +{ + rt_base_t level = __nds32__mfsr(NDS32_SR_PSW); + + GIE_DISABLE(); + + return level; +} + +void rt_hw_interrupt_enable(rt_base_t level) +{ + if (level & PSW_mskGIE) + GIE_ENABLE(); +} + +/* For relax support, must initial $gp at task init*/ +extern uint32_t _SDA_BASE_ __attribute__ ((weak)); + +/************************************************************** + * 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) +{ + rt_int32_t i; + rt_uint32_t *pxTopOfStack; + + pxTopOfStack = (rt_uint32_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 4); + + /* Simulate the stack frame as it would be created by a context switch */ + /* R0 ~ R5 registers */ + for (i = 5; i >= 1; i--) /* R5, R4, R3, R2 and R1. */ + *--pxTopOfStack = (rt_uint32_t)0x01010101UL * i; + *--pxTopOfStack = (rt_uint32_t)parameter; /* R0 : Argument */ + + /* R6 ~ R30 registers */ + *--pxTopOfStack = (rt_uint32_t)texit; /* R30: $LP */ + *--pxTopOfStack = (rt_uint32_t)&_SDA_BASE_; /* R29: $GP */ + *--pxTopOfStack = (rt_uint32_t)0x2828282828; /* R28: $FP */ +#ifdef __NDS32_REDUCE_REGS__ + *--pxTopOfStack = (rt_uint32_t)0x1515151515; /* R15 */ + for (i = 10; i >= 6; i--) /* R10 ~ R6 */ + *--pxTopOfStack = (rt_uint32_t)0x01010101UL * i; +#else + for (i = 27; i >= 6; i--) /* R27 ~ R6 */ + *--pxTopOfStack = (rt_uint32_t)0x01010101UL * i; +#endif + + /* IFC system register */ +#ifdef __TARGET_IFC_EXT + *--pxTopOfStack = (rt_uint32_t)0x0; /* $IFC_LP */ +#endif + + /* ZOL system registers */ +#ifdef __TARGET_ZOL_EXT + *--pxTopOfStack = (rt_uint32_t)0x0; /* $LC */ + *--pxTopOfStack = (rt_uint32_t)0x0; /* $LE */ + *--pxTopOfStack = (rt_uint32_t)0x0; /* $LB */ +#endif + + /* IPSW and IPC system registers */ + /* Default IPSW: enable GIE, set CPL to 7, clear IFCON */ + i = (__nds32__mfsr(NDS32_SR_PSW) | PSW_mskGIE | PSW_mskCPL) & ~PSW_mskIFCON; + *--pxTopOfStack = (rt_uint32_t)i; /* $IPSW */ + *--pxTopOfStack = (rt_uint32_t)tentry; /* $IPC */ + + /* Dummy word for 8-byte stack alignment */ +#if defined(__TARGET_IFC_EXT) && defined(__TARGET_ZOL_EXT) + *--pxTopOfStack = (rt_uint32_t)0xFFFFFFFF; /* Dummy */ +#endif + + /* FPU registers */ +#ifdef __TARGET_FPU_EXT + for (i = 0; i < FPU_REGS; i++) + *--pxTopOfStack = (rt_uint32_t)0x0; /* FPU */ +#endif + + return (rt_uint8_t *)pxTopOfStack; +} + +/** + * This function set the hook, which is invoked on fault exception handling. + * + * @param exception_handle the exception handling hook function. + */ +void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context)) +{ + rt_exception_hook = exception_handle; +} + +#ifdef RT_USING_CPU_FFS +/** + * This function finds the first bit set (beginning with the least significant bit) + * in value and return the index of that bit. + * + * Bits are numbered starting at 1 (the least significant bit). A return value of + * zero from any of these functions means that the argument was zero. + * + * @return return the index of the first bit set. If value is 0, then this function + * shall return 0. + */ +#if defined(__CC_ARM) +__asm int __rt_ffs(int value) +{ + CMP r0, #0x00 + BEQ exit + RBIT r0, r0 + CLZ r0, r0 + ADDS r0, r0, #0x01 + + exit + BX lr +} +#elif defined(__IAR_SYSTEMS_ICC__) +int __rt_ffs(int value) +{ + if (value == 0) return value; + + __ASM("RBIT r0, r0"); + __ASM("CLZ r0, r0"); + __ASM("ADDS r0, r0, #0x01"); +} +#elif defined(__GNUC__) +int __rt_ffs(int value) +{ + return __builtin_ffs(value); +} +#endif + +#endif diff --git a/libcpu/nds32/os_cpu.h b/libcpu/nds32/os_cpu.h new file mode 100644 index 0000000000..2eea70298a --- /dev/null +++ b/libcpu/nds32/os_cpu.h @@ -0,0 +1,33 @@ +#ifndef OS_CPU_H +#define OS_CPU_H + +#include "nds32.h" +/* + * ********************************************************************************************************* + * * DATA TYPES + * * (Compiler Specific) + * ********************************************************************************************************* + * */ +typedef unsigned char BOOLEAN; +typedef unsigned char INT8U; /* Unsigned 8 bit quantity */ +typedef signed char INT8S; /* Signed 8 bit quantity */ +typedef unsigned short INT16U; /* Unsigned 16 bit quantity */ +typedef signed short INT16S; /* Signed 16 bit quantity */ +typedef unsigned int INT32U; /* Unsigned 32 bit quantity */ +typedef signed int INT32S; /* Signed 32 bit quantity */ +typedef float FP32; /* Single precision floating point */ +typedef double FP64; /* Double precision floating point */ + +typedef unsigned long OS_STK; /* Each stack entry is 32-bit wide */ +typedef unsigned long OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */ + +void OS_CPU_IRQ_ISR(void); /* See OS_CPU_A.S */ +void OS_CPU_IRQ_ISR_Handler(void); /* See BSP code */ + +void OSCtxSw(void); +void CtxSave(void); +void CtxRestore(void); + +void OS_DCache_Writeback(void *aVA, unsigned aSize); + +#endif -- cgit v1.3.1