summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernard Xiong <[email protected]>2015-04-16 16:29:44 +0800
committerBernard Xiong <[email protected]>2015-04-16 16:29:44 +0800
commit97a8426ce040ba9cac2340141414346cd528a40d (patch)
treeaaef2ff0fb5f06ed5aa4834945d768fb3e7c52c8
parentf1e268607cde784badba3ad60817f867d454f075 (diff)
parent61609a5bf052d630690f8c36ea7f821ed060d722 (diff)
Merge pull request #460 from ArdaFu/master
[cpu] Split ARM926 cpu code from SAM9260 BSP
-rw-r--r--bsp/at91sam9260/applications/startup.c25
-rw-r--r--bsp/at91sam9260/debug_scripts/at91sam9260.ini248
-rw-r--r--bsp/at91sam9260/debug_scripts/at91sam9260.mac252
-rw-r--r--bsp/at91sam9260/link_scripts/at91sam9260_ram.icf81
-rw-r--r--[-rwxr-xr-x]bsp/at91sam9260/link_scripts/at91sam9260_ram.ld (renamed from bsp/at91sam9260/at91sam9260_ram.ld)11
-rw-r--r--bsp/at91sam9260/link_scripts/at91sam9260_ram.scat58
-rw-r--r--bsp/at91sam9260/platform/interrupt.c49
-rw-r--r--bsp/at91sam9260/platform/interrupt.h25
-rw-r--r--bsp/at91sam9260/platform/rt_low_level_gcc.inc33
-rw-r--r--bsp/at91sam9260/platform/rt_low_level_iar.inc33
-rw-r--r--bsp/at91sam9260/platform/rt_low_level_init.c64
-rw-r--r--bsp/at91sam9260/platform/rt_low_level_keil.inc34
-rw-r--r--bsp/at91sam9260/platform/start_gcc.S392
-rw-r--r--bsp/at91sam9260/platform/start_rvds.S325
-rw-r--r--bsp/at91sam9260/platform/trap.c185
-rwxr-xr-xbsp/at91sam9260/rtconfig.py101
-rw-r--r--libcpu/arm/arm926/context_gcc.S148
-rw-r--r--libcpu/arm/arm926/context_iar.S96
-rw-r--r--libcpu/arm/arm926/context_rvds.S150
-rw-r--r--libcpu/arm/arm926/cpuport.c205
-rw-r--r--libcpu/arm/arm926/mmu.c462
-rw-r--r--libcpu/arm/arm926/mmu.h50
-rw-r--r--libcpu/arm/arm926/stack.c66
-rw-r--r--libcpu/arm/arm926/start_gcc.S319
-rw-r--r--libcpu/arm/arm926/start_iar.S291
-rw-r--r--libcpu/arm/arm926/start_rvds.S323
-rw-r--r--libcpu/arm/arm926/trap.c230
27 files changed, 2868 insertions, 1388 deletions
diff --git a/bsp/at91sam9260/applications/startup.c b/bsp/at91sam9260/applications/startup.c
index 15e8138886..2f77f4ad68 100644
--- a/bsp/at91sam9260/applications/startup.c
+++ b/bsp/at91sam9260/applications/startup.c
@@ -47,19 +47,18 @@ 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;
+extern int Image$$ER_ZI$$ZI$$Limit;
+#define HEAP_START ((void*)&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__;
+#define HEAP_START ((void*)&__bss_end__)
+#elif (defined (__ICCARM__))
+#pragma section="HEAP"
+#define HEAP_START (__section_begin("HEAP"))
#endif
+#define HEAP_END ((void*)0x24000000)
+
#ifdef RT_USING_FINSH
extern void finsh_system_init(void);
#endif
@@ -96,11 +95,7 @@ void rtthread_startup(void)
rt_system_timer_init();
/* initialize heap memory system */
-#ifdef __CC_ARM
- rt_system_heap_init((void*)&Image$$ER_ZI$$ZI$$Limit, (void*)0x24000000);
-#else
- rt_system_heap_init((void*)&__bss_end, (void*)0x23f00000);
-#endif
+ rt_system_heap_init(HEAP_START, HEAP_END);
#ifdef RT_USING_MODULE
/* initialize module system*/
diff --git a/bsp/at91sam9260/debug_scripts/at91sam9260.ini b/bsp/at91sam9260/debug_scripts/at91sam9260.ini
new file mode 100644
index 0000000000..7101955498
--- /dev/null
+++ b/bsp/at91sam9260/debug_scripts/at91sam9260.ini
@@ -0,0 +1,248 @@
+// ----------------------------------------------------------------------------
+// ATMEL Microcontroller Software Support
+// ----------------------------------------------------------------------------
+// Copyright (c) 2008, Atmel Corporation
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the disclaimer below.
+//
+// Atmel's name may not be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+// DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// ----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+// File Name : at91sam9260-ek-sdram.ini
+// Object : Generic Macro File for KEIL
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+// _MapRAMAt0()
+// Function description: Maps RAM at 0.
+//----------------------------------------------------------------------------
+
+DEFINE INT __mac_i;
+
+FUNC void _MapRAMAt0(){
+
+
+ printf ("Changing mapping: RAM mapped to 0 \n");
+ // Test and set Remap
+ __mac_i = _RDWORD(0xFFFFEF00);
+ if ( ((__mac_i & 0x01) == 0) || ((__mac_i & 0x02) == 0))
+ {
+ _WDWORD(0xFFFFEF00,0x03); // toggle remap bits
+ }
+ else
+ {
+ printf ("------------------------------- The Remap is done -----------------------------------\n");
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// _InitRSTC()
+// Function description
+// Initializes the RSTC (Reset controller).
+// This makes sense since the default is to not allow user resets, which makes it impossible to
+// apply a second RESET via J-Link
+//----------------------------------------------------------------------------
+
+FUNC void _InitRSTC() {
+
+ _WDWORD(0xFFFFFD08,0xA5000001); // Allow user reset
+
+}
+
+//----------------------------------------------------------------------------
+//
+// _PllSetting()
+// Function description
+// Initializes the PMC.
+// 1. Enable the Main Oscillator
+// 2. Configure PLL
+// 3. Switch Master
+//----------------------------------------------------------------------------
+
+FUNC void __PllSetting()
+{
+
+ if ((_RDWORD(0xFFFFFC30)&0x3) != 0 )
+ {
+ // Disable all PMC interrupt ( $$ JPP)
+ // AT91C_PMC_IDR ((AT91_REG *) 0xFFFFFC64) //(PMC) Interrupt Disable Register
+ // pPmc->PMC_IDR = 0xFFFFFFFF;
+ _WDWORD(0xFFFFFC64,0xFFFFFFFF);
+ // AT91C_PMC_PCDR ((AT91_REG *) 0xFFFFFC14) //(PMC) Peripheral Clock Disable Register
+ _WDWORD(0xFFFFFC14,0xFFFFFFFF);
+ // Disable all clock only Processor clock is enabled.
+ _WDWORD(0xFFFFFC04,0xFFFFFFFE);
+ // AT91C_PMC_MCKR ((AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register
+ _WDWORD(0xFFFFFC30,0x00000001);
+ _sleep_(10);
+ // write reset value to PLLA and PLLB
+ // AT91C_PMC_PLLAR ((AT91_REG *) 0xFFFFFC28) // (PMC) PLL A Register
+ _WDWORD(0xFFFFFC28,0x00003F00);
+
+ // AT91C_PMC_PLLBR ((AT91_REG *) 0xFFFFFC2C) // (PMC) PLL B Register
+ _WDWORD(0xFFFFFC2C,0x00003F00);
+ _sleep_(10);
+
+ printf ( "------------------------------- PLL Enable -----------------------------------------");
+
+ }
+ else {
+ printf( " ********* Core in SLOW CLOCK mode ********* ");
+ }
+}
+
+
+//----------------------------------------------------------------------------
+//
+// __PllSetting100MHz()
+// Function description
+// Set core at 200 MHz and MCK at 100 MHz
+//----------------------------------------------------------------------------
+
+FUNC void __PllSetting100MHz()
+{
+
+ printf( "------------------------------- PLL Set at 100 MHz ----------------------------------");
+
+ //* pPmc->PMC_MOR = (( AT91C_CKGR_OSCOUNT & (0x40 <<8) | AT91C_CKGR_MOSCEN ));
+ _WDWORD(0xFFFFFC20,0x00004001);
+ _sleep_(10);
+ // AT91C_PMC_MCKR ((AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register
+ _WDWORD(0xFFFFFC30,0x00000001);
+ _sleep_(10);
+ //* AT91C_BASE_CKGR->CKGR_PLLAR = (AT91C_CKGR_SRCA | ((96 << 16) & AT91C_CKGR_MULA) |
+ // (AT91C_CKGR_PLLACOUNT | (AT91C_CKGR_OUTA_0 | (9);
+ _WDWORD(0xFFFFFC28,0x2060BF09);
+ _sleep_(10);
+ // Configure PLLB
+ _WDWORD(0xFFFFFC2C,0x207C3F0C);
+ _sleep_(10);
+ //* AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_PLLA_CLK | AT91C_PMC_PRES_CLK | AT91C_PMC_MDIV_2;;
+ _WDWORD(0xFFFFFC30,0x00000102);
+ _sleep_(10);
+
+}
+
+//----------------------------------------------------------------------------
+// __initSDRAM()
+// Function description
+// Set SDRAM for works at 100 MHz
+//----------------------------------------------------------------------------
+
+FUNC void __initSDRAM()
+{
+
+ // Configure EBI Chip select
+ // pCCFG->CCFG_EBICSA |= AT91C_EBI_CS1A_SDRAMC;
+ // AT91C_CCFG_EBICSA ((AT91_REG *) 0xFFFFEF1C) // (CCFG) EBI Chip Select Assignement Register
+ _WDWORD(0xFFFFEF1C,0x0001003A);
+
+ // Configure PIOs
+ // AT91F_PIO_CfgPeriph( AT91C_BASE_PIOC, AT91C_PC16_D16 to AT91C_PC16_D31
+ // pPio->PIO_ASR = periphAEnable; AT91C_PIOC_ASR ((AT91_REG *) 0xFFFFF870) // (PIOC) Select A Register
+ // pPio->PIO_BSR = periphBEnable;AT91C_PIOC_BSR ((AT91_REG *) 0xFFFFF874) // (PIOC) Select B Register
+ // pPio->PIO_PDR = (periphAEnable | periphBEnable); // Set in Periph mode
+ _WDWORD(0xFFFFF870,0xFFFF0000);
+ _WDWORD(0xFFFFF874,0x00000000);
+ _WDWORD(0xFFFFF804,0xFFFF0000);
+
+ // psdrc->SDRAMC_CR = AT91C_SDRAMC_NC_9 | AT91C_SDRAMC_NR_13 | AT91C_SDRAMC_CAS_2 |
+ // AT91C_SDRAMC_NB_4_BANKS | AT91C_SDRAMC_DBW_32_BITS | AT91C_SDRAMC_TWR_2 | AT91C_SDRAMC_TRC_7 |
+ // AT91C_SDRAMC_TRP_2 | AT91C_SDRAMC_TRCD_2 | AT91C_SDRAMC_TRAS_5 | AT91C_SDRAMC_TXSR_8 ;
+ _WDWORD(0xFFFFEA08,0x85227259);
+ _sleep_(10);
+ // psdrc->SDRAMC_MR = 0x00000002; // Set PRCHG AL
+ _WDWORD(0xFFFFEA00,0x00000002);
+ // *AT91C_SDRAM = 0x00000000; // Perform PRCHG
+ _WDWORD(0x20000000,0x00000000);
+ _sleep_(10);
+
+ // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 1st CBR
+ _WDWORD(0xFFFFEA00,0x00000004);
+
+ // *(AT91C_SDRAM+4) = 0x00000001; // Perform CBR
+ _WDWORD(0x20000010,0x00000001);
+
+ // psdrc->SDRAMC_MR = 0x00000004; // Set 2 CBR
+ _WDWORD(0xFFFFEA00,0x00000004);
+ // *(AT91C_SDRAM+8) = 0x00000002; // Perform CBR
+ _WDWORD(0x20000020,0x00000002);
+
+ // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 3 CBR
+ _WDWORD(0xFFFFEA00,0x00000004);
+ // *(AT91C_SDRAM+0xc) = 0x00000003; // Perform CBR
+ _WDWORD(0x20000030,0x00000003);
+
+ // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 4 CBR
+ _WDWORD(0xFFFFEA00,0x00000004);
+ // *(AT91C_SDRAM+0x10) = 0x00000004; // Perform CBR
+ _WDWORD(0x20000040,0x00000004);
+
+ // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 5 CBR
+ _WDWORD(0xFFFFEA00,0x00000004);
+ // *(AT91C_SDRAM+0x14) = 0x00000005; // Perform CBR
+ _WDWORD(0x20000050,0x00000005);
+
+ // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 6 CBR
+ _WDWORD(0xFFFFEA00,0x00000004);
+ // *(AT91C_SDRAM+0x18) = 0x00000006; // Perform CBR
+ _WDWORD(0x20000060,0x00000006);
+
+ // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 7 CBR
+ _WDWORD(0xFFFFEA00,0x00000004);
+ // *(AT91C_SDRAM+0x1c) = 0x00000007; // Perform CBR
+ _WDWORD(0x20000070,0x00000007);
+
+ // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 8 CBR
+ _WDWORD(0xFFFFEA00,0x00000004);
+ // *(AT91C_SDRAM+0x20) = 0x00000008; // Perform CBR
+ _WDWORD(0x20000080,0x00000008);
+
+ // psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_LMR_CMD; // Set LMR operation
+ _WDWORD(0xFFFFEA00,0x00000003);
+ // *(AT91C_SDRAM+0x24) = 0xcafedede; // Perform LMR burst=1, lat=2
+ _WDWORD(0x20000090,0xCAFEDEDE);
+
+ // psdrc->SDRAMC_TR = (AT91C_MASTER_CLOCK * 7)/1000000; // Set Refresh Timer 390 for 25MHz (TR= 15.6 * F )
+ _WDWORD(0xFFFFEA04,0x000002B9);
+
+ //* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_NORMAL_CMD; // Set Normal mode
+ _WDWORD(0xFFFFEA00,0x00000000);
+
+ //* *AT91C_SDRAM = 0x00000000; // Perform Normal mode
+ _WDWORD(0x20000000,0x00000000);
+ printf( "------------------------------- SDRAM Done at 100 MHz -------------------------------");
+
+
+}
+
+
+__PllSetting(); //* Init PLL
+__PllSetting100MHz();
+__initSDRAM();
+_MapRAMAt0(); //* Set the RAM memory at 0x0020 0000 & 0x0000 0000
+_InitRSTC();
+DEBUG_CLOCK = 2000000;
+LOAD Objects\\template.axf INCREMENTAL
+PC = 0x20000000;
+//g,main \ No newline at end of file
diff --git a/bsp/at91sam9260/debug_scripts/at91sam9260.mac b/bsp/at91sam9260/debug_scripts/at91sam9260.mac
new file mode 100644
index 0000000000..4745aafd37
--- /dev/null
+++ b/bsp/at91sam9260/debug_scripts/at91sam9260.mac
@@ -0,0 +1,252 @@
+// ---------------------------------------------------------
+// ATMEL Microcontroller Software Support - ROUSSET -
+// ---------------------------------------------------------
+// The software is delivered "AS IS" without warranty or
+// condition of any kind, either express, implied or
+// statutory. This includes without limitation any warranty
+// or condition with respect to merchantability or fitness
+// for any particular purpose, or against the infringements of
+// intellectual property rights of others.
+// ---------------------------------------------------------
+// File: SAM9_SDRAM.mac
+// User setup file for CSPY debugger.
+// 1.1 08/Aug/06 jpp : Creation
+//
+// $Revision: 1.1.2.1 $
+//
+// ---------------------------------------------------------
+__var __mac_i;
+__var __mac_pt;
+
+/*********************************************************************
+*
+* execUserReset() : JTAG set initially to Full Speed
+*/
+execUserReset()
+{
+ __message "------------------------------ execUserReset ---------------------------------";
+ _MapRAMAt0(); //* Set the RAM memory at 0x00200000 & 0x00000000
+ __PllSetting(); //* Init PLL
+ __PllSetting100MHz();
+ __message "-------------------------------Set PC Reset ----------------------------------";
+}
+
+/*********************************************************************
+*
+* execUserPreload() : JTAG set initially to 32kHz
+*/
+execUserPreload()
+{
+ __message "------------------------------ execUserPreload ---------------------------------";
+ __hwReset(0); //* Hardware Reset: CPU is automatically halted after the reset (JTAG is already configured to 32kHz)
+ __writeMemory32(0xD3,0x98,"Register"); //* Set CPSR
+ __PllSetting(); //* Init PLL
+ __PllSetting100MHz();
+ __initSDRAM(); //* Init SDRAM before load
+ _MapRAMAt0(); //* Set the RAM memory at 0x0020 0000 & 0x0000 0000
+ _InitRSTC(); //* Enable User Reset to allow execUserReset() execution
+}
+
+
+
+/*********************************************************************
+*
+* _InitRSTC()
+*
+* Function description
+* Initializes the RSTC (Reset controller).
+* This makes sense since the default is to not allow user resets, which makes it impossible to
+* apply a second RESET via J-Link
+*/
+_InitRSTC() {
+ __writeMemory32(0xA5000001, 0xFFFFFD08,"Memory"); // Allow user reset
+}
+
+
+/*********************************************************************
+*
+* __initSDRAM()
+* Function description
+* Set SDRAM for works at 100 MHz
+*/
+__initSDRAM()
+{
+//* Configure EBI Chip select
+// pCCFG->CCFG_EBICSA |= AT91C_EBI_CS1A_SDRAMC | (1 << 16);
+// AT91C_CCFG_EBICSA ((AT91_REG *) 0xFFFFEF1C) // (CCFG) EBI Chip Select Assignement Register
+ __writeMemory32(0x0001003A,0xFFFFEF1C,"Memory");
+
+
+//* Configure PIOs
+//* AT91F_PIO_CfgPeriph( AT91C_BASE_PIOC, AT91C_PC16_D16 to AT91C_PC16_D31
+// pPio->PIO_ASR = periphAEnable; AT91C_PIOC_ASR ((AT91_REG *) 0xFFFFF870) // (PIOC) Select A Register
+// pPio->PIO_BSR = periphBEnable;AT91C_PIOC_BSR ((AT91_REG *) 0xFFFFF874) // (PIOC) Select B Register
+// pPio->PIO_PDR = (periphAEnable | periphBEnable); // Set in Periph mode
+ __writeMemory32(0xFFFF0000,0xFFFFF870,"Memory");
+ __writeMemory32(0x00000000,0xFFFFF874,"Memory");
+ __writeMemory32(0xFFFF0000,0xFFFFF804,"Memory");
+
+//* psdrc->SDRAMC_CR = AT91C_SDRAMC_NC_9 | AT91C_SDRAMC_NR_13 | AT91C_SDRAMC_CAS_2 |
+// AT91C_SDRAMC_NB_4_BANKS | AT91C_SDRAMC_DBW_32_BITS | AT91C_SDRAMC_TWR_2 | AT91C_SDRAMC_TRC_7 |
+// AT91C_SDRAMC_TRP_2 | AT91C_SDRAMC_TRCD_2 | AT91C_SDRAMC_TRAS_5 | AT91C_SDRAMC_TXSR_8 ;
+ __writeMemory32(0x85227259,0xFFFFEA08,"Memory");
+ __delay(1); //100
+//* psdrc->SDRAMC_MR = 0x00000002; // Set PRCHG AL
+ __writeMemory32(0x00000002,0xFFFFEA00,"Memory");
+//* *AT91C_SDRAM = 0x00000000; // Perform PRCHG
+ __writeMemory32(0x00000000,0x20000000,"Memory");
+ __delay(1); //100
+
+
+//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 1st CBR
+ __writeMemory32(0x00000004,0xFFFFEA00,"Memory");
+
+//* *(AT91C_SDRAM+4) = 0x00000001; // Perform CBR
+ __writeMemory32(0x00000001,0x20000010,"Memory");
+
+//* psdrc->SDRAMC_MR = 0x00000004; // Set 2 CBR
+ __writeMemory32(0x00000004,0xFFFFEA00,"Memory");
+//* *(AT91C_SDRAM+8) = 0x00000002; // Perform CBR
+ __writeMemory32(0x00000002,0x20000020,"Memory");
+
+//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 3 CBR
+ __writeMemory32(0x00000004,0xFFFFEA00,"Memory");
+//* *(AT91C_SDRAM+0xc) = 0x00000003; // Perform CBR
+ __writeMemory32(0x00000003,0x20000030,"Memory");
+
+//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 4 CBR
+ __writeMemory32(0x00000004,0xFFFFEA00,"Memory");
+//* *(AT91C_SDRAM+0x10) = 0x00000004; // Perform CBR
+ __writeMemory32(0x00000004,0x20000040,"Memory");
+
+//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 5 CBR
+ __writeMemory32(0x00000004,0xFFFFEA00,"Memory");
+//* *(AT91C_SDRAM+0x14) = 0x00000005; // Perform CBR
+ __writeMemory32(0x00000005,0x20000050,"Memory");
+
+//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 6 CBR
+ __writeMemory32(0x00000004,0xFFFFEA00,"Memory");
+//* *(AT91C_SDRAM+0x18) = 0x00000006; // Perform CBR
+ __writeMemory32(0x00000006,0x20000060,"Memory");
+
+//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 7 CBR
+ __writeMemory32(0x00000004,0xFFFFEA00,"Memory");
+//* *(AT91C_SDRAM+0x1c) = 0x00000007; // Perform CBR
+ __writeMemory32(0x00000007,0x20000070,"Memory");
+
+//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_RFSH_CMD; // Set 8 CBR
+ __writeMemory32(0x00000004,0xFFFFEA00,"Memory");
+//* *(AT91C_SDRAM+0x20) = 0x00000008; // Perform CBR
+ __writeMemory32(0x00000008,0x20000080,"Memory");
+
+//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_LMR_CMD; // Set LMR operation
+ __writeMemory32(0x00000003,0xFFFFEA00,"Memory");
+//* *(AT91C_SDRAM+0x24) = 0xcafedede; // Perform LMR burst=1, lat=2
+ __writeMemory32(0xCAFEDEDE,0x20000090,"Memory");
+
+//* psdrc->SDRAMC_TR = (AT91C_MASTER_CLOCK * 7)/1000000; // Set Refresh Timer 390 for 25MHz (TR= 15.6 * F )
+// // (F : system clock freq. MHz
+
+ __writeMemory32(0x000002B7,0xFFFFEA04,"Memory");
+
+//* psdrc->SDRAMC_MR = AT91C_SDRAMC_MODE_NORMAL_CMD; // Set Normal mode
+ __writeMemory32(0x00000000,0xFFFFEA00,"Memory");
+
+//* *AT91C_SDRAM = 0x00000000; // Perform Normal mode
+ __writeMemory32(0x00000000,0x20000000,"Memory");
+ __message "------------------------------- SDRAM Done at 100 MHz -------------------------------";
+
+}
+
+/*********************************************************************
+*
+* _MapRAMAt0()
+* Function description
+* Remap RAM at 0
+*/
+_MapRAMAt0()
+{
+// AT91C_MATRIX_MRCR ((AT91_REG *) 0xFFFFEF00) // (MATRIX) Master Remp Control Register
+ __mac_i=__readMemory32(0xFFFFEF00,"Memory");
+ __message "----- AT91C_MATRIX_MRCR : 0x",__mac_i:%X;
+
+ if ( ((__mac_i & 0x01) == 0) || ((__mac_i & 0x02) == 0)){
+ __message "------------------------------- The Remap is NOT & REMAP ----------------------------";
+ __writeMemory32(0x00000003,0xFFFFEF00,"Memory");
+ __mac_i=__readMemory32(0xFFFFEF00,"Memory");
+ __message "----- AT91C_MATRIX_MRCR : 0x",__mac_i:%X;
+ } else {
+ __message "------------------------------- The Remap is done -----------------------------------";
+ }
+}
+
+
+/*********************************************************************
+*
+* __PllSetting()
+* Function description
+* Initializes the PMC.
+* 1. Enable the Main Oscillator
+* 2. Configure PLL
+* 3. Switch Master
+*/
+__PllSetting()
+{
+ if ((__readMemory32(0xFFFFFC30,"Memory")&0x3) != 0 ) {
+//* Disable all PMC interrupt ( $$ JPP)
+//* AT91C_PMC_IDR ((AT91_REG *) 0xFFFFFC64) //(PMC) Interrupt Disable Register
+//* pPmc->PMC_IDR = 0xFFFFFFFF;
+ __writeMemory32(0xFFFFFFFF,0xFFFFFC64,"Memory");
+//* AT91C_PMC_PCDR ((AT91_REG *) 0xFFFFFC14) //(PMC) Peripheral Clock Disable Register
+ __writeMemory32(0xFFFFFFFF,0xFFFFFC14,"Memory");
+// Disable all clock only Processor clock is enabled.
+ __writeMemory32(0xFFFFFFFE,0xFFFFFC04,"Memory");
+
+// AT91C_PMC_MCKR ((AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register
+ __writeMemory32(0x00000001,0xFFFFFC30,"Memory");
+ __delay(10); //10000
+
+// write reset value to PLLA and PLLB
+// AT91C_PMC_PLLAR ((AT91_REG *) 0xFFFFFC28) // (PMC) PLL A Register
+ __writeMemory32(0x00003F00,0xFFFFFC28,"Memory");
+
+// AT91C_PMC_PLLBR ((AT91_REG *) 0xFFFFFC2C) // (PMC) PLL B Register
+ __writeMemory32(0x00003F00,0xFFFFFC2C,"Memory");
+ __delay(10); //10000
+
+ __message "------------------------------- PLL Enable -----------------------------------------";
+ } else {
+ __message " ********* Core in SLOW CLOCK mode ********* "; }
+}
+
+
+/*********************************************************************
+*
+* __PllSetting100MHz()
+* Function description
+* Set core at 200 MHz and MCK at 100 MHz
+*/
+__PllSetting100MHz()
+{
+
+ __message "------------------------------- PLL Set at 100 MHz ----------------------------------";
+
+//* pPmc->PMC_MOR = (( AT91C_CKGR_OSCOUNT & (0x40 <<8) | AT91C_CKGR_MOSCEN ));
+ __writeMemory32(0x00004001,0xFFFFFC20,"Memory");
+ __delay(10); //10000
+// AT91C_PMC_MCKR ((AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register
+ __writeMemory32(0x00000001,0xFFFFFC30,"Memory");
+ __delay(10); //10000
+//* AT91C_BASE_CKGR->CKGR_PLLAR = (AT91C_CKGR_SRCA | ((96 << 16) & AT91C_CKGR_MULA) |
+// (AT91C_CKGR_PLLACOUNT | (AT91C_CKGR_OUTA_0 | (9);
+ __writeMemory32(0x2060BF09,0xFFFFFC28,"Memory");
+ __delay(10); //10000
+// AT91C_BASE_PMC->PMC_PLLBR = BOARD_USBDIV| BOARD_CKGR_PLLB | BOARD_PLLBCOUNT | BOARD_MULB| BOARD_DIVB;
+ __writeMemory32(0x207C3F0C,0xFFFFFC2C,"Memory");
+ __delay(10); //10000
+//* AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_PLLA_CLK | AT91C_PMC_PRES_CLK | AT91C_PMC_MDIV_2;;
+ __writeMemory32(0x00000102,0xFFFFFC30,"Memory");
+ __delay(10); //10000
+
+}
+
diff --git a/bsp/at91sam9260/link_scripts/at91sam9260_ram.icf b/bsp/at91sam9260/link_scripts/at91sam9260_ram.icf
new file mode 100644
index 0000000000..e9659fb594
--- /dev/null
+++ b/bsp/at91sam9260/link_scripts/at91sam9260_ram.icf
@@ -0,0 +1,81 @@
+//*****************************************************************************
+//
+// blinky.icf - Linker configuration file for blinky.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the DK-TM4C129X Firmware Package.
+//
+//*****************************************************************************
+
+//
+// Define a memory region that covers the entire 4 GB addressible space of the
+// processor.
+//
+define memory mem with size = 4G;
+
+//
+// Define a region for the on-chip flash.
+//
+define region FLASH = mem:[from 0x20000000 to 0x207FFFFF];
+
+//
+// Define a region for the on-chip SRAM.
+//
+define region SRAM = mem:[from 0x20800000 to 0x23FFFFFF];
+
+//
+// Define a block for the heap. The size should be set to something other
+// than zero if things in the C library that require the heap are used.
+//
+define block HEAP with alignment = 8, size = 0x02000000 { };
+
+//
+// Indicate that the read/write values should be initialized by copying from
+// flash.
+//
+initialize by copy { readwrite };
+
+//
+// Indicate that the noinit values should be left alone. This includes the
+// stack, which if initialized will destroy the return address from the
+// initialization code, causing the processor to branch to zero and fault.
+//
+do not initialize { section .noinit };
+
+//
+// Place the interrupt vectors at the start of flash.
+//
+place at start of FLASH { readonly section .intvec };
+
+//
+// Place the remainder of the read-only items into flash.
+//
+place in FLASH { readonly };
+
+//
+// Place the RAM vector table at the start of SRAM.
+//
+place at start of SRAM { section VTABLE };
+
+//
+// Place all read/write items into SRAM.
+//
+place in SRAM { readwrite, block HEAP };
+keep { section FSymTab };
+keep { section VSymTab };
+keep { section .rti_fn* };
diff --git a/bsp/at91sam9260/at91sam9260_ram.ld b/bsp/at91sam9260/link_scripts/at91sam9260_ram.ld
index 501287d981..258881b082 100755..100644
--- a/bsp/at91sam9260/at91sam9260_ram.ld
+++ b/bsp/at91sam9260/link_scripts/at91sam9260_ram.ld
@@ -1,6 +1,6 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
-ENTRY(_start)
+ENTRY(entry)
SECTIONS
{
. = 0x20000000;
@@ -66,12 +66,11 @@ SECTIONS
. = ALIGN(4);
.nobss : { *(.nobss) }
-
- . = 0x20300000;
+
. = ALIGN(4);
- __bss_start = .;
- .bss : { *(.bss) }
- __bss_end = .;
+ __bss_start__ = .;
+ .bss : { *(.bss)}
+ __bss_end__ = .;
/* stabs debugging sections. */
.stab 0 : { *(.stab) }
diff --git a/bsp/at91sam9260/link_scripts/at91sam9260_ram.scat b/bsp/at91sam9260/link_scripts/at91sam9260_ram.scat
new file mode 100644
index 0000000000..3243902c9c
--- /dev/null
+++ b/bsp/at91sam9260/link_scripts/at91sam9260_ram.scat
@@ -0,0 +1,58 @@
+; * ----------------------------------------------------------------------------
+; * ATMEL Microcontroller Software Support
+; * ----------------------------------------------------------------------------
+; * Copyright (c) 2008, Atmel Corporation
+; *
+; * All rights reserved.
+; *
+; * Redistribution and use in source and binary forms, with or without
+; * modification, are permitted provided that the following conditions are met:
+; *
+; * - Redistributions of source code must retain the above copyright notice,
+; * this list of conditions and the disclaimer below.
+; *
+; * Atmel's name may not be used to endorse or promote products derived from
+; * this software without specific prior written permission.
+; *
+; * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+; * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+; * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+; * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+; * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+; * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+; * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+; * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+; * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+; * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+; * ----------------------------------------------------------------------------
+
+; *------------------------------------------------------------------------------
+; * Linker scatter for running in external SDRAM on the AT91SAM9260
+; *----------------------------------------------------------------------------*/
+
+Load_region 0x20000000 0x00800000
+{
+
+ Fixed_region 0x20000000
+ {
+ * (RESET +First)
+ .ANY (+RO +RW)
+ }
+ ER_ZI +0
+ {
+ * (+ZI)
+ } ; Application ZI data (.bss)
+
+ ;Relocate_region 0x200000 0x1000
+ ;{
+ ; *.o (VECTOR, +First)
+ ;}
+
+ ARM_LIB_HEAP 0x21FFE000 EMPTY 0x1000
+ {
+ }
+
+ ARM_LIB_STACK 0x22000000 EMPTY -0x1000
+ {
+ }
+}
diff --git a/bsp/at91sam9260/platform/interrupt.c b/bsp/at91sam9260/platform/interrupt.c
index 099345ef11..0d15781c61 100644
--- a/bsp/at91sam9260/platform/interrupt.c
+++ b/bsp/at91sam9260/platform/interrupt.c
@@ -24,7 +24,7 @@
#include <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)
{
diff --git a/bsp/at91sam9260/platform/interrupt.h b/bsp/at91sam9260/platform/interrupt.h
new file mode 100644
index 0000000000..36111c4a8c
--- /dev/null
+++ b/bsp/at91sam9260/platform/interrupt.h
@@ -0,0 +1,25 @@
+/*
+ * File : interrupt.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2011, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2013-07-06 Bernard first version
+ */
+
+#ifndef __INTERRUPT_H__
+#define __INTERRUPT_H__
+
+#define INT_IRQ 0x00
+#define INT_FIQ 0x01
+
+
+rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq, rt_uint32_t* id);
+void rt_hw_interrupt_ack(rt_uint32_t fiq_irq);
+
+#endif
diff --git a/bsp/at91sam9260/platform/rt_low_level_gcc.inc b/bsp/at91sam9260/platform/rt_low_level_gcc.inc
new file mode 100644
index 0000000000..f9825f5b53
--- /dev/null
+++ b/bsp/at91sam9260/platform/rt_low_level_gcc.inc
@@ -0,0 +1,33 @@
+/*
+ * File : rt_low_level_gcc.inc
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2015-04-14 ArdaFu first version
+ */
+
+/*--------- Stack size of CPU modes ------------------------------------------*/
+.equ UND_STK_SIZE, 2048
+.equ SVC_STK_SIZE, 4096
+.equ ABT_STK_SIZE, 2048
+.equ IRQ_STK_SIZE, 4096
+.equ FIQ_STK_SIZE, 4096
+.equ SYS_STK_SIZE, 2048
+/* vector table start should be 0x00000000 or 0xFFFF0000 */
+.equ VECTOR_TABLE_START, 0x00000000
diff --git a/bsp/at91sam9260/platform/rt_low_level_iar.inc b/bsp/at91sam9260/platform/rt_low_level_iar.inc
new file mode 100644
index 0000000000..e5e62b04cb
--- /dev/null
+++ b/bsp/at91sam9260/platform/rt_low_level_iar.inc
@@ -0,0 +1,33 @@
+/*
+ * File : rt_low_level_iar.inc
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2015-04-14 ArdaFu first version
+ */
+
+/*-------- Stack size of CPU modes -------------------------------------------*/
+#define UND_STK_SIZE 512
+#define SVC_STK_SIZE 4096
+#define ABT_STK_SIZE 512
+#define IRQ_STK_SIZE 1024
+#define FIQ_STK_SIZE 1024
+#define SYS_STK_SIZE 512
+/* vector table start should be 0x00000000 or 0xFFFF0000 */
+#define VECTOR_TABLE_START 0x00000000
diff --git a/bsp/at91sam9260/platform/rt_low_level_init.c b/bsp/at91sam9260/platform/rt_low_level_init.c
new file mode 100644
index 0000000000..b7bc8e0a1a
--- /dev/null
+++ b/bsp/at91sam9260/platform/rt_low_level_init.c
@@ -0,0 +1,64 @@
+/*
+ * File : rt_low_level_init.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2015-04-14 ArdaFu first version
+ */
+
+/* write register a=address, v=value */
+#define write_reg(a,v) (*(volatile unsigned int *)(a) = (v))
+/* Processor Reset */
+#define AT91_RSTC_PROCRST (1 << 0)
+#define AT91_RSTC_PERRST (1 << 2)
+#define AT91_RSTC_KEY (0xa5 << 24)
+#define AT91_MATRIX_BASE (0XFFFFEE00)
+/* 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 (AT91_AIC_BASE + 0x124)
+/* Interrupt Clear Command Register */
+#define AT91_AIC_ICCR (AT91_AIC_BASE + 0x128)
+
+#define AT91_WDT_BASE (0XFFFFFD40)
+#define AT91_WDT_CR (AT91_WDT_BASE + 0x00)
+#define AT91_WDT_CR_KEY (0xA5000000)
+#define AT91_WDT_CR_WDRSTT (0x00000001)
+#define AT91_WDT_MR (AT91_WDT_BASE + 0x04)
+#define AT91_WDT_MR_WDDIS (0x00008000)
+
+void rt_low_level_init(void)
+{
+ // Mask all IRQs by clearing all bits in the INTMRS
+ write_reg(AT91_AIC_IDCR, 0xFFFFFFFF);
+ write_reg(AT91_AIC_ICCR, 0xFFFFFFFF);
+ // Remap internal ram to 0x00000000 Address
+ write_reg(AT91_MATRIX_MRCR, AT91_MATRIX_RCB0 | AT91_MATRIX_RCB1);
+ // Disable the watchdog
+ write_reg(AT91_WDT_CR, AT91_WDT_CR_KEY|AT91_WDT_CR_WDRSTT);
+ write_reg(AT91_WDT_MR, AT91_WDT_MR_WDDIS);
+
+}
+
diff --git a/bsp/at91sam9260/platform/rt_low_level_keil.inc b/bsp/at91sam9260/platform/rt_low_level_keil.inc
new file mode 100644
index 0000000000..a78d8e85df
--- /dev/null
+++ b/bsp/at91sam9260/platform/rt_low_level_keil.inc
@@ -0,0 +1,34 @@
+;/*
+; * File : rt_low_level_keil.inc
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
+; *
+; * This program is free software; you can redistribute it and/or modify
+; * it under the terms of the GNU General Public License as published by
+; * the Free Software Foundation; either version 2 of the License, or
+; * (at your option) any later version.
+; *
+; * This program is distributed in the hope that it will be useful,
+; * but WITHOUT ANY WARRANTY; without even the implied warranty of
+; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; * GNU General Public License for more details.
+; *
+; * You should have received a copy of the GNU General Public License along
+; * with this program; if not, write to the Free Software Foundation, Inc.,
+; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+; *
+; * Change Logs:
+; * Date Author Notes
+; * 2015-04-14 ArdaFu first version
+; */
+
+;/*-------- Stack size of CPU modes ------------------------------------------*/
+UND_STK_SIZE EQU 512
+SVC_STK_SIZE EQU 4096
+ABT_STK_SIZE EQU 512
+IRQ_STK_SIZE EQU 1024
+FIQ_STK_SIZE EQU 1024
+SYS_STK_SIZE EQU 512
+;/* vector table start should be 0x00000000 or 0xFFFF0000 */
+VECTOR_TABLE_START EQU 0x00000000
+ END
diff --git a/bsp/at91sam9260/platform/start_gcc.S b/bsp/at91sam9260/platform/start_gcc.S
deleted file mode 100644
index b5c7897938..0000000000
--- a/bsp/at91sam9260/platform/start_gcc.S
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * File : start.S
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006, RT-Thread Development Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Change Logs:
- * Date Author Notes
- * 2011-01-13 weety first version
- */
-
-#define CONFIG_STACKSIZE 512
-#define S_FRAME_SIZE 72
-
-#define S_OLD_R0 68
-#define S_PSR 64
-#define S_PC 60
-#define S_LR 56
-#define S_SP 52
-
-#define S_IP 48
-#define S_FP 44
-#define S_R10 40
-#define S_R9 36
-#define S_R8 32
-#define S_R7 28
-#define S_R6 24
-#define S_R5 20
-#define S_R4 16
-#define S_R3 12
-#define S_R2 8
-#define S_R1 4
-#define S_R0 0
-
-.equ USERMODE, 0x10
-.equ FIQMODE, 0x11
-.equ IRQMODE, 0x12
-.equ SVCMODE, 0x13
-.equ ABORTMODE, 0x17
-.equ UNDEFMODE, 0x1b
-.equ MODEMASK, 0x1f
-.equ NOINT, 0xc0
-
-.equ RAM_BASE, 0x00000000 /*Start address of RAM */
-.equ ROM_BASE, 0x20000000 /*Start address of Flash */
-
-
-#define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */
-#define AT91_RSTC_PERRST (1 << 2)
-#define AT91_RSTC_KEY (0xa5 << 24)
-#define AT91_MATRIX_BASE 0xffffee00
-#define AT91_MATRIX_MRCR (AT91_MATRIX_BASE + 0x100) /* Master Remap Control Register */
-#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
-#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
-#define AT91_AIC_BASE 0xfffff000
-#define AT91_AIC_IDCR 0x124 /* Interrupt Disable Command Register */
-#define AT91_AIC_ICCR 0x128 /* Interrupt Clear Command Register */
-
-
-/*
- *************************************************************************
- *
- * Jump vector table
- *
- *************************************************************************
- */
-
-.section .init, "ax"
-.code 32
-
-.globl _start
-_start:
- b reset
- ldr pc, _vector_undef
- ldr pc, _vector_swi
- ldr pc, _vector_pabt
- ldr pc, _vector_dabt
- ldr pc, _vector_resv
- ldr pc, _vector_irq
- ldr pc, _vector_fiq
-
-_vector_undef: .word vector_undef
-_vector_swi: .word vector_swi
-_vector_pabt: .word vector_pabt
-_vector_dabt: .word vector_dabt
-_vector_resv: .word vector_resv
-_vector_irq: .word vector_irq
-_vector_fiq: .word vector_fiq
-
-.balignl 16,0xdeadbeef
-
-/*
- *************************************************************************
- *
- * Startup Code (reset vector)
- * relocate armboot to ram
- * setup stack
- * jump to second stage
- *
- *************************************************************************
- */
-
-_TEXT_BASE:
- .word TEXT_BASE
-
-/*
- * rtthread kernel start and end
- * which are defined in linker script
- */
-.globl _rtthread_start
-_rtthread_start:
- .word _start
-
-.globl _rtthread_end
-_rtthread_end:
- .word _end
-
-/*
- * rtthread bss start and end which are defined in linker script
- */
-.globl _bss_start
-_bss_start:
- .word __bss_start
-
-.globl _bss_end
-_bss_end:
- .word __bss_end
-
-/* IRQ stack memory (calculated at run-time) */
-.globl IRQ_STACK_START
-IRQ_STACK_START:
- .word _irq_stack_start + 1024
-
-.globl FIQ_STACK_START
-FIQ_STACK_START:
- .word _fiq_stack_start + 1024
-
-.globl UNDEFINED_STACK_START
-UNDEFINED_STACK_START:
- .word _undefined_stack_start + CONFIG_STACKSIZE
-
-.globl ABORT_STACK_START
-ABORT_STACK_START:
- .word _abort_stack_start + CONFIG_STACKSIZE
-
-.globl _STACK_START
-_STACK_START:
- .word _svc_stack_start + 4096
-
-/* ----------------------------------entry------------------------------*/
-reset:
-
- /* set the cpu to SVC32 mode */
- mrs r0,cpsr
- bic r0,r0,#MODEMASK
- orr r0,r0,#SVCMODE
- msr cpsr,r0
-
- /* mask all IRQs by clearing all bits in the INTMRs */
- ldr r1, =AT91_AIC_BASE
- ldr r0, =0xffffffff
- str r0, [r1, #AT91_AIC_IDCR]
- str r0, [r1, #AT91_AIC_ICCR]
-
-
- /*remap internal ram to 0x00000000 address*/
- ldr r0, =AT91_MATRIX_MRCR
- ldr r1, =(AT91_MATRIX_RCB0|AT91_MATRIX_RCB1)
- str r1, [r0]
-
- /* set interrupt vector */
- ldr r0, _TEXT_BASE
- mov r1, #0x00
- add r2, r0, #0x40 /* size, 32bytes */
-
-copy_loop:
- ldmia r0!, {r3-r10} /* copy from source address [r0] */
- stmia r1!, {r3-r10} /* copy to target address [r1] */
- cmp r0, r2 /* until source end addreee [r2] */
- ble copy_loop
-
- /* setup stack */
- bl stack_setup
-
- /* clear .bss */
- mov r0,#0 /* get a zero */
- ldr r1,=__bss_start /* bss start */
- ldr r2,=__bss_end /* bss end */
-
-bss_loop:
- cmp r1,r2 /* check if data to clear */
- strlo r0,[r1],#4 /* clear 4 bytes */
- blo bss_loop /* loop until done */
-
- /* call C++ constructors of global objects */
- ldr r0, =__ctors_start__
- ldr r1, =__ctors_end__
-
-ctor_loop:
- cmp r0, r1
- beq ctor_end
- ldr r2, [r0], #4
- stmfd sp!, {r0-r1}
- mov lr, pc
- bx r2
- ldmfd sp!, {r0-r1}
- b ctor_loop
-
-ctor_end:
-
- /* start RT-Thread Kernel */
- ldr pc, _rtthread_startup
-
-_rtthread_startup:
- .word rtthread_startup
-#if defined (__FLASH_BUILD__)
-_load_address:
- .word ROM_BASE + _TEXT_BASE
-#else
-_load_address:
- .word RAM_BASE + _TEXT_BASE
-#endif
-
-.global cpu_reset
-cpu_reset:
- ldr r0, =0xfffffd00
- ldr r1, =(AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST)
- str r1, [r0]
- mov pc, lr
-
-/*
- *************************************************************************
- *
- * Interrupt handling
- *
- *************************************************************************
- */
-
-/* exception handlers */
- .align 5
-vector_undef:
- sub sp, sp, #S_FRAME_SIZE
- stmia sp, {r0 - r12} /* Calling r0-r12 */
- add r8, sp, #S_PC
- stmdb r8, {sp, lr}^ /* Calling SP, LR */
- str lr, [r8, #0] /* Save calling PC */
- mrs r6, spsr
- str r6, [r8, #4] /* Save CPSR */
- str r0, [r8, #8] /* Save OLD_R0 */
- mov r0, sp
-
- bl rt_hw_trap_udef
-
- .align 5
-vector_swi:
- bl rt_hw_trap_swi
-
- .align 5
-vector_pabt:
- bl rt_hw_trap_pabt
-
- .align 5
-vector_dabt:
- sub sp, sp, #S_FRAME_SIZE
- stmia sp, {r0 - r12} /* Calling r0-r12 */
- add r8, sp, #S_PC
- stmdb r8, {sp, lr}^ /* Calling SP, LR */
- str lr, [r8, #0] /* Save calling PC */
- mrs r6, spsr
- str r6, [r8, #4] /* Save CPSR */
- str r0, [r8, #8] /* Save OLD_R0 */
- mov r0, sp
-
- bl rt_hw_trap_dabt
-
- .align 5
-vector_resv:
- bl rt_hw_trap_resv
-
-.globl rt_interrupt_enter
-.globl rt_interrupt_leave
-.globl rt_thread_switch_interrupt_flag
-.globl rt_interrupt_from_thread
-.globl rt_interrupt_to_thread
-vector_irq:
- stmfd sp!, {r0-r12,lr}
- bl rt_interrupt_enter
- bl rt_hw_trap_irq
- bl rt_interrupt_leave
-
- /* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */
- ldr r0, =rt_thread_switch_interrupt_flag
- ldr r1, [r0]
- cmp r1, #1
- beq _interrupt_thread_switch
-
- ldmfd sp!, {r0-r12,lr}
- subs pc, lr, #4
-
- .align 5
-vector_fiq:
- stmfd sp!,{r0-r7,lr}
- bl rt_hw_trap_fiq
- ldmfd sp!,{r0-r7,lr}
- subs pc,lr,#4
-
-_interrupt_thread_switch:
- mov r1, #0 /* clear rt_thread_switch_interrupt_flag*/
- str r1, [r0]
-
- ldmfd sp!, {r0-r12,lr} /* reload saved registers */
- stmfd sp!, {r0-r3} /* save r0-r3 */
- mov r1, sp
- add sp, sp, #16 /* restore sp */
- sub r2, lr, #4 /* save old task's pc to r2 */
-
- mrs r3, spsr /* disable interrupt */
- orr r0, r3, #NOINT
- msr spsr_c, r0
-
- ldr r0, =.+8 /* switch to interrupted task's stack*/
- movs pc, r0
-
- stmfd sp!, {r2} /* push old task's pc */
- stmfd sp!, {r4-r12,lr} /* push old task's lr,r12-r4 */
- mov r4, r1 /* Special optimised code below */
- mov r5, r3
- ldmfd r4!, {r0-r3}
- stmfd sp!, {r0-r3} /* push old task's r3-r0 */
- stmfd sp!, {r5} /* push old task's psr */
- mrs r4, spsr
- stmfd sp!, {r4} /* push old task's spsr */
-
- ldr r4, =rt_interrupt_from_thread
- ldr r5, [r4]
- str sp, [r5] /* store sp in preempted tasks's TCB*/
-
- ldr r6, =rt_interrupt_to_thread
- ldr r6, [r6]
- ldr sp, [r6] /* get new task's stack pointer */
-
- ldmfd sp!, {r4} /* pop new task's spsr */
- msr SPSR_cxsf, r4
- ldmfd sp!, {r4} /* pop new task's psr */
- msr CPSR_cxsf, r4
-
- ldmfd sp!, {r0-r12,lr,pc} /* pop new task's r0-r12,lr & pc */
-
-stack_setup:
- mrs r0, cpsr
- bic r0, r0, #MODEMASK
- orr r1, r0, #UNDEFMODE|NOINT
- msr cpsr_cxsf, r1 /* undef mode */
- ldr sp, UNDEFINED_STACK_START
-
- orr r1,r0,#ABORTMODE|NOINT
- msr cpsr_cxsf,r1 /* abort mode */
- ldr sp, ABORT_STACK_START
-
- orr r1,r0,#IRQMODE|NOINT
- msr cpsr_cxsf,r1 /* IRQ mode */
- ldr sp, IRQ_STACK_START
-
- orr r1,r0,#FIQMODE|NOINT
- msr cpsr_cxsf,r1 /* FIQ mode */
- ldr sp, FIQ_STACK_START
-
- bic r0,r0,#MODEMASK
- orr r1,r0,#SVCMODE|NOINT
- msr cpsr_cxsf,r1 /* SVC mode */
-
- ldr sp, _STACK_START
-
- /* USER mode is not initialized. */
- mov pc,lr /* The LR register may be not valid for the mode changes.*/
-
-/*/*}*/
-
-
diff --git a/bsp/at91sam9260/platform/start_rvds.S b/bsp/at91sam9260/platform/start_rvds.S
deleted file mode 100644
index 58661f9cb0..0000000000
--- a/bsp/at91sam9260/platform/start_rvds.S
+++ /dev/null
@@ -1,325 +0,0 @@
-;/*
-; * File : start_rvds.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006, RT-Thread Development Team
-; *
-; * This program is free software; you can redistribute it and/or modify
-; * it under the terms of the GNU General Public License as published by
-; * the Free Software Foundation; either version 2 of the License, or
-; * (at your option) any later version.
-; *
-; * This program is distributed in the hope that it will be useful,
-; * but WITHOUT ANY WARRANTY; without even the implied warranty of
-; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; * GNU General Public License for more details.
-; *
-; * You should have received a copy of the GNU General Public License along
-; * with this program; if not, write to the Free Software Foundation, Inc.,
-; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-; *
-; * Change Logs:
-; * Date Author Notes
-; * 2011-08-14 weety first version
-; */
-
-
-; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
-
-Mode_USR EQU 0x10
-Mode_FIQ EQU 0x11
-Mode_IRQ EQU 0x12
-Mode_SVC EQU 0x13
-Mode_ABT EQU 0x17
-Mode_UND EQU 0x1B
-Mode_SYS EQU 0x1F
-
-SVCMODE EQU 0x13
-MODEMASK EQU 0x1f
-
-I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
-F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
-
-
-;----------------------- Stack and Heap Definitions ----------------------------
-
-;// <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
-
diff --git a/bsp/at91sam9260/platform/trap.c b/bsp/at91sam9260/platform/trap.c
deleted file mode 100644
index 7fd4011451..0000000000
--- a/bsp/at91sam9260/platform/trap.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * File : trap.c
- * 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 modified from mini2440
- */
-
-#include <rtthread.h>
-#include <rthw.h>
-
-#include "at91sam926x.h"
-
-/**
- * @addtogroup AT91SAM926X
- */
-/*@{*/
-
-extern struct rt_thread *rt_current_thread;
-#ifdef RT_USING_FINSH
-extern long list_thread(void);
-#endif
-
-/**
- * this function will show registers of CPU
- *
- * @param regs the registers point
- */
-
-void rt_hw_show_register (struct rt_hw_register *regs)
-{
- rt_kprintf("Execption:\n");
- rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
- rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
- rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
- rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
- rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
- rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
-}
-
-/**
- * When ARM7TDMI comes across an instruction which it cannot handle,
- * it takes the undefined instruction trap.
- *
- * @param regs system registers
- *
- * @note never invoke this function in application
- */
-void rt_hw_trap_udef(struct rt_hw_register *regs)
-{
- rt_hw_show_register(regs);
-
- rt_kprintf("undefined instruction\n");
- rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
-
-#ifdef RT_USING_FINSH
- list_thread();
-#endif
- rt_hw_cpu_shutdown();
-}
-
-/**
- * The software interrupt instruction (SWI) is used for entering
- * Supervisor mode, usually to request a particular supervisor
- * function.
- *
- * @param regs system registers
- *
- * @note never invoke this function in application
- */
-void rt_hw_trap_swi(struct rt_hw_register *regs)
-{
- rt_hw_show_register(regs);
-
- rt_kprintf("software interrupt\n");
- rt_hw_cpu_shutdown();
-}
-
-/**
- * An abort indicates that the current memory access cannot be completed,
- * which occurs during an instruction prefetch.
- *
- * @param regs system registers
- *
- * @note never invoke this function in application
- */
-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);
-
-#ifdef RT_USING_FINSH
- list_thread();
-#endif
- rt_hw_cpu_shutdown();
-}
-
-/**
- * An abort indicates that the current memory access cannot be completed,
- * which occurs during a data access.
- *
- * @param regs system registers
- *
- * @note never invoke this function in application
- */
-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);
-
-#ifdef RT_USING_FINSH
- list_thread();
-#endif
- rt_hw_cpu_shutdown();
-}
-
-/**
- * Normally, system will never reach here
- *
- * @param regs system registers
- *
- * @note never invoke this function in application
- */
-void rt_hw_trap_resv(struct rt_hw_register *regs)
-{
- rt_kprintf("not used\n");
- rt_hw_show_register(regs);
- rt_hw_cpu_shutdown();
-}
-
-extern struct rt_irq_desc irq_desc[];
-
-void rt_hw_trap_irq()
-{
- rt_isr_handler_t isr_func;
- rt_uint32_t irqstat, irq, mask;
- 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);
- if (irqstat == 0)
- {
- rt_kprintf("No interrupt occur\n");
- at91_sys_write(AT91_AIC_EOICR, 0);
- return;
- }
-
- /* get interrupt service routine */
- isr_func = irq_desc[irq].handler;
- param = irq_desc[irq].param;
-
- /* turn to interrupt service routine */
- isr_func(irq, param);
- at91_sys_write(AT91_AIC_EOICR, 0x55555555); //EIOCR must be write any value after interrupt, or else can't response next interrupt
- irq_desc[irq].counter ++;
-}
-
-void rt_hw_trap_fiq()
-{
- rt_kprintf("fast interrupt request\n");
-}
-
-/*@}*/
diff --git a/bsp/at91sam9260/rtconfig.py b/bsp/at91sam9260/rtconfig.py
index 10870f8807..ce27048716 100755
--- a/bsp/at91sam9260/rtconfig.py
+++ b/bsp/at91sam9260/rtconfig.py
@@ -1,26 +1,23 @@
import os
-
-# toolchains options
ARCH = 'arm'
CPU = 'arm926'
-TextBase = '0x20000000'
-
+# toolchains options
CROSS_TOOL = 'gcc'
+#------- toolchains path -------------------------------------------------------
if os.getenv('RTT_CC'):
CROSS_TOOL = 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!'
- print '================================================='
- exit(0)
+ PLATFORM = 'iar'
+ IAR_PATH = 'C:/Program Files (x86)/IAR Systems/Embedded Workbench 7.0'
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
@@ -28,6 +25,12 @@ if os.getenv('RTT_EXEC_PATH'):
#BUILD = 'debug'
BUILD = 'release'
+CORE = 'arm926ej-s'
+MAP_FILE = 'rtthread_at91sam9260.map'
+LINK_FILE = 'link_scripts/at91sam9260_ram'
+TARGET_NAME = 'rtthread.bin'
+
+#------- GCC settings ----------------------------------------------------------
if PLATFORM == 'gcc':
# toolchains
PREFIX = 'arm-none-eabi-'
@@ -43,8 +46,11 @@ if PLATFORM == 'gcc':
DEVICE = ' -mcpu=arm926ej-s'
CFLAGS = DEVICE
- AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + ' -DTEXT_BASE=' + TextBase
- LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread_at91sam9260.map,-cref,-u,_start -T at91sam9260_ram.ld' + ' -Ttext ' + TextBase
+ AFLAGS = '-c'+ DEVICE + ' -x assembler-with-cpp'
+ AFLAGS += ' -Iplatform'
+ LFLAGS = DEVICE
+ LFLAGS += ' -Wl,--gc-sections,-cref,-Map=' + MAP_FILE
+ LFLAGS += ' -T ' + LINK_FILE + '.ld'
CPATH = ''
LPATH = ''
@@ -55,8 +61,9 @@ if PLATFORM == 'gcc':
else:
CFLAGS += ' -O2'
- POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
-
+ POST_ACTION = OBJCPY + ' -O binary $TARGET ' + TARGET_NAME + '\n'
+ POST_ACTION += SIZE + ' $TARGET\n'
+#------- Keil settings ---------------------------------------------------------
elif PLATFORM == 'armcc':
# toolchains
CC = 'armcc'
@@ -64,16 +71,15 @@ elif PLATFORM == 'armcc':
AR = 'armar'
LINK = 'armlink'
TARGET_EXT = 'axf'
+ EXEC_PATH += '/arm/armcc/bin/'
- DEVICE = ' --device DARMATS9'
+ DEVICE = ' --cpu=' + CORE
CFLAGS = DEVICE + ' --apcs=interwork --diag_suppress=870'
- AFLAGS = DEVICE
- LFLAGS = DEVICE + ' --strict --info sizes --info totals --info unused --info veneers --list rtthread-at91sam9260.map --ro-base 0x20000000 --entry Entry_Point --first Entry_Point'
-
- CFLAGS += ' -I"' + EXEC_PATH + '/ARM/RV31/INC"'
- LFLAGS += ' --libpath "' + EXEC_PATH + '/ARM/RV31/LIB"'
-
- EXEC_PATH += '/arm/bin40/'
+ AFLAGS = DEVICE + ' -Iplatform'
+ LFLAGS = DEVICE + ' --strict'
+ LFLAGS += ' --info sizes --info totals --info unused --info veneers'
+ LFLAGS += ' --list ' + MAP_FILE
+ LFLAGS += ' --scatter ' + LINK_FILE + '.scat'
if BUILD == 'debug':
CFLAGS += ' -g -O0'
@@ -81,4 +87,53 @@ elif PLATFORM == 'armcc':
else:
CFLAGS += ' -O2'
- POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET'
+ POST_ACTION = 'fromelf --bin $TARGET --output ' + TARGET_NAME + ' \n'
+ POST_ACTION += 'fromelf -z $TARGET\n'
+#------- IAR settings ----------------------------------------------------------
+elif PLATFORM == 'iar':
+ # toolchains
+ CC = 'iccarm'
+ AS = 'iasmarm'
+ AR = 'iarchive'
+ LINK = 'ilinkarm'
+ TARGET_EXT = 'out'
+
+ DEVICE = CORE
+
+ CFLAGS = '--cpu=' + DEVICE
+ CFLAGS += ' --diag_suppress Pa050'
+ CFLAGS += ' --no_cse'
+ CFLAGS += ' --no_unroll'
+ CFLAGS += ' --no_inline'
+ CFLAGS += ' --no_code_motion'
+ CFLAGS += ' --no_tbaa'
+ CFLAGS += ' --no_clustering'
+ CFLAGS += ' --no_scheduling'
+
+ CFLAGS += ' --endian=little'
+ CFLAGS += ' -e'
+ CFLAGS += ' --fpu=none'
+ CFLAGS += ' --dlib_config "' + IAR_PATH + '/arm/INC/c/DLib_Config_Normal.h"'
+ CFLAGS += ' --silent'
+
+ AFLAGS = '--cpu '+ DEVICE
+ AFLAGS += ' -s+'
+ AFLAGS += ' -w+'
+ AFLAGS += ' -r'
+ AFLAGS += ' --fpu none'
+ AFLAGS += ' -S'
+ AFLAGS += ' -Iplatform'
+
+ if BUILD == 'debug':
+ CFLAGS += ' --debug'
+ CFLAGS += ' -On'
+ else:
+ CFLAGS += ' -Oh'
+
+ LFLAGS = '--config ' + LINK_FILE +'.icf'
+ LFLAGS += ' --entry __iar_program_start'
+ LFLAGS += ' --map ' + MAP_FILE
+ LFLAGS += ' --silent'
+
+ EXEC_PATH = IAR_PATH + '/arm/bin/'
+ POST_ACTION = 'ielftool --silent --bin $TARGET ' + TARGET_NAME
diff --git a/libcpu/arm/arm926/context_gcc.S b/libcpu/arm/arm926/context_gcc.S
index a3f07a1860..419c5565de 100644
--- a/libcpu/arm/arm926/context_gcc.S
+++ b/libcpu/arm/arm926/context_gcc.S
@@ -1,110 +1,92 @@
-/*
- * 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
- */
-/*@{*/
+;/*
+; * 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
+#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
+ 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!, {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
-
- ldmfd sp!, {r0-r12, lr, pc} @ pop new task r0-r12, lr & pc
+ ldr sp, [r0] @; get new task stack pointer
+ ldmfd sp!, {r4} @; pop new task cpsr
+ msr spsr_cxsf, r4
+ ldmfd sp!, {r0-r12, lr, pc}^ @; pop new task r0-r12, lr & pc
/*
* void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
*/
-.globl rt_thread_switch_interrupt_flag
-.globl rt_interrupt_from_thread
-.globl rt_interrupt_to_thread
-.globl rt_hw_context_switch_interrupt
+ .globl rt_thread_switch_interrupt_flag
+ .globl rt_interrupt_from_thread
+ .globl rt_interrupt_to_thread
+ .globl rt_hw_context_switch_interrupt
rt_hw_context_switch_interrupt:
- ldr r2, =rt_thread_switch_interrupt_flag
- ldr r3, [r2]
- cmp r3, #1
- beq _reswitch
- mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1
- str r3, [r2]
- ldr r2, =rt_interrupt_from_thread @ set rt_interrupt_from_thread
- str r0, [r2]
+ LDR R2, =rt_thread_switch_interrupt_flag
+ LDR R3, [R2]
+ CMP R3, #1
+ BEQ _reswitch
+ MOV R3, #1 @; set flag to 1
+ STR R3, [R2]
+ LDR R2, =rt_interrupt_from_thread @; set rt_interrupt_from_thread
+ STR R0, [R2]
_reswitch:
- ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread
- str r1, [r2]
- mov pc, lr
+ LDR R2, =rt_interrupt_to_thread @; set rt_interrupt_to_thread
+ STR R1, [R2]
+ BX LR
diff --git a/libcpu/arm/arm926/context_iar.S b/libcpu/arm/arm926/context_iar.S
new file mode 100644
index 0000000000..14110e5220
--- /dev/null
+++ b/libcpu/arm/arm926/context_iar.S
@@ -0,0 +1,96 @@
+;/*
+; * 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
+; * 2015-04-15 ArdaFu convert from context_gcc.s
+; */
+
+#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
+ 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!, {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!, {R0-R12, LR, PC}^ ; pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ */
+ IMPORT rt_thread_switch_interrupt_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+ PUBLIC rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+ LDR R2, =rt_thread_switch_interrupt_flag
+ LDR R3, [R2]
+ CMP R3, #1
+ BEQ _reswitch
+ MOV R3, #1 ; set flag to 1
+ STR R3, [R2]
+ LDR R2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
+ STR R0, [R2]
+_reswitch:
+ LDR R2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
+ STR R1, [R2]
+ MOV PC, LR
+ END
+
diff --git a/libcpu/arm/arm926/context_rvds.S b/libcpu/arm/arm926/context_rvds.S
index 631da83372..32bd235fef 100644
--- a/libcpu/arm/arm926/context_rvds.S
+++ b/libcpu/arm/arm926/context_rvds.S
@@ -1,117 +1,105 @@
;/*
-; * 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
+ 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!, {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
-
- LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
- ENDP
+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!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc
+ endp
;/*
; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
; */
- IMPORT rt_thread_switch_interrupt_flag
- IMPORT rt_interrupt_from_thread
- IMPORT rt_interrupt_to_thread
+ import rt_thread_switch_interrupt_flag
+ import rt_interrupt_from_thread
+ import rt_interrupt_to_thread
-rt_hw_context_switch_interrupt PROC
- EXPORT rt_hw_context_switch_interrupt
- LDR r2, =rt_thread_switch_interrupt_flag
- LDR r3, [r2]
- CMP r3, #1
- BEQ _reswitch
- MOV r3, #1 ; set rt_thread_switch_interrupt_flag to 1
- STR r3, [r2]
- LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
- STR r0, [r2]
+rt_hw_context_switch_interrupt proc
+ export rt_hw_context_switch_interrupt
+ ldr r2, =rt_thread_switch_interrupt_flag
+ ldr r3, [r2]
+ cmp r3, #1
+ beq _reswitch
+ mov r3, #1 ; set flag to 1
+ str r3, [r2]
+ ldr r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
+ str r0, [r2]
_reswitch
- LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
- STR r1, [r2]
- BX lr
- ENDP
+ ldr r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
+ str r1, [r2]
+ bx lr
+ endp
- END
+ end
diff --git a/libcpu/arm/arm926/cpuport.c b/libcpu/arm/arm926/cpuport.c
index 9908471a5c..8d5c21660c 100644
--- a/libcpu/arm/arm926/cpuport.c
+++ b/libcpu/arm/arm926/cpuport.c
@@ -20,13 +20,14 @@
* Change Logs:
* Date Author Notes
* 2011-01-13 weety modified from mini2440
+ * 2015-04-15 ArdaFu Add code for IAR
*/
#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 +35,102 @@ extern void machine_shutdown(void);
#ifdef __GNUC__
rt_inline rt_uint32_t cp15_rd(void)
{
- rt_uint32_t i;
+ rt_uint32_t i;
- asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
- return i;
+ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+ return i;
}
rt_inline void cache_enable(rt_uint32_t bit)
{
- __asm__ __volatile__( \
- "mrc p15,0,r0,c1,c0,0\n\t" \
- "orr r0,r0,%0\n\t" \
- "mcr p15,0,r0,c1,c0,0" \
- : \
- :"r" (bit) \
- :"memory");
+ __asm__ __volatile__(\
+ "mrc p15,0,r0,c1,c0,0\n\t" \
+ "orr r0,r0,%0\n\t" \
+ "mcr p15,0,r0,c1,c0,0" \
+ : \
+ :"r" (bit) \
+ :"memory");
}
rt_inline void cache_disable(rt_uint32_t bit)
{
- __asm__ __volatile__( \
- "mrc p15,0,r0,c1,c0,0\n\t" \
- "bic r0,r0,%0\n\t" \
- "mcr p15,0,r0,c1,c0,0" \
- : \
- :"r" (bit) \
- :"memory");
+ __asm__ __volatile__(\
+ "mrc p15,0,r0,c1,c0,0\n\t" \
+ "bic r0,r0,%0\n\t" \
+ "mcr p15,0,r0,c1,c0,0" \
+ : \
+ :"r" (bit) \
+ :"memory");
}
#endif
#ifdef __CC_ARM
rt_inline rt_uint32_t cp15_rd(void)
{
- rt_uint32_t i;
+ rt_uint32_t i;
- __asm
- {
- mrc p15, 0, i, c1, c0, 0
- }
+ __asm
+ {
+ mrc p15, 0, i, c1, c0, 0
+ }
- return i;
+ return i;
}
rt_inline void cache_enable(rt_uint32_t bit)
{
- rt_uint32_t value;
+ rt_uint32_t value;
- __asm
- {
- mrc p15, 0, value, c1, c0, 0
- orr value, value, bit
- mcr p15, 0, value, c1, c0, 0
- }
+ __asm
+ {
+ mrc p15, 0, value, c1, c0, 0
+ orr value, value, bit
+ mcr p15, 0, value, c1, c0, 0
+ }
}
rt_inline void cache_disable(rt_uint32_t bit)
{
- rt_uint32_t value;
+ rt_uint32_t value;
- __asm
- {
- mrc p15, 0, value, c1, c0, 0
- bic value, value, bit
- mcr p15, 0, value, c1, c0, 0
- }
+ __asm
+ {
+ mrc p15, 0, value, c1, c0, 0
+ bic value, value, bit
+ mcr p15, 0, value, c1, c0, 0
+ }
+}
+#endif
+
+#ifdef __ICCARM__
+rt_inline rt_uint32_t cp15_rd(void)
+{
+ rt_uint32_t i;
+
+ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+ return i;
+}
+
+rt_inline void cache_enable(rt_uint32_t bit)
+{
+ asm volatile(\
+ "mrc p15,0,r0,c1,c0,0\n\t" \
+ "orr r0,r0,%0\n\t" \
+ "mcr p15,0,r0,c1,c0,0" \
+ : \
+ :"r" (bit) \
+ :"memory");
+}
+
+rt_inline void cache_disable(rt_uint32_t bit)
+{
+ asm volatile(\
+ "mrc p15,0,r0,c1,c0,0\n\t" \
+ "bic r0,r0,%0\n\t" \
+ "mcr p15,0,r0,c1,c0,0" \
+ : \
+ :"r" (bit) \
+ :"memory");
}
#endif
@@ -107,7 +140,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 +149,7 @@ void rt_hw_cpu_icache_enable()
*/
void rt_hw_cpu_icache_disable()
{
- cache_disable(ICACHE_MASK);
+ cache_disable(ICACHE_MASK);
}
/**
@@ -125,7 +158,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 +167,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 +176,7 @@ void rt_hw_cpu_dcache_enable()
*/
void rt_hw_cpu_dcache_disable()
{
- cache_disable(DCACHE_MASK);
+ cache_disable(DCACHE_MASK);
}
/**
@@ -152,7 +185,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 +194,13 @@ rt_base_t rt_hw_cpu_dcache_status()
*/
void rt_hw_cpu_reset()
{
-
- rt_kprintf("Restarting system...\n");
- machine_reset();
- while(1); /* loop forever and wait for reset to happen */
+ rt_kprintf("Restarting system...\n");
+ machine_reset();
+
+ while(1); /* loop forever and wait for reset to happen */
- /* NEVER REACHED */
+ /* NEVER REACHED */
}
/**
@@ -176,67 +209,67 @@ void rt_hw_cpu_reset()
*/
void rt_hw_cpu_shutdown()
{
- rt_uint32_t level;
- rt_kprintf("shutdown...\n");
+ rt_uint32_t level;
+ rt_kprintf("shutdown...\n");
- level = rt_hw_interrupt_disable();
- machine_shutdown();
- while (level)
- {
- RT_ASSERT(0);
- }
+ level = rt_hw_interrupt_disable();
+ machine_shutdown();
+ while (level)
+ {
+ RT_ASSERT(0);
+ }
}
#ifdef RT_USING_CPU_FFS
/**
- * This function finds the first bit set (beginning with the least significant bit)
+ * This function finds the first bit set (beginning with the least significant bit)
* in value and return the index of that bit.
*
- * Bits are numbered starting at 1 (the least significant bit). A return value of
+ * Bits are numbered starting at 1 (the least significant bit). A return value of
* zero from any of these functions means that the argument was zero.
- *
- * @return return the index of the first bit set. If value is 0, then this function
+ *
+ * @return return the index of the first bit set. If value is 0, then this function
* shall return 0.
*/
#if defined(__CC_ARM)
int __rt_ffs(int value)
{
- register rt_uint32_t x;
+ register rt_uint32_t x;
+
+ if (value == 0)
+ return value;
- if (value == 0)
- return value;
-
- __asm
- {
- rsb x, value, #0
- and x, x, value
- clz x, x
- rsb x, x, #32
- }
+ __asm
+ {
+ rsb x, value, #0
+ and x, x, value
+ clz x, x
+ rsb x, x, #32
+ }
- return x;
+ return x;
}
-#elif defined(__IAR_SYSTEMS_ICC__)
+#elif defined(__ICCARM__)
int __rt_ffs(int value)
{
- if (value == 0)
- return value;
+ if (value == 0)
+ return value;
- __ASM("RSB r4, r0, #0");
- __ASM("AND r4, r4, r0");
- __ASM("CLZ r4, r4");
- __ASM("RSB r0, r4, #32");
+ __ASM("RSB r4, r0, #0");
+ __ASM("AND r4, r4, r0");
+ __ASM("CLZ r4, r4");
+ __ASM("RSB r0, r4, #32");
}
#elif defined(__GNUC__)
int __rt_ffs(int value)
{
- if (value == 0)
- return value;
+ if (value == 0)
+ return value;
- value &= (-value);
- asm ("clz %0, %1": "=r"(value) :"r"(value));
+ value &= (-value);
+ asm ("clz %0, %1": "=r"(value) :"r"(value));
- return (32 - value);
+ return (32 - value);
}
#endif
diff --git a/libcpu/arm/arm926/mmu.c b/libcpu/arm/arm926/mmu.c
index debb88f267..b0b1d428bd 100644
--- a/libcpu/arm/arm926/mmu.c
+++ b/libcpu/arm/arm926/mmu.c
@@ -19,6 +19,7 @@
*
* Change Logs:
* Date Author Notes
+ * 2015-04-15 ArdaFu Add code for IAR
*/
#include "mmu.h"
@@ -26,22 +27,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;
+ /* 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, 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 +168,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 +246,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));
+ /* 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));
+ 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 +569,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 +577,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 +618,46 @@ void mmu_invalidate_dcache_all()
#endif
/* level1 page table */
-static volatile unsigned int _page_table[4*1024] __attribute__((aligned(16*1024)));
-void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd, rt_uint32_t paddrStart, rt_uint32_t attr)
+#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++)
+ for(i=0; i<=nSec; i++)
{
- *pTT = attr |(((paddrStart>>20)+i)<<20);
- pTT++;
+ *pTT = attr |(((paddrStart>>20)+i)<<20);
+ pTT++;
}
}
void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size)
{
- /* disable I/D cache */
- mmu_disable_dcache();
- mmu_disable_icache();
- mmu_disable();
- mmu_invalidate_tlb();
+ /* disable I/D cache */
+ mmu_disable_dcache();
+ mmu_disable_icache();
+ mmu_disable();
+ mmu_invalidate_tlb();
- /* set page table */
- for (; size > 0; size--)
- {
- mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end,
- mdesc->paddr_start, mdesc->attr);
- mdesc++;
- }
+ /* set page table */
+ for (; size > 0; size--)
+ {
+ mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end,
+ mdesc->paddr_start, mdesc->attr);
+ mdesc++;
+ }
- /* set MMU table address */
- mmu_setttbase((rt_uint32_t)_page_table);
+ /* set MMU table address */
+ mmu_setttbase((rt_uint32_t)_page_table);
/* enables MMU */
mmu_enable();
@@ -476,4 +671,3 @@ void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size)
mmu_invalidate_icache();
mmu_invalidate_dcache_all();
}
-
diff --git a/libcpu/arm/arm926/mmu.h b/libcpu/arm/arm926/mmu.h
index d6c497efb9..34fc8f0824 100644
--- a/libcpu/arm/arm926/mmu.h
+++ b/libcpu/arm/arm926/mmu.h
@@ -26,38 +26,38 @@
#include <rtthread.h>
-#define CACHE_LINE_SIZE 32
+#define CACHE_LINE_SIZE 32
-#define DESC_SEC (0x2|(1<<4))
-#define CB (3<<2) //cache_on, write_back
-#define CNB (2<<2) //cache_on, write_through
-#define NCB (1<<2) //cache_off,WR_BUF on
-#define NCNB (0<<2) //cache_off,WR_BUF off
-#define AP_RW (3<<10) //supervisor=RW, user=RW
-#define AP_RO (2<<10) //supervisor=RW, user=RO
+#define DESC_SEC (0x2|(1<<4))
+#define CB (3<<2) //cache_on, write_back
+#define CNB (2<<2) //cache_on, write_through
+#define NCB (1<<2) //cache_off,WR_BUF on
+#define NCNB (0<<2) //cache_off,WR_BUF off
+#define AP_RW (3<<10) //supervisor=RW, user=RW
+#define AP_RO (2<<10) //supervisor=RW, user=RO
-#define DOMAIN_FAULT (0x0)
-#define DOMAIN_CHK (0x1)
-#define DOMAIN_NOTCHK (0x3)
-#define DOMAIN0 (0x0<<5)
-#define DOMAIN1 (0x1<<5)
+#define DOMAIN_FAULT (0x0)
+#define DOMAIN_CHK (0x1)
+#define DOMAIN_NOTCHK (0x3)
+#define DOMAIN0 (0x0<<5)
+#define DOMAIN1 (0x1<<5)
-#define DOMAIN0_ATTR (DOMAIN_CHK<<0)
-#define DOMAIN1_ATTR (DOMAIN_FAULT<<2)
+#define DOMAIN0_ATTR (DOMAIN_CHK<<0)
+#define DOMAIN1_ATTR (DOMAIN_FAULT<<2)
-#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) /* Read/Write, cache, write back */
-#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) /* Read/Write, cache, write through */
-#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */
-#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */
+#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) /* Read/Write, cache, write back */
+#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) /* Read/Write, cache, write through */
+#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */
+#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */
-struct mem_desc {
- rt_uint32_t vaddr_start;
- rt_uint32_t vaddr_end;
- rt_uint32_t paddr_start;
- rt_uint32_t attr;
+struct mem_desc
+{
+ 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);
#endif
-
diff --git a/libcpu/arm/arm926/stack.c b/libcpu/arm/arm926/stack.c
index f58b43cbd4..53508e5acf 100644
--- a/libcpu/arm/arm926/stack.c
+++ b/libcpu/arm/arm926/stack.c
@@ -26,50 +26,52 @@
/*****************************/
/* 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
*
* @param tentry the entry of thread
- * @param parameter the parameter of entry
+ * @param parameter the parameter of entry
* @param stack_addr the beginning stack address
* @param texit the function will be called when thread exit
*
* @return stack address
*/
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
- rt_uint8_t *stack_addr, void *texit)
+ rt_uint8_t *stack_addr, void *texit)
{
- rt_uint32_t *stk;
+ 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 */
+ /* cpsr */
+ if ((rt_uint32_t)tentry & 0x01)
+ *(--stk) = SVCMODE | 0x20; /* thumb mode */
+ else
+ *(--stk) = SVCMODE; /* arm mode */
- /* return task's current stack address */
- return (rt_uint8_t *)stk;
+ /* return task's current stack address */
+ return (rt_uint8_t *)stk;
}
-
diff --git a/libcpu/arm/arm926/start_gcc.S b/libcpu/arm/arm926/start_gcc.S
new file mode 100644
index 0000000000..f2cceeb8f9
--- /dev/null
+++ b/libcpu/arm/arm926/start_gcc.S
@@ -0,0 +1,319 @@
+/*
+ * File : start_gcc.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2011-01-13 weety first version
+ * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP
+ */
+
+#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 and Heap Definitions ---------------------------
+ .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, =VECTOR_TABLE_START @; 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-R2} @; Save R0-R2
+ SUB R1, SP, #4*3 @; Save old task's SP to R1
+ SUB R2, LR, #4 @; Save old task's PC to R2
+
+ MRS R0, SPSR @; Get CPSR of interrupt thread
+
+ MSR CPSR_c, #MODE_SVC|NOINT @; Switch to SVC mode and no interrupt
+
+ STMFD SP!, {R2} @; Push old task's PC
+ STMFD SP!, {R3-R12,LR} @; Push old task's LR,R12-R3
+ LDMFD R1, {R1-R3}
+ STMFD SP!, {R1-R3} @; Push old task's R2-R0
+ STMFD SP!, {R0} @; Push old task's CPSR
+
+ LDR R4, =rt_interrupt_from_thread
+ LDR R5, [R4] @; R5 = stack ptr in old tasks's TCB
+ 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!, {R0-R12,LR,PC}^ @; pop new task's R0-R12,LR & PC SPSR 2 CPSR
diff --git a/libcpu/arm/arm926/start_iar.S b/libcpu/arm/arm926/start_iar.S
new file mode 100644
index 0000000000..187ae35bbf
--- /dev/null
+++ b/libcpu/arm/arm926/start_iar.S
@@ -0,0 +1,291 @@
+;/*
+; * 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
+; * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP
+; */
+
+#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"
+
+;----------------------- Stack and Heap Definitions ----------------------------
+ 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, =VECTOR_TABLE_START ; 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-R2} ; Save R0-R2
+ SUB R1, SP, #4*3 ; Save old task's SP to R1
+ SUB R2, LR, #4 ; Save old task's PC to R2
+
+ MRS R0, SPSR ; Get CPSR of interrupt thread
+
+ MSR CPSR_c, #MODE_SVC|NOINT ; Switch to SVC mode and no interrupt
+
+ STMFD SP!, {R2} ; Push old task's PC
+ STMFD SP!, {R3-R12,LR} ; Push old task's LR,R12-R3
+ LDMFD R1, {R1-R3}
+ STMFD SP!, {R1-R3} ; Push old task's R2-R0
+ STMFD SP!, {R0} ; Push old task's CPSR
+
+ LDR R4, =rt_interrupt_from_thread
+ LDR R5, [R4] ; R5 = stack ptr in old tasks's TCB
+ 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!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC SPSR to CPSR
+ END
diff --git a/libcpu/arm/arm926/start_rvds.S b/libcpu/arm/arm926/start_rvds.S
new file mode 100644
index 0000000000..edf2fcb96e
--- /dev/null
+++ b/libcpu/arm/arm926/start_rvds.S
@@ -0,0 +1,323 @@
+;/*
+; * 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
+; * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP
+; */
+
+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
+
+ GET rt_low_level_keil.inc
+
+;----------------------- Stack and Heap Definitions ----------------------------
+ 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
+
+ PRESERVE8
+;--------------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, =VECTOR_TABLE_START ; 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-R2} ; Save R0-R2
+ SUB R1, SP, #4*3 ; Save old task's SP to R1
+ SUB R2, LR, #4 ; Save old task's PC to R2
+
+ MRS R0, SPSR ; Get CPSR of interrupt thread
+
+ MSR CPSR_c, #MODE_SVC:OR:NOINT ; Switch to SVC mode and no interrupt
+
+ STMFD SP!, {R2} ; Push old task's PC
+ STMFD SP!, {R3-R12,LR} ; Push old task's LR,R12-R3
+ LDMFD R1, {R1-R3}
+ STMFD SP!, {R1-R3} ; Push old task's R2-R0
+ STMFD SP!, {R0} ; Push old task's CPSR
+
+ LDR R4, =rt_interrupt_from_thread
+ LDR R5, [R4] ; R5 = stack ptr in old tasks's TCB
+ 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!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC SPSR to CPSR
+ ENDP
+
+ IF :DEF:__MICROLIB
+
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+ ; User Initial Stack & Heap
+ AREA |.text|, CODE, READONLY
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+__user_initial_stackheap
+ LDR R0, = Heap_Mem
+ LDR R1, = (Stack_Mem + SYS_STK_SIZE)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+ ENDIF
+ END
diff --git a/libcpu/arm/arm926/trap.c b/libcpu/arm/arm926/trap.c
new file mode 100644
index 0000000000..77816a2aa6
--- /dev/null
+++ b/libcpu/arm/arm926/trap.c
@@ -0,0 +1,230 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2011-01-13 weety modified from mini2440
+ * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+#include <interrupt.h>
+
+
+extern struct rt_thread *rt_current_thread;
+#ifdef RT_USING_FINSH
+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
+ *
+ * @param regs the registers point
+ */
+
+void rt_hw_show_register (struct rt_hw_register *regs)
+{
+ rt_kprintf("Execption:\n");
+ rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n",
+ regs->r0, regs->r1, regs->r2, regs->r3);
+ rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n",
+ regs->r4, regs->r5, regs->r6, regs->r7);
+ rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n",
+ regs->r8, regs->r9, regs->r10);
+ rt_kprintf("fp :0x%08x ip :0x%08x\n",
+ regs->fp, regs->ip);
+ rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n",
+ regs->sp, regs->lr, regs->pc);
+ rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
+}
+
+/**
+ * When ARM7TDMI comes across an instruction which it cannot handle,
+ * it takes the undefined instruction trap.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_udef(struct rt_hw_register *regs)
+{
+ rt_hw_show_register(regs);
+
+ rt_kprintf("undefined instruction\n");
+ rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+ list_thread();
+#endif
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * The software interrupt instruction (SWI) is used for entering
+ * Supervisor mode, usually to request a particular supervisor
+ * function.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_swi(struct rt_hw_register *regs)
+{
+ rt_hw_show_register(regs);
+
+ rt_kprintf("software interrupt\n");
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during an instruction prefetch.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+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_NAME_MAX, rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+ list_thread();
+#endif
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during a data access.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+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_NAME_MAX, rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+ list_thread();
+#endif
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * Normally, system will never reach here
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_resv(struct rt_hw_register *regs)
+{
+ rt_kprintf("not used\n");
+ rt_hw_show_register(regs);
+ rt_hw_cpu_shutdown();
+}
+
+
+
+void rt_hw_trap_irq()
+{
+ rt_isr_handler_t isr_func;
+ rt_uint32_t irqstat;
+ rt_uint32_t irq;
+ void *param;
+ extern struct rt_irq_desc irq_desc[];
+
+ /* get irq number */
+ irqstat = rt_hw_interrupt_get_active(INT_IRQ, &irq);
+ if (irqstat == 0)
+ {
+ rt_kprintf("No interrupt occur\n");
+ rt_hw_interrupt_ack(INT_IRQ);
+ return;
+ }
+
+ /* get interrupt service routine */
+ isr_func = irq_desc[irq].handler;
+ param = irq_desc[irq].param;
+
+ /* turn to interrupt service routine */
+ isr_func(irq, param);
+
+ rt_hw_interrupt_ack(INT_IRQ);
+ irq_desc[irq].counter ++;
+}
+
+void rt_hw_trap_fiq()
+{
+ rt_isr_handler_t isr_func;
+ rt_uint32_t irqstat;
+ rt_uint32_t irq;
+ void *param;
+ extern struct rt_irq_desc irq_desc[];
+
+ /* get irq number */
+ irqstat = rt_hw_interrupt_get_active(INT_FIQ, &irq);
+ if (irqstat == 0)
+ {
+ rt_kprintf("No interrupt occur\n");
+ rt_hw_interrupt_ack(INT_FIQ);
+ return;
+ }
+
+ /* get interrupt service routine */
+ isr_func = irq_desc[irq].handler;
+ param = irq_desc[irq].param;
+
+ /* turn to interrupt service routine */
+ isr_func(irq, param);
+
+ rt_hw_interrupt_ack(INT_FIQ);
+ irq_desc[irq].counter ++;
+}