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 old mode 100755 new mode 100644 similarity index 95% rename from bsp/at91sam9260/at91sam9260_ram.ld rename to bsp/at91sam9260/link_scripts/at91sam9260_ram.ld index 501287d981..258881b082 --- 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 #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 ---------------------------- - -;// Stack Configuration (Stack Sizes in Bytes) -;// Undefined Mode <0x0-0xFFFFFFFF:8> -;// Supervisor Mode <0x0-0xFFFFFFFF:8> -;// Abort Mode <0x0-0xFFFFFFFF:8> -;// Fast Interrupt Mode <0x0-0xFFFFFFFF:8> -;// Interrupt Mode <0x0-0xFFFFFFFF:8> -;// User/System Mode <0x0-0xFFFFFFFF:8> -;// - -UND_Stack_Size EQU 512 -SVC_Stack_Size EQU 4096 -ABT_Stack_Size EQU 512 -FIQ_Stack_Size EQU 1024 -IRQ_Stack_Size EQU 1024 -USR_Stack_Size EQU 512 - -ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ - FIQ_Stack_Size + IRQ_Stack_Size) - - AREA STACK, NOINIT, READWRITE, ALIGN=3 - -Stack_Mem SPACE USR_Stack_Size -__initial_sp SPACE ISR_Stack_Size -Stack_Top - - -;// Heap Configuration -;// Heap Size (in Bytes) <0x0-0xFFFFFFFF> -;// - -Heap_Size EQU 0x00000000 - - AREA HEAP, NOINIT, READWRITE, ALIGN=3 -__heap_base -Heap_Mem SPACE Heap_Size -__heap_limit - - -;----------------------- Memory Definitions ------------------------------------ - -AT91_MATRIX_BASE EQU 0xffffee00 -AT91_MATRIX_MRCR EQU (AT91_MATRIX_BASE + 0x100) -AT91_MATRIX_RCB0 EQU 0x00000001 -AT91_MATRIX_RCB1 EQU 0x00000002 -AT91_AIC_BASE EQU 0xfffff000 -AT91_AIC_IDCR EQU 0x124 -AT91_AIC_ICCR EQU 0x128 - -;----------------------- CODE -------------------------------------------------- - - PRESERVE8 - - -; Area Definition and Entry Point -; Startup Code must be linked first at Address at which it expects to run. - - AREA RESET, CODE, READONLY - ARM - -; Exception Vectors -; Mapped to Address 0. -; Absolute addressing mode must be used. -; Dummy Handlers are implemented as infinite loops which can be modified. - - EXPORT Entry_Point -Entry_Point -Vectors LDR PC, Reset_Addr - LDR PC, Undef_Addr - LDR PC, SWI_Addr - LDR PC, PAbt_Addr - LDR PC, DAbt_Addr - NOP - LDR PC, IRQ_Addr - LDR PC, FIQ_Addr - -Reset_Addr DCD Reset_Handler -Undef_Addr DCD Undef_Handler -SWI_Addr DCD SWI_Handler -PAbt_Addr DCD PAbt_Handler -DAbt_Addr DCD DAbt_Handler - DCD 0 ; Reserved Address -IRQ_Addr DCD IRQ_Handler -FIQ_Addr DCD FIQ_Handler - -Undef_Handler B Undef_Handler -SWI_Handler B SWI_Handler -PAbt_Handler B PAbt_Handler -;DAbt_Handler B DAbt_Handler -FIQ_Handler B FIQ_Handler - -;* -;************************************************************************* -;* -;* Interrupt handling -;* -;************************************************************************* -;* -; DAbt Handler -DAbt_Handler - IMPORT rt_hw_trap_dabt - - sub sp, sp, #72 - stmia sp, {r0 - r12} ;/* Calling r0-r12 */ - add r8, sp, #60 - stmdb r8, {sp, lr} ;/* Calling SP, LR */ - str lr, [r8, #0] ;/* Save calling PC */ - mrs r6, spsr - str r6, [r8, #4] ;/* Save CPSR */ - str r0, [r8, #8] ;/* Save OLD_R0 */ - mov r0, sp - - bl rt_hw_trap_dabt - - -;########################################## -; Reset Handler - - EXPORT Reset_Handler -Reset_Handler - - -; set the cpu to SVC32 mode----------------------------------------------------- - - MRS R0,CPSR - BIC R0,R0,#MODEMASK - ORR R0,R0,#SVCMODE - MSR CPSR_cxsf,R0 - LDR R1, =AT91_AIC_BASE - LDR R0, =0xffffffff - STR R0, [R1, #AT91_AIC_IDCR] - STR R0, [R1, #AT91_AIC_ICCR] - -; remap internal ram to 0x00000000 address - LDR R0, =AT91_MATRIX_MRCR - LDR R1, =(AT91_MATRIX_RCB0|AT91_MATRIX_RCB1) - STR R1, [R0] - - -; Copy Exception Vectors to Internal RAM --------------------------------------- - - ADR R8, Vectors ; Source - LDR R9, =0x00 ; Destination - LDMIA R8!, {R0-R7} ; Load Vectors - STMIA R9!, {R0-R7} ; Store Vectors - LDMIA R8!, {R0-R7} ; Load Handler Addresses - STMIA R9!, {R0-R7} ; Store Handler Addresses - - -; Setup Stack for each mode ---------------------------------------------------- - - LDR R0, =Stack_Top - -; Enter Undefined Instruction Mode and set its Stack Pointer - MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit - MOV SP, R0 - SUB R0, R0, #UND_Stack_Size - -; Enter Abort Mode and set its Stack Pointer - MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit - MOV SP, R0 - SUB R0, R0, #ABT_Stack_Size - -; Enter FIQ Mode and set its Stack Pointer - MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit - MOV SP, R0 - SUB R0, R0, #FIQ_Stack_Size - -; Enter IRQ Mode and set its Stack Pointer - MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit - MOV SP, R0 - SUB R0, R0, #IRQ_Stack_Size - -; Enter Supervisor Mode and set its Stack Pointer - MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit - MOV SP, R0 - SUB R0, R0, #SVC_Stack_Size - -; Enter User Mode and set its Stack Pointer - ; MSR CPSR_c, #Mode_USR - MOV SP, R0 - SUB SL, SP, #USR_Stack_Size - -; Enter the C code ------------------------------------------------------------- - - IMPORT __main - LDR R0, =__main - BX R0 - - IMPORT rt_interrupt_enter - IMPORT rt_interrupt_leave - IMPORT rt_thread_switch_interrupt_flag - IMPORT rt_interrupt_from_thread - IMPORT rt_interrupt_to_thread - IMPORT rt_hw_trap_irq - -IRQ_Handler PROC - EXPORT IRQ_Handler - STMFD sp!, {r0-r12,lr} - BL rt_interrupt_enter - BL rt_hw_trap_irq - BL rt_interrupt_leave - - ; if rt_thread_switch_interrupt_flag set, jump to - ; rt_hw_context_switch_interrupt_do and don't return - LDR r0, =rt_thread_switch_interrupt_flag - LDR r1, [r0] - CMP r1, #1 - BEQ rt_hw_context_switch_interrupt_do - - LDMFD sp!, {r0-r12,lr} - SUBS pc, lr, #4 - ENDP - -; /* -; * void rt_hw_context_switch_interrupt_do(rt_base_t flag) -; */ -rt_hw_context_switch_interrupt_do PROC - EXPORT rt_hw_context_switch_interrupt_do - MOV r1, #0 ; clear flag - STR r1, [r0] - - LDMFD sp!, {r0-r12,lr}; reload saved registers - STMFD sp!, {r0-r3} ; save r0-r3 - MOV r1, sp - ADD sp, sp, #16 ; restore sp - SUB r2, lr, #4 ; save old task's pc to r2 - - MRS r3, spsr ; get cpsr of interrupt thread - - ; switch to SVC mode and no interrupt - MSR cpsr_c, #I_Bit:OR:F_Bit:OR:Mode_SVC - - STMFD sp!, {r2} ; push old task's pc - STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4 - MOV r4, r1 ; Special optimised code below - MOV r5, r3 - LDMFD r4!, {r0-r3} - STMFD sp!, {r0-r3} ; push old task's r3-r0 - STMFD sp!, {r5} ; push old task's cpsr - MRS r4, spsr - STMFD sp!, {r4} ; push old task's spsr - - LDR r4, =rt_interrupt_from_thread - LDR r5, [r4] - STR sp, [r5] ; store sp in preempted tasks's TCB - - LDR r6, =rt_interrupt_to_thread - LDR r6, [r6] - LDR sp, [r6] ; get new task's stack pointer - - LDMFD sp!, {r4} ; pop new task's spsr - MSR spsr_cxsf, r4 - LDMFD sp!, {r4} ; pop new task's psr - MSR cpsr_cxsf, r4 - - LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc - ENDP - - IF :DEF:__MICROLIB - - EXPORT __heap_base - EXPORT __heap_limit - - ELSE -; User Initial Stack & Heap - AREA |.text|, CODE, READONLY - - IMPORT __use_two_region_memory - EXPORT __user_initial_stackheap -__user_initial_stackheap - - LDR R0, = Heap_Mem - LDR R1, =(Stack_Mem + USR_Stack_Size) - LDR R2, = (Heap_Mem + Heap_Size) - LDR R3, = Stack_Mem - BX LR - ENDIF - - - END - diff --git a/bsp/at91sam9260/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 -#include - -#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 - */ +;/* +; * File : context_iar.S +; * This file is part of RT-Thread RTOS +; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * +; * This program is free software; you can redistribute it and/or modify +; * it under the terms of the GNU General Public License as published by +; * the Free Software Foundation; either version 2 of the License, or +; * (at your option) any later version. +; * +; * This program is distributed in the hope that it will be useful, +; * but WITHOUT ANY WARRANTY; without even the implied warranty of +; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; * GNU General Public License for more details. +; * +; * You should have received a copy of the GNU General Public License along +; * with this program; if not, write to the Free Software Foundation, Inc., +; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +; * +; * Change Logs: +; * Date Author Notes +; * 2011-08-14 weety copy from mini2440 +; */ -/*! - * \addtogroup AT91SAM926X - */ -/*@{*/ +#define NOINT 0xC0 -#define NOINT 0xc0 - - -/* - * rt_base_t rt_hw_interrupt_disable(); - */ -.globl rt_hw_interrupt_disable +;/* +; * rt_base_t rt_hw_interrupt_disable(); +; */ + .globl rt_hw_interrupt_disable rt_hw_interrupt_disable: - mrs r0, cpsr - orr r1, r0, #NOINT - msr cpsr_c, r1 - mov pc, lr + MRS R0, CPSR + ORR R1, R0, #NOINT + MSR CPSR_c, R1 + BX LR /* * void rt_hw_interrupt_enable(rt_base_t level); */ -.globl rt_hw_interrupt_enable + .globl rt_hw_interrupt_enable rt_hw_interrupt_enable: - msr cpsr, r0 - mov pc, lr + MSR CPSR, R0 + BX LR /* * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); * r0 --> from * r1 --> to */ -.globl rt_hw_context_switch + .globl rt_hw_context_switch rt_hw_context_switch: - stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) - stmfd sp!, {r0-r12, lr} @ push lr & register file - - mrs r4, cpsr - stmfd sp!, {r4} @ push cpsr - mrs r4, spsr - stmfd sp!, {r4} @ push spsr - - str sp, [r0] @ store sp in preempted tasks TCB - ldr sp, [r1] @ get new task stack pointer - - ldmfd sp!, {r4} @ pop new task spsr - msr spsr_cxsf, r4 - ldmfd sp!, {r4} @ pop new task cpsr - msr spsr_cxsf, r4 - - ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc + stmfd sp!, {lr} @; push pc (lr should be pushed in place of pc) + stmfd sp!, {r0-r12, lr} @; push lr & register file + mrs r4, cpsr + stmfd sp!, {r4} @; push cpsr + 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 #include -#define ICACHE_MASK (rt_uint32_t)(1 << 12) -#define DCACHE_MASK (rt_uint32_t)(1 << 2) +#define ICACHE_MASK (rt_uint32_t)(1 << 12) +#define DCACHE_MASK (rt_uint32_t)(1 << 2) extern void machine_reset(void); extern void machine_shutdown(void); @@ -34,70 +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(); - /* NEVER REACHED */ + while(1); /* loop forever and wait for reset to happen */ + + /* 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; - - __asm - { - rsb x, value, #0 - and x, x, value - clz x, x - rsb x, x, #32 - } + if (value == 0) + return value; - return x; + __asm + { + rsb x, value, #0 + and x, x, value + clz x, x + rsb x, x, #32 + } + + 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,133 @@ void mmu_invalidate_dcache_all() #elif defined(__GNUC__) void mmu_setttbase(register rt_uint32_t i) { - register rt_uint32_t value; + register rt_uint32_t value; - /* Invalidates all TLBs.Domain access is selected as - * client by configuring domain access register, - * in that case access controlled by permission value - * set by page table entry - */ - value = 0; - asm ("mcr p15, 0, %0, c8, c7, 0"::"r"(value)); + /* 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 +383,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 +391,224 @@ void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size) void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size) { - unsigned int ptr; + unsigned int ptr; - ptr = buffer & ~(CACHE_LINE_SIZE - 1); + ptr = buffer & ~(CACHE_LINE_SIZE - 1); - while (ptr < buffer + size) - { - asm ("mcr p15, 0, %0, c7, c10, 1": :"r" (ptr)); - ptr += CACHE_LINE_SIZE; - } + while (ptr < buffer + size) + { + asm ("mcr p15, 0, %0, c7, c10, 1": :"r" (ptr)); + ptr += CACHE_LINE_SIZE; + } } void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size) { - unsigned int ptr; + unsigned int ptr; - ptr = buffer & ~(CACHE_LINE_SIZE - 1); + ptr = buffer & ~(CACHE_LINE_SIZE - 1); - while (ptr < buffer + size) - { - asm ("mcr p15, 0, %0, c7, c6, 1": :"r" (ptr)); - ptr += CACHE_LINE_SIZE; - } + while (ptr < buffer + size) + { + asm ("mcr p15, 0, %0, c7, c6, 1": :"r" (ptr)); + ptr += CACHE_LINE_SIZE; + } } void mmu_invalidate_tlb() { - asm ("mcr p15, 0, %0, c8, c7, 0": :"r" (0)); + asm ("mcr p15, 0, %0, c8, c7, 0": :"r" (0)); } void mmu_invalidate_icache() { - asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0)); + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0)); +} + +void mmu_invalidate_dcache_all() +{ + asm ("mcr p15, 0, %0, c7, c6, 0": :"r" (0)); +} +#elif defined(__ICCARM__) +void mmu_setttbase(register rt_uint32_t i) +{ + register rt_uint32_t value; + + /* Invalidates all TLBs.Domain access is selected as + * client by configuring domain access register, + * in that case access controlled by permission value + * set by page table entry + */ + value = 0; + asm ("mcr p15, 0, %0, c8, c7, 0"::"r"(value)); + + value = 0x55555555; + asm ("mcr p15, 0, %0, c3, c0, 0"::"r"(value)); + asm ("mcr p15, 0, %0, c2, c0, 0"::"r"(i)); +} + +void mmu_set_domain(register rt_uint32_t i) +{ + asm ("mcr p15,0, %0, c3, c0, 0": :"r" (i)); +} + +void mmu_enable() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= 0x1; + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disable() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~0x1; + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_enable_icache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= (1 << 12); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_enable_dcache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= (1 << 2); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disable_icache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~(1 << 12); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disable_dcache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~(1 << 2); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_enable_alignfault() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= (1 << 1); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disable_alignfault() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~(1 << 1); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_clean_invalidated_cache_index(int index) +{ + asm ("mcr p15, 0, %0, c7, c14, 2": :"r" (index)); +} + +void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size) +{ + unsigned int ptr; + + ptr = buffer & ~(CACHE_LINE_SIZE - 1); + + while(ptr < buffer + size) + { + asm ("mcr p15, 0, %0, c7, c14, 1": :"r" (ptr)); + ptr += CACHE_LINE_SIZE; + } +} + + +void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size) +{ + unsigned int ptr; + + ptr = buffer & ~(CACHE_LINE_SIZE - 1); + + while (ptr < buffer + size) + { + asm ("mcr p15, 0, %0, c7, c10, 1": :"r" (ptr)); + ptr += CACHE_LINE_SIZE; + } +} + +void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size) +{ + unsigned int ptr; + + ptr = buffer & ~(CACHE_LINE_SIZE - 1); + + while (ptr < buffer + size) + { + asm ("mcr p15, 0, %0, c7, c6, 1": :"r" (ptr)); + ptr += CACHE_LINE_SIZE; + } +} + +void mmu_invalidate_tlb() +{ + asm ("mcr p15, 0, %0, c8, c7, 0": :"r" (0)); +} + +void mmu_invalidate_icache() +{ + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0)); } void mmu_invalidate_dcache_all() @@ -431,38 +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 -#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 +#include +#include + + +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 ++; +}