瀏覽代碼

1. [cpu] split ARM926 cpu code from AT91SAM9260 BSP

ardafu 10 年之前
父節點
當前提交
39452b67b0

+ 7 - 11
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

+ 48 - 1
bsp/at91sam9260/platform/interrupt.c

@@ -24,7 +24,7 @@
 
 #include <rthw.h>
 #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)
 {

+ 25 - 0
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

+ 7 - 0
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

+ 7 - 0
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

+ 27 - 0
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);
+}
+

+ 8 - 0
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

+ 0 - 392
bsp/at91sam9260/platform/start_gcc.S

@@ -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.*/
-
-/*/*}*/
-
-

+ 0 - 325
bsp/at91sam9260/platform/start_rvds.S

@@ -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 ----------------------------
-
-;// <h> Stack Configuration (Stack Sizes in Bytes)
-;//   <o0> Undefined Mode      <0x0-0xFFFFFFFF:8>
-;//   <o1> Supervisor Mode     <0x0-0xFFFFFFFF:8>
-;//   <o2> Abort Mode          <0x0-0xFFFFFFFF:8>
-;//   <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
-;//   <o4> Interrupt Mode      <0x0-0xFFFFFFFF:8>
-;//   <o5> User/System Mode    <0x0-0xFFFFFFFF:8>
-;// </h>
-
-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
-
-
-;// <h> Heap Configuration
-;//   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF>
-;// </h>
-
-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
-

+ 6 - 5
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"'

+ 71 - 82
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
- */
-
-/*!
- * \addtogroup AT91SAM926X
- */
-/*@{*/
-
-#define NOINT			0xc0
+;/*
+; * 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
 
-/*
- * 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
-
-	ldmfd	sp!, {r4}		@ pop new task spsr
-	msr	spsr_cxsf, r4
-	ldmfd	sp!, {r4}		@ pop new task cpsr
-	msr	cpsr_cxsf, r4
+    ldr     sp, [r0]                @; get new task stack pointer
 
-	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

+ 103 - 0
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
+    

+ 75 - 80
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
-
-	LDMFD	sp!, {r4}			; pop new task spsr
-	MSR	spsr_cxsf, r4
-	LDMFD	sp!, {r4}			; pop new task cpsr
-	MSR	cpsr_cxsf, r4
+rt_hw_context_switch_to    proc
+    export rt_hw_context_switch_to
+    ldr     sp, [r0]                ; get new task stack pointer
 
-	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

+ 117 - 85
libcpu/arm/arm926/cpuport.c

@@ -25,8 +25,8 @@
 #include <rthw.h>
 #include <rtthread.h>
 
-#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;
-
-	__asm
-	{
-		mrc p15, 0, value, c1, c0, 0
-		orr value, value, bit
-		mcr p15, 0, value, c1, c0, 0
-	}
+    rt_uint32_t value;
+
+    __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
+    }
+}
+#endif
 
-	__asm
-	{
-		mrc p15, 0, value, c1, c0, 0
-		bic value, value, bit
-		mcr p15, 0, value, c1, c0, 0
-	}
+#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");
-
-	level = rt_hw_interrupt_disable();
-	machine_shutdown();
-	while (level)
-	{
-		RT_ASSERT(0);
-	}
+    rt_uint32_t level;
+    rt_kprintf("shutdown...\n");
+
+    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;
-
-	if (value == 0)
-		return value;
-	
-	__asm
-	{
-		rsb x, value, #0
-		and x, x, value
-		clz x, x
-		rsb x, x, #32
-	}
-
-	return 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
+    }
+
+    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
 

+ 314 - 122
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,319 @@ 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 = 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()
+{
+    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 = 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 +568,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 +576,38 @@ 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()
@@ -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();
-
-	/* 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);
+    /* 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 MMU table address */
+    mmu_setttbase((rt_uint32_t)_page_table);
 
     /* enables MMU */
     mmu_enable();

+ 27 - 27
libcpu/arm/arm926/mmu.h

@@ -26,35 +26,35 @@
 
 #include <rtthread.h>
 
-#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 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 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 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 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 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);

+ 30 - 30
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;
 }
 

+ 327 - 0
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

+ 296 - 0
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

+ 338 - 0
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

+ 33 - 9
bsp/at91sam9260/platform/trap.c → libcpu/arm/arm926/trap.c

@@ -25,7 +25,7 @@
 #include <rtthread.h>
 #include <rthw.h>
 
-#include "at91sam926x.h"
+#include <interrupt.h>
 
 /**
  * @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 ++;
 }