From 39452b67b0351ac7b0b941971c4fe3be8f76d57e Mon Sep 17 00:00:00 2001 From: ardafu Date: Tue, 14 Apr 2015 21:56:34 +0800 Subject: [PATCH 1/9] 1. [cpu] split ARM926 cpu code from AT91SAM9260 BSP --- bsp/at91sam9260/applications/startup.c | 18 +- bsp/at91sam9260/platform/interrupt.c | 49 +- bsp/at91sam9260/platform/interrupt.h | 25 + bsp/at91sam9260/platform/rt_low_level_gcc.inc | 7 + bsp/at91sam9260/platform/rt_low_level_iar.inc | 7 + bsp/at91sam9260/platform/rt_low_level_init.c | 27 ++ .../platform/rt_low_level_keil.inc | 8 + bsp/at91sam9260/platform/start_gcc.S | 392 ---------------- bsp/at91sam9260/platform/start_rvds.S | 325 ------------- bsp/at91sam9260/rtconfig.py | 11 +- libcpu/arm/arm926/context_gcc.S | 153 +++---- libcpu/arm/arm926/context_iar.S | 103 +++++ libcpu/arm/arm926/context_rvds.S | 155 +++---- libcpu/arm/arm926/cpuport.c | 194 ++++---- libcpu/arm/arm926/mmu.c | 432 +++++++++++++----- libcpu/arm/arm926/mmu.h | 46 +- libcpu/arm/arm926/stack.c | 60 +-- libcpu/arm/arm926/start_gcc.S | 327 +++++++++++++ libcpu/arm/arm926/start_iar.S | 296 ++++++++++++ libcpu/arm/arm926/start_rvds.S | 338 ++++++++++++++ .../platform => libcpu/arm/arm926}/trap.c | 42 +- 21 files changed, 1856 insertions(+), 1159 deletions(-) create mode 100644 bsp/at91sam9260/platform/interrupt.h create mode 100644 bsp/at91sam9260/platform/rt_low_level_gcc.inc create mode 100644 bsp/at91sam9260/platform/rt_low_level_iar.inc create mode 100644 bsp/at91sam9260/platform/rt_low_level_init.c create mode 100644 bsp/at91sam9260/platform/rt_low_level_keil.inc delete mode 100644 bsp/at91sam9260/platform/start_gcc.S delete mode 100644 bsp/at91sam9260/platform/start_rvds.S create mode 100644 libcpu/arm/arm926/context_iar.S create mode 100644 libcpu/arm/arm926/start_gcc.S create mode 100644 libcpu/arm/arm926/start_iar.S create mode 100644 libcpu/arm/arm926/start_rvds.S rename {bsp/at91sam9260/platform => libcpu/arm/arm926}/trap.c (82%) diff --git a/bsp/at91sam9260/applications/startup.c b/bsp/at91sam9260/applications/startup.c index 15e8138886..7221efbfd6 100644 --- a/bsp/at91sam9260/applications/startup.c +++ b/bsp/at91sam9260/applications/startup.c @@ -47,17 +47,11 @@ extern void rt_application_init(void); /*@{*/ #if defined(__CC_ARM) - extern int Image$$ER_ZI$$ZI$$Base; - extern int Image$$ER_ZI$$ZI$$Length; extern int Image$$ER_ZI$$ZI$$Limit; #elif (defined (__GNUC__)) - rt_uint8_t _irq_stack_start[1024]; - rt_uint8_t _fiq_stack_start[1024]; - rt_uint8_t _undefined_stack_start[512]; - rt_uint8_t _abort_stack_start[512]; - rt_uint8_t _svc_stack_start[4096] SECTION(".nobss"); - extern unsigned char __bss_start; - extern unsigned char __bss_end; + extern unsigned char __bss_end__; +#elif (defined (__ICCARM__)) + #pragma section="HEAP" #endif #ifdef RT_USING_FINSH @@ -98,8 +92,10 @@ void rtthread_startup(void) /* initialize heap memory system */ #ifdef __CC_ARM rt_system_heap_init((void*)&Image$$ER_ZI$$ZI$$Limit, (void*)0x24000000); -#else - rt_system_heap_init((void*)&__bss_end, (void*)0x23f00000); +#elif (defined (__GNUC__)) + rt_system_heap_init((void*)&__bss_end__, (void*)0x23f00000); +#elif (defined (__ICCARM__)) + rt_system_heap_init(__section_begin("HEAP"),(void*)0x23f00000); #endif #ifdef RT_USING_MODULE diff --git a/bsp/at91sam9260/platform/interrupt.c b/bsp/at91sam9260/platform/interrupt.c index 099345ef11..0d15781c61 100644 --- a/bsp/at91sam9260/platform/interrupt.c +++ b/bsp/at91sam9260/platform/interrupt.c @@ -24,7 +24,7 @@ #include #include "at91sam926x.h" - +#include "interrupt.h" #define MAX_HANDLERS (AIC_IRQS + PIN_IRQS) extern rt_uint32_t rt_interrupt_nest; @@ -374,6 +374,53 @@ static int at91_aic_set_type(unsigned irq, unsigned type) return 0; } +rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq, rt_uint32_t* id) +{ + + rt_uint32_t irqstat; + if (fiq_irq == INT_FIQ) + { + *id = 0; + } + else //IRQ + { + /* get irq number */ + *id = (rt_uint32_t)at91_sys_read(AT91_AIC_IVR); + /* clear pending register */ + irqstat = (rt_uint32_t)at91_sys_read(AT91_AIC_ISR); + } + + return irqstat; +} + +void rt_hw_interrupt_ack(rt_uint32_t fiq_irq) +{ + if (fiq_irq == INT_FIQ) + { + /* new FIQ generation */ + + } + else + { + // EIOCR must be write any value after interrupt, + // or else can't response next interrupt + /* new IRQ generation */ + at91_sys_write(AT91_AIC_EOICR, 0x55555555); + } +} + + + + + + + + + + + + + #ifdef RT_USING_FINSH void list_irq(void) { diff --git a/bsp/at91sam9260/platform/interrupt.h b/bsp/at91sam9260/platform/interrupt.h new file mode 100644 index 0000000000..36111c4a8c --- /dev/null +++ b/bsp/at91sam9260/platform/interrupt.h @@ -0,0 +1,25 @@ +/* + * File : interrupt.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2011, 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 + * 2013-07-06 Bernard first version + */ + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +#define INT_IRQ 0x00 +#define INT_FIQ 0x01 + + +rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq, rt_uint32_t* id); +void rt_hw_interrupt_ack(rt_uint32_t fiq_irq); + +#endif diff --git a/bsp/at91sam9260/platform/rt_low_level_gcc.inc b/bsp/at91sam9260/platform/rt_low_level_gcc.inc new file mode 100644 index 0000000000..35690892d1 --- /dev/null +++ b/bsp/at91sam9260/platform/rt_low_level_gcc.inc @@ -0,0 +1,7 @@ +//;--------- Stack size of CPU modes ------------------------------------------- +.equ UND_STK_SIZE, 2048 +.equ SVC_STK_SIZE, 4096 +.equ ABT_STK_SIZE, 2048 +.equ IRQ_STK_SIZE, 4096 +.equ FIQ_STK_SIZE, 4096 +.equ SYS_STK_SIZE, 2048 diff --git a/bsp/at91sam9260/platform/rt_low_level_iar.inc b/bsp/at91sam9260/platform/rt_low_level_iar.inc new file mode 100644 index 0000000000..40427d2a06 --- /dev/null +++ b/bsp/at91sam9260/platform/rt_low_level_iar.inc @@ -0,0 +1,7 @@ +;--------- Stack size of CPU modes -------------------------------------------- +#define UND_STK_SIZE 512 +#define SVC_STK_SIZE 4096 +#define ABT_STK_SIZE 512 +#define IRQ_STK_SIZE 1024 +#define FIQ_STK_SIZE 1024 +#define SYS_STK_SIZE 512 diff --git a/bsp/at91sam9260/platform/rt_low_level_init.c b/bsp/at91sam9260/platform/rt_low_level_init.c new file mode 100644 index 0000000000..4e74e2ef47 --- /dev/null +++ b/bsp/at91sam9260/platform/rt_low_level_init.c @@ -0,0 +1,27 @@ +#define write_reg(a,v) (*(volatile unsigned int *)(a) = (v)) +/* Processor Reset */ +#define AT91_RSTC_PROCRST (1 << 0) +#define AT91_RSTC_PERRST (1 << 2) +#define AT91_RSTC_KEY (0xa5 << 24) +#define AT91_MATRIX_BASE (0XFFFFEE00) +/* Master Remap Control Register */ +#define AT91_MATRIX_MRCR (AT91_MATRIX_BASE + 0x100) +/* Remap Command for AHB Master 0 (ARM926EJ-S InSTRuction Master) */ +#define AT91_MATRIX_RCB0 (1 << 0) +/* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ +#define AT91_MATRIX_RCB1 (1 << 1) +#define AT91_AIC_BASE (0XFFFFF000) +/* Interrupt DisaBLe Command Register */ +#define AT91_AIC_IDCR (0x124) +/* Interrupt Clear Command Register */ +#define AT91_AIC_ICCR (0x128) + +void rt_low_level_init(void) +{ + // Mask all IRQs by clearing all bits in the INTMRS + write_reg(AT91_AIC_BASE + AT91_AIC_IDCR, 0xFFFFFFFF); + write_reg(AT91_AIC_BASE + AT91_AIC_ICCR, 0xFFFFFFFF); + // Remap internal ram to 0x00000000 Address + write_reg(AT91_MATRIX_MRCR, AT91_MATRIX_RCB0 | AT91_MATRIX_RCB1); +} + diff --git a/bsp/at91sam9260/platform/rt_low_level_keil.inc b/bsp/at91sam9260/platform/rt_low_level_keil.inc new file mode 100644 index 0000000000..452fb39c03 --- /dev/null +++ b/bsp/at91sam9260/platform/rt_low_level_keil.inc @@ -0,0 +1,8 @@ +;--------- Stack size of CPU modes -------------------------------------------- +UND_STK_SIZE EQU 512 +SVC_STK_SIZE EQU 4096 +ABT_STK_SIZE EQU 512 +IRQ_STK_SIZE EQU 1024 +FIQ_STK_SIZE EQU 1024 +SYS_STK_SIZE EQU 512 + END \ No newline at end of file diff --git a/bsp/at91sam9260/platform/start_gcc.S b/bsp/at91sam9260/platform/start_gcc.S deleted file mode 100644 index b5c7897938..0000000000 --- a/bsp/at91sam9260/platform/start_gcc.S +++ /dev/null @@ -1,392 +0,0 @@ -/* - * File : start.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Development Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2011-01-13 weety first version - */ - -#define CONFIG_STACKSIZE 512 -#define S_FRAME_SIZE 72 - -#define S_OLD_R0 68 -#define S_PSR 64 -#define S_PC 60 -#define S_LR 56 -#define S_SP 52 - -#define S_IP 48 -#define S_FP 44 -#define S_R10 40 -#define S_R9 36 -#define S_R8 32 -#define S_R7 28 -#define S_R6 24 -#define S_R5 20 -#define S_R4 16 -#define S_R3 12 -#define S_R2 8 -#define S_R1 4 -#define S_R0 0 - -.equ USERMODE, 0x10 -.equ FIQMODE, 0x11 -.equ IRQMODE, 0x12 -.equ SVCMODE, 0x13 -.equ ABORTMODE, 0x17 -.equ UNDEFMODE, 0x1b -.equ MODEMASK, 0x1f -.equ NOINT, 0xc0 - -.equ RAM_BASE, 0x00000000 /*Start address of RAM */ -.equ ROM_BASE, 0x20000000 /*Start address of Flash */ - - -#define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */ -#define AT91_RSTC_PERRST (1 << 2) -#define AT91_RSTC_KEY (0xa5 << 24) -#define AT91_MATRIX_BASE 0xffffee00 -#define AT91_MATRIX_MRCR (AT91_MATRIX_BASE + 0x100) /* Master Remap Control Register */ -#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ -#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ -#define AT91_AIC_BASE 0xfffff000 -#define AT91_AIC_IDCR 0x124 /* Interrupt Disable Command Register */ -#define AT91_AIC_ICCR 0x128 /* Interrupt Clear Command Register */ - - -/* - ************************************************************************* - * - * Jump vector table - * - ************************************************************************* - */ - -.section .init, "ax" -.code 32 - -.globl _start -_start: - b reset - ldr pc, _vector_undef - ldr pc, _vector_swi - ldr pc, _vector_pabt - ldr pc, _vector_dabt - ldr pc, _vector_resv - ldr pc, _vector_irq - ldr pc, _vector_fiq - -_vector_undef: .word vector_undef -_vector_swi: .word vector_swi -_vector_pabt: .word vector_pabt -_vector_dabt: .word vector_dabt -_vector_resv: .word vector_resv -_vector_irq: .word vector_irq -_vector_fiq: .word vector_fiq - -.balignl 16,0xdeadbeef - -/* - ************************************************************************* - * - * Startup Code (reset vector) - * relocate armboot to ram - * setup stack - * jump to second stage - * - ************************************************************************* - */ - -_TEXT_BASE: - .word TEXT_BASE - -/* - * rtthread kernel start and end - * which are defined in linker script - */ -.globl _rtthread_start -_rtthread_start: - .word _start - -.globl _rtthread_end -_rtthread_end: - .word _end - -/* - * rtthread bss start and end which are defined in linker script - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word __bss_end - -/* IRQ stack memory (calculated at run-time) */ -.globl IRQ_STACK_START -IRQ_STACK_START: - .word _irq_stack_start + 1024 - -.globl FIQ_STACK_START -FIQ_STACK_START: - .word _fiq_stack_start + 1024 - -.globl UNDEFINED_STACK_START -UNDEFINED_STACK_START: - .word _undefined_stack_start + CONFIG_STACKSIZE - -.globl ABORT_STACK_START -ABORT_STACK_START: - .word _abort_stack_start + CONFIG_STACKSIZE - -.globl _STACK_START -_STACK_START: - .word _svc_stack_start + 4096 - -/* ----------------------------------entry------------------------------*/ -reset: - - /* set the cpu to SVC32 mode */ - mrs r0,cpsr - bic r0,r0,#MODEMASK - orr r0,r0,#SVCMODE - msr cpsr,r0 - - /* mask all IRQs by clearing all bits in the INTMRs */ - ldr r1, =AT91_AIC_BASE - ldr r0, =0xffffffff - str r0, [r1, #AT91_AIC_IDCR] - str r0, [r1, #AT91_AIC_ICCR] - - - /*remap internal ram to 0x00000000 address*/ - ldr r0, =AT91_MATRIX_MRCR - ldr r1, =(AT91_MATRIX_RCB0|AT91_MATRIX_RCB1) - str r1, [r0] - - /* set interrupt vector */ - ldr r0, _TEXT_BASE - mov r1, #0x00 - add r2, r0, #0x40 /* size, 32bytes */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end addreee [r2] */ - ble copy_loop - - /* setup stack */ - bl stack_setup - - /* clear .bss */ - mov r0,#0 /* get a zero */ - ldr r1,=__bss_start /* bss start */ - ldr r2,=__bss_end /* bss end */ - -bss_loop: - cmp r1,r2 /* check if data to clear */ - strlo r0,[r1],#4 /* clear 4 bytes */ - blo bss_loop /* loop until done */ - - /* call C++ constructors of global objects */ - ldr r0, =__ctors_start__ - ldr r1, =__ctors_end__ - -ctor_loop: - cmp r0, r1 - beq ctor_end - ldr r2, [r0], #4 - stmfd sp!, {r0-r1} - mov lr, pc - bx r2 - ldmfd sp!, {r0-r1} - b ctor_loop - -ctor_end: - - /* start RT-Thread Kernel */ - ldr pc, _rtthread_startup - -_rtthread_startup: - .word rtthread_startup -#if defined (__FLASH_BUILD__) -_load_address: - .word ROM_BASE + _TEXT_BASE -#else -_load_address: - .word RAM_BASE + _TEXT_BASE -#endif - -.global cpu_reset -cpu_reset: - ldr r0, =0xfffffd00 - ldr r1, =(AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST) - str r1, [r0] - mov pc, lr - -/* - ************************************************************************* - * - * Interrupt handling - * - ************************************************************************* - */ - -/* exception handlers */ - .align 5 -vector_undef: - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} /* Calling r0-r12 */ - add r8, sp, #S_PC - stmdb r8, {sp, lr}^ /* Calling SP, LR */ - str lr, [r8, #0] /* Save calling PC */ - mrs r6, spsr - str r6, [r8, #4] /* Save CPSR */ - str r0, [r8, #8] /* Save OLD_R0 */ - mov r0, sp - - bl rt_hw_trap_udef - - .align 5 -vector_swi: - bl rt_hw_trap_swi - - .align 5 -vector_pabt: - bl rt_hw_trap_pabt - - .align 5 -vector_dabt: - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} /* Calling r0-r12 */ - add r8, sp, #S_PC - stmdb r8, {sp, lr}^ /* Calling SP, LR */ - str lr, [r8, #0] /* Save calling PC */ - mrs r6, spsr - str r6, [r8, #4] /* Save CPSR */ - str r0, [r8, #8] /* Save OLD_R0 */ - mov r0, sp - - bl rt_hw_trap_dabt - - .align 5 -vector_resv: - bl rt_hw_trap_resv - -.globl rt_interrupt_enter -.globl rt_interrupt_leave -.globl rt_thread_switch_interrupt_flag -.globl rt_interrupt_from_thread -.globl rt_interrupt_to_thread -vector_irq: - stmfd sp!, {r0-r12,lr} - bl rt_interrupt_enter - bl rt_hw_trap_irq - bl rt_interrupt_leave - - /* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */ - ldr r0, =rt_thread_switch_interrupt_flag - ldr r1, [r0] - cmp r1, #1 - beq _interrupt_thread_switch - - ldmfd sp!, {r0-r12,lr} - subs pc, lr, #4 - - .align 5 -vector_fiq: - stmfd sp!,{r0-r7,lr} - bl rt_hw_trap_fiq - ldmfd sp!,{r0-r7,lr} - subs pc,lr,#4 - -_interrupt_thread_switch: - mov r1, #0 /* clear rt_thread_switch_interrupt_flag*/ - str r1, [r0] - - ldmfd sp!, {r0-r12,lr} /* reload saved registers */ - stmfd sp!, {r0-r3} /* save r0-r3 */ - mov r1, sp - add sp, sp, #16 /* restore sp */ - sub r2, lr, #4 /* save old task's pc to r2 */ - - mrs r3, spsr /* disable interrupt */ - orr r0, r3, #NOINT - msr spsr_c, r0 - - ldr r0, =.+8 /* switch to interrupted task's stack*/ - movs pc, r0 - - stmfd sp!, {r2} /* push old task's pc */ - stmfd sp!, {r4-r12,lr} /* push old task's lr,r12-r4 */ - mov r4, r1 /* Special optimised code below */ - mov r5, r3 - ldmfd r4!, {r0-r3} - stmfd sp!, {r0-r3} /* push old task's r3-r0 */ - stmfd sp!, {r5} /* push old task's psr */ - mrs r4, spsr - stmfd sp!, {r4} /* push old task's spsr */ - - ldr r4, =rt_interrupt_from_thread - ldr r5, [r4] - str sp, [r5] /* store sp in preempted tasks's TCB*/ - - ldr r6, =rt_interrupt_to_thread - ldr r6, [r6] - ldr sp, [r6] /* get new task's stack pointer */ - - ldmfd sp!, {r4} /* pop new task's spsr */ - msr SPSR_cxsf, r4 - ldmfd sp!, {r4} /* pop new task's psr */ - msr CPSR_cxsf, r4 - - ldmfd sp!, {r0-r12,lr,pc} /* pop new task's r0-r12,lr & pc */ - -stack_setup: - mrs r0, cpsr - bic r0, r0, #MODEMASK - orr r1, r0, #UNDEFMODE|NOINT - msr cpsr_cxsf, r1 /* undef mode */ - ldr sp, UNDEFINED_STACK_START - - orr r1,r0,#ABORTMODE|NOINT - msr cpsr_cxsf,r1 /* abort mode */ - ldr sp, ABORT_STACK_START - - orr r1,r0,#IRQMODE|NOINT - msr cpsr_cxsf,r1 /* IRQ mode */ - ldr sp, IRQ_STACK_START - - orr r1,r0,#FIQMODE|NOINT - msr cpsr_cxsf,r1 /* FIQ mode */ - ldr sp, FIQ_STACK_START - - bic r0,r0,#MODEMASK - orr r1,r0,#SVCMODE|NOINT - msr cpsr_cxsf,r1 /* SVC mode */ - - ldr sp, _STACK_START - - /* USER mode is not initialized. */ - mov pc,lr /* The LR register may be not valid for the mode changes.*/ - -/*/*}*/ - - diff --git a/bsp/at91sam9260/platform/start_rvds.S b/bsp/at91sam9260/platform/start_rvds.S deleted file mode 100644 index 58661f9cb0..0000000000 --- a/bsp/at91sam9260/platform/start_rvds.S +++ /dev/null @@ -1,325 +0,0 @@ -;/* -; * File : start_rvds.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, RT-Thread Development Team -; * -; * This program is free software; you can redistribute it and/or modify -; * it under the terms of the GNU General Public License as published by -; * the Free Software Foundation; either version 2 of the License, or -; * (at your option) any later version. -; * -; * This program is distributed in the hope that it will be useful, -; * but WITHOUT ANY WARRANTY; without even the implied warranty of -; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; * GNU General Public License for more details. -; * -; * You should have received a copy of the GNU General Public License along -; * with this program; if not, write to the Free Software Foundation, Inc., -; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -; * -; * Change Logs: -; * Date Author Notes -; * 2011-08-14 weety first version -; */ - - -; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs - -Mode_USR EQU 0x10 -Mode_FIQ EQU 0x11 -Mode_IRQ EQU 0x12 -Mode_SVC EQU 0x13 -Mode_ABT EQU 0x17 -Mode_UND EQU 0x1B -Mode_SYS EQU 0x1F - -SVCMODE EQU 0x13 -MODEMASK EQU 0x1f - -I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled -F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled - - -;----------------------- Stack and Heap Definitions ---------------------------- - -;// Stack Configuration (Stack Sizes in Bytes) -;// Undefined Mode <0x0-0xFFFFFFFF:8> -;// Supervisor Mode <0x0-0xFFFFFFFF:8> -;// Abort Mode <0x0-0xFFFFFFFF:8> -;// Fast Interrupt Mode <0x0-0xFFFFFFFF:8> -;// Interrupt Mode <0x0-0xFFFFFFFF:8> -;// User/System Mode <0x0-0xFFFFFFFF:8> -;// - -UND_Stack_Size EQU 512 -SVC_Stack_Size EQU 4096 -ABT_Stack_Size EQU 512 -FIQ_Stack_Size EQU 1024 -IRQ_Stack_Size EQU 1024 -USR_Stack_Size EQU 512 - -ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ - FIQ_Stack_Size + IRQ_Stack_Size) - - AREA STACK, NOINIT, READWRITE, ALIGN=3 - -Stack_Mem SPACE USR_Stack_Size -__initial_sp SPACE ISR_Stack_Size -Stack_Top - - -;// Heap Configuration -;// Heap Size (in Bytes) <0x0-0xFFFFFFFF> -;// - -Heap_Size EQU 0x00000000 - - AREA HEAP, NOINIT, READWRITE, ALIGN=3 -__heap_base -Heap_Mem SPACE Heap_Size -__heap_limit - - -;----------------------- Memory Definitions ------------------------------------ - -AT91_MATRIX_BASE EQU 0xffffee00 -AT91_MATRIX_MRCR EQU (AT91_MATRIX_BASE + 0x100) -AT91_MATRIX_RCB0 EQU 0x00000001 -AT91_MATRIX_RCB1 EQU 0x00000002 -AT91_AIC_BASE EQU 0xfffff000 -AT91_AIC_IDCR EQU 0x124 -AT91_AIC_ICCR EQU 0x128 - -;----------------------- CODE -------------------------------------------------- - - PRESERVE8 - - -; Area Definition and Entry Point -; Startup Code must be linked first at Address at which it expects to run. - - AREA RESET, CODE, READONLY - ARM - -; Exception Vectors -; Mapped to Address 0. -; Absolute addressing mode must be used. -; Dummy Handlers are implemented as infinite loops which can be modified. - - EXPORT Entry_Point -Entry_Point -Vectors LDR PC, Reset_Addr - LDR PC, Undef_Addr - LDR PC, SWI_Addr - LDR PC, PAbt_Addr - LDR PC, DAbt_Addr - NOP - LDR PC, IRQ_Addr - LDR PC, FIQ_Addr - -Reset_Addr DCD Reset_Handler -Undef_Addr DCD Undef_Handler -SWI_Addr DCD SWI_Handler -PAbt_Addr DCD PAbt_Handler -DAbt_Addr DCD DAbt_Handler - DCD 0 ; Reserved Address -IRQ_Addr DCD IRQ_Handler -FIQ_Addr DCD FIQ_Handler - -Undef_Handler B Undef_Handler -SWI_Handler B SWI_Handler -PAbt_Handler B PAbt_Handler -;DAbt_Handler B DAbt_Handler -FIQ_Handler B FIQ_Handler - -;* -;************************************************************************* -;* -;* Interrupt handling -;* -;************************************************************************* -;* -; DAbt Handler -DAbt_Handler - IMPORT rt_hw_trap_dabt - - sub sp, sp, #72 - stmia sp, {r0 - r12} ;/* Calling r0-r12 */ - add r8, sp, #60 - stmdb r8, {sp, lr} ;/* Calling SP, LR */ - str lr, [r8, #0] ;/* Save calling PC */ - mrs r6, spsr - str r6, [r8, #4] ;/* Save CPSR */ - str r0, [r8, #8] ;/* Save OLD_R0 */ - mov r0, sp - - bl rt_hw_trap_dabt - - -;########################################## -; Reset Handler - - EXPORT Reset_Handler -Reset_Handler - - -; set the cpu to SVC32 mode----------------------------------------------------- - - MRS R0,CPSR - BIC R0,R0,#MODEMASK - ORR R0,R0,#SVCMODE - MSR CPSR_cxsf,R0 - LDR R1, =AT91_AIC_BASE - LDR R0, =0xffffffff - STR R0, [R1, #AT91_AIC_IDCR] - STR R0, [R1, #AT91_AIC_ICCR] - -; remap internal ram to 0x00000000 address - LDR R0, =AT91_MATRIX_MRCR - LDR R1, =(AT91_MATRIX_RCB0|AT91_MATRIX_RCB1) - STR R1, [R0] - - -; Copy Exception Vectors to Internal RAM --------------------------------------- - - ADR R8, Vectors ; Source - LDR R9, =0x00 ; Destination - LDMIA R8!, {R0-R7} ; Load Vectors - STMIA R9!, {R0-R7} ; Store Vectors - LDMIA R8!, {R0-R7} ; Load Handler Addresses - STMIA R9!, {R0-R7} ; Store Handler Addresses - - -; Setup Stack for each mode ---------------------------------------------------- - - LDR R0, =Stack_Top - -; Enter Undefined Instruction Mode and set its Stack Pointer - MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit - MOV SP, R0 - SUB R0, R0, #UND_Stack_Size - -; Enter Abort Mode and set its Stack Pointer - MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit - MOV SP, R0 - SUB R0, R0, #ABT_Stack_Size - -; Enter FIQ Mode and set its Stack Pointer - MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit - MOV SP, R0 - SUB R0, R0, #FIQ_Stack_Size - -; Enter IRQ Mode and set its Stack Pointer - MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit - MOV SP, R0 - SUB R0, R0, #IRQ_Stack_Size - -; Enter Supervisor Mode and set its Stack Pointer - MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit - MOV SP, R0 - SUB R0, R0, #SVC_Stack_Size - -; Enter User Mode and set its Stack Pointer - ; MSR CPSR_c, #Mode_USR - MOV SP, R0 - SUB SL, SP, #USR_Stack_Size - -; Enter the C code ------------------------------------------------------------- - - IMPORT __main - LDR R0, =__main - BX R0 - - IMPORT rt_interrupt_enter - IMPORT rt_interrupt_leave - IMPORT rt_thread_switch_interrupt_flag - IMPORT rt_interrupt_from_thread - IMPORT rt_interrupt_to_thread - IMPORT rt_hw_trap_irq - -IRQ_Handler PROC - EXPORT IRQ_Handler - STMFD sp!, {r0-r12,lr} - BL rt_interrupt_enter - BL rt_hw_trap_irq - BL rt_interrupt_leave - - ; if rt_thread_switch_interrupt_flag set, jump to - ; rt_hw_context_switch_interrupt_do and don't return - LDR r0, =rt_thread_switch_interrupt_flag - LDR r1, [r0] - CMP r1, #1 - BEQ rt_hw_context_switch_interrupt_do - - LDMFD sp!, {r0-r12,lr} - SUBS pc, lr, #4 - ENDP - -; /* -; * void rt_hw_context_switch_interrupt_do(rt_base_t flag) -; */ -rt_hw_context_switch_interrupt_do PROC - EXPORT rt_hw_context_switch_interrupt_do - MOV r1, #0 ; clear flag - STR r1, [r0] - - LDMFD sp!, {r0-r12,lr}; reload saved registers - STMFD sp!, {r0-r3} ; save r0-r3 - MOV r1, sp - ADD sp, sp, #16 ; restore sp - SUB r2, lr, #4 ; save old task's pc to r2 - - MRS r3, spsr ; get cpsr of interrupt thread - - ; switch to SVC mode and no interrupt - MSR cpsr_c, #I_Bit:OR:F_Bit:OR:Mode_SVC - - STMFD sp!, {r2} ; push old task's pc - STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4 - MOV r4, r1 ; Special optimised code below - MOV r5, r3 - LDMFD r4!, {r0-r3} - STMFD sp!, {r0-r3} ; push old task's r3-r0 - STMFD sp!, {r5} ; push old task's cpsr - MRS r4, spsr - STMFD sp!, {r4} ; push old task's spsr - - LDR r4, =rt_interrupt_from_thread - LDR r5, [r4] - STR sp, [r5] ; store sp in preempted tasks's TCB - - LDR r6, =rt_interrupt_to_thread - LDR r6, [r6] - LDR sp, [r6] ; get new task's stack pointer - - LDMFD sp!, {r4} ; pop new task's spsr - MSR spsr_cxsf, r4 - LDMFD sp!, {r4} ; pop new task's psr - MSR cpsr_cxsf, r4 - - LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc - ENDP - - IF :DEF:__MICROLIB - - EXPORT __heap_base - EXPORT __heap_limit - - ELSE -; User Initial Stack & Heap - AREA |.text|, CODE, READONLY - - IMPORT __use_two_region_memory - EXPORT __user_initial_stackheap -__user_initial_stackheap - - LDR R0, = Heap_Mem - LDR R1, =(Stack_Mem + USR_Stack_Size) - LDR R2, = (Heap_Mem + Heap_Size) - LDR R3, = Stack_Mem - BX LR - ENDIF - - - END - diff --git a/bsp/at91sam9260/rtconfig.py b/bsp/at91sam9260/rtconfig.py index 10870f8807..c75d864741 100755 --- a/bsp/at91sam9260/rtconfig.py +++ b/bsp/at91sam9260/rtconfig.py @@ -12,10 +12,11 @@ if os.getenv('RTT_CC'): if CROSS_TOOL == 'gcc': PLATFORM = 'gcc' - EXEC_PATH = '/opt/arm-2010q1/bin/' + #EXEC_PATH = 'D:/ArdaArmTools/Sourcery_Lite/bin' + EXEC_PATH = 'D:/ArdaArmTools/GNUARM_4.9_2015q1/bin' elif CROSS_TOOL == 'keil': PLATFORM = 'armcc' - EXEC_PATH = 'C:/Keil' + EXEC_PATH = 'C:/Keil_v5' elif CROSS_TOOL == 'iar': print '================ERROR============================' print 'Not support yet!' @@ -43,7 +44,7 @@ if PLATFORM == 'gcc': DEVICE = ' -mcpu=arm926ej-s' CFLAGS = DEVICE - AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + ' -DTEXT_BASE=' + TextBase + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + ' -Iplatform'+' -DTEXT_BASE=' + TextBase LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread_at91sam9260.map,-cref,-u,_start -T at91sam9260_ram.ld' + ' -Ttext ' + TextBase CPATH = '' @@ -65,9 +66,9 @@ elif PLATFORM == 'armcc': LINK = 'armlink' TARGET_EXT = 'axf' - DEVICE = ' --device DARMATS9' + DEVICE = ' --cpu=ARM926EJ-S' CFLAGS = DEVICE + ' --apcs=interwork --diag_suppress=870' - AFLAGS = DEVICE + AFLAGS = DEVICE + ' -Iplatform' LFLAGS = DEVICE + ' --strict --info sizes --info totals --info unused --info veneers --list rtthread-at91sam9260.map --ro-base 0x20000000 --entry Entry_Point --first Entry_Point' CFLAGS += ' -I"' + EXEC_PATH + '/ARM/RV31/INC"' diff --git a/libcpu/arm/arm926/context_gcc.S b/libcpu/arm/arm926/context_gcc.S index a3f07a1860..5357b36d20 100644 --- a/libcpu/arm/arm926/context_gcc.S +++ b/libcpu/arm/arm926/context_gcc.S @@ -1,110 +1,99 @@ -/* - * File : context.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Development Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2011-01-13 weety copy from mini2440 - */ +;/* +; * File : context_iar.S +; * This file is part of RT-Thread RTOS +; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * +; * This program is free software; you can redistribute it and/or modify +; * it under the terms of the GNU General Public License as published by +; * the Free Software Foundation; either version 2 of the License, or +; * (at your option) any later version. +; * +; * This program is distributed in the hope that it will be useful, +; * but WITHOUT ANY WARRANTY; without even the implied warranty of +; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; * GNU General Public License for more details. +; * +; * You should have received a copy of the GNU General Public License along +; * with this program; if not, write to the Free Software Foundation, Inc., +; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +; * +; * Change Logs: +; * Date Author Notes +; * 2011-08-14 weety copy from mini2440 +; */ -/*! - * \addtogroup AT91SAM926X - */ -/*@{*/ +#define NOINT 0xC0 -#define NOINT 0xc0 - - -/* - * rt_base_t rt_hw_interrupt_disable(); - */ -.globl rt_hw_interrupt_disable +;/* +; * rt_base_t rt_hw_interrupt_disable(); +; */ + .globl rt_hw_interrupt_disable rt_hw_interrupt_disable: - mrs r0, cpsr - orr r1, r0, #NOINT - msr cpsr_c, r1 - mov pc, lr + MRS R0, CPSR + ORR R1, R0, #NOINT + MSR CPSR_c, R1 + BX LR /* * void rt_hw_interrupt_enable(rt_base_t level); */ -.globl rt_hw_interrupt_enable + .globl rt_hw_interrupt_enable rt_hw_interrupt_enable: - msr cpsr, r0 - mov pc, lr + MSR CPSR, R0 + BX LR /* * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); * r0 --> from * r1 --> to */ -.globl rt_hw_context_switch + .globl rt_hw_context_switch rt_hw_context_switch: - stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) - stmfd sp!, {r0-r12, lr} @ push lr & register file - - mrs r4, cpsr - stmfd sp!, {r4} @ push cpsr - mrs r4, spsr - stmfd sp!, {r4} @ push spsr - - str sp, [r0] @ store sp in preempted tasks TCB - ldr sp, [r1] @ get new task stack pointer - - ldmfd sp!, {r4} @ pop new task spsr - msr spsr_cxsf, r4 - ldmfd sp!, {r4} @ pop new task cpsr - msr spsr_cxsf, r4 - - ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc + stmfd sp!, {lr} @; push pc (lr should be pushed in place of pc) + stmfd sp!, {r0-r12, lr} @; push lr & register file + mrs r4, cpsr + stmfd sp!, {r4} @; push cpsr + mrs r4, spsr + stmfd sp!, {r4} @; push spsr + str sp, [r0] @; store sp in preempted tasks tcb + ldr sp, [r1] @; get new task stack pointer + ldmfd sp!, {r4} @; pop new task spsr + msr spsr_cxsf, r4 + ldmfd sp!, {r4} @; pop new task cpsr + msr spsr_cxsf, r4 + ldmfd sp!, {r0-r12, lr, pc}^ @; pop new task r0-r12, lr & pc /* * void rt_hw_context_switch_to(rt_uint32 to); * r0 --> to */ -.globl rt_hw_context_switch_to + .globl rt_hw_context_switch_to rt_hw_context_switch_to: - ldr sp, [r0] @ get new task stack pointer + ldr sp, [r0] @; get new task stack pointer - ldmfd sp!, {r4} @ pop new task spsr - msr spsr_cxsf, r4 - ldmfd sp!, {r4} @ pop new task cpsr - msr cpsr_cxsf, r4 - - ldmfd sp!, {r0-r12, lr, pc} @ pop new task r0-r12, lr & pc + ldmfd sp!, {r4} @; pop new task spsr + msr spsr_cxsf, r4 + ldmfd sp!, {r4} @; pop new task cpsr + msr spsr_cxsf, r4 + ldmfd sp!, {r0-r12, lr, pc}^ @; pop new task r0-r12, lr & pc /* * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); */ -.globl rt_thread_switch_interrupt_flag -.globl rt_interrupt_from_thread -.globl rt_interrupt_to_thread -.globl rt_hw_context_switch_interrupt + .globl rt_thread_switch_interrupt_flag + .globl rt_interrupt_from_thread + .globl rt_interrupt_to_thread + .globl rt_hw_context_switch_interrupt rt_hw_context_switch_interrupt: - ldr r2, =rt_thread_switch_interrupt_flag - ldr r3, [r2] - cmp r3, #1 - beq _reswitch - mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1 - str r3, [r2] - ldr r2, =rt_interrupt_from_thread @ set rt_interrupt_from_thread - str r0, [r2] + LDR R2, =rt_thread_switch_interrupt_flag + LDR R3, [R2] + CMP R3, #1 + BEQ _reswitch + MOV R3, #1 @; set flag to 1 + STR R3, [R2] + LDR R2, =rt_interrupt_from_thread @; set rt_interrupt_from_thread + STR R0, [R2] _reswitch: - ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread - str r1, [r2] - mov pc, lr + LDR R2, =rt_interrupt_to_thread @; set rt_interrupt_to_thread + STR R1, [R2] + BX LR diff --git a/libcpu/arm/arm926/context_iar.S b/libcpu/arm/arm926/context_iar.S new file mode 100644 index 0000000000..678c7bacff --- /dev/null +++ b/libcpu/arm/arm926/context_iar.S @@ -0,0 +1,103 @@ +;/* +; * File : context_iar.S +; * This file is part of RT-Thread RTOS +; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * +; * This program is free software; you can redistribute it and/or modify +; * it under the terms of the GNU General Public License as published by +; * the Free Software Foundation; either version 2 of the License, or +; * (at your option) any later version. +; * +; * This program is distributed in the hope that it will be useful, +; * but WITHOUT ANY WARRANTY; without even the implied warranty of +; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; * GNU General Public License for more details. +; * +; * You should have received a copy of the GNU General Public License along +; * with this program; if not, write to the Free Software Foundation, Inc., +; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +; * +; * Change Logs: +; * Date Author Notes +; * 2011-08-14 weety copy from mini2440 +; */ + +#define NOINT 0xc0 + + SECTION .text:CODE(6) +/* + * rt_base_t rt_hw_interrupt_disable(); + */ + PUBLIC rt_hw_interrupt_disable +rt_hw_interrupt_disable: + MRS R0, CPSR + ORR R1, R0, #NOINT + MSR CPSR_C, R1 + MOV PC, LR + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ + PUBLIC rt_hw_interrupt_enable +rt_hw_interrupt_enable: + MSR CPSR_CXSF, R0 + MOV PC, LR + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); + * r0 --> from + * r1 --> to + */ + PUBLIC rt_hw_context_switch +rt_hw_context_switch: + STMFD SP!, {LR} ; push pc (lr should be pushed in place of PC) + STMFD SP!, {R0-R12, LR} ; push lr & register file + MRS R4, CPSR + STMFD SP!, {R4} ; push cpsr + MRS R4, SPSR + STMFD SP!, {R4} ; push spsr + STR SP, [R0] ; store sp in preempted tasks TCB + LDR SP, [R1] ; get new task stack pointer + LDMFD SP!, {R4} ; pop new task spsr + MSR SPSR_cxsf, R4 + LDMFD SP!, {R4} ; pop new task cpsr + MSR SPSR_cxsf, R4 + LDMFD SP!, {R0-R12, LR, PC}^ ; pop new task r0-r12, lr & pc + +/* + * void rt_hw_context_switch_to(rt_uint32 to); + * r0 --> to + */ + PUBLIC rt_hw_context_switch_to +rt_hw_context_switch_to: + LDR SP, [R0] ; get new task stack pointer + + LDMFD SP!, {R4} ; pop new task spsr + MSR SPSR_cxsf, R4 + LDMFD SP!, {R4} ; pop new task cpsr + MSR SPSR_cxsf, R4 + + LDMFD SP!, {R0-R12, LR, PC}^ ; pop new task r0-r12, lr & pc + +/* + * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); + */ + IMPORT rt_thread_switch_interrupt_flag + IMPORT rt_interrupt_from_thread + IMPORT rt_interrupt_to_thread + PUBLIC rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: + LDR R2, =rt_thread_switch_interrupt_flag + LDR R3, [R2] + CMP R3, #1 + BEQ _reswitch + MOV R3, #1 ; set flag to 1 + STR R3, [R2] + LDR R2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread + STR R0, [R2] +_reswitch: + LDR R2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread + STR R1, [R2] + MOV PC, LR + END + diff --git a/libcpu/arm/arm926/context_rvds.S b/libcpu/arm/arm926/context_rvds.S index 631da83372..e5fda293df 100644 --- a/libcpu/arm/arm926/context_rvds.S +++ b/libcpu/arm/arm926/context_rvds.S @@ -1,117 +1,112 @@ ;/* -; * File : context_rvds.S -; * This file is part of RT-Thread RTOS -; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * file : context_rvds.s +; * this file is part of rt-thread rtos +; * copyright (c) 2006, rt-thread development team ; * -; * This program is free software; you can redistribute it and/or modify -; * it under the terms of the GNU General Public License as published by -; * the Free Software Foundation; either version 2 of the License, or +; * this program is free software; you can redistribute it and/or modify +; * it under the terms of the gnu general public license as published by +; * the free software foundation; either version 2 of the license, or ; * (at your option) any later version. ; * -; * This program is distributed in the hope that it will be useful, -; * but WITHOUT ANY WARRANTY; without even the implied warranty of -; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; * GNU General Public License for more details. +; * this program is distributed in the hope that it will be useful, +; * but without any warranty; without even the implied warranty of +; * merchantability or fitness for a particular purpose. see the +; * gnu general public license for more details. ; * -; * You should have received a copy of the GNU General Public License along -; * with this program; if not, write to the Free Software Foundation, Inc., -; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +; * you should have received a copy of the gnu general public license along +; * with this program; if not, write to the free software foundation, inc., +; * 51 franklin street, fifth floor, boston, ma 02110-1301 usa. ; * -; * Change Logs: -; * Date Author Notes +; * change logs: +; * date author notes ; * 2011-08-14 weety copy from mini2440 ; */ -NOINT EQU 0xc0 ; disable interrupt in psr +NOINT EQU 0XC0 ; disable interrupt in psr - AREA |.text|, CODE, READONLY, ALIGN=2 - ARM - REQUIRE8 - PRESERVE8 + AREA |.TEXT|, CODE, READONLY, ALIGN=2 + ARM + REQUIRE8 + PRESERVE8 ;/* ; * rt_base_t rt_hw_interrupt_disable(); ; */ -rt_hw_interrupt_disable PROC - EXPORT rt_hw_interrupt_disable - MRS r0, cpsr - ORR r1, r0, #NOINT - MSR cpsr_c, r1 - BX lr - ENDP +rt_hw_interrupt_disable PROC + EXPORT rt_hw_interrupt_disable + MRS R0, CPSR + ORR R1, R0, #NOINT + MSR CPSR_C, R1 + BX LR + ENDP ;/* ; * void rt_hw_interrupt_enable(rt_base_t level); ; */ -rt_hw_interrupt_enable PROC - EXPORT rt_hw_interrupt_enable - MSR cpsr_c, r0 - BX lr - ENDP +rt_hw_interrupt_enable proc + export rt_hw_interrupt_enable + msr cpsr_c, r0 + bx lr + endp ;/* ; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); ; * r0 --> from ; * r1 --> to ; */ -rt_hw_context_switch PROC - EXPORT rt_hw_context_switch - STMFD sp!, {lr} ; push pc (lr should be pushed in place of PC) - STMFD sp!, {r0-r12, lr} ; push lr & register file - - MRS r4, cpsr - STMFD sp!, {r4} ; push cpsr - MRS r4, spsr - STMFD sp!, {r4} ; push spsr - - STR sp, [r0] ; store sp in preempted tasks TCB - LDR sp, [r1] ; get new task stack pointer - - LDMFD sp!, {r4} ; pop new task spsr - MSR spsr_cxsf, r4 - LDMFD sp!, {r4} ; pop new task cpsr - MSR spsr_cxsf, r4 - - LDMFD sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc - ENDP +rt_hw_context_switch proc + export rt_hw_context_switch + stmfd sp!, {lr} ; push pc (lr should be pushed in place of pc) + stmfd sp!, {r0-r12, lr} ; push lr & register file + mrs r4, cpsr + stmfd sp!, {r4} ; push cpsr + mrs r4, spsr + stmfd sp!, {r4} ; push spsr + str sp, [r0] ; store sp in preempted tasks tcb + ldr sp, [r1] ; get new task stack pointer + ldmfd sp!, {r4} ; pop new task spsr + msr spsr_cxsf, r4 + ldmfd sp!, {r4} ; pop new task cpsr + msr spsr_cxsf, r4 + ldmfd sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc + endp ;/* ; * void rt_hw_context_switch_to(rt_uint32 to); ; * r0 --> to ; */ -rt_hw_context_switch_to PROC - EXPORT rt_hw_context_switch_to - LDR sp, [r0] ; get new task stack pointer +rt_hw_context_switch_to proc + export rt_hw_context_switch_to + ldr sp, [r0] ; get new task stack pointer - LDMFD sp!, {r4} ; pop new task spsr - MSR spsr_cxsf, r4 - LDMFD sp!, {r4} ; pop new task cpsr - MSR cpsr_cxsf, r4 - - LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc - ENDP + ldmfd sp!, {r4} ; pop new task spsr + msr spsr_cxsf, r4 + ldmfd sp!, {r4} ; pop new task cpsr + msr spsr_cxsf, r4 + ldmfd sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc + endp ;/* ; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); ; */ - IMPORT rt_thread_switch_interrupt_flag - IMPORT rt_interrupt_from_thread - IMPORT rt_interrupt_to_thread + import rt_thread_switch_interrupt_flag + import rt_interrupt_from_thread + import rt_interrupt_to_thread -rt_hw_context_switch_interrupt PROC - EXPORT rt_hw_context_switch_interrupt - LDR r2, =rt_thread_switch_interrupt_flag - LDR r3, [r2] - CMP r3, #1 - BEQ _reswitch - MOV r3, #1 ; set rt_thread_switch_interrupt_flag to 1 - STR r3, [r2] - LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread - STR r0, [r2] +rt_hw_context_switch_interrupt proc + export rt_hw_context_switch_interrupt + ldr r2, =rt_thread_switch_interrupt_flag + ldr r3, [r2] + cmp r3, #1 + beq _reswitch + mov r3, #1 ; set flag to 1 + str r3, [r2] + ldr r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread + str r0, [r2] _reswitch - LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread - STR r1, [r2] - BX lr - ENDP + ldr r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread + str r1, [r2] + bx lr + endp - END + end diff --git a/libcpu/arm/arm926/cpuport.c b/libcpu/arm/arm926/cpuport.c index 9908471a5c..fd707384f6 100644 --- a/libcpu/arm/arm926/cpuport.c +++ b/libcpu/arm/arm926/cpuport.c @@ -25,8 +25,8 @@ #include #include -#define ICACHE_MASK (rt_uint32_t)(1 << 12) -#define DCACHE_MASK (rt_uint32_t)(1 << 2) +#define ICACHE_MASK (rt_uint32_t)(1 << 12) +#define DCACHE_MASK (rt_uint32_t)(1 << 2) extern void machine_reset(void); extern void machine_shutdown(void); @@ -34,70 +34,102 @@ extern void machine_shutdown(void); #ifdef __GNUC__ rt_inline rt_uint32_t cp15_rd(void) { - rt_uint32_t i; + rt_uint32_t i; - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - return i; + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + return i; } rt_inline void cache_enable(rt_uint32_t bit) { - __asm__ __volatile__( \ - "mrc p15,0,r0,c1,c0,0\n\t" \ - "orr r0,r0,%0\n\t" \ - "mcr p15,0,r0,c1,c0,0" \ - : \ - :"r" (bit) \ - :"memory"); + __asm__ __volatile__( \ + "mrc p15,0,r0,c1,c0,0\n\t" \ + "orr r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + :"r" (bit) \ + :"memory"); } rt_inline void cache_disable(rt_uint32_t bit) { - __asm__ __volatile__( \ - "mrc p15,0,r0,c1,c0,0\n\t" \ - "bic r0,r0,%0\n\t" \ - "mcr p15,0,r0,c1,c0,0" \ - : \ - :"r" (bit) \ - :"memory"); + __asm__ __volatile__( \ + "mrc p15,0,r0,c1,c0,0\n\t" \ + "bic r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + :"r" (bit) \ + :"memory"); } #endif #ifdef __CC_ARM rt_inline rt_uint32_t cp15_rd(void) { - rt_uint32_t i; + rt_uint32_t i; - __asm - { - mrc p15, 0, i, c1, c0, 0 - } + __asm + { + mrc p15, 0, i, c1, c0, 0 + } - return i; + return i; } rt_inline void cache_enable(rt_uint32_t bit) { - rt_uint32_t value; + rt_uint32_t value; - __asm - { - mrc p15, 0, value, c1, c0, 0 - orr value, value, bit - mcr p15, 0, value, c1, c0, 0 - } + __asm + { + mrc p15, 0, value, c1, c0, 0 + orr value, value, bit + mcr p15, 0, value, c1, c0, 0 + } } rt_inline void cache_disable(rt_uint32_t bit) { - rt_uint32_t value; + rt_uint32_t value; - __asm - { - mrc p15, 0, value, c1, c0, 0 - bic value, value, bit - mcr p15, 0, value, c1, c0, 0 - } + __asm + { + mrc p15, 0, value, c1, c0, 0 + bic value, value, bit + mcr p15, 0, value, c1, c0, 0 + } +} +#endif + +#ifdef __ICCARM__ +rt_inline rt_uint32_t cp15_rd(void) +{ + rt_uint32_t i; + + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + return i; +} + +rt_inline void cache_enable(rt_uint32_t bit) +{ + asm volatile( \ + "mrc p15,0,r0,c1,c0,0\n\t" \ + "orr r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + :"r" (bit) \ + :"memory"); +} + +rt_inline void cache_disable(rt_uint32_t bit) +{ + asm volatile( \ + "mrc p15,0,r0,c1,c0,0\n\t" \ + "bic r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + :"r" (bit) \ + :"memory"); } #endif @@ -107,7 +139,7 @@ rt_inline void cache_disable(rt_uint32_t bit) */ void rt_hw_cpu_icache_enable() { - cache_enable(ICACHE_MASK); + cache_enable(ICACHE_MASK); } /** @@ -116,7 +148,7 @@ void rt_hw_cpu_icache_enable() */ void rt_hw_cpu_icache_disable() { - cache_disable(ICACHE_MASK); + cache_disable(ICACHE_MASK); } /** @@ -125,7 +157,7 @@ void rt_hw_cpu_icache_disable() */ rt_base_t rt_hw_cpu_icache_status() { - return (cp15_rd() & ICACHE_MASK); + return (cp15_rd() & ICACHE_MASK); } /** @@ -134,7 +166,7 @@ rt_base_t rt_hw_cpu_icache_status() */ void rt_hw_cpu_dcache_enable() { - cache_enable(DCACHE_MASK); + cache_enable(DCACHE_MASK); } /** @@ -143,7 +175,7 @@ void rt_hw_cpu_dcache_enable() */ void rt_hw_cpu_dcache_disable() { - cache_disable(DCACHE_MASK); + cache_disable(DCACHE_MASK); } /** @@ -152,7 +184,7 @@ void rt_hw_cpu_dcache_disable() */ rt_base_t rt_hw_cpu_dcache_status() { - return (cp15_rd() & DCACHE_MASK); + return (cp15_rd() & DCACHE_MASK); } /** @@ -161,13 +193,13 @@ rt_base_t rt_hw_cpu_dcache_status() */ void rt_hw_cpu_reset() { - - rt_kprintf("Restarting system...\n"); - machine_reset(); + + rt_kprintf("Restarting system...\n"); + machine_reset(); - while(1); /* loop forever and wait for reset to happen */ + while(1); /* loop forever and wait for reset to happen */ - /* NEVER REACHED */ + /* NEVER REACHED */ } /** @@ -176,15 +208,15 @@ void rt_hw_cpu_reset() */ void rt_hw_cpu_shutdown() { - rt_uint32_t level; - rt_kprintf("shutdown...\n"); + rt_uint32_t level; + rt_kprintf("shutdown...\n"); - level = rt_hw_interrupt_disable(); - machine_shutdown(); - while (level) - { - RT_ASSERT(0); - } + level = rt_hw_interrupt_disable(); + machine_shutdown(); + while (level) + { + RT_ASSERT(0); + } } #ifdef RT_USING_CPU_FFS @@ -201,42 +233,42 @@ void rt_hw_cpu_shutdown() #if defined(__CC_ARM) int __rt_ffs(int value) { - register rt_uint32_t x; + register rt_uint32_t x; - if (value == 0) - return value; - - __asm - { - rsb x, value, #0 - and x, x, value - clz x, x - rsb x, x, #32 - } + if (value == 0) + return value; + + __asm + { + rsb x, value, #0 + and x, x, value + clz x, x + rsb x, x, #32 + } - return x; + return x; } #elif defined(__IAR_SYSTEMS_ICC__) int __rt_ffs(int value) { - if (value == 0) - return value; + if (value == 0) + return value; - __ASM("RSB r4, r0, #0"); - __ASM("AND r4, r4, r0"); - __ASM("CLZ r4, r4"); - __ASM("RSB r0, r4, #32"); + __ASM("RSB r4, r0, #0"); + __ASM("AND r4, r4, r0"); + __ASM("CLZ r4, r4"); + __ASM("RSB r0, r4, #32"); } #elif defined(__GNUC__) int __rt_ffs(int value) { - if (value == 0) - return value; + if (value == 0) + return value; - value &= (-value); - asm ("clz %0, %1": "=r"(value) :"r"(value)); + value &= (-value); + asm ("clz %0, %1": "=r"(value) :"r"(value)); - return (32 - value); + return (32 - value); } #endif diff --git a/libcpu/arm/arm926/mmu.c b/libcpu/arm/arm926/mmu.c index debb88f267..fa074e895f 100644 --- a/libcpu/arm/arm926/mmu.c +++ b/libcpu/arm/arm926/mmu.c @@ -26,22 +26,22 @@ #ifdef __CC_ARM void mmu_setttbase(rt_uint32_t i) { - register rt_uint32_t value; + register rt_uint32_t value; /* Invalidates all TLBs.Domain access is selected as * client by configuring domain access register, * in that case access controlled by permission value * set by page table entry */ - value = 0; + value = 0; __asm { mcr p15, 0, value, c8, c7, 0 - } + } - value = 0x55555555; - __asm - { + value = 0x55555555; + __asm + { mcr p15, 0, value, c3, c0, 0 mcr p15, 0, i, c2, c0, 0 } @@ -167,44 +167,44 @@ void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size) while(ptr < buffer + size) { - __asm - { - MCR p15, 0, ptr, c7, c14, 1 - } + __asm + { + MCR p15, 0, ptr, c7, c14, 1 + } ptr += CACHE_LINE_SIZE; } } void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size) { - unsigned int ptr; + unsigned int ptr; - ptr = buffer & ~(CACHE_LINE_SIZE - 1); + ptr = buffer & ~(CACHE_LINE_SIZE - 1); - while (ptr < buffer + size) - { - __asm - { - MCR p15, 0, ptr, c7, c10, 1 - } - ptr += CACHE_LINE_SIZE; - } + while (ptr < buffer + size) + { + __asm + { + MCR p15, 0, ptr, c7, c10, 1 + } + ptr += CACHE_LINE_SIZE; + } } void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size) { - unsigned int ptr; + unsigned int ptr; - ptr = buffer & ~(CACHE_LINE_SIZE - 1); + ptr = buffer & ~(CACHE_LINE_SIZE - 1); - while (ptr < buffer + size) - { - __asm - { - MCR p15, 0, ptr, c7, c6, 1 - } - ptr += CACHE_LINE_SIZE; - } + while (ptr < buffer + size) + { + __asm + { + MCR p15, 0, ptr, c7, c6, 1 + } + ptr += CACHE_LINE_SIZE; + } } void mmu_invalidate_tlb() @@ -245,133 +245,133 @@ void mmu_invalidate_dcache_all() #elif defined(__GNUC__) void mmu_setttbase(register rt_uint32_t i) { - register rt_uint32_t value; + register rt_uint32_t value; /* Invalidates all TLBs.Domain access is selected as * client by configuring domain access register, * in that case access controlled by permission value * set by page table entry */ - value = 0; - asm ("mcr p15, 0, %0, c8, c7, 0"::"r"(value)); + value = 0; + asm ("mcr p15, 0, %0, c8, c7, 0"::"r"(value)); - value = 0x55555555; - asm ("mcr p15, 0, %0, c3, c0, 0"::"r"(value)); - asm ("mcr p15, 0, %0, c2, c0, 0"::"r"(i)); + value = 0x55555555; + asm ("mcr p15, 0, %0, c3, c0, 0"::"r"(value)); + asm ("mcr p15, 0, %0, c2, c0, 0"::"r"(i)); } void mmu_set_domain(register rt_uint32_t i) { - asm ("mcr p15,0, %0, c3, c0, 0": :"r" (i)); + asm ("mcr p15,0, %0, c3, c0, 0": :"r" (i)); } void mmu_enable() { - register rt_uint32_t i; + register rt_uint32_t i; - /* read control register */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i |= 0x1; + i |= 0x1; - /* write back to control register */ - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); } void mmu_disable() { - register rt_uint32_t i; + register rt_uint32_t i; - /* read control register */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~0x1; + i &= ~0x1; - /* write back to control register */ - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); } void mmu_enable_icache() { - register rt_uint32_t i; + register rt_uint32_t i; - /* read control register */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i |= (1 << 12); + i |= (1 << 12); - /* write back to control register */ - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); } void mmu_enable_dcache() { - register rt_uint32_t i; + register rt_uint32_t i; - /* read control register */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i |= (1 << 2); + i |= (1 << 2); - /* write back to control register */ - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); } void mmu_disable_icache() { - register rt_uint32_t i; + register rt_uint32_t i; - /* read control register */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~(1 << 12); + i &= ~(1 << 12); - /* write back to control register */ - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); } void mmu_disable_dcache() { - register rt_uint32_t i; + register rt_uint32_t i; - /* read control register */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~(1 << 2); + i &= ~(1 << 2); - /* write back to control register */ - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); } void mmu_enable_alignfault() { - register rt_uint32_t i; + register rt_uint32_t i; - /* read control register */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i |= (1 << 1); + i |= (1 << 1); - /* write back to control register */ - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); } void mmu_disable_alignfault() { - register rt_uint32_t i; + register rt_uint32_t i; - /* read control register */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~(1 << 1); + i &= ~(1 << 1); - /* write back to control register */ - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); } void mmu_clean_invalidated_cache_index(int index) { - asm ("mcr p15, 0, %0, c7, c14, 2": :"r" (index)); + asm ("mcr p15, 0, %0, c7, c14, 2": :"r" (index)); } void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size) @@ -382,7 +382,7 @@ void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size) while(ptr < buffer + size) { - asm ("mcr p15, 0, %0, c7, c14, 1": :"r" (ptr)); + asm ("mcr p15, 0, %0, c7, c14, 1": :"r" (ptr)); ptr += CACHE_LINE_SIZE; } } @@ -390,38 +390,224 @@ void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size) void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size) { - unsigned int ptr; + unsigned int ptr; - ptr = buffer & ~(CACHE_LINE_SIZE - 1); + ptr = buffer & ~(CACHE_LINE_SIZE - 1); - while (ptr < buffer + size) - { - asm ("mcr p15, 0, %0, c7, c10, 1": :"r" (ptr)); - ptr += CACHE_LINE_SIZE; - } + while (ptr < buffer + size) + { + asm ("mcr p15, 0, %0, c7, c10, 1": :"r" (ptr)); + ptr += CACHE_LINE_SIZE; + } } void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size) { - unsigned int ptr; + unsigned int ptr; - ptr = buffer & ~(CACHE_LINE_SIZE - 1); + ptr = buffer & ~(CACHE_LINE_SIZE - 1); - while (ptr < buffer + size) - { - asm ("mcr p15, 0, %0, c7, c6, 1": :"r" (ptr)); - ptr += CACHE_LINE_SIZE; - } + while (ptr < buffer + size) + { + asm ("mcr p15, 0, %0, c7, c6, 1": :"r" (ptr)); + ptr += CACHE_LINE_SIZE; + } } void mmu_invalidate_tlb() { - asm ("mcr p15, 0, %0, c8, c7, 0": :"r" (0)); + asm ("mcr p15, 0, %0, c8, c7, 0": :"r" (0)); } void mmu_invalidate_icache() { - asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0)); + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0)); +} + +void mmu_invalidate_dcache_all() +{ + asm ("mcr p15, 0, %0, c7, c6, 0": :"r" (0)); +} +#elif defined(__ICCARM__) +void mmu_setttbase(register rt_uint32_t i) +{ + register rt_uint32_t value; + + /* Invalidates all TLBs.Domain access is selected as + * client by configuring domain access register, + * in that case access controlled by permission value + * set by page table entry + */ + value = 0; + asm ("mcr p15, 0, %0, c8, c7, 0"::"r"(value)); + + value = 0x55555555; + asm ("mcr p15, 0, %0, c3, c0, 0"::"r"(value)); + asm ("mcr p15, 0, %0, c2, c0, 0"::"r"(i)); +} + +void mmu_set_domain(register rt_uint32_t i) +{ + asm ("mcr p15,0, %0, c3, c0, 0": :"r" (i)); +} + +void mmu_enable() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= 0x1; + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disable() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~0x1; + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_enable_icache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= (1 << 12); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_enable_dcache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= (1 << 2); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disable_icache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~(1 << 12); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disable_dcache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~(1 << 2); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_enable_alignfault() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= (1 << 1); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disable_alignfault() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~(1 << 1); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_clean_invalidated_cache_index(int index) +{ + asm ("mcr p15, 0, %0, c7, c14, 2": :"r" (index)); +} + +void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size) +{ + unsigned int ptr; + + ptr = buffer & ~(CACHE_LINE_SIZE - 1); + + while(ptr < buffer + size) + { + asm ("mcr p15, 0, %0, c7, c14, 1": :"r" (ptr)); + ptr += CACHE_LINE_SIZE; + } +} + + +void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size) +{ + unsigned int ptr; + + ptr = buffer & ~(CACHE_LINE_SIZE - 1); + + while (ptr < buffer + size) + { + asm ("mcr p15, 0, %0, c7, c10, 1": :"r" (ptr)); + ptr += CACHE_LINE_SIZE; + } +} + +void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size) +{ + unsigned int ptr; + + ptr = buffer & ~(CACHE_LINE_SIZE - 1); + + while (ptr < buffer + size) + { + asm ("mcr p15, 0, %0, c7, c6, 1": :"r" (ptr)); + ptr += CACHE_LINE_SIZE; + } +} + +void mmu_invalidate_tlb() +{ + asm ("mcr p15, 0, %0, c8, c7, 0": :"r" (0)); +} + +void mmu_invalidate_icache() +{ + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0)); } void mmu_invalidate_dcache_all() @@ -431,38 +617,44 @@ void mmu_invalidate_dcache_all() #endif /* level1 page table */ +#if defined(__ICCARM__) +#pragma data_alignment=(16*1024) +static volatile unsigned int _page_table[4*1024];; +#else static volatile unsigned int _page_table[4*1024] __attribute__((aligned(16*1024))); +#endif void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd, rt_uint32_t paddrStart, rt_uint32_t attr) { volatile rt_uint32_t *pTT; - volatile int i,nSec; + volatile int nSec; + int i = 0; pTT=(rt_uint32_t *)_page_table+(vaddrStart>>20); nSec=(vaddrEnd>>20)-(vaddrStart>>20); for(i=0;i<=nSec;i++) { - *pTT = attr |(((paddrStart>>20)+i)<<20); - pTT++; + *pTT = attr |(((paddrStart>>20)+i)<<20); + pTT++; } } void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size) { - /* disable I/D cache */ - mmu_disable_dcache(); - mmu_disable_icache(); - mmu_disable(); - mmu_invalidate_tlb(); + /* disable I/D cache */ + mmu_disable_dcache(); + mmu_disable_icache(); + mmu_disable(); + mmu_invalidate_tlb(); - /* set page table */ - for (; size > 0; size--) - { - mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end, - mdesc->paddr_start, mdesc->attr); - mdesc++; - } + /* set page table */ + for (; size > 0; size--) + { + mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end, + mdesc->paddr_start, mdesc->attr); + mdesc++; + } - /* set MMU table address */ - mmu_setttbase((rt_uint32_t)_page_table); + /* set MMU table address */ + mmu_setttbase((rt_uint32_t)_page_table); /* enables MMU */ mmu_enable(); diff --git a/libcpu/arm/arm926/mmu.h b/libcpu/arm/arm926/mmu.h index d6c497efb9..adbfe95934 100644 --- a/libcpu/arm/arm926/mmu.h +++ b/libcpu/arm/arm926/mmu.h @@ -26,35 +26,35 @@ #include -#define CACHE_LINE_SIZE 32 +#define CACHE_LINE_SIZE 32 -#define DESC_SEC (0x2|(1<<4)) -#define CB (3<<2) //cache_on, write_back -#define CNB (2<<2) //cache_on, write_through -#define NCB (1<<2) //cache_off,WR_BUF on -#define NCNB (0<<2) //cache_off,WR_BUF off -#define AP_RW (3<<10) //supervisor=RW, user=RW -#define AP_RO (2<<10) //supervisor=RW, user=RO +#define DESC_SEC (0x2|(1<<4)) +#define CB (3<<2) //cache_on, write_back +#define CNB (2<<2) //cache_on, write_through +#define NCB (1<<2) //cache_off,WR_BUF on +#define NCNB (0<<2) //cache_off,WR_BUF off +#define AP_RW (3<<10) //supervisor=RW, user=RW +#define AP_RO (2<<10) //supervisor=RW, user=RO -#define DOMAIN_FAULT (0x0) -#define DOMAIN_CHK (0x1) -#define DOMAIN_NOTCHK (0x3) -#define DOMAIN0 (0x0<<5) -#define DOMAIN1 (0x1<<5) +#define DOMAIN_FAULT (0x0) +#define DOMAIN_CHK (0x1) +#define DOMAIN_NOTCHK (0x3) +#define DOMAIN0 (0x0<<5) +#define DOMAIN1 (0x1<<5) -#define DOMAIN0_ATTR (DOMAIN_CHK<<0) -#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) +#define DOMAIN0_ATTR (DOMAIN_CHK<<0) +#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) -#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) /* Read/Write, cache, write back */ -#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) /* Read/Write, cache, write through */ -#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */ -#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */ +#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) /* Read/Write, cache, write back */ +#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) /* Read/Write, cache, write through */ +#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */ +#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */ struct mem_desc { - rt_uint32_t vaddr_start; - rt_uint32_t vaddr_end; - rt_uint32_t paddr_start; - rt_uint32_t attr; + rt_uint32_t vaddr_start; + rt_uint32_t vaddr_end; + rt_uint32_t paddr_start; + rt_uint32_t attr; }; void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size); diff --git a/libcpu/arm/arm926/stack.c b/libcpu/arm/arm926/stack.c index f58b43cbd4..b9bb3c8508 100644 --- a/libcpu/arm/arm926/stack.c +++ b/libcpu/arm/arm926/stack.c @@ -26,14 +26,14 @@ /*****************************/ /* CPU Mode */ /*****************************/ -#define USERMODE 0x10 -#define FIQMODE 0x11 -#define IRQMODE 0x12 -#define SVCMODE 0x13 -#define ABORTMODE 0x17 -#define UNDEFMODE 0x1b -#define MODEMASK 0x1f -#define NOINT 0xc0 +#define USERMODE 0x10 +#define FIQMODE 0x11 +#define IRQMODE 0x12 +#define SVCMODE 0x13 +#define ABORTMODE 0x17 +#define UNDEFMODE 0x1b +#define MODEMASK 0x1f +#define NOINT 0xc0 /** * This function will initialize thread stack @@ -46,30 +46,30 @@ * @return stack address */ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, - rt_uint8_t *stack_addr, void *texit) + rt_uint8_t *stack_addr, void *texit) { - rt_uint32_t *stk; + rt_uint32_t *stk; - stk = (rt_uint32_t*)stack_addr; - *(stk) = (rt_uint32_t)tentry; /* entry point */ - *(--stk) = (rt_uint32_t)texit; /* lr */ - *(--stk) = 0; /* r12 */ - *(--stk) = 0; /* r11 */ - *(--stk) = 0; /* r10 */ - *(--stk) = 0; /* r9 */ - *(--stk) = 0; /* r8 */ - *(--stk) = 0; /* r7 */ - *(--stk) = 0; /* r6 */ - *(--stk) = 0; /* r5 */ - *(--stk) = 0; /* r4 */ - *(--stk) = 0; /* r3 */ - *(--stk) = 0; /* r2 */ - *(--stk) = 0; /* r1 */ - *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ - *(--stk) = SVCMODE; /* cpsr */ - *(--stk) = SVCMODE; /* spsr */ + stk = (rt_uint32_t*)stack_addr; + *(stk) = (rt_uint32_t)tentry; /* entry point */ + *(--stk) = (rt_uint32_t)texit; /* lr */ + *(--stk) = 0; /* r12 */ + *(--stk) = 0; /* r11 */ + *(--stk) = 0; /* r10 */ + *(--stk) = 0; /* r9 */ + *(--stk) = 0; /* r8 */ + *(--stk) = 0; /* r7 */ + *(--stk) = 0; /* r6 */ + *(--stk) = 0; /* r5 */ + *(--stk) = 0; /* r4 */ + *(--stk) = 0; /* r3 */ + *(--stk) = 0; /* r2 */ + *(--stk) = 0; /* r1 */ + *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ + *(--stk) = SVCMODE; /* cpsr */ + *(--stk) = SVCMODE; /* spsr */ - /* return task's current stack address */ - return (rt_uint8_t *)stk; + /* return task's current stack address */ + return (rt_uint8_t *)stk; } diff --git a/libcpu/arm/arm926/start_gcc.S b/libcpu/arm/arm926/start_gcc.S new file mode 100644 index 0000000000..b6377ed676 --- /dev/null +++ b/libcpu/arm/arm926/start_gcc.S @@ -0,0 +1,327 @@ +/* + * File : start.S + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2011-01-13 weety first version + */ +#define CONFIG_STACKSIZE 512 +#define S_FRAME_SIZE (18*4) //72 + +@#define S_SPSR (17*4) //SPSR +@#define S_CPSR (16*4) //CPSR +#define S_PC (15*4) //R15 +@#define S_LR (14*4) //R14 +@#define S_SP (13*4) //R13 + +@#define S_IP (12*4) //R12 +@#define S_FP (11*4) //R11 +@#define S_R10 (10*4) +@#define S_R9 (9*4) +@#define S_R8 (8*4) +@#define S_R7 (7*4) +@#define S_R6 (6*4) +@#define S_R5 (5*4) +@#define S_R4 (4*4) +@#define S_R3 (3*4) +@#define S_R2 (2*4) +@#define S_R1 (1*4) +@#define S_R0 (0*4) + +#define MODE_SYS 0x1F +#define MODE_FIQ 0x11 +#define MODE_IRQ 0x12 +#define MODE_SVC 0x13 +#define MODE_ABT 0x17 +#define MODE_UND 0x1B +#define MODEMASK 0x1F +#define NOINT 0xC0 + +.include "rt_low_level_gcc.inc" + +@; stack table----------------------------------------------------------------- + .section .nobss, "w" + + .space UND_STK_SIZE + .global UND_STACK_START +UND_STACK_START: + + .space SVC_STK_SIZE + .align 2 + .global SVC_STACK_START +SVC_STACK_START: + + .space ABT_STK_SIZE + .align 2 + .global ABT_STACK_START +ABT_STACK_START: + + .space IRQ_STK_SIZE + .align 2 + .global IRQ_STACK_START +IRQ_STACK_START: + + .space FIQ_STK_SIZE + .align 2 + .global FIQ_STACK_START +FIQ_STACK_START: + + .skip SYS_STK_SIZE + .align 2 + .global SYS_STACK_START +SYS_STACK_START: + + +@; Jump vector table----------------------------------------------------------- + + .section .init, "ax" + .arm + + .global entry +entry: + LDR PC, vector_reset + LDR PC, vector_undef + LDR PC, vector_swi + LDR PC, vector_pabt + LDR PC, vector_dabt + LDR PC, vector_resv + LDR PC, vector_irq + LDR PC, vector_fiq + +vector_reset: + .word Reset_Handler +vector_undef: + .word Undef_Handler +vector_swi: + .word SWI_Handler +vector_pabt: + .word PAbt_Handler +vector_dabt: + .word DAbt_Handler +vector_resv: + .word Resv_Handler +vector_irq: + .word IRQ_Handler +vector_fiq: + .word FIQ_Handler + + .balignl 16,0xdeadbeef + +@;----------------- Reset Handler --------------------------------------------- + .global rt_low_level_init + .global main + .global Reset_Handler +Reset_Handler: + @; Set the cpu to SVC32 mode + MRS R0, CPSR + BIC R0, R0, #MODEMASK + ORR R0, R0, #MODE_SVC|NOINT + MSR CPSR, R0 + LDR SP, =SVC_STACK_START + + @; Call low level init function, + @; disable and clear all IRQs and remap internal ram to 0x00000000. + LDR R0, =rt_low_level_init + BLX R0 + + @; Copy Exception Vectors to Internal RAM + LDR R8, =entry @; Source + LDR R9, =0x00000000 @; Destination + CMP R8, R9 + BEQ Setup_Stack + LDMIA R8!, {R0-R7} @; Load Vectors + STMIA R9!, {R0-R7} @; Store Vectors + LDMIA R8!, {R0-R7} @; Load Handler Addresses + STMIA R9!, {R0-R7} @; Store Handler Addresses + +Setup_Stack: + @; Setup Stack for each mode + MRS R0, CPSR + BIC R0, R0, #MODEMASK + + ORR R1, R0, #MODE_UND|NOINT + MSR CPSR_cxsf, R1 @; Undef mode + LDR SP, =UND_STACK_START + + ORR R1, R0, #MODE_ABT|NOINT + MSR CPSR_cxsf, R1 @; Abort mode + LDR SP, =ABT_STACK_START + + ORR R1, R0, #MODE_IRQ|NOINT + MSR CPSR_cxsf, R1 @; IRQ mode + LDR SP, =IRQ_STACK_START + + ORR R1, R0, #MODE_FIQ|NOINT + MSR CPSR_cxsf, R1 @; FIQ mode + LDR SP, =FIQ_STACK_START + + ORR R1, R0, #MODE_SYS|NOINT + MSR CPSR_cxsf,R1 @; SYS/User mode + LDR SP, =SYS_STACK_START + + ORR R1, R0, #MODE_SVC|NOINT + MSR CPSR_cxsf, R1 @; SVC mode + LDR SP, =SVC_STACK_START + + + @; clear .bss + MOV R0, #0 @; get a zero + LDR R1, =__bss_start__ @; bss start + LDR R2, =__bss_end__ @; bss end + +bss_clear_loop: + CMP R1, R2 @; check if data to clear + STRLO R0, [R1], #4 @; clear 4 bytes + BLO bss_clear_loop @; loop until done + + @; call C++ constructors of global objects + LDR R0, =__ctors_start__ + LDR R1, =__ctors_end__ + +ctor_loop: + CMP R0, R1 + BEQ ctor_end + LDR R2, [R0], #4 + STMFD SP!, {R0-R1} + MOV LR, PC + BX R2 + LDMFD SP!, {R0-R1} + B ctor_loop + +ctor_end: + @; Enter the C code + LDR R0, =main + BLX R0 + +@;----------------- Exception Handler ----------------------------------------- + .global rt_hw_trap_udef + .global rt_hw_trap_swi + .global rt_hw_trap_pabt + .global rt_hw_trap_dabt + .global rt_hw_trap_resv + .global rt_hw_trap_irq + .global rt_hw_trap_fiq + + .global rt_interrupt_enter + .global rt_interrupt_leave + .global rt_thread_switch_interrupt_flag + .global rt_interrupt_from_thread + .global rt_interrupt_to_thread + + .align 5 +Undef_Handler: + SUB SP, SP, #S_FRAME_SIZE + STMIA SP, {R0 - R12} @; Calling R0-R12 + ADD R8, SP, #S_PC + STMDB R8, {SP, LR} @; Calling SP, LR + STR LR, [R8, #0] @; Save calling PC + MRS R6, SPSR + STR R6, [R8, #4] @; Save CPSR + STR R0, [R8, #8] @; Save SPSR + MOV R0, SP + BL rt_hw_trap_udef + + .align 5 +SWI_Handler: + BL rt_hw_trap_swi + + .align 5 +PAbt_Handler: + BL rt_hw_trap_pabt + + .align 5 +DAbt_Handler: + SUB SP, SP, #S_FRAME_SIZE + STMIA SP, {R0 - R12} @; Calling R0-R12 + ADD R8, SP, #S_PC + STMDB R8, {SP, LR} @; Calling SP, LR + STR LR, [R8, #0] @; Save calling PC + MRS R6, SPSR + STR R6, [R8, #4] @; Save CPSR + STR R0, [R8, #8] @; Save SPSR + MOV R0, SP + BL rt_hw_trap_dabt + + .align 5 +Resv_Handler: + BL rt_hw_trap_resv + + .align 5 +FIQ_Handler: + STMFD SP!, {R0-R7,LR} + BL rt_hw_trap_fiq + LDMFD SP!, {R0-R7,LR} + SUBS PC, LR, #4 + + .align 5 +IRQ_Handler: + STMFD SP!, {R0-R12,LR} + BL rt_interrupt_enter + BL rt_hw_trap_irq + BL rt_interrupt_leave + + @; If rt_thread_switch_interrupt_flag set, + @; jump to rt_hw_context_switch_interrupt_do and don't return + LDR R0, =rt_thread_switch_interrupt_flag + LDR R1, [R0] + CMP R1, #1 + BEQ rt_hw_context_switch_interrupt_do + + LDMFD SP!, {R0-R12,LR} + SUBS PC, LR, #4 + +@;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) ----------------- +rt_hw_context_switch_interrupt_do: + MOV R1, #0 @; Clear flag + STR R1, [R0] @; Save to flag variable + + LDMFD SP!, {R0-R12,LR} @; Reload saved registers + STMFD SP!, {R0-R3} @; Save R0-R3 + MOV R1, SP @; Save old task's SP to R1 + ADD SP, SP, #16 @; Restore SP + SUB R2, LR, #4 @; Save old task's PC to R2 + + MRS R3, SPSR @; Get CPSR of interrupt thread + + MSR CPSR_c, #MODE_SVC|NOINT @; Switch to SVC mode and no interrupt + + STMFD SP!, {R2} @; Push old task's PC + STMFD SP!, {R4-R12,LR} @; Push old task's LR,R12-R4 + MOV R4, R1 @; Special optimised code below + MOV R5, R3 + LDMFD R4!, {R0-R3} + STMFD SP!, {R0-R3} @; Push old task's R3-R0 + STMFD SP!, {R5} @; Push old task's CPSR + MRS R4, SPSR + STMFD SP!, {R4} @; Push old task's SPSR + + LDR R4, =rt_interrupt_from_thread + LDR R5, [R4] @; R5 = stack ptr in old tasks's TCB + STR SP, [R5] @; Store SP in preempted tasks's TCB + + LDR R6, =rt_interrupt_to_thread + LDR R6, [R6] @; R6 = stack ptr in new tasks's TCB + LDR SP, [R6] @; Get new task's stack pointer + + LDMFD SP!, {R4} @; Pop new task's SPSR + MSR SPSR_cxsf, R4 + LDMFD SP!, {R4} @; Pop new task's CPSR + MSR SPSR_cxsf, R4 + + LDMFD SP!, {R0-R12,LR,PC}^ @; pop new task's R0-R12,LR & PC diff --git a/libcpu/arm/arm926/start_iar.S b/libcpu/arm/arm926/start_iar.S new file mode 100644 index 0000000000..1f516462b2 --- /dev/null +++ b/libcpu/arm/arm926/start_iar.S @@ -0,0 +1,296 @@ +;/* +; * File : start.S +; * This file is part of RT-Thread RTOS +; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * +; * This program is free software; you can redistribute it and/or modify +; * it under the terms of the GNU General Public License as published by +; * the Free Software Foundation; either version 2 of the License, or +; * (at your option) any later version. +; * +; * This program is distributed in the hope that it will be useful, +; * but WITHOUT ANY WARRANTY; without even the implied warranty of +; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; * GNU General Public License for more details. +; * +; * You should have received a copy of the GNU General Public License along +; * with this program; if not, write to the Free Software Foundation, Inc., +; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +; * +; * Change Logs: +; * Date Author Notes +; * 2011-01-13 weety first version +; */ + +#define S_FRAME_SIZE (18*4) ;72 + +;#define S_SPSR (17*4) ;SPSR +;#define S_CPSR (16*4) ;CPSR +#define S_PC (15*4) ;R15 +;#define S_LR (14*4) ;R14 +;#define S_SP (13*4) ;R13 + +;#define S_IP (12*4) ;R12 +;#define S_FP (11*4) ;R11 +;#define S_R10 (10*4) +;#define S_R9 (9*4) +;#define S_R8 (8*4) +;#define S_R7 (7*4) +;#define S_R6 (6*4) +;#define S_R5 (5*4) +;#define S_R4 (4*4) +;#define S_R3 (3*4) +;#define S_R2 (2*4) +;#define S_R1 (1*4) +;#define S_R0 (0*4) + +#define MODE_SYS 0x1F +#define MODE_FIQ 0x11 +#define MODE_IRQ 0x12 +#define MODE_SVC 0x13 +#define MODE_ABT 0x17 +#define MODE_UND 0x1B +#define MODEMASK 0x1F +#define NOINT 0xC0 + +#include "rt_low_level_iar.inc" + + MODULE ?cstartup + SECTION .noinit:DATA:NOROOT(3) + DATA + + DS8 UND_STK_SIZE + PUBLIC UND_STACK_START +UND_STACK_START: + + ALIGNRAM 2 + DS8 ABT_STK_SIZE + PUBLIC ABT_STACK_START +ABT_STACK_START: + + ALIGNRAM 2 + DS8 FIQ_STK_SIZE + PUBLIC FIQ_STACK_START +FIQ_STACK_START: + + ALIGNRAM 2 + DS8 IRQ_STK_SIZE + PUBLIC IRQ_STACK_START +IRQ_STACK_START: + + ALIGNRAM 2 + DS8 SVC_STK_SIZE + PUBLIC SVC_STACK_START +SVC_STACK_START: + + ALIGNRAM 2 + DS8 SYS_STK_SIZE + PUBLIC SYS_STACK_START +SYS_STACK_START: + +;--------------Jump vector table------------------------------------------------ + SECTION .intvec:CODE:ROOT(2) + ARM + PUBLIC Entry_Point +Entry_Point: +__iar_init$$done: ; The interrupt vector is not needed + ; until after copy initialization is done + LDR PC, vector_reset + LDR PC, vector_undef + LDR PC, vector_swi + LDR PC, vector_pabt + LDR PC, vector_dabt + LDR PC, vector_resv + LDR PC, vector_irq + LDR PC, vector_fiq + +vector_reset: + DC32 Reset_Handler +vector_undef: + DC32 Undef_Handler +vector_swi: + DC32 SWI_Handler +vector_pabt: + DC32 PAbt_Handler +vector_dabt: + DC32 DAbt_Handler +vector_resv: + DC32 Resv_Handler +vector_irq: + DC32 IRQ_Handler +vector_fiq: + DC32 FIQ_Handler + +;----------------- Reset Handler ----------------------------------------------- + EXTERN rt_low_level_init + EXTERN ?main + PUBLIC __iar_program_start +__iar_program_start: +Reset_Handler: + ; Set the cpu to SVC32 mode + MRS R0, CPSR + BIC R0, R0, #MODEMASK + ORR R0, R0, #MODE_SVC|NOINT + MSR CPSR_cxsf, R0 + LDR SP, =SVC_STACK_START + + ; Call low level init function, + ; disable and clear all IRQs and remap internal ram to 0x00000000. + LDR R0, =rt_low_level_init + BLX R0 + + ; Copy Exception Vectors to Internal RAM + LDR R8, =Entry_Point ; Source + LDR R9, =0x00000000 ; Destination + CMP R8, R9 + BEQ Setup_Stack + LDMIA R8!, {R0-R7} ; Load Vectors + STMIA R9!, {R0-R7} ; Store Vectors + LDMIA R8!, {R0-R7} ; Load Handler Addresses + STMIA R9!, {R0-R7} ; Store Handler Addresses + +Setup_Stack: + ; Setup Stack for each mode + MRS R0, CPSR + BIC R0, R0, #MODEMASK + + ORR R1, R0, #MODE_UND|NOINT + MSR CPSR_cxsf, R1 ; Undef mode + LDR SP, =UND_STACK_START + + ORR R1,R0,#MODE_ABT|NOINT + MSR CPSR_cxsf,R1 ; Abort mode + LDR SP, =ABT_STACK_START + + ORR R1,R0,#MODE_IRQ|NOINT + MSR CPSR_cxsf,R1 ; IRQ mode + LDR SP, =IRQ_STACK_START + + ORR R1,R0,#MODE_FIQ|NOINT + MSR CPSR_cxsf,R1 ; FIQ mode + LDR SP, =FIQ_STACK_START + + ORR R1,R0,#MODE_SYS|NOINT + MSR CPSR_cxsf,R1 ; SYS/User mode + LDR SP, =SYS_STACK_START + + ORR R1,R0,#MODE_SVC|NOINT + MSR CPSR_cxsf,R1 ; SVC mode + LDR SP, =SVC_STACK_START + + ; Enter the C code + LDR R0, =?main + BLX R0 + +;----------------- Exception Handler ------------------------------------------- + IMPORT rt_hw_trap_udef + IMPORT rt_hw_trap_swi + IMPORT rt_hw_trap_pabt + IMPORT rt_hw_trap_dabt + IMPORT rt_hw_trap_resv + IMPORT rt_hw_trap_irq + IMPORT rt_hw_trap_fiq + + IMPORT rt_interrupt_enter + IMPORT rt_interrupt_leave + IMPORT rt_thread_switch_interrupt_flag + IMPORT rt_interrupt_from_thread + IMPORT rt_interrupt_to_thread + + SECTION .text:CODE:ROOT(2) + ARM +Undef_Handler: + SUB SP, SP, #S_FRAME_SIZE + STMIA SP, {R0 - R12} ; Calling R0-R12 + ADD R8, SP, #S_PC + STMDB R8, {SP, LR} ; Calling SP, LR + STR LR, [R8, #0] ; Save calling PC + MRS R6, SPSR + STR R6, [R8, #4] ; Save CPSR + STR R0, [R8, #8] ; Save SPSR + MOV R0, SP + BL rt_hw_trap_udef + +SWI_Handler: + BL rt_hw_trap_swi + +PAbt_Handler: + BL rt_hw_trap_pabt + +DAbt_Handler: + SUB SP, SP, #S_FRAME_SIZE + STMIA SP, {R0 - R12} ; Calling R0-R12 + ADD R8, SP, #S_PC + STMDB R8, {SP, LR} ; Calling SP, LR + STR LR, [R8, #0] ; Save calling PC + MRS R6, SPSR + STR R6, [R8, #4] ; Save CPSR + STR R0, [R8, #8] ; Save SPSR + MOV R0, SP + BL rt_hw_trap_dabt + +Resv_Handler: + BL rt_hw_trap_resv + +IRQ_Handler: + STMFD SP!, {R0-R12,LR} + BL rt_interrupt_enter + BL rt_hw_trap_irq + BL rt_interrupt_leave + + ; If rt_thread_switch_interrupt_flag set, + ; jump to rt_hw_context_switch_interrupt_do and don't return + LDR R0, =rt_thread_switch_interrupt_flag + LDR R1, [R0] + CMP R1, #1 + BEQ rt_hw_context_switch_interrupt_do + + LDMFD SP!, {R0-R12,LR} + SUBS PC, LR, #4 + +FIQ_Handler: + STMFD SP!, {R0-R7,LR} + BL rt_hw_trap_fiq + LDMFD SP!, {R0-R7,LR} + SUBS PC, LR, #4 + +;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) ----------------- +rt_hw_context_switch_interrupt_do: + MOV R1, #0 ; Clear flag + STR R1, [R0] ; Save to flag variable + + LDMFD SP!, {R0-R12,LR} ; Reload saved registers + STMFD SP!, {R0-R3} ; Save R0-R3 + MOV R1, SP ; Save old task's SP to R1 + ADD SP, SP, #16 ; Restore SP + SUB R2, LR, #4 ; Save old task's PC to R2 + + MRS R3, SPSR ; Get CPSR of interrupt thread + + MSR CPSR_c, #MODE_SVC|NOINT ; Switch to SVC mode and no interrupt + + STMFD SP!, {R2} ; Push old task's PC + STMFD SP!, {R4-R12,LR} ; Push old task's LR,R12-R4 + MOV R4, R1 ; Special optimised code below + MOV R5, R3 + LDMFD R4!, {R0-R3} + STMFD SP!, {R0-R3} ; Push old task's R3-R0 + STMFD SP!, {R5} ; Push old task's CPSR + MRS R4, SPSR + STMFD SP!, {R4} ; Push old task's SPSR + + LDR R4, =rt_interrupt_from_thread + LDR R5, [R4] ; R5 = stack ptr in old tasks's TCB + STR SP, [R5] ; Store SP in preempted tasks's TCB + + LDR R6, =rt_interrupt_to_thread + LDR R6, [R6] ; R6 = stack ptr in new tasks's TCB + LDR SP, [R6] ; Get new task's stack pointer + + LDMFD SP!, {R4} ; Pop new task's SPSR + MSR SPSR_cxsf, R4 + LDMFD SP!, {R4} ; Pop new task's CPSR + MSR SPSR_cxsf, R4 + + LDMFD SP!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC + END diff --git a/libcpu/arm/arm926/start_rvds.S b/libcpu/arm/arm926/start_rvds.S new file mode 100644 index 0000000000..42144334bd --- /dev/null +++ b/libcpu/arm/arm926/start_rvds.S @@ -0,0 +1,338 @@ +;/* +; * File : start_rvds.S +; * This file is part of RT-Thread RTOS +; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * +; * This program is free software; you can redistribute it and/or modify +; * it under the terms of the GNU General Public License as published by +; * the Free Software Foundation; either version 2 of the License, or +; * (at your option) any later version. +; * +; * This program is distributed in the hope that it will be useful, +; * but WITHOUT ANY WARRANTY; without even the implied warranty of +; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; * GNU General Public License for more details. +; * +; * You should have received a copy of the GNU General Public License along +; * with this program; if not, write to the Free Software Foundation, Inc., +; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +; * +; * Change Logs: +; * Date Author Notes +; * 2011-08-14 weety first version +; */ + + +; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs + +S_FRAME_SIZE EQU (18*4) ;72 +;S_SPSR EQU (17*4) ;SPSR +;S_CPSR EQU (16*4) ;CPSR +S_PC EQU (15*4) ;R15 +;S_LR EQU (14*4) ;R14 +;S_SP EQU (13*4) ;R13 + +;S_IP EQU (12*4) ;R12 +;S_FP EQU (11*4) ;R11 +;S_R10 EQU (10*4) +;S_R9 EQU (9*4) +;S_R8 EQU (8*4) +;S_R7 EQU (7*4) +;S_R6 EQU (6*4) +;S_R5 EQU (5*4) +;S_R4 EQU (4*4) +;S_R3 EQU (3*4) +;S_R2 EQU (2*4) +;S_R1 EQU (1*4) +;S_R0 EQU (0*4) + + +MODE_USR EQU 0X10 +MODE_FIQ EQU 0X11 +MODE_IRQ EQU 0X12 +MODE_SVC EQU 0X13 +MODE_ABT EQU 0X17 +MODE_UND EQU 0X1B +MODE_SYS EQU 0X1F +MODEMASK EQU 0X1F + +NOINT EQU 0xC0 + +;----------------------- Stack and Heap Definitions ---------------------------- + AREA STACK, NOINIT, READWRITE, ALIGN=3 + GET rt_low_level_keil.inc + +;-------------- stack area ----------------------------------------------------- + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem + + SPACE UND_STK_SIZE + EXPORT UND_STACK_START +UND_STACK_START + + ALIGN 8 + SPACE ABT_STK_SIZE + EXPORT ABT_STACK_START +ABT_STACK_START + + ALIGN 8 + SPACE FIQ_STK_SIZE + EXPORT FIQ_STACK_START +FIQ_STACK_START + + ALIGN 8 + SPACE IRQ_STK_SIZE + EXPORT IRQ_STACK_START +IRQ_STACK_START + + ALIGN 8 + SPACE SVC_STK_SIZE + EXPORT SVC_STACK_START +SVC_STACK_START + + ALIGN 8 + SPACE SYS_STK_SIZE + EXPORT SYS_STACK_START +SYS_STACK_START +Stack_Top + +Heap_Size EQU 0x00000000 + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem + SPACE Heap_Size +__heap_limit + +;----------------------- CODE -------------------------------------------------- + PRESERVE8 +; Area Definition and Entry Point +; Startup Code must be linked first at Address at which it expects to run. + +;--------------Jump vector table------------------------------------------------ + EXPORT Entry_Point + AREA RESET, CODE, READONLY + ARM +Entry_Point + LDR PC, vector_reset + LDR PC, vector_undef + LDR PC, vector_swi + LDR PC, vector_pabt + LDR PC, vector_dabt + LDR PC, vector_resv + LDR PC, vector_irq + LDR PC, vector_fiq + +vector_reset + DCD Reset_Handler +vector_undef + DCD Undef_Handler +vector_swi + DCD SWI_Handler +vector_pabt + DCD PAbt_Handler +vector_dabt + DCD DAbt_Handler +vector_resv + DCD Resv_Handler +vector_irq + DCD IRQ_Handler +vector_fiq + DCD FIQ_Handler + +;----------------- Reset Handler ----------------------------------------------- + IMPORT rt_low_level_init + IMPORT __main + EXPORT Reset_Handler +Reset_Handler + ; set the cpu to SVC32 mode + MRS R0,CPSR + BIC R0,R0,#MODEMASK + ORR R0,R0,#MODE_SVC + MSR CPSR_CXSF,R0 + LDR SP, =SVC_STACK_START + + ; Call low level init function, + ; disable and clear all IRQs and remap internal ram to 0x00000000. + LDR R0, =rt_low_level_init + BLX R0 + + ; Copy Exception Vectors to Internal RAM + LDR R8, =Entry_Point ; Source + LDR R9, =0x00000000 ; Destination + CMP R8, R9 + BEQ Setup_Stack + LDMIA R8!, {R0-R7} ; Load Vectors + STMIA R9!, {R0-R7} ; Store Vectors + LDMIA R8!, {R0-R7} ; Load Handler Addresses + STMIA R9!, {R0-R7} ; Store Handler Addresses + +Setup_Stack + ; Setup Stack for each mode + MRS R0, CPSR + BIC R0, R0, #MODEMASK + + ORR R1, R0, #MODE_UND:OR:NOINT + MSR CPSR_cxsf, R1 ; Undef mode + LDR SP, =UND_STACK_START + + ORR R1,R0,#MODE_ABT:OR:NOINT + MSR CPSR_cxsf,R1 ; Abort mode + LDR SP, =ABT_STACK_START + + ORR R1,R0,#MODE_IRQ:OR:NOINT + MSR CPSR_cxsf,R1 ; IRQ mode + LDR SP, =IRQ_STACK_START + + ORR R1,R0,#MODE_FIQ:OR:NOINT + MSR CPSR_cxsf,R1 ; FIQ mode + LDR SP, =FIQ_STACK_START + + ORR R1,R0,#MODE_SYS:OR:NOINT + MSR CPSR_cxsf,R1 ; SYS/User mode + LDR SP, =SYS_STACK_START + + ORR R1,R0,#MODE_SVC:OR:NOINT + MSR CPSR_cxsf,R1 ; SVC mode + LDR SP, =SVC_STACK_START + + ; Enter the C code + LDR R0, =__main + BLX R0 + +;----------------- Exception Handler ------------------------------------------- + IMPORT rt_hw_trap_udef + IMPORT rt_hw_trap_swi + IMPORT rt_hw_trap_pabt + IMPORT rt_hw_trap_dabt + IMPORT rt_hw_trap_resv + IMPORT rt_hw_trap_irq + IMPORT rt_hw_trap_fiq + + IMPORT rt_interrupt_enter + IMPORT rt_interrupt_leave + IMPORT rt_thread_switch_interrupt_flag + IMPORT rt_interrupt_from_thread + IMPORT rt_interrupt_to_thread + +Undef_Handler PROC + SUB SP, SP, #S_FRAME_SIZE + STMIA SP, {R0 - R12} ; Calling R0-R12 + ADD R8, SP, #S_PC + STMDB R8, {SP, LR} ; Calling SP, LR + STR LR, [R8, #0] ; Save calling PC + MRS R6, SPSR + STR R6, [R8, #4] ; Save CPSR + STR R0, [R8, #8] ; Save SPSR + MOV R0, SP + BL rt_hw_trap_udef + ENDP + +SWI_Handler PROC + BL rt_hw_trap_swi + ENDP + +PAbt_Handler PROC + BL rt_hw_trap_pabt + ENDP + +DAbt_Handler PROC + SUB SP, SP, #S_FRAME_SIZE + STMIA SP, {R0 - R12} ; Calling R0-R12 + ADD R8, SP, #S_PC + STMDB R8, {SP, LR} ; Calling SP, LR + STR LR, [R8, #0] ; Save calling PC + MRS R6, SPSR + STR R6, [R8, #4] ; Save CPSR + STR R0, [R8, #8] ; Save SPSR + MOV R0, SP + BL rt_hw_trap_dabt + ENDP + +Resv_Handler PROC + BL rt_hw_trap_resv + ENDP + +FIQ_Handler PROC + STMFD SP!, {R0-R7,LR} + BL rt_hw_trap_fiq + LDMFD SP!, {R0-R7,LR} + SUBS PC, LR, #4 + ENDP + +IRQ_Handler PROC + STMFD SP!, {R0-R12,LR} + BL rt_interrupt_enter + BL rt_hw_trap_irq + BL rt_interrupt_leave + + ; If rt_thread_switch_interrupt_flag set, + ; jump to rt_hw_context_switch_interrupt_do and don't return + LDR R0, =rt_thread_switch_interrupt_flag + LDR R1, [R0] + CMP R1, #1 + BEQ rt_hw_context_switch_interrupt_do + + LDMFD SP!, {R0-R12,LR} + SUBS PC, LR, #4 + ENDP + +;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) ----------------- +rt_hw_context_switch_interrupt_do PROC + MOV R1, #0 ; Clear flag + STR R1, [R0] ; Save to flag variable + + LDMFD SP!, {R0-R12,LR} ; Reload saved registers + STMFD SP!, {R0-R3} ; Save R0-R3 + MOV R1, SP ; Save old task's SP to R1 + ADD SP, SP, #16 ; Restore SP + SUB R2, LR, #4 ; Save old task's PC to R2 + + MRS R3, SPSR ; Get CPSR of interrupt thread + + MSR CPSR_c, #MODE_SVC:OR:NOINT ; Switch to SVC mode and no interrupt + + STMFD SP!, {R2} ; Push old task's PC + STMFD SP!, {R4-R12,LR} ; Push old task's LR,R12-R4 + MOV R4, R1 ; Special optimised code below + MOV R5, R3 + LDMFD R4!, {R0-R3} + STMFD SP!, {R0-R3} ; Push old task's R3-R0 + STMFD SP!, {R5} ; Push old task's CPSR + MRS R4, SPSR + STMFD SP!, {R4} ; Push old task's SPSR + + LDR R4, =rt_interrupt_from_thread + LDR R5, [R4] ; R5 = stack ptr in old tasks's TCB + STR SP, [R5] ; Store SP in preempted tasks's TCB + + LDR R6, =rt_interrupt_to_thread + LDR R6, [R6] ; R6 = stack ptr in new tasks's TCB + LDR SP, [R6] ; Get new task's stack pointer + + LDMFD SP!, {R4} ; Pop new task's SPSR + MSR SPSR_cxsf, R4 + LDMFD SP!, {R4} ; Pop new task's CPSR + MSR SPSR_cxsf, R4 + + LDMFD SP!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC + ENDP + + IF :DEF:__MICROLIB + + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + ; User Initial Stack & Heap + AREA |.text|, CODE, READONLY + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap +__user_initial_stackheap + LDR R0, = Heap_Mem + LDR R1, = (Stack_Mem + SYS_STK_SIZE) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDIF + END diff --git a/bsp/at91sam9260/platform/trap.c b/libcpu/arm/arm926/trap.c similarity index 82% rename from bsp/at91sam9260/platform/trap.c rename to libcpu/arm/arm926/trap.c index 7fd4011451..f44c76064e 100644 --- a/bsp/at91sam9260/platform/trap.c +++ b/libcpu/arm/arm926/trap.c @@ -25,7 +25,7 @@ #include #include -#include "at91sam926x.h" +#include /** * @addtogroup AT91SAM926X @@ -37,6 +37,28 @@ extern struct rt_thread *rt_current_thread; extern long list_thread(void); #endif +struct rt_hw_register +{ + rt_uint32_t r0; + rt_uint32_t r1; + rt_uint32_t r2; + rt_uint32_t r3; + rt_uint32_t r4; + rt_uint32_t r5; + rt_uint32_t r6; + rt_uint32_t r7; + rt_uint32_t r8; + rt_uint32_t r9; + rt_uint32_t r10; + rt_uint32_t fp; + rt_uint32_t ip; + rt_uint32_t sp; + rt_uint32_t lr; + rt_uint32_t pc; + rt_uint32_t cpsr; + rt_uint32_t ORIG_r0; +}; + /** * this function will show registers of CPU * @@ -105,7 +127,7 @@ void rt_hw_trap_pabt(struct rt_hw_register *regs) rt_hw_show_register(regs); rt_kprintf("prefetch abort\n"); - rt_kprintf("thread - %s stack:\n", rt_current_thread->name); + rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name); #ifdef RT_USING_FINSH list_thread(); @@ -126,7 +148,7 @@ void rt_hw_trap_dabt(struct rt_hw_register *regs) rt_hw_show_register(regs); rt_kprintf("data abort\n"); - rt_kprintf("thread - %s stack:\n", rt_current_thread->name); + rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name); #ifdef RT_USING_FINSH list_thread(); @@ -149,21 +171,21 @@ void rt_hw_trap_resv(struct rt_hw_register *regs) } extern struct rt_irq_desc irq_desc[]; +rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq, rt_uint32_t* id); +extern void rt_hw_interrupt_ack(rt_uint32_t fiq_irq); void rt_hw_trap_irq() { rt_isr_handler_t isr_func; - rt_uint32_t irqstat, irq, mask; + rt_uint32_t irqstat, irq; void *param; //rt_kprintf("irq interrupt request\n"); /* get irq number */ - irq = at91_sys_read(AT91_AIC_IVR); - /* clear pending register */ - irqstat = at91_sys_read(AT91_AIC_ISR); + irqstat = rt_hw_interrupt_get_active(INT_IRQ, &irq); if (irqstat == 0) { rt_kprintf("No interrupt occur\n"); - at91_sys_write(AT91_AIC_EOICR, 0); + rt_hw_interrupt_ack(INT_IRQ); return; } @@ -173,7 +195,9 @@ void rt_hw_trap_irq() /* turn to interrupt service routine */ isr_func(irq, param); - at91_sys_write(AT91_AIC_EOICR, 0x55555555); //EIOCR must be write any value after interrupt, or else can't response next interrupt + // EIOCR must be write any value after interrupt, + // or else can't response next interrupt + rt_hw_interrupt_ack(INT_IRQ); irq_desc[irq].counter ++; } From 81d7ef1e9f0de1996eb582f688120344b615f4e1 Mon Sep 17 00:00:00 2001 From: Grissiom Date: Tue, 14 Apr 2015 18:22:46 +0800 Subject: [PATCH 2/9] SConscript: fix the `--keep` parameter for Keil The old `--keep` parameter for Keil is wrong. RTFM of Keil and get it right. --- components/finsh/SConscript | 4 ++-- src/SConscript | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/finsh/SConscript b/components/finsh/SConscript index edb52eb357..8d6729e4a7 100644 --- a/components/finsh/SConscript +++ b/components/finsh/SConscript @@ -28,10 +28,10 @@ msh.c CPPPATH = [cwd] if rtconfig.CROSS_TOOL == 'keil': - LINKFLAGS = ' --keep __fsym_*' + LINKFLAGS = ' --keep *.o(FSymTab)' if not GetDepend('FINSH_USING_MSH_ONLY'): - LINKFLAGS = LINKFLAGS + ' --keep __vsym_* ' + LINKFLAGS = LINKFLAGS + ' --keep *.o(VSymTab) ' else: LINKFLAGS = '' diff --git a/src/SConscript b/src/SConscript index 6d59365195..0242d4634c 100644 --- a/src/SConscript +++ b/src/SConscript @@ -9,9 +9,9 @@ if rtconfig.CROSS_TOOL == 'keil': # add more link flags for module and components_init. LINKFLAGS = '' if GetDepend('RT_USING_MODULE'): - LINKFLAGS = ' --keep __rtmsym_* ' + LINKFLAGS = ' --keep *.o(RTMSymTab) ' if GetDepend('RT_USING_COMPONENTS_INIT'): - LINKFLAGS = ' --keep __rt_init* ' + LINKFLAGS = ' --keep *.o(.rti_fn.*) ' else: LINKFLAGS = '' From f435a214d4617a9acc98033c571c5dc14dcf6b97 Mon Sep 17 00:00:00 2001 From: Grissiom Date: Tue, 14 Apr 2015 18:34:09 +0800 Subject: [PATCH 3/9] SConscript: fix LINKFLAGS over-written Fix a regression on 62a0172d11e5592. --- src/SConscript | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SConscript b/src/SConscript index 0242d4634c..953ea5060d 100644 --- a/src/SConscript +++ b/src/SConscript @@ -9,9 +9,9 @@ if rtconfig.CROSS_TOOL == 'keil': # add more link flags for module and components_init. LINKFLAGS = '' if GetDepend('RT_USING_MODULE'): - LINKFLAGS = ' --keep *.o(RTMSymTab) ' + LINKFLAGS += ' --keep *.o(RTMSymTab) ' if GetDepend('RT_USING_COMPONENTS_INIT'): - LINKFLAGS = ' --keep *.o(.rti_fn.*) ' + LINKFLAGS += ' --keep *.o(.rti_fn.*) ' else: LINKFLAGS = '' From 6aa242645fc55cc776cfb1e87414e70037ecdd43 Mon Sep 17 00:00:00 2001 From: ardafu Date: Wed, 15 Apr 2015 16:08:43 +0800 Subject: [PATCH 4/9] 1. [bsp][sam9260] Fix the bug that auto reset after boot 20s. Disable watchdog in rt_lovel_level_init function. 2. [bsp][sam9260] Modify SCONS scripts to support IAR tool chain. 3. [bsp][sam9260] Move link strips in to folder link_scripts. 4. [libcpu][arm926] Add copy right to source file and format code. --- bsp/at91sam9260/applications/startup.c | 19 +- .../link_scripts/at91sam9260_ram.icf | 81 ++++++++ .../link_scripts/at91sam9260_ram.ld | 90 +++++++++ .../link_scripts/at91sam9260_ram.scat | 58 ++++++ bsp/at91sam9260/platform/rt_low_level_gcc.inc | 26 ++- bsp/at91sam9260/platform/rt_low_level_iar.inc | 26 ++- bsp/at91sam9260/platform/rt_low_level_init.c | 63 ++++-- .../platform/rt_low_level_keil.inc | 28 ++- bsp/at91sam9260/rtconfig.py | 101 +++++++--- libcpu/arm/arm926/context_iar.S | 3 +- libcpu/arm/arm926/cpuport.c | 71 +++---- libcpu/arm/arm926/mmu.c | 44 +++-- libcpu/arm/arm926/mmu.h | 42 ++-- libcpu/arm/arm926/stack.c | 51 +++-- libcpu/arm/arm926/start_gcc.S | 15 +- libcpu/arm/arm926/start_iar.S | 2 + libcpu/arm/arm926/start_rvds.S | 16 +- libcpu/arm/arm926/trap.c | 179 ++++++++++-------- 18 files changed, 662 insertions(+), 253 deletions(-) create mode 100644 bsp/at91sam9260/link_scripts/at91sam9260_ram.icf create mode 100644 bsp/at91sam9260/link_scripts/at91sam9260_ram.ld create mode 100644 bsp/at91sam9260/link_scripts/at91sam9260_ram.scat diff --git a/bsp/at91sam9260/applications/startup.c b/bsp/at91sam9260/applications/startup.c index 7221efbfd6..2f77f4ad68 100644 --- a/bsp/at91sam9260/applications/startup.c +++ b/bsp/at91sam9260/applications/startup.c @@ -47,13 +47,18 @@ extern void rt_application_init(void); /*@{*/ #if defined(__CC_ARM) - extern int Image$$ER_ZI$$ZI$$Limit; +extern int Image$$ER_ZI$$ZI$$Limit; +#define HEAP_START ((void*)&Image$$ER_ZI$$ZI$$Limit) #elif (defined (__GNUC__)) - extern unsigned char __bss_end__; +extern unsigned char __bss_end__; +#define HEAP_START ((void*)&__bss_end__) #elif (defined (__ICCARM__)) - #pragma section="HEAP" +#pragma section="HEAP" +#define HEAP_START (__section_begin("HEAP")) #endif +#define HEAP_END ((void*)0x24000000) + #ifdef RT_USING_FINSH extern void finsh_system_init(void); #endif @@ -90,13 +95,7 @@ void rtthread_startup(void) rt_system_timer_init(); /* initialize heap memory system */ -#ifdef __CC_ARM - rt_system_heap_init((void*)&Image$$ER_ZI$$ZI$$Limit, (void*)0x24000000); -#elif (defined (__GNUC__)) - rt_system_heap_init((void*)&__bss_end__, (void*)0x23f00000); -#elif (defined (__ICCARM__)) - rt_system_heap_init(__section_begin("HEAP"),(void*)0x23f00000); -#endif + rt_system_heap_init(HEAP_START, HEAP_END); #ifdef RT_USING_MODULE /* initialize module system*/ diff --git a/bsp/at91sam9260/link_scripts/at91sam9260_ram.icf b/bsp/at91sam9260/link_scripts/at91sam9260_ram.icf new file mode 100644 index 0000000000..e9659fb594 --- /dev/null +++ b/bsp/at91sam9260/link_scripts/at91sam9260_ram.icf @@ -0,0 +1,81 @@ +//***************************************************************************** +// +// blinky.icf - Linker configuration file for blinky. +// +// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.0.12573 of the DK-TM4C129X Firmware Package. +// +//***************************************************************************** + +// +// Define a memory region that covers the entire 4 GB addressible space of the +// processor. +// +define memory mem with size = 4G; + +// +// Define a region for the on-chip flash. +// +define region FLASH = mem:[from 0x20000000 to 0x207FFFFF]; + +// +// Define a region for the on-chip SRAM. +// +define region SRAM = mem:[from 0x20800000 to 0x23FFFFFF]; + +// +// Define a block for the heap. The size should be set to something other +// than zero if things in the C library that require the heap are used. +// +define block HEAP with alignment = 8, size = 0x02000000 { }; + +// +// Indicate that the read/write values should be initialized by copying from +// flash. +// +initialize by copy { readwrite }; + +// +// Indicate that the noinit values should be left alone. This includes the +// stack, which if initialized will destroy the return address from the +// initialization code, causing the processor to branch to zero and fault. +// +do not initialize { section .noinit }; + +// +// Place the interrupt vectors at the start of flash. +// +place at start of FLASH { readonly section .intvec }; + +// +// Place the remainder of the read-only items into flash. +// +place in FLASH { readonly }; + +// +// Place the RAM vector table at the start of SRAM. +// +place at start of SRAM { section VTABLE }; + +// +// Place all read/write items into SRAM. +// +place in SRAM { readwrite, block HEAP }; +keep { section FSymTab }; +keep { section VSymTab }; +keep { section .rti_fn* }; diff --git a/bsp/at91sam9260/link_scripts/at91sam9260_ram.ld b/bsp/at91sam9260/link_scripts/at91sam9260_ram.ld new file mode 100644 index 0000000000..258881b082 --- /dev/null +++ b/bsp/at91sam9260/link_scripts/at91sam9260_ram.ld @@ -0,0 +1,90 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(entry) +SECTIONS +{ + . = 0x20000000; + + . = ALIGN(4); + .text : + { + *(.init) + *(.text) + *(.gnu.linkonce.t*) + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + + /* section information for modules */ + . = ALIGN(4); + __rtmsymtab_start = .; + KEEP(*(RTMSymTab)) + __rtmsymtab_end = .; + } + + . = ALIGN(4); + .rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) *(.eh_frame) } + + . = ALIGN(4); + .ctors : + { + PROVIDE(__ctors_start__ = .); + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + PROVIDE(__ctors_end__ = .); + } + + .dtors : + { + PROVIDE(__dtors_start__ = .); + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + PROVIDE(__dtors_end__ = .); + } + + . = ALIGN(4); + .data : + { + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + } + + . = ALIGN(4); + .nobss : { *(.nobss) } + + . = ALIGN(4); + __bss_start__ = .; + .bss : { *(.bss)} + __bss_end__ = .; + + /* stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } + + _end = .; +} diff --git a/bsp/at91sam9260/link_scripts/at91sam9260_ram.scat b/bsp/at91sam9260/link_scripts/at91sam9260_ram.scat new file mode 100644 index 0000000000..3243902c9c --- /dev/null +++ b/bsp/at91sam9260/link_scripts/at91sam9260_ram.scat @@ -0,0 +1,58 @@ +; * ---------------------------------------------------------------------------- +; * ATMEL Microcontroller Software Support +; * ---------------------------------------------------------------------------- +; * Copyright (c) 2008, Atmel Corporation +; * +; * All rights reserved. +; * +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * +; * - Redistributions of source code must retain the above copyright notice, +; * this list of conditions and the disclaimer below. +; * +; * Atmel's name may not be used to endorse or promote products derived from +; * this software without specific prior written permission. +; * +; * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR +; * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +; * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE +; * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, +; * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +; * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +; * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +; * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +; * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +; * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; * ---------------------------------------------------------------------------- + +; *------------------------------------------------------------------------------ +; * Linker scatter for running in external SDRAM on the AT91SAM9260 +; *----------------------------------------------------------------------------*/ + +Load_region 0x20000000 0x00800000 +{ + + Fixed_region 0x20000000 + { + * (RESET +First) + .ANY (+RO +RW) + } + ER_ZI +0 + { + * (+ZI) + } ; Application ZI data (.bss) + + ;Relocate_region 0x200000 0x1000 + ;{ + ; *.o (VECTOR, +First) + ;} + + ARM_LIB_HEAP 0x21FFE000 EMPTY 0x1000 + { + } + + ARM_LIB_STACK 0x22000000 EMPTY -0x1000 + { + } +} diff --git a/bsp/at91sam9260/platform/rt_low_level_gcc.inc b/bsp/at91sam9260/platform/rt_low_level_gcc.inc index 35690892d1..c6edd3787c 100644 --- a/bsp/at91sam9260/platform/rt_low_level_gcc.inc +++ b/bsp/at91sam9260/platform/rt_low_level_gcc.inc @@ -1,4 +1,28 @@ -//;--------- Stack size of CPU modes ------------------------------------------- +/* + * File : rt_low_level_gcc.inc + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-04-14 ArdaFu first version + */ + +/*--------- Stack size of CPU modes ------------------------------------------*/ .equ UND_STK_SIZE, 2048 .equ SVC_STK_SIZE, 4096 .equ ABT_STK_SIZE, 2048 diff --git a/bsp/at91sam9260/platform/rt_low_level_iar.inc b/bsp/at91sam9260/platform/rt_low_level_iar.inc index 40427d2a06..3046253d07 100644 --- a/bsp/at91sam9260/platform/rt_low_level_iar.inc +++ b/bsp/at91sam9260/platform/rt_low_level_iar.inc @@ -1,4 +1,28 @@ -;--------- Stack size of CPU modes -------------------------------------------- +/* + * File : rt_low_level_iar.inc + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-04-14 ArdaFu first version + */ + +/*-------- Stack size of CPU modes -------------------------------------------*/ #define UND_STK_SIZE 512 #define SVC_STK_SIZE 4096 #define ABT_STK_SIZE 512 diff --git a/bsp/at91sam9260/platform/rt_low_level_init.c b/bsp/at91sam9260/platform/rt_low_level_init.c index 4e74e2ef47..b7bc8e0a1a 100644 --- a/bsp/at91sam9260/platform/rt_low_level_init.c +++ b/bsp/at91sam9260/platform/rt_low_level_init.c @@ -1,27 +1,64 @@ -#define write_reg(a,v) (*(volatile unsigned int *)(a) = (v)) +/* + * File : rt_low_level_init.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-04-14 ArdaFu first version + */ + +/* write register a=address, v=value */ +#define write_reg(a,v) (*(volatile unsigned int *)(a) = (v)) /* Processor Reset */ -#define AT91_RSTC_PROCRST (1 << 0) -#define AT91_RSTC_PERRST (1 << 2) -#define AT91_RSTC_KEY (0xa5 << 24) -#define AT91_MATRIX_BASE (0XFFFFEE00) +#define AT91_RSTC_PROCRST (1 << 0) +#define AT91_RSTC_PERRST (1 << 2) +#define AT91_RSTC_KEY (0xa5 << 24) +#define AT91_MATRIX_BASE (0XFFFFEE00) /* Master Remap Control Register */ -#define AT91_MATRIX_MRCR (AT91_MATRIX_BASE + 0x100) +#define AT91_MATRIX_MRCR (AT91_MATRIX_BASE + 0x100) /* Remap Command for AHB Master 0 (ARM926EJ-S InSTRuction Master) */ -#define AT91_MATRIX_RCB0 (1 << 0) +#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ -#define AT91_MATRIX_RCB1 (1 << 1) -#define AT91_AIC_BASE (0XFFFFF000) +#define AT91_MATRIX_RCB1 (1 << 1) + +#define AT91_AIC_BASE (0XFFFFF000) /* Interrupt DisaBLe Command Register */ -#define AT91_AIC_IDCR (0x124) +#define AT91_AIC_IDCR (AT91_AIC_BASE + 0x124) /* Interrupt Clear Command Register */ -#define AT91_AIC_ICCR (0x128) +#define AT91_AIC_ICCR (AT91_AIC_BASE + 0x128) + +#define AT91_WDT_BASE (0XFFFFFD40) +#define AT91_WDT_CR (AT91_WDT_BASE + 0x00) +#define AT91_WDT_CR_KEY (0xA5000000) +#define AT91_WDT_CR_WDRSTT (0x00000001) +#define AT91_WDT_MR (AT91_WDT_BASE + 0x04) +#define AT91_WDT_MR_WDDIS (0x00008000) void rt_low_level_init(void) { // Mask all IRQs by clearing all bits in the INTMRS - write_reg(AT91_AIC_BASE + AT91_AIC_IDCR, 0xFFFFFFFF); - write_reg(AT91_AIC_BASE + AT91_AIC_ICCR, 0xFFFFFFFF); + write_reg(AT91_AIC_IDCR, 0xFFFFFFFF); + write_reg(AT91_AIC_ICCR, 0xFFFFFFFF); // Remap internal ram to 0x00000000 Address write_reg(AT91_MATRIX_MRCR, AT91_MATRIX_RCB0 | AT91_MATRIX_RCB1); + // Disable the watchdog + write_reg(AT91_WDT_CR, AT91_WDT_CR_KEY|AT91_WDT_CR_WDRSTT); + write_reg(AT91_WDT_MR, AT91_WDT_MR_WDDIS); + } diff --git a/bsp/at91sam9260/platform/rt_low_level_keil.inc b/bsp/at91sam9260/platform/rt_low_level_keil.inc index 452fb39c03..c3cde15ded 100644 --- a/bsp/at91sam9260/platform/rt_low_level_keil.inc +++ b/bsp/at91sam9260/platform/rt_low_level_keil.inc @@ -1,8 +1,32 @@ -;--------- Stack size of CPU modes -------------------------------------------- +;/* +; * File : rt_low_level_keil.inc +; * This file is part of RT-Thread RTOS +; * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team +; * +; * This program is free software; you can redistribute it and/or modify +; * it under the terms of the GNU General Public License as published by +; * the Free Software Foundation; either version 2 of the License, or +; * (at your option) any later version. +; * +; * This program is distributed in the hope that it will be useful, +; * but WITHOUT ANY WARRANTY; without even the implied warranty of +; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; * GNU General Public License for more details. +; * +; * You should have received a copy of the GNU General Public License along +; * with this program; if not, write to the Free Software Foundation, Inc., +; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +; * +; * Change Logs: +; * Date Author Notes +; * 2015-04-14 ArdaFu first version +; */ + +;/*-------- Stack size of CPU modes ------------------------------------------*/ UND_STK_SIZE EQU 512 SVC_STK_SIZE EQU 4096 ABT_STK_SIZE EQU 512 IRQ_STK_SIZE EQU 1024 FIQ_STK_SIZE EQU 1024 SYS_STK_SIZE EQU 512 - END \ No newline at end of file + END diff --git a/bsp/at91sam9260/rtconfig.py b/bsp/at91sam9260/rtconfig.py index c75d864741..f7fff9fd3e 100755 --- a/bsp/at91sam9260/rtconfig.py +++ b/bsp/at91sam9260/rtconfig.py @@ -1,27 +1,23 @@ import os - -# toolchains options ARCH = 'arm' CPU = 'arm926' -TextBase = '0x20000000' - -CROSS_TOOL = 'gcc' +# toolchains options +CROSS_TOOL = 'iar' +#------- toolchains path ------------------------------------------------------- if os.getenv('RTT_CC'): CROSS_TOOL = os.getenv('RTT_CC') if CROSS_TOOL == 'gcc': PLATFORM = 'gcc' - #EXEC_PATH = 'D:/ArdaArmTools/Sourcery_Lite/bin' - EXEC_PATH = 'D:/ArdaArmTools/GNUARM_4.9_2015q1/bin' + #EXEC_PATH = 'D:/ArdaArmTools/Sourcery_Lite' + EXEC_PATH = 'D:/ArdaArmTools/GNUARM_4.9_2015q1' elif CROSS_TOOL == 'keil': PLATFORM = 'armcc' EXEC_PATH = 'C:/Keil_v5' elif CROSS_TOOL == 'iar': - print '================ERROR============================' - print 'Not support yet!' - print '=================================================' - exit(0) + PLATFORM = 'iar' + IAR_PATH = 'C:/Program Files (x86)/IAR Systems/Embedded Workbench 7.0' if os.getenv('RTT_EXEC_PATH'): EXEC_PATH = os.getenv('RTT_EXEC_PATH') @@ -29,6 +25,12 @@ if os.getenv('RTT_EXEC_PATH'): #BUILD = 'debug' BUILD = 'release' +CORE = 'arm926ej-s' +MAP_FILE = 'rtthread_at91sam9260.map' +LINK_FILE = 'link_scripts/at91sam9260_ram' +TARGET_NAME = 'rtthread.bin' + +#------- GCC settings ---------------------------------------------------------- if PLATFORM == 'gcc': # toolchains PREFIX = 'arm-none-eabi-' @@ -41,11 +43,15 @@ if PLATFORM == 'gcc': SIZE = PREFIX + 'size' OBJDUMP = PREFIX + 'objdump' OBJCPY = PREFIX + 'objcopy' + EXEC_PATH += '/bin/' DEVICE = ' -mcpu=arm926ej-s' CFLAGS = DEVICE - AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + ' -Iplatform'+' -DTEXT_BASE=' + TextBase - LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread_at91sam9260.map,-cref,-u,_start -T at91sam9260_ram.ld' + ' -Ttext ' + TextBase + AFLAGS = '-c'+ DEVICE + ' -x assembler-with-cpp' + AFLAGS += ' -Iplatform' + LFLAGS = DEVICE + LFLAGS += ' -Wl,--gc-sections,-cref,-Map=' + MAP_FILE + LFLAGS += ' -T ' + LINK_FILE + '.ld' CPATH = '' LPATH = '' @@ -56,8 +62,9 @@ if PLATFORM == 'gcc': else: CFLAGS += ' -O2' - POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' - + POST_ACTION = OBJCPY + ' -O binary $TARGET ' + TARGET_NAME + '\n' + POST_ACTION += SIZE + ' $TARGET\n' +#------- Keil settings --------------------------------------------------------- elif PLATFORM == 'armcc': # toolchains CC = 'armcc' @@ -65,16 +72,15 @@ elif PLATFORM == 'armcc': AR = 'armar' LINK = 'armlink' TARGET_EXT = 'axf' + EXEC_PATH += '/arm/armcc/bin/' - DEVICE = ' --cpu=ARM926EJ-S' + DEVICE = ' --cpu=' + CORE CFLAGS = DEVICE + ' --apcs=interwork --diag_suppress=870' AFLAGS = DEVICE + ' -Iplatform' - LFLAGS = DEVICE + ' --strict --info sizes --info totals --info unused --info veneers --list rtthread-at91sam9260.map --ro-base 0x20000000 --entry Entry_Point --first Entry_Point' - - CFLAGS += ' -I"' + EXEC_PATH + '/ARM/RV31/INC"' - LFLAGS += ' --libpath "' + EXEC_PATH + '/ARM/RV31/LIB"' - - EXEC_PATH += '/arm/bin40/' + LFLAGS = DEVICE + ' --strict' + LFLAGS += ' --info sizes --info totals --info unused --info veneers' + LFLAGS += ' --list ' + MAP_FILE + LFLAGS += ' --scatter ' + LINK_FILE + '.scat' if BUILD == 'debug': CFLAGS += ' -g -O0' @@ -82,4 +88,53 @@ elif PLATFORM == 'armcc': else: CFLAGS += ' -O2' - POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' + POST_ACTION = 'fromelf --bin $TARGET --output ' + TARGET_NAME + ' \n' + POST_ACTION += 'fromelf -z $TARGET\n' +#------- IAR settings ---------------------------------------------------------- +elif PLATFORM == 'iar': + # toolchains + CC = 'iccarm' + AS = 'iasmarm' + AR = 'iarchive' + LINK = 'ilinkarm' + TARGET_EXT = 'out' + + DEVICE = CORE + + CFLAGS = '--cpu=' + DEVICE + CFLAGS += ' --diag_suppress Pa050' + CFLAGS += ' --no_cse' + CFLAGS += ' --no_unroll' + CFLAGS += ' --no_inline' + CFLAGS += ' --no_code_motion' + CFLAGS += ' --no_tbaa' + CFLAGS += ' --no_clustering' + CFLAGS += ' --no_scheduling' + + CFLAGS += ' --endian=little' + CFLAGS += ' -e' + CFLAGS += ' --fpu=none' + CFLAGS += ' --dlib_config "' + IAR_PATH + '/arm/INC/c/DLib_Config_Normal.h"' + CFLAGS += ' --silent' + + AFLAGS = '--cpu '+ DEVICE + AFLAGS += ' -s+' + AFLAGS += ' -w+' + AFLAGS += ' -r' + AFLAGS += ' --fpu none' + AFLAGS += ' -S' + AFLAGS += ' -Iplatform' + + if BUILD == 'debug': + CFLAGS += ' --debug' + CFLAGS += ' -On' + else: + CFLAGS += ' -Oh' + + LFLAGS = '--config ' + LINK_FILE +'.icf' + LFLAGS += ' --entry __iar_program_start' + LFLAGS += ' --map ' + MAP_FILE + LFLAGS += ' --silent' + + EXEC_PATH = IAR_PATH + '/arm/bin/' + POST_ACTION = 'ielftool --silent --bin $TARGET ' + TARGET_NAME diff --git a/libcpu/arm/arm926/context_iar.S b/libcpu/arm/arm926/context_iar.S index 678c7bacff..9727dbd96d 100644 --- a/libcpu/arm/arm926/context_iar.S +++ b/libcpu/arm/arm926/context_iar.S @@ -19,7 +19,8 @@ ; * ; * Change Logs: ; * Date Author Notes -; * 2011-08-14 weety copy from mini2440 +; * 2011-08-14 weety copy from mini2440 +; * 2015-04-15 ArdaFu convert from context_gcc.s ; */ #define NOINT 0xc0 diff --git a/libcpu/arm/arm926/cpuport.c b/libcpu/arm/arm926/cpuport.c index fd707384f6..8d5c21660c 100644 --- a/libcpu/arm/arm926/cpuport.c +++ b/libcpu/arm/arm926/cpuport.c @@ -20,6 +20,7 @@ * Change Logs: * Date Author Notes * 2011-01-13 weety modified from mini2440 + * 2015-04-15 ArdaFu Add code for IAR */ #include @@ -42,24 +43,24 @@ rt_inline rt_uint32_t cp15_rd(void) rt_inline void cache_enable(rt_uint32_t bit) { - __asm__ __volatile__( \ - "mrc p15,0,r0,c1,c0,0\n\t" \ - "orr r0,r0,%0\n\t" \ - "mcr p15,0,r0,c1,c0,0" \ - : \ - :"r" (bit) \ - :"memory"); + __asm__ __volatile__(\ + "mrc p15,0,r0,c1,c0,0\n\t" \ + "orr r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + :"r" (bit) \ + :"memory"); } rt_inline void cache_disable(rt_uint32_t bit) { - __asm__ __volatile__( \ - "mrc p15,0,r0,c1,c0,0\n\t" \ - "bic r0,r0,%0\n\t" \ - "mcr p15,0,r0,c1,c0,0" \ - : \ - :"r" (bit) \ - :"memory"); + __asm__ __volatile__(\ + "mrc p15,0,r0,c1,c0,0\n\t" \ + "bic r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + :"r" (bit) \ + :"memory"); } #endif @@ -112,24 +113,24 @@ rt_inline rt_uint32_t cp15_rd(void) rt_inline void cache_enable(rt_uint32_t bit) { - asm volatile( \ - "mrc p15,0,r0,c1,c0,0\n\t" \ - "orr r0,r0,%0\n\t" \ - "mcr p15,0,r0,c1,c0,0" \ - : \ - :"r" (bit) \ - :"memory"); + asm volatile(\ + "mrc p15,0,r0,c1,c0,0\n\t" \ + "orr r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + :"r" (bit) \ + :"memory"); } rt_inline void cache_disable(rt_uint32_t bit) { - asm volatile( \ - "mrc p15,0,r0,c1,c0,0\n\t" \ - "bic r0,r0,%0\n\t" \ - "mcr p15,0,r0,c1,c0,0" \ - : \ - :"r" (bit) \ - :"memory"); + asm volatile(\ + "mrc p15,0,r0,c1,c0,0\n\t" \ + "bic r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + :"r" (bit) \ + :"memory"); } #endif @@ -193,7 +194,7 @@ rt_base_t rt_hw_cpu_dcache_status() */ void rt_hw_cpu_reset() { - + rt_kprintf("Restarting system...\n"); machine_reset(); @@ -221,13 +222,13 @@ void rt_hw_cpu_shutdown() #ifdef RT_USING_CPU_FFS /** - * This function finds the first bit set (beginning with the least significant bit) + * 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 + * 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 + * + * @return return the index of the first bit set. If value is 0, then this function * shall return 0. */ #if defined(__CC_ARM) @@ -237,7 +238,7 @@ int __rt_ffs(int value) if (value == 0) return value; - + __asm { rsb x, value, #0 @@ -248,7 +249,7 @@ int __rt_ffs(int value) return x; } -#elif defined(__IAR_SYSTEMS_ICC__) +#elif defined(__ICCARM__) int __rt_ffs(int value) { if (value == 0) diff --git a/libcpu/arm/arm926/mmu.c b/libcpu/arm/arm926/mmu.c index fa074e895f..b0b1d428bd 100644 --- a/libcpu/arm/arm926/mmu.c +++ b/libcpu/arm/arm926/mmu.c @@ -19,6 +19,7 @@ * * Change Logs: * Date Author Notes + * 2015-04-15 ArdaFu Add code for IAR */ #include "mmu.h" @@ -28,11 +29,11 @@ void mmu_setttbase(rt_uint32_t i) { register rt_uint32_t value; - /* Invalidates all TLBs.Domain access is selected as - * client by configuring domain access register, - * in that case access controlled by permission value - * set by page table entry - */ + /* Invalidates all TLBs.Domain access is selected as + * client by configuring domain access register, + * in that case access controlled by permission value + * set by page table entry + */ value = 0; __asm { @@ -247,11 +248,11 @@ void mmu_setttbase(register rt_uint32_t i) { register rt_uint32_t value; - /* Invalidates all TLBs.Domain access is selected as - * client by configuring domain access register, - * in that case access controlled by permission value - * set by page table entry - */ + /* Invalidates all TLBs.Domain access is selected as + * client by configuring domain access register, + * in that case access controlled by permission value + * set by page table entry + */ value = 0; asm ("mcr p15, 0, %0, c8, c7, 0"::"r"(value)); @@ -433,11 +434,11 @@ void mmu_setttbase(register rt_uint32_t i) { register rt_uint32_t value; - /* Invalidates all TLBs.Domain access is selected as - * client by configuring domain access register, - * in that case access controlled by permission value - * set by page table entry - */ + /* Invalidates all TLBs.Domain access is selected as + * client by configuring domain access register, + * in that case access controlled by permission value + * set by page table entry + */ value = 0; asm ("mcr p15, 0, %0, c8, c7, 0"::"r"(value)); @@ -621,16 +622,18 @@ void mmu_invalidate_dcache_all() #pragma data_alignment=(16*1024) static volatile unsigned int _page_table[4*1024];; #else -static volatile unsigned int _page_table[4*1024] __attribute__((aligned(16*1024))); +static volatile unsigned int _page_table[4*1024] \ +__attribute__((aligned(16*1024))); #endif -void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd, rt_uint32_t paddrStart, rt_uint32_t attr) +void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd, + rt_uint32_t paddrStart, rt_uint32_t attr) { volatile rt_uint32_t *pTT; volatile int nSec; int i = 0; pTT=(rt_uint32_t *)_page_table+(vaddrStart>>20); nSec=(vaddrEnd>>20)-(vaddrStart>>20); - for(i=0;i<=nSec;i++) + for(i=0; i<=nSec; i++) { *pTT = attr |(((paddrStart>>20)+i)<<20); pTT++; @@ -648,8 +651,8 @@ void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size) /* set page table */ for (; size > 0; size--) { - mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end, - mdesc->paddr_start, mdesc->attr); + mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end, + mdesc->paddr_start, mdesc->attr); mdesc++; } @@ -668,4 +671,3 @@ void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size) mmu_invalidate_icache(); mmu_invalidate_dcache_all(); } - diff --git a/libcpu/arm/arm926/mmu.h b/libcpu/arm/arm926/mmu.h index adbfe95934..34fc8f0824 100644 --- a/libcpu/arm/arm926/mmu.h +++ b/libcpu/arm/arm926/mmu.h @@ -26,31 +26,32 @@ #include -#define CACHE_LINE_SIZE 32 +#define CACHE_LINE_SIZE 32 -#define DESC_SEC (0x2|(1<<4)) -#define CB (3<<2) //cache_on, write_back -#define CNB (2<<2) //cache_on, write_through -#define NCB (1<<2) //cache_off,WR_BUF on -#define NCNB (0<<2) //cache_off,WR_BUF off -#define AP_RW (3<<10) //supervisor=RW, user=RW -#define AP_RO (2<<10) //supervisor=RW, user=RO +#define DESC_SEC (0x2|(1<<4)) +#define CB (3<<2) //cache_on, write_back +#define CNB (2<<2) //cache_on, write_through +#define NCB (1<<2) //cache_off,WR_BUF on +#define NCNB (0<<2) //cache_off,WR_BUF off +#define AP_RW (3<<10) //supervisor=RW, user=RW +#define AP_RO (2<<10) //supervisor=RW, user=RO -#define DOMAIN_FAULT (0x0) -#define DOMAIN_CHK (0x1) -#define DOMAIN_NOTCHK (0x3) -#define DOMAIN0 (0x0<<5) -#define DOMAIN1 (0x1<<5) +#define DOMAIN_FAULT (0x0) +#define DOMAIN_CHK (0x1) +#define DOMAIN_NOTCHK (0x3) +#define DOMAIN0 (0x0<<5) +#define DOMAIN1 (0x1<<5) -#define DOMAIN0_ATTR (DOMAIN_CHK<<0) -#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) +#define DOMAIN0_ATTR (DOMAIN_CHK<<0) +#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) -#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) /* Read/Write, cache, write back */ -#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) /* Read/Write, cache, write through */ -#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */ -#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */ +#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) /* Read/Write, cache, write back */ +#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) /* Read/Write, cache, write through */ +#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */ +#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */ -struct mem_desc { +struct mem_desc +{ rt_uint32_t vaddr_start; rt_uint32_t vaddr_end; rt_uint32_t paddr_start; @@ -60,4 +61,3 @@ struct mem_desc { void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size); #endif - diff --git a/libcpu/arm/arm926/stack.c b/libcpu/arm/arm926/stack.c index b9bb3c8508..ba3a11d208 100644 --- a/libcpu/arm/arm926/stack.c +++ b/libcpu/arm/arm926/stack.c @@ -27,49 +27,48 @@ /* CPU Mode */ /*****************************/ #define USERMODE 0x10 -#define FIQMODE 0x11 -#define IRQMODE 0x12 -#define SVCMODE 0x13 -#define ABORTMODE 0x17 -#define UNDEFMODE 0x1b +#define FIQMODE 0x11 +#define IRQMODE 0x12 +#define SVCMODE 0x13 +#define ABORTMODE 0x17 +#define UNDEFMODE 0x1b #define MODEMASK 0x1f -#define NOINT 0xc0 +#define NOINT 0xc0 /** * This function will initialize thread stack * * @param tentry the entry of thread - * @param parameter the parameter of entry + * @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_uint8_t *stack_addr, void *texit) { rt_uint32_t *stk; stk = (rt_uint32_t*)stack_addr; - *(stk) = (rt_uint32_t)tentry; /* entry point */ - *(--stk) = (rt_uint32_t)texit; /* lr */ - *(--stk) = 0; /* r12 */ - *(--stk) = 0; /* r11 */ - *(--stk) = 0; /* r10 */ - *(--stk) = 0; /* r9 */ - *(--stk) = 0; /* r8 */ - *(--stk) = 0; /* r7 */ - *(--stk) = 0; /* r6 */ - *(--stk) = 0; /* r5 */ - *(--stk) = 0; /* r4 */ - *(--stk) = 0; /* r3 */ - *(--stk) = 0; /* r2 */ - *(--stk) = 0; /* r1 */ - *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ - *(--stk) = SVCMODE; /* cpsr */ - *(--stk) = SVCMODE; /* spsr */ + *(stk) = (rt_uint32_t)tentry; /* entry point */ + *(--stk) = (rt_uint32_t)texit; /* lr */ + *(--stk) = 0; /* r12 */ + *(--stk) = 0; /* r11 */ + *(--stk) = 0; /* r10 */ + *(--stk) = 0; /* r9 */ + *(--stk) = 0; /* r8 */ + *(--stk) = 0; /* r7 */ + *(--stk) = 0; /* r6 */ + *(--stk) = 0; /* r5 */ + *(--stk) = 0; /* r4 */ + *(--stk) = 0; /* r3 */ + *(--stk) = 0; /* r2 */ + *(--stk) = 0; /* r1 */ + *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ + *(--stk) = SVCMODE; /* cpsr */ + *(--stk) = SVCMODE; /* spsr */ /* return task's current stack address */ return (rt_uint8_t *)stk; } - diff --git a/libcpu/arm/arm926/start_gcc.S b/libcpu/arm/arm926/start_gcc.S index b6377ed676..ee26f96fc6 100644 --- a/libcpu/arm/arm926/start_gcc.S +++ b/libcpu/arm/arm926/start_gcc.S @@ -1,7 +1,7 @@ /* - * File : start.S + * File : start_gcc.S * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Development Team + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,8 +20,9 @@ * Change Logs: * Date Author Notes * 2011-01-13 weety first version + * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP */ -#define CONFIG_STACKSIZE 512 + #define S_FRAME_SIZE (18*4) //72 @#define S_SPSR (17*4) //SPSR @@ -55,7 +56,7 @@ .include "rt_low_level_gcc.inc" -@; stack table----------------------------------------------------------------- +@;----------------------- Stack and Heap Definitions --------------------------- .section .nobss, "w" .space UND_STK_SIZE @@ -88,8 +89,7 @@ FIQ_STACK_START: SYS_STACK_START: -@; Jump vector table----------------------------------------------------------- - +@;--------------Jump vector table----------------------------------------------- .section .init, "ax" .arm @@ -179,7 +179,6 @@ Setup_Stack: MSR CPSR_cxsf, R1 @; SVC mode LDR SP, =SVC_STACK_START - @; clear .bss MOV R0, #0 @; get a zero LDR R1, =__bss_start__ @; bss start @@ -203,8 +202,8 @@ ctor_loop: BX R2 LDMFD SP!, {R0-R1} B ctor_loop - ctor_end: + @; Enter the C code LDR R0, =main BLX R0 diff --git a/libcpu/arm/arm926/start_iar.S b/libcpu/arm/arm926/start_iar.S index 1f516462b2..db3a253414 100644 --- a/libcpu/arm/arm926/start_iar.S +++ b/libcpu/arm/arm926/start_iar.S @@ -20,6 +20,7 @@ ; * Change Logs: ; * Date Author Notes ; * 2011-01-13 weety first version +; * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP ; */ #define S_FRAME_SIZE (18*4) ;72 @@ -55,6 +56,7 @@ #include "rt_low_level_iar.inc" +;----------------------- Stack and Heap Definitions ---------------------------- MODULE ?cstartup SECTION .noinit:DATA:NOROOT(3) DATA diff --git a/libcpu/arm/arm926/start_rvds.S b/libcpu/arm/arm926/start_rvds.S index 42144334bd..00e0c6136a 100644 --- a/libcpu/arm/arm926/start_rvds.S +++ b/libcpu/arm/arm926/start_rvds.S @@ -20,11 +20,9 @@ ; * Change Logs: ; * Date Author Notes ; * 2011-08-14 weety first version +; * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP ; */ - -; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs - S_FRAME_SIZE EQU (18*4) ;72 ;S_SPSR EQU (17*4) ;SPSR ;S_CPSR EQU (16*4) ;CPSR @@ -58,11 +56,9 @@ MODEMASK EQU 0X1F NOINT EQU 0xC0 -;----------------------- Stack and Heap Definitions ---------------------------- - AREA STACK, NOINIT, READWRITE, ALIGN=3 GET rt_low_level_keil.inc - -;-------------- stack area ----------------------------------------------------- + +;----------------------- Stack and Heap Definitions ---------------------------- AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem @@ -103,11 +99,7 @@ Heap_Mem SPACE Heap_Size __heap_limit -;----------------------- CODE -------------------------------------------------- PRESERVE8 -; Area Definition and Entry Point -; Startup Code must be linked first at Address at which it expects to run. - ;--------------Jump vector table------------------------------------------------ EXPORT Entry_Point AREA RESET, CODE, READONLY @@ -331,7 +323,7 @@ rt_hw_context_switch_interrupt_do PROC __user_initial_stackheap LDR R0, = Heap_Mem LDR R1, = (Stack_Mem + SYS_STK_SIZE) - LDR R2, = (Heap_Mem + Heap_Size) + LDR R2, = (Heap_Mem + Heap_Size) LDR R3, = Stack_Mem BX LR ENDIF diff --git a/libcpu/arm/arm926/trap.c b/libcpu/arm/arm926/trap.c index f44c76064e..77816a2aa6 100644 --- a/libcpu/arm/arm926/trap.c +++ b/libcpu/arm/arm926/trap.c @@ -1,7 +1,7 @@ /* * File : trap.c * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Development Team + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,17 +20,13 @@ * Change Logs: * Date Author Notes * 2011-01-13 weety modified from mini2440 + * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP */ #include #include - #include -/** - * @addtogroup AT91SAM926X - */ -/*@{*/ extern struct rt_thread *rt_current_thread; #ifdef RT_USING_FINSH @@ -39,24 +35,24 @@ extern long list_thread(void); struct rt_hw_register { - rt_uint32_t r0; - rt_uint32_t r1; - rt_uint32_t r2; - rt_uint32_t r3; - rt_uint32_t r4; - rt_uint32_t r5; - rt_uint32_t r6; - rt_uint32_t r7; - rt_uint32_t r8; - rt_uint32_t r9; - rt_uint32_t r10; - rt_uint32_t fp; - rt_uint32_t ip; - rt_uint32_t sp; - rt_uint32_t lr; - rt_uint32_t pc; - rt_uint32_t cpsr; - rt_uint32_t ORIG_r0; + rt_uint32_t r0; + rt_uint32_t r1; + rt_uint32_t r2; + rt_uint32_t r3; + rt_uint32_t r4; + rt_uint32_t r5; + rt_uint32_t r6; + rt_uint32_t r7; + rt_uint32_t r8; + rt_uint32_t r9; + rt_uint32_t r10; + rt_uint32_t fp; + rt_uint32_t ip; + rt_uint32_t sp; + rt_uint32_t lr; + rt_uint32_t pc; + rt_uint32_t cpsr; + rt_uint32_t ORIG_r0; }; /** @@ -67,13 +63,18 @@ struct rt_hw_register void rt_hw_show_register (struct rt_hw_register *regs) { - rt_kprintf("Execption:\n"); - rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3); - rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7); - rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10); - rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip); - rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc); - rt_kprintf("cpsr:0x%08x\n", regs->cpsr); + rt_kprintf("Execption:\n"); + rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", + regs->r0, regs->r1, regs->r2, regs->r3); + rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", + regs->r4, regs->r5, regs->r6, regs->r7); + rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", + regs->r8, regs->r9, regs->r10); + rt_kprintf("fp :0x%08x ip :0x%08x\n", + regs->fp, regs->ip); + rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", + regs->sp, regs->lr, regs->pc); + rt_kprintf("cpsr:0x%08x\n", regs->cpsr); } /** @@ -86,15 +87,15 @@ void rt_hw_show_register (struct rt_hw_register *regs) */ void rt_hw_trap_udef(struct rt_hw_register *regs) { - rt_hw_show_register(regs); + rt_hw_show_register(regs); - rt_kprintf("undefined instruction\n"); - rt_kprintf("thread - %s stack:\n", rt_current_thread->name); + rt_kprintf("undefined instruction\n"); + rt_kprintf("thread - %s stack:\n", rt_current_thread->name); #ifdef RT_USING_FINSH - list_thread(); + list_thread(); #endif - rt_hw_cpu_shutdown(); + rt_hw_cpu_shutdown(); } /** @@ -108,10 +109,10 @@ void rt_hw_trap_udef(struct rt_hw_register *regs) */ void rt_hw_trap_swi(struct rt_hw_register *regs) { - rt_hw_show_register(regs); + rt_hw_show_register(regs); - rt_kprintf("software interrupt\n"); - rt_hw_cpu_shutdown(); + rt_kprintf("software interrupt\n"); + rt_hw_cpu_shutdown(); } /** @@ -124,15 +125,15 @@ void rt_hw_trap_swi(struct rt_hw_register *regs) */ void rt_hw_trap_pabt(struct rt_hw_register *regs) { - rt_hw_show_register(regs); + rt_hw_show_register(regs); - rt_kprintf("prefetch abort\n"); - rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name); + rt_kprintf("prefetch abort\n"); + rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name); #ifdef RT_USING_FINSH - list_thread(); + list_thread(); #endif - rt_hw_cpu_shutdown(); + rt_hw_cpu_shutdown(); } /** @@ -145,15 +146,15 @@ void rt_hw_trap_pabt(struct rt_hw_register *regs) */ void rt_hw_trap_dabt(struct rt_hw_register *regs) { - rt_hw_show_register(regs); + rt_hw_show_register(regs); - rt_kprintf("data abort\n"); - rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name); + rt_kprintf("data abort\n"); + rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name); #ifdef RT_USING_FINSH - list_thread(); + list_thread(); #endif - rt_hw_cpu_shutdown(); + rt_hw_cpu_shutdown(); } /** @@ -165,45 +166,65 @@ void rt_hw_trap_dabt(struct rt_hw_register *regs) */ void rt_hw_trap_resv(struct rt_hw_register *regs) { - rt_kprintf("not used\n"); - rt_hw_show_register(regs); - rt_hw_cpu_shutdown(); + rt_kprintf("not used\n"); + rt_hw_show_register(regs); + rt_hw_cpu_shutdown(); } -extern struct rt_irq_desc irq_desc[]; -rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq, rt_uint32_t* id); -extern void rt_hw_interrupt_ack(rt_uint32_t fiq_irq); + void rt_hw_trap_irq() { - rt_isr_handler_t isr_func; - rt_uint32_t irqstat, irq; - void *param; - //rt_kprintf("irq interrupt request\n"); - /* get irq number */ - irqstat = rt_hw_interrupt_get_active(INT_IRQ, &irq); - if (irqstat == 0) - { - rt_kprintf("No interrupt occur\n"); - rt_hw_interrupt_ack(INT_IRQ); - return; - } - - /* get interrupt service routine */ - isr_func = irq_desc[irq].handler; - param = irq_desc[irq].param; + rt_isr_handler_t isr_func; + rt_uint32_t irqstat; + rt_uint32_t irq; + void *param; + extern struct rt_irq_desc irq_desc[]; - /* turn to interrupt service routine */ - isr_func(irq, param); - // EIOCR must be write any value after interrupt, - // or else can't response next interrupt - rt_hw_interrupt_ack(INT_IRQ); + /* get irq number */ + irqstat = rt_hw_interrupt_get_active(INT_IRQ, &irq); + if (irqstat == 0) + { + rt_kprintf("No interrupt occur\n"); + rt_hw_interrupt_ack(INT_IRQ); + return; + } + + /* get interrupt service routine */ + isr_func = irq_desc[irq].handler; + param = irq_desc[irq].param; + + /* turn to interrupt service routine */ + isr_func(irq, param); + + rt_hw_interrupt_ack(INT_IRQ); irq_desc[irq].counter ++; } void rt_hw_trap_fiq() { - rt_kprintf("fast interrupt request\n"); -} + rt_isr_handler_t isr_func; + rt_uint32_t irqstat; + rt_uint32_t irq; + void *param; + extern struct rt_irq_desc irq_desc[]; -/*@}*/ + /* get irq number */ + irqstat = rt_hw_interrupt_get_active(INT_FIQ, &irq); + if (irqstat == 0) + { + rt_kprintf("No interrupt occur\n"); + rt_hw_interrupt_ack(INT_FIQ); + return; + } + + /* get interrupt service routine */ + isr_func = irq_desc[irq].handler; + param = irq_desc[irq].param; + + /* turn to interrupt service routine */ + isr_func(irq, param); + + rt_hw_interrupt_ack(INT_FIQ); + irq_desc[irq].counter ++; +} From a478e0b41a3f8eb6dd550fd2bc9eef68b6d47253 Mon Sep 17 00:00:00 2001 From: ardafu Date: Wed, 15 Apr 2015 17:21:41 +0800 Subject: [PATCH 5/9] 1. [bsp][sam9260] Switch to use Sourcery Lite GCC tool chain. --- bsp/at91sam9260/rtconfig.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bsp/at91sam9260/rtconfig.py b/bsp/at91sam9260/rtconfig.py index f7fff9fd3e..a9d440b337 100755 --- a/bsp/at91sam9260/rtconfig.py +++ b/bsp/at91sam9260/rtconfig.py @@ -2,7 +2,7 @@ import os ARCH = 'arm' CPU = 'arm926' # toolchains options -CROSS_TOOL = 'iar' +CROSS_TOOL = 'gcc' #------- toolchains path ------------------------------------------------------- if os.getenv('RTT_CC'): @@ -10,8 +10,8 @@ if os.getenv('RTT_CC'): if CROSS_TOOL == 'gcc': PLATFORM = 'gcc' - #EXEC_PATH = 'D:/ArdaArmTools/Sourcery_Lite' - EXEC_PATH = 'D:/ArdaArmTools/GNUARM_4.9_2015q1' + EXEC_PATH = 'D:/ArdaArmTools/Sourcery_Lite' + #EXEC_PATH = 'D:/ArdaArmTools/GNUARM_4.9_2015q1' elif CROSS_TOOL == 'keil': PLATFORM = 'armcc' EXEC_PATH = 'C:/Keil_v5' From cf3d639fcb80d61e098b20ae3f24c9783a096217 Mon Sep 17 00:00:00 2001 From: ardafu Date: Thu, 16 Apr 2015 10:35:12 +0800 Subject: [PATCH 6/9] [libcpu][arm926] Define vector table start at BSP/{board}/platform/ assemble INC files. --- bsp/at91sam9260/platform/rt_low_level_gcc.inc | 2 ++ bsp/at91sam9260/platform/rt_low_level_iar.inc | 2 ++ bsp/at91sam9260/platform/rt_low_level_keil.inc | 2 ++ libcpu/arm/arm926/start_gcc.S | 2 +- libcpu/arm/arm926/start_iar.S | 2 +- libcpu/arm/arm926/start_rvds.S | 2 +- 6 files changed, 9 insertions(+), 3 deletions(-) diff --git a/bsp/at91sam9260/platform/rt_low_level_gcc.inc b/bsp/at91sam9260/platform/rt_low_level_gcc.inc index c6edd3787c..f9825f5b53 100644 --- a/bsp/at91sam9260/platform/rt_low_level_gcc.inc +++ b/bsp/at91sam9260/platform/rt_low_level_gcc.inc @@ -29,3 +29,5 @@ .equ IRQ_STK_SIZE, 4096 .equ FIQ_STK_SIZE, 4096 .equ SYS_STK_SIZE, 2048 +/* vector table start should be 0x00000000 or 0xFFFF0000 */ +.equ VECTOR_TABLE_START, 0x00000000 diff --git a/bsp/at91sam9260/platform/rt_low_level_iar.inc b/bsp/at91sam9260/platform/rt_low_level_iar.inc index 3046253d07..e5e62b04cb 100644 --- a/bsp/at91sam9260/platform/rt_low_level_iar.inc +++ b/bsp/at91sam9260/platform/rt_low_level_iar.inc @@ -29,3 +29,5 @@ #define IRQ_STK_SIZE 1024 #define FIQ_STK_SIZE 1024 #define SYS_STK_SIZE 512 +/* vector table start should be 0x00000000 or 0xFFFF0000 */ +#define VECTOR_TABLE_START 0x00000000 diff --git a/bsp/at91sam9260/platform/rt_low_level_keil.inc b/bsp/at91sam9260/platform/rt_low_level_keil.inc index c3cde15ded..3ff929c3a6 100644 --- a/bsp/at91sam9260/platform/rt_low_level_keil.inc +++ b/bsp/at91sam9260/platform/rt_low_level_keil.inc @@ -29,4 +29,6 @@ ABT_STK_SIZE EQU 512 IRQ_STK_SIZE EQU 1024 FIQ_STK_SIZE EQU 1024 SYS_STK_SIZE EQU 512 +;/* vector table start should be 0x00000000 or 0xFFFF0000 */ +VECTOR_TABLE_START 0x00000000 END diff --git a/libcpu/arm/arm926/start_gcc.S b/libcpu/arm/arm926/start_gcc.S index ee26f96fc6..05b39debc5 100644 --- a/libcpu/arm/arm926/start_gcc.S +++ b/libcpu/arm/arm926/start_gcc.S @@ -142,7 +142,7 @@ Reset_Handler: @; Copy Exception Vectors to Internal RAM LDR R8, =entry @; Source - LDR R9, =0x00000000 @; Destination + LDR R9, =VECTOR_TABLE_START @; Destination CMP R8, R9 BEQ Setup_Stack LDMIA R8!, {R0-R7} @; Load Vectors diff --git a/libcpu/arm/arm926/start_iar.S b/libcpu/arm/arm926/start_iar.S index db3a253414..b7cc9e170e 100644 --- a/libcpu/arm/arm926/start_iar.S +++ b/libcpu/arm/arm926/start_iar.S @@ -143,7 +143,7 @@ Reset_Handler: ; Copy Exception Vectors to Internal RAM LDR R8, =Entry_Point ; Source - LDR R9, =0x00000000 ; Destination + LDR R9, =VECTOR_TABLE_START ; Destination CMP R8, R9 BEQ Setup_Stack LDMIA R8!, {R0-R7} ; Load Vectors diff --git a/libcpu/arm/arm926/start_rvds.S b/libcpu/arm/arm926/start_rvds.S index 00e0c6136a..cabcd6590b 100644 --- a/libcpu/arm/arm926/start_rvds.S +++ b/libcpu/arm/arm926/start_rvds.S @@ -150,7 +150,7 @@ Reset_Handler ; Copy Exception Vectors to Internal RAM LDR R8, =Entry_Point ; Source - LDR R9, =0x00000000 ; Destination + LDR R9, =VECTOR_TABLE_START ; Destination CMP R8, R9 BEQ Setup_Stack LDMIA R8!, {R0-R7} ; Load Vectors From f4555bf71189ee76c41a4ad2398ad54da4b1d7bf Mon Sep 17 00:00:00 2001 From: ardafu Date: Thu, 16 Apr 2015 11:00:48 +0800 Subject: [PATCH 7/9] 1. [bsp][sam9260] Fix the path of gcc tool chain for travis-ci 2. [bsp][sam9260] Remove unused ld file 3. [bsp][sam9260] Add J-Link debug scripts --- bsp/at91sam9260/at91sam9260_ram.ld | 91 ------- bsp/at91sam9260/debug_scripts/at91sam9260.ini | 248 +++++++++++++++++ bsp/at91sam9260/debug_scripts/at91sam9260.mac | 252 ++++++++++++++++++ bsp/at91sam9260/rtconfig.py | 5 +- 4 files changed, 502 insertions(+), 94 deletions(-) delete mode 100755 bsp/at91sam9260/at91sam9260_ram.ld create mode 100644 bsp/at91sam9260/debug_scripts/at91sam9260.ini create mode 100644 bsp/at91sam9260/debug_scripts/at91sam9260.mac diff --git a/bsp/at91sam9260/at91sam9260_ram.ld b/bsp/at91sam9260/at91sam9260_ram.ld deleted file mode 100755 index 501287d981..0000000000 --- a/bsp/at91sam9260/at91sam9260_ram.ld +++ /dev/null @@ -1,91 +0,0 @@ -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x20000000; - - . = ALIGN(4); - .text : - { - *(.init) - *(.text) - *(.gnu.linkonce.t*) - - /* section information for finsh shell */ - . = ALIGN(4); - __fsymtab_start = .; - KEEP(*(FSymTab)) - __fsymtab_end = .; - . = ALIGN(4); - __vsymtab_start = .; - KEEP(*(VSymTab)) - __vsymtab_end = .; - . = ALIGN(4); - - . = ALIGN(4); - __rt_init_start = .; - KEEP(*(SORT(.rti_fn*))) - __rt_init_end = .; - . = ALIGN(4); - - /* section information for modules */ - . = ALIGN(4); - __rtmsymtab_start = .; - KEEP(*(RTMSymTab)) - __rtmsymtab_end = .; - } - - . = ALIGN(4); - .rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) *(.eh_frame) } - - . = ALIGN(4); - .ctors : - { - PROVIDE(__ctors_start__ = .); - KEEP(*(SORT(.ctors.*))) - KEEP(*(.ctors)) - PROVIDE(__ctors_end__ = .); - } - - .dtors : - { - PROVIDE(__dtors_start__ = .); - KEEP(*(SORT(.dtors.*))) - KEEP(*(.dtors)) - PROVIDE(__dtors_end__ = .); - } - - . = ALIGN(4); - .data : - { - *(.data) - *(.data.*) - *(.gnu.linkonce.d*) - } - - . = ALIGN(4); - .nobss : { *(.nobss) } - - . = 0x20300000; - . = ALIGN(4); - __bss_start = .; - .bss : { *(.bss) } - __bss_end = .; - - /* stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_info 0 : { *(.debug_info) } - .debug_line 0 : { *(.debug_line) } - .debug_pubnames 0 : { *(.debug_pubnames) } - .debug_aranges 0 : { *(.debug_aranges) } - - _end = .; -} diff --git a/bsp/at91sam9260/debug_scripts/at91sam9260.ini b/bsp/at91sam9260/debug_scripts/at91sam9260.ini new file mode 100644 index 0000000000..7101955498 --- /dev/null +++ b/bsp/at91sam9260/debug_scripts/at91sam9260.ini @@ -0,0 +1,248 @@ +// ---------------------------------------------------------------------------- +// ATMEL Microcontroller Software Support +// ---------------------------------------------------------------------------- +// Copyright (c) 2008, Atmel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the disclaimer below. +// +// Atmel's name may not be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE +// DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// ---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// File Name : at91sam9260-ek-sdram.ini +// Object : Generic Macro File for KEIL +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// _MapRAMAt0() +// Function description: Maps RAM at 0. +//---------------------------------------------------------------------------- + +DEFINE INT __mac_i; + +FUNC void _MapRAMAt0(){ + + + printf ("Changing mapping: RAM mapped to 0 \n"); + // Test and set Remap + __mac_i = _RDWORD(0xFFFFEF00); + if ( ((__mac_i & 0x01) == 0) || ((__mac_i & 0x02) == 0)) + { + _WDWORD(0xFFFFEF00,0x03); // toggle remap bits + } + else + { + printf ("------------------------------- The Remap is done -----------------------------------\n"); + } +} + + +//---------------------------------------------------------------------------- +// _InitRSTC() +// Function description +// Initializes the RSTC (Reset controller). +// This makes sense since the default is to not allow user resets, which makes it impossible to +// apply a second RESET via J-Link +//---------------------------------------------------------------------------- + +FUNC void _InitRSTC() { + + _WDWORD(0xFFFFFD08,0xA5000001); // Allow user reset + +} + +//---------------------------------------------------------------------------- +// +// _PllSetting() +// Function description +// Initializes the PMC. +// 1. Enable the Main Oscillator +// 2. Configure PLL +// 3. Switch Master +//---------------------------------------------------------------------------- + +FUNC void __PllSetting() +{ + + if ((_RDWORD(0xFFFFFC30)&0x3) != 0 ) + { + // Disable all PMC interrupt ( $$ JPP) + // AT91C_PMC_IDR ((AT91_REG *) 0xFFFFFC64) //(PMC) Interrupt Disable Register + // pPmc->PMC_IDR = 0xFFFFFFFF; + _WDWORD(0xFFFFFC64,0xFFFFFFFF); + // AT91C_PMC_PCDR ((AT91_REG *) 0xFFFFFC14) //(PMC) Peripheral Clock Disable Register + _WDWORD(0xFFFFFC14,0xFFFFFFFF); + // Disable all clock only Processor clock is enabled. + _WDWORD(0xFFFFFC04,0xFFFFFFFE); + // AT91C_PMC_MCKR ((AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register + _WDWORD(0xFFFFFC30,0x00000001); + _sleep_(10); + // write reset value to PLLA and PLLB + // AT91C_PMC_PLLAR ((AT91_REG *) 0xFFFFFC28) // (PMC) PLL A Register + _WDWORD(0xFFFFFC28,0x00003F00); + + // AT91C_PMC_PLLBR ((AT91_REG *) 0xFFFFFC2C) // (PMC) PLL B Register + _WDWORD(0xFFFFFC2C,0x00003F00); + _sleep_(10); + + printf ( "------------------------------- PLL Enable -----------------------------------------"); + + } + else { + printf( " ********* Core in SLOW CLOCK mode ********* "); + } +} + + +//---------------------------------------------------------------------------- +// +// __PllSetting100MHz() +// Function description +// Set core at 200 MHz and MCK at 100 MHz +//---------------------------------------------------------------------------- + +FUNC void __PllSetting100MHz() +{ + + printf( "------------------------------- PLL Set at 100 MHz ----------------------------------"); + + //* pPmc->PMC_MOR = (( AT91C_CKGR_OSCOUNT & (0x40 <<8) | AT91C_CKGR_MOSCEN )); + _WDWORD(0xFFFFFC20,0x00004001); + _sleep_(10); + // AT91C_PMC_MCKR ((AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register + _WDWORD(0xFFFFFC30,0x00000001); + _sleep_(10); + //* AT91C_BASE_CKGR->CKGR_PLLAR = (AT91C_CKGR_SRCA | ((96 << 16) & AT91C_CKGR_MULA) | + // (AT91C_CKGR_PLLACOUNT | (AT91C_CKGR_OUTA_0 | (9); + _WDWORD(0xFFFFFC28,0x2060BF09); + _sleep_(10); + // Configure PLLB + _WDWORD(0xFFFFFC2C,0x207C3F0C); + _sleep_(10); + //* AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_PLLA_CLK | AT91C_PMC_PRES_CLK | AT91C_PMC_MDIV_2;; + _WDWORD(0xFFFFFC30,0x00000102); + _sleep_(10); + +} + +//---------------------------------------------------------------------------- +// __initSDRAM() +// Function description +// Set SDRAM for works at 100 MHz +//---------------------------------------------------------------------------- + +FUNC void __initSDRAM() +{ + + // Configure EBI Chip select + // pCCFG->CCFG_EBICSA |= AT91C_EBI_CS1A_SDRAMC; + // AT91C_CCFG_EBICSA ((AT91_REG *) 0xFFFFEF1C) // (CCFG) EBI Chip Select Assignement Register + _WDWORD(0xFFFFEF1C,0x0001003A); + + // Configure PIOs + // AT91F_PIO_CfgPeriph( AT91C_BASE_PIOC, AT91C_PC16_D16 to AT91C_PC16_D31 + // pPio->PIO_ASR = periphAEnable; AT91C_PIOC_ASR ((AT91_REG *) 0xFFFFF870) // (PIOC) Select A Register + // pPio->PIO_BSR = periphBEnable;AT91C_PIOC_BSR ((AT91_REG *) 0xFFFFF874) // (PIOC) Select B Register + // pPio->PIO_PDR = (periphAEnable | periphBEnable); // Set in Periph mode + _WDWORD(0xFFFFF870,0xFFFF0000); + _WDWORD(0xFFFFF874,0x00000000); + _WDWORD(0xFFFFF804,0xFFFF0000); + + // psdrc->SDRAMC_CR = AT91C_SDRAMC_NC_9 | AT91C_SDRAMC_NR_13 | AT91C_SDRAMC_CAS_2 | + // AT91C_SDRAMC_NB_4_BANKS | AT91C_SDRAMC_DBW_32_BITS | AT91C_SDRAMC_TWR_2 | AT91C_SDRAMC_TRC_7 | + // AT91C_SDRAMC_TRP_2 | AT91C_SDRAMC_TRCD_2 | AT91C_SDRAMC_TRAS_5 | AT91C_SDRAMC_TXSR_8 ; + _WDWORD(0xFFFFEA08,0x85227259); + _sleep_(10); + // psdrc->SDRAMC_MR = 0x00000002; // Set PRCHG AL + _WDWORD(0xFFFFEA00,0x00000002); + // *AT91C_SDRAM = 0x00000000; // Perform PRCHG + _WDWORD(0x20000000,0x00000000); + _sleep_(10); + + // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 1st CBR + _WDWORD(0xFFFFEA00,0x00000004); + + // *(AT91C_SDRAM+4) = 0x00000001; // Perform CBR + _WDWORD(0x20000010,0x00000001); + + // psdrc->SDRAMC_MR = 0x00000004; // Set 2 CBR + _WDWORD(0xFFFFEA00,0x00000004); + // *(AT91C_SDRAM+8) = 0x00000002; // Perform CBR + _WDWORD(0x20000020,0x00000002); + + // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 3 CBR + _WDWORD(0xFFFFEA00,0x00000004); + // *(AT91C_SDRAM+0xc) = 0x00000003; // Perform CBR + _WDWORD(0x20000030,0x00000003); + + // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 4 CBR + _WDWORD(0xFFFFEA00,0x00000004); + // *(AT91C_SDRAM+0x10) = 0x00000004; // Perform CBR + _WDWORD(0x20000040,0x00000004); + + // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 5 CBR + _WDWORD(0xFFFFEA00,0x00000004); + // *(AT91C_SDRAM+0x14) = 0x00000005; // Perform CBR + _WDWORD(0x20000050,0x00000005); + + // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 6 CBR + _WDWORD(0xFFFFEA00,0x00000004); + // *(AT91C_SDRAM+0x18) = 0x00000006; // Perform CBR + _WDWORD(0x20000060,0x00000006); + + // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 7 CBR + _WDWORD(0xFFFFEA00,0x00000004); + // *(AT91C_SDRAM+0x1c) = 0x00000007; // Perform CBR + _WDWORD(0x20000070,0x00000007); + + // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 8 CBR + _WDWORD(0xFFFFEA00,0x00000004); + // *(AT91C_SDRAM+0x20) = 0x00000008; // Perform CBR + _WDWORD(0x20000080,0x00000008); + + // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_LMR_CMD; // Set LMR operation + _WDWORD(0xFFFFEA00,0x00000003); + // *(AT91C_SDRAM+0x24) = 0xcafedede; // Perform LMR burst=1, lat=2 + _WDWORD(0x20000090,0xCAFEDEDE); + + // psdrc->SDRAMC_TR = (AT91C_MASTER_CLOCK * 7)/1000000; // Set Refresh Timer 390 for 25MHz (TR= 15.6 * F ) + _WDWORD(0xFFFFEA04,0x000002B9); + + //* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_NORMAL_CMD; // Set Normal mode + _WDWORD(0xFFFFEA00,0x00000000); + + //* *AT91C_SDRAM = 0x00000000; // Perform Normal mode + _WDWORD(0x20000000,0x00000000); + printf( "------------------------------- SDRAM Done at 100 MHz -------------------------------"); + + +} + + +__PllSetting(); //* Init PLL +__PllSetting100MHz(); +__initSDRAM(); +_MapRAMAt0(); //* Set the RAM memory at 0x0020 0000 & 0x0000 0000 +_InitRSTC(); +DEBUG_CLOCK = 2000000; +LOAD Objects\\template.axf INCREMENTAL +PC = 0x20000000; +//g,main \ No newline at end of file diff --git a/bsp/at91sam9260/debug_scripts/at91sam9260.mac b/bsp/at91sam9260/debug_scripts/at91sam9260.mac new file mode 100644 index 0000000000..4745aafd37 --- /dev/null +++ b/bsp/at91sam9260/debug_scripts/at91sam9260.mac @@ -0,0 +1,252 @@ +// --------------------------------------------------------- +// ATMEL Microcontroller Software Support - ROUSSET - +// --------------------------------------------------------- +// The software is delivered "AS IS" without warranty or +// condition of any kind, either express, implied or +// statutory. This includes without limitation any warranty +// or condition with respect to merchantability or fitness +// for any particular purpose, or against the infringements of +// intellectual property rights of others. +// --------------------------------------------------------- +// File: SAM9_SDRAM.mac +// User setup file for CSPY debugger. +// 1.1 08/Aug/06 jpp : Creation +// +// $Revision: 1.1.2.1 $ +// +// --------------------------------------------------------- +__var __mac_i; +__var __mac_pt; + +/********************************************************************* +* +* execUserReset() : JTAG set initially to Full Speed +*/ +execUserReset() +{ + __message "------------------------------ execUserReset ---------------------------------"; + _MapRAMAt0(); //* Set the RAM memory at 0x00200000 & 0x00000000 + __PllSetting(); //* Init PLL + __PllSetting100MHz(); + __message "-------------------------------Set PC Reset ----------------------------------"; +} + +/********************************************************************* +* +* execUserPreload() : JTAG set initially to 32kHz +*/ +execUserPreload() +{ + __message "------------------------------ execUserPreload ---------------------------------"; + __hwReset(0); //* Hardware Reset: CPU is automatically halted after the reset (JTAG is already configured to 32kHz) + __writeMemory32(0xD3,0x98,"Register"); //* Set CPSR + __PllSetting(); //* Init PLL + __PllSetting100MHz(); + __initSDRAM(); //* Init SDRAM before load + _MapRAMAt0(); //* Set the RAM memory at 0x0020 0000 & 0x0000 0000 + _InitRSTC(); //* Enable User Reset to allow execUserReset() execution +} + + + +/********************************************************************* +* +* _InitRSTC() +* +* Function description +* Initializes the RSTC (Reset controller). +* This makes sense since the default is to not allow user resets, which makes it impossible to +* apply a second RESET via J-Link +*/ +_InitRSTC() { + __writeMemory32(0xA5000001, 0xFFFFFD08,"Memory"); // Allow user reset +} + + +/********************************************************************* +* +* __initSDRAM() +* Function description +* Set SDRAM for works at 100 MHz +*/ +__initSDRAM() +{ +//* Configure EBI Chip select +// pCCFG->CCFG_EBICSA |= AT91C_EBI_CS1A_SDRAMC | (1 << 16); +// AT91C_CCFG_EBICSA ((AT91_REG *) 0xFFFFEF1C) // (CCFG) EBI Chip Select Assignement Register + __writeMemory32(0x0001003A,0xFFFFEF1C,"Memory"); + + +//* Configure PIOs +//* AT91F_PIO_CfgPeriph( AT91C_BASE_PIOC, AT91C_PC16_D16 to AT91C_PC16_D31 +// pPio->PIO_ASR = periphAEnable; AT91C_PIOC_ASR ((AT91_REG *) 0xFFFFF870) // (PIOC) Select A Register +// pPio->PIO_BSR = periphBEnable;AT91C_PIOC_BSR ((AT91_REG *) 0xFFFFF874) // (PIOC) Select B Register +// pPio->PIO_PDR = (periphAEnable | periphBEnable); // Set in Periph mode + __writeMemory32(0xFFFF0000,0xFFFFF870,"Memory"); + __writeMemory32(0x00000000,0xFFFFF874,"Memory"); + __writeMemory32(0xFFFF0000,0xFFFFF804,"Memory"); + +//* psdrc->SDRAMC_CR = AT91C_SDRAMC_NC_9 | AT91C_SDRAMC_NR_13 | AT91C_SDRAMC_CAS_2 | +// AT91C_SDRAMC_NB_4_BANKS | AT91C_SDRAMC_DBW_32_BITS | AT91C_SDRAMC_TWR_2 | AT91C_SDRAMC_TRC_7 | +// AT91C_SDRAMC_TRP_2 | AT91C_SDRAMC_TRCD_2 | AT91C_SDRAMC_TRAS_5 | AT91C_SDRAMC_TXSR_8 ; + __writeMemory32(0x85227259,0xFFFFEA08,"Memory"); + __delay(1); //100 +//* psdrc->SDRAMC_MR = 0x00000002; // Set PRCHG AL + __writeMemory32(0x00000002,0xFFFFEA00,"Memory"); +//* *AT91C_SDRAM = 0x00000000; // Perform PRCHG + __writeMemory32(0x00000000,0x20000000,"Memory"); + __delay(1); //100 + + +//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 1st CBR + __writeMemory32(0x00000004,0xFFFFEA00,"Memory"); + +//* *(AT91C_SDRAM+4) = 0x00000001; // Perform CBR + __writeMemory32(0x00000001,0x20000010,"Memory"); + +//* psdrc->SDRAMC_MR = 0x00000004; // Set 2 CBR + __writeMemory32(0x00000004,0xFFFFEA00,"Memory"); +//* *(AT91C_SDRAM+8) = 0x00000002; // Perform CBR + __writeMemory32(0x00000002,0x20000020,"Memory"); + +//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 3 CBR + __writeMemory32(0x00000004,0xFFFFEA00,"Memory"); +//* *(AT91C_SDRAM+0xc) = 0x00000003; // Perform CBR + __writeMemory32(0x00000003,0x20000030,"Memory"); + +//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 4 CBR + __writeMemory32(0x00000004,0xFFFFEA00,"Memory"); +//* *(AT91C_SDRAM+0x10) = 0x00000004; // Perform CBR + __writeMemory32(0x00000004,0x20000040,"Memory"); + +//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 5 CBR + __writeMemory32(0x00000004,0xFFFFEA00,"Memory"); +//* *(AT91C_SDRAM+0x14) = 0x00000005; // Perform CBR + __writeMemory32(0x00000005,0x20000050,"Memory"); + +//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 6 CBR + __writeMemory32(0x00000004,0xFFFFEA00,"Memory"); +//* *(AT91C_SDRAM+0x18) = 0x00000006; // Perform CBR + __writeMemory32(0x00000006,0x20000060,"Memory"); + +//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 7 CBR + __writeMemory32(0x00000004,0xFFFFEA00,"Memory"); +//* *(AT91C_SDRAM+0x1c) = 0x00000007; // Perform CBR + __writeMemory32(0x00000007,0x20000070,"Memory"); + +//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 8 CBR + __writeMemory32(0x00000004,0xFFFFEA00,"Memory"); +//* *(AT91C_SDRAM+0x20) = 0x00000008; // Perform CBR + __writeMemory32(0x00000008,0x20000080,"Memory"); + +//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_LMR_CMD; // Set LMR operation + __writeMemory32(0x00000003,0xFFFFEA00,"Memory"); +//* *(AT91C_SDRAM+0x24) = 0xcafedede; // Perform LMR burst=1, lat=2 + __writeMemory32(0xCAFEDEDE,0x20000090,"Memory"); + +//* psdrc->SDRAMC_TR = (AT91C_MASTER_CLOCK * 7)/1000000; // Set Refresh Timer 390 for 25MHz (TR= 15.6 * F ) +// // (F : system clock freq. MHz + + __writeMemory32(0x000002B7,0xFFFFEA04,"Memory"); + +//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_NORMAL_CMD; // Set Normal mode + __writeMemory32(0x00000000,0xFFFFEA00,"Memory"); + +//* *AT91C_SDRAM = 0x00000000; // Perform Normal mode + __writeMemory32(0x00000000,0x20000000,"Memory"); + __message "------------------------------- SDRAM Done at 100 MHz -------------------------------"; + +} + +/********************************************************************* +* +* _MapRAMAt0() +* Function description +* Remap RAM at 0 +*/ +_MapRAMAt0() +{ +// AT91C_MATRIX_MRCR ((AT91_REG *) 0xFFFFEF00) // (MATRIX) Master Remp Control Register + __mac_i=__readMemory32(0xFFFFEF00,"Memory"); + __message "----- AT91C_MATRIX_MRCR : 0x",__mac_i:%X; + + if ( ((__mac_i & 0x01) == 0) || ((__mac_i & 0x02) == 0)){ + __message "------------------------------- The Remap is NOT & REMAP ----------------------------"; + __writeMemory32(0x00000003,0xFFFFEF00,"Memory"); + __mac_i=__readMemory32(0xFFFFEF00,"Memory"); + __message "----- AT91C_MATRIX_MRCR : 0x",__mac_i:%X; + } else { + __message "------------------------------- The Remap is done -----------------------------------"; + } +} + + +/********************************************************************* +* +* __PllSetting() +* Function description +* Initializes the PMC. +* 1. Enable the Main Oscillator +* 2. Configure PLL +* 3. Switch Master +*/ +__PllSetting() +{ + if ((__readMemory32(0xFFFFFC30,"Memory")&0x3) != 0 ) { +//* Disable all PMC interrupt ( $$ JPP) +//* AT91C_PMC_IDR ((AT91_REG *) 0xFFFFFC64) //(PMC) Interrupt Disable Register +//* pPmc->PMC_IDR = 0xFFFFFFFF; + __writeMemory32(0xFFFFFFFF,0xFFFFFC64,"Memory"); +//* AT91C_PMC_PCDR ((AT91_REG *) 0xFFFFFC14) //(PMC) Peripheral Clock Disable Register + __writeMemory32(0xFFFFFFFF,0xFFFFFC14,"Memory"); +// Disable all clock only Processor clock is enabled. + __writeMemory32(0xFFFFFFFE,0xFFFFFC04,"Memory"); + +// AT91C_PMC_MCKR ((AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register + __writeMemory32(0x00000001,0xFFFFFC30,"Memory"); + __delay(10); //10000 + +// write reset value to PLLA and PLLB +// AT91C_PMC_PLLAR ((AT91_REG *) 0xFFFFFC28) // (PMC) PLL A Register + __writeMemory32(0x00003F00,0xFFFFFC28,"Memory"); + +// AT91C_PMC_PLLBR ((AT91_REG *) 0xFFFFFC2C) // (PMC) PLL B Register + __writeMemory32(0x00003F00,0xFFFFFC2C,"Memory"); + __delay(10); //10000 + + __message "------------------------------- PLL Enable -----------------------------------------"; + } else { + __message " ********* Core in SLOW CLOCK mode ********* "; } +} + + +/********************************************************************* +* +* __PllSetting100MHz() +* Function description +* Set core at 200 MHz and MCK at 100 MHz +*/ +__PllSetting100MHz() +{ + + __message "------------------------------- PLL Set at 100 MHz ----------------------------------"; + +//* pPmc->PMC_MOR = (( AT91C_CKGR_OSCOUNT & (0x40 <<8) | AT91C_CKGR_MOSCEN )); + __writeMemory32(0x00004001,0xFFFFFC20,"Memory"); + __delay(10); //10000 +// AT91C_PMC_MCKR ((AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register + __writeMemory32(0x00000001,0xFFFFFC30,"Memory"); + __delay(10); //10000 +//* AT91C_BASE_CKGR->CKGR_PLLAR = (AT91C_CKGR_SRCA | ((96 << 16) & AT91C_CKGR_MULA) | +// (AT91C_CKGR_PLLACOUNT | (AT91C_CKGR_OUTA_0 | (9); + __writeMemory32(0x2060BF09,0xFFFFFC28,"Memory"); + __delay(10); //10000 +// AT91C_BASE_PMC->PMC_PLLBR = BOARD_USBDIV| BOARD_CKGR_PLLB | BOARD_PLLBCOUNT | BOARD_MULB| BOARD_DIVB; + __writeMemory32(0x207C3F0C,0xFFFFFC2C,"Memory"); + __delay(10); //10000 +//* AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_PLLA_CLK | AT91C_PMC_PRES_CLK | AT91C_PMC_MDIV_2;; + __writeMemory32(0x00000102,0xFFFFFC30,"Memory"); + __delay(10); //10000 + +} + diff --git a/bsp/at91sam9260/rtconfig.py b/bsp/at91sam9260/rtconfig.py index a9d440b337..ce27048716 100755 --- a/bsp/at91sam9260/rtconfig.py +++ b/bsp/at91sam9260/rtconfig.py @@ -10,8 +10,8 @@ if os.getenv('RTT_CC'): if CROSS_TOOL == 'gcc': PLATFORM = 'gcc' - EXEC_PATH = 'D:/ArdaArmTools/Sourcery_Lite' - #EXEC_PATH = 'D:/ArdaArmTools/GNUARM_4.9_2015q1' + EXEC_PATH = 'D:/ArdaArmTools/Sourcery_Lite/bin' + #EXEC_PATH = 'D:/ArdaArmTools/GNUARM_4.9_2015q1/bin' elif CROSS_TOOL == 'keil': PLATFORM = 'armcc' EXEC_PATH = 'C:/Keil_v5' @@ -43,7 +43,6 @@ if PLATFORM == 'gcc': SIZE = PREFIX + 'size' OBJDUMP = PREFIX + 'objdump' OBJCPY = PREFIX + 'objcopy' - EXEC_PATH += '/bin/' DEVICE = ' -mcpu=arm926ej-s' CFLAGS = DEVICE From 175e357acecdbe86200fdc8a0866716d822ca516 Mon Sep 17 00:00:00 2001 From: ardafu Date: Thu, 16 Apr 2015 14:13:43 +0800 Subject: [PATCH 8/9] [libcpu][arm926] Remove unused SPSR register PUSH/POP when os switch thread. --- libcpu/arm/arm926/context_gcc.S | 7 ------- libcpu/arm/arm926/context_iar.S | 8 -------- libcpu/arm/arm926/context_rvds.S | 7 ------- libcpu/arm/arm926/stack.c | 7 +++++-- libcpu/arm/arm926/start_gcc.S | 25 +++++++++---------------- libcpu/arm/arm926/start_iar.S | 23 ++++++++--------------- libcpu/arm/arm926/start_rvds.S | 23 ++++++++--------------- 7 files changed, 30 insertions(+), 70 deletions(-) diff --git a/libcpu/arm/arm926/context_gcc.S b/libcpu/arm/arm926/context_gcc.S index 5357b36d20..419c5565de 100644 --- a/libcpu/arm/arm926/context_gcc.S +++ b/libcpu/arm/arm926/context_gcc.S @@ -53,14 +53,10 @@ rt_hw_context_switch: stmfd sp!, {r0-r12, lr} @; push lr & register file mrs r4, cpsr stmfd sp!, {r4} @; push cpsr - mrs r4, spsr - stmfd sp!, {r4} @; push spsr str sp, [r0] @; store sp in preempted tasks tcb ldr sp, [r1] @; get new task stack pointer ldmfd sp!, {r4} @; pop new task spsr msr spsr_cxsf, r4 - ldmfd sp!, {r4} @; pop new task cpsr - msr spsr_cxsf, r4 ldmfd sp!, {r0-r12, lr, pc}^ @; pop new task r0-r12, lr & pc /* @@ -70,9 +66,6 @@ rt_hw_context_switch: .globl rt_hw_context_switch_to rt_hw_context_switch_to: ldr sp, [r0] @; get new task stack pointer - - ldmfd sp!, {r4} @; pop new task spsr - msr spsr_cxsf, r4 ldmfd sp!, {r4} @; pop new task cpsr msr spsr_cxsf, r4 ldmfd sp!, {r0-r12, lr, pc}^ @; pop new task r0-r12, lr & pc diff --git a/libcpu/arm/arm926/context_iar.S b/libcpu/arm/arm926/context_iar.S index 9727dbd96d..14110e5220 100644 --- a/libcpu/arm/arm926/context_iar.S +++ b/libcpu/arm/arm926/context_iar.S @@ -55,14 +55,10 @@ rt_hw_context_switch: STMFD SP!, {R0-R12, LR} ; push lr & register file MRS R4, CPSR STMFD SP!, {R4} ; push cpsr - MRS R4, SPSR - STMFD SP!, {R4} ; push spsr STR SP, [R0] ; store sp in preempted tasks TCB LDR SP, [R1] ; get new task stack pointer LDMFD SP!, {R4} ; pop new task spsr MSR SPSR_cxsf, R4 - LDMFD SP!, {R4} ; pop new task cpsr - MSR SPSR_cxsf, R4 LDMFD SP!, {R0-R12, LR, PC}^ ; pop new task r0-r12, lr & pc /* @@ -72,12 +68,8 @@ rt_hw_context_switch: PUBLIC rt_hw_context_switch_to rt_hw_context_switch_to: LDR SP, [R0] ; get new task stack pointer - LDMFD SP!, {R4} ; pop new task spsr MSR SPSR_cxsf, R4 - LDMFD SP!, {R4} ; pop new task cpsr - MSR SPSR_cxsf, R4 - LDMFD SP!, {R0-R12, LR, PC}^ ; pop new task r0-r12, lr & pc /* diff --git a/libcpu/arm/arm926/context_rvds.S b/libcpu/arm/arm926/context_rvds.S index e5fda293df..32bd235fef 100644 --- a/libcpu/arm/arm926/context_rvds.S +++ b/libcpu/arm/arm926/context_rvds.S @@ -60,14 +60,10 @@ rt_hw_context_switch proc stmfd sp!, {r0-r12, lr} ; push lr & register file mrs r4, cpsr stmfd sp!, {r4} ; push cpsr - mrs r4, spsr - stmfd sp!, {r4} ; push spsr str sp, [r0] ; store sp in preempted tasks tcb ldr sp, [r1] ; get new task stack pointer ldmfd sp!, {r4} ; pop new task spsr msr spsr_cxsf, r4 - ldmfd sp!, {r4} ; pop new task cpsr - msr spsr_cxsf, r4 ldmfd sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc endp @@ -78,11 +74,8 @@ rt_hw_context_switch proc rt_hw_context_switch_to proc export rt_hw_context_switch_to ldr sp, [r0] ; get new task stack pointer - ldmfd sp!, {r4} ; pop new task spsr msr spsr_cxsf, r4 - ldmfd sp!, {r4} ; pop new task cpsr - msr spsr_cxsf, r4 ldmfd sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc endp diff --git a/libcpu/arm/arm926/stack.c b/libcpu/arm/arm926/stack.c index ba3a11d208..53508e5acf 100644 --- a/libcpu/arm/arm926/stack.c +++ b/libcpu/arm/arm926/stack.c @@ -66,8 +66,11 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, *(--stk) = 0; /* r2 */ *(--stk) = 0; /* r1 */ *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ - *(--stk) = SVCMODE; /* cpsr */ - *(--stk) = SVCMODE; /* spsr */ + /* cpsr */ + if ((rt_uint32_t)tentry & 0x01) + *(--stk) = SVCMODE | 0x20; /* thumb mode */ + else + *(--stk) = SVCMODE; /* arm mode */ /* return task's current stack address */ return (rt_uint8_t *)stk; diff --git a/libcpu/arm/arm926/start_gcc.S b/libcpu/arm/arm926/start_gcc.S index 05b39debc5..f2cceeb8f9 100644 --- a/libcpu/arm/arm926/start_gcc.S +++ b/libcpu/arm/arm926/start_gcc.S @@ -291,24 +291,19 @@ rt_hw_context_switch_interrupt_do: STR R1, [R0] @; Save to flag variable LDMFD SP!, {R0-R12,LR} @; Reload saved registers - STMFD SP!, {R0-R3} @; Save R0-R3 - MOV R1, SP @; Save old task's SP to R1 - ADD SP, SP, #16 @; Restore SP + STMFD SP, {R0-R2} @; Save R0-R2 + SUB R1, SP, #4*3 @; Save old task's SP to R1 SUB R2, LR, #4 @; Save old task's PC to R2 - MRS R3, SPSR @; Get CPSR of interrupt thread - + MRS R0, SPSR @; Get CPSR of interrupt thread + MSR CPSR_c, #MODE_SVC|NOINT @; Switch to SVC mode and no interrupt STMFD SP!, {R2} @; Push old task's PC - STMFD SP!, {R4-R12,LR} @; Push old task's LR,R12-R4 - MOV R4, R1 @; Special optimised code below - MOV R5, R3 - LDMFD R4!, {R0-R3} - STMFD SP!, {R0-R3} @; Push old task's R3-R0 - STMFD SP!, {R5} @; Push old task's CPSR - MRS R4, SPSR - STMFD SP!, {R4} @; Push old task's SPSR + STMFD SP!, {R3-R12,LR} @; Push old task's LR,R12-R3 + LDMFD R1, {R1-R3} + STMFD SP!, {R1-R3} @; Push old task's R2-R0 + STMFD SP!, {R0} @; Push old task's CPSR LDR R4, =rt_interrupt_from_thread LDR R5, [R4] @; R5 = stack ptr in old tasks's TCB @@ -320,7 +315,5 @@ rt_hw_context_switch_interrupt_do: LDMFD SP!, {R4} @; Pop new task's SPSR MSR SPSR_cxsf, R4 - LDMFD SP!, {R4} @; Pop new task's CPSR - MSR SPSR_cxsf, R4 - LDMFD SP!, {R0-R12,LR,PC}^ @; pop new task's R0-R12,LR & PC + LDMFD SP!, {R0-R12,LR,PC}^ @; pop new task's R0-R12,LR & PC SPSR 2 CPSR diff --git a/libcpu/arm/arm926/start_iar.S b/libcpu/arm/arm926/start_iar.S index b7cc9e170e..187ae35bbf 100644 --- a/libcpu/arm/arm926/start_iar.S +++ b/libcpu/arm/arm926/start_iar.S @@ -262,24 +262,19 @@ rt_hw_context_switch_interrupt_do: STR R1, [R0] ; Save to flag variable LDMFD SP!, {R0-R12,LR} ; Reload saved registers - STMFD SP!, {R0-R3} ; Save R0-R3 - MOV R1, SP ; Save old task's SP to R1 - ADD SP, SP, #16 ; Restore SP + STMFD SP, {R0-R2} ; Save R0-R2 + SUB R1, SP, #4*3 ; Save old task's SP to R1 SUB R2, LR, #4 ; Save old task's PC to R2 - MRS R3, SPSR ; Get CPSR of interrupt thread + MRS R0, SPSR ; Get CPSR of interrupt thread MSR CPSR_c, #MODE_SVC|NOINT ; Switch to SVC mode and no interrupt STMFD SP!, {R2} ; Push old task's PC - STMFD SP!, {R4-R12,LR} ; Push old task's LR,R12-R4 - MOV R4, R1 ; Special optimised code below - MOV R5, R3 - LDMFD R4!, {R0-R3} - STMFD SP!, {R0-R3} ; Push old task's R3-R0 - STMFD SP!, {R5} ; Push old task's CPSR - MRS R4, SPSR - STMFD SP!, {R4} ; Push old task's SPSR + STMFD SP!, {R3-R12,LR} ; Push old task's LR,R12-R3 + LDMFD R1, {R1-R3} + STMFD SP!, {R1-R3} ; Push old task's R2-R0 + STMFD SP!, {R0} ; Push old task's CPSR LDR R4, =rt_interrupt_from_thread LDR R5, [R4] ; R5 = stack ptr in old tasks's TCB @@ -291,8 +286,6 @@ rt_hw_context_switch_interrupt_do: LDMFD SP!, {R4} ; Pop new task's SPSR MSR SPSR_cxsf, R4 - LDMFD SP!, {R4} ; Pop new task's CPSR - MSR SPSR_cxsf, R4 - LDMFD SP!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC + LDMFD SP!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC SPSR to CPSR END diff --git a/libcpu/arm/arm926/start_rvds.S b/libcpu/arm/arm926/start_rvds.S index cabcd6590b..edf2fcb96e 100644 --- a/libcpu/arm/arm926/start_rvds.S +++ b/libcpu/arm/arm926/start_rvds.S @@ -274,24 +274,19 @@ rt_hw_context_switch_interrupt_do PROC STR R1, [R0] ; Save to flag variable LDMFD SP!, {R0-R12,LR} ; Reload saved registers - STMFD SP!, {R0-R3} ; Save R0-R3 - MOV R1, SP ; Save old task's SP to R1 - ADD SP, SP, #16 ; Restore SP + STMFD SP, {R0-R2} ; Save R0-R2 + SUB R1, SP, #4*3 ; Save old task's SP to R1 SUB R2, LR, #4 ; Save old task's PC to R2 - MRS R3, SPSR ; Get CPSR of interrupt thread + MRS R0, SPSR ; Get CPSR of interrupt thread MSR CPSR_c, #MODE_SVC:OR:NOINT ; Switch to SVC mode and no interrupt STMFD SP!, {R2} ; Push old task's PC - STMFD SP!, {R4-R12,LR} ; Push old task's LR,R12-R4 - MOV R4, R1 ; Special optimised code below - MOV R5, R3 - LDMFD R4!, {R0-R3} - STMFD SP!, {R0-R3} ; Push old task's R3-R0 - STMFD SP!, {R5} ; Push old task's CPSR - MRS R4, SPSR - STMFD SP!, {R4} ; Push old task's SPSR + STMFD SP!, {R3-R12,LR} ; Push old task's LR,R12-R3 + LDMFD R1, {R1-R3} + STMFD SP!, {R1-R3} ; Push old task's R2-R0 + STMFD SP!, {R0} ; Push old task's CPSR LDR R4, =rt_interrupt_from_thread LDR R5, [R4] ; R5 = stack ptr in old tasks's TCB @@ -303,10 +298,8 @@ rt_hw_context_switch_interrupt_do PROC LDMFD SP!, {R4} ; Pop new task's SPSR MSR SPSR_cxsf, R4 - LDMFD SP!, {R4} ; Pop new task's CPSR - MSR SPSR_cxsf, R4 - LDMFD SP!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC + LDMFD SP!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC SPSR to CPSR ENDP IF :DEF:__MICROLIB From 61609a5bf052d630690f8c36ea7f821ed060d722 Mon Sep 17 00:00:00 2001 From: ardafu Date: Thu, 16 Apr 2015 14:15:00 +0800 Subject: [PATCH 9/9] [bsp][sam9260] Fix Keil compile error. --- bsp/at91sam9260/platform/rt_low_level_keil.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp/at91sam9260/platform/rt_low_level_keil.inc b/bsp/at91sam9260/platform/rt_low_level_keil.inc index 3ff929c3a6..a78d8e85df 100644 --- a/bsp/at91sam9260/platform/rt_low_level_keil.inc +++ b/bsp/at91sam9260/platform/rt_low_level_keil.inc @@ -30,5 +30,5 @@ IRQ_STK_SIZE EQU 1024 FIQ_STK_SIZE EQU 1024 SYS_STK_SIZE EQU 512 ;/* vector table start should be 0x00000000 or 0xFFFF0000 */ -VECTOR_TABLE_START 0x00000000 +VECTOR_TABLE_START EQU 0x00000000 END