Merge pull request #460 from ArdaFu/master
[cpu] Split ARM926 cpu code from SAM9260 BSP
This commit is contained in:
commit
97a8426ce0
|
@ -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*/
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
@ -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* };
|
11
bsp/at91sam9260/at91sam9260_ram.ld → bsp/at91sam9260/link_scripts/at91sam9260_ram.ld
Executable file → Normal file
11
bsp/at91sam9260/at91sam9260_ram.ld → bsp/at91sam9260/link_scripts/at91sam9260_ram.ld
Executable file → Normal file
|
@ -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) }
|
|
@ -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
|
||||
{
|
||||
}
|
||||
}
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include <rthw.h>
|
||||
#include "at91sam926x.h"
|
||||
|
||||
#include "interrupt.h"
|
||||
#define MAX_HANDLERS (AIC_IRQS + PIN_IRQS)
|
||||
|
||||
extern rt_uint32_t rt_interrupt_nest;
|
||||
|
@ -374,6 +374,53 @@ static int at91_aic_set_type(unsigned irq, unsigned type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq, rt_uint32_t* id)
|
||||
{
|
||||
|
||||
rt_uint32_t irqstat;
|
||||
if (fiq_irq == INT_FIQ)
|
||||
{
|
||||
*id = 0;
|
||||
}
|
||||
else //IRQ
|
||||
{
|
||||
/* get irq number */
|
||||
*id = (rt_uint32_t)at91_sys_read(AT91_AIC_IVR);
|
||||
/* clear pending register */
|
||||
irqstat = (rt_uint32_t)at91_sys_read(AT91_AIC_ISR);
|
||||
}
|
||||
|
||||
return irqstat;
|
||||
}
|
||||
|
||||
void rt_hw_interrupt_ack(rt_uint32_t fiq_irq)
|
||||
{
|
||||
if (fiq_irq == INT_FIQ)
|
||||
{
|
||||
/* new FIQ generation */
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// EIOCR must be write any value after interrupt,
|
||||
// or else can't response next interrupt
|
||||
/* new IRQ generation */
|
||||
at91_sys_write(AT91_AIC_EOICR, 0x55555555);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
void list_irq(void)
|
||||
{
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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.*/
|
||||
|
||||
/*/*}*/
|
||||
|
||||
|
|
@ -1,325 +0,0 @@
|
|||
;/*
|
||||
; * File : start_rvds.S
|
||||
; * This file is part of RT-Thread RTOS
|
||||
; * COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||
; *
|
||||
; * This program is free software; you can redistribute it and/or modify
|
||||
; * it under the terms of the GNU General Public License as published by
|
||||
; * the Free Software Foundation; either version 2 of the License, or
|
||||
; * (at your option) any later version.
|
||||
; *
|
||||
; * This program is distributed in the hope that it will be useful,
|
||||
; * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; * GNU General Public License for more details.
|
||||
; *
|
||||
; * You should have received a copy of the GNU General Public License along
|
||||
; * with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
; *
|
||||
; * Change Logs:
|
||||
; * Date Author Notes
|
||||
; * 2011-08-14 weety first version
|
||||
; */
|
||||
|
||||
|
||||
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
|
||||
|
||||
Mode_USR EQU 0x10
|
||||
Mode_FIQ EQU 0x11
|
||||
Mode_IRQ EQU 0x12
|
||||
Mode_SVC EQU 0x13
|
||||
Mode_ABT EQU 0x17
|
||||
Mode_UND EQU 0x1B
|
||||
Mode_SYS EQU 0x1F
|
||||
|
||||
SVCMODE EQU 0x13
|
||||
MODEMASK EQU 0x1f
|
||||
|
||||
I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
|
||||
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
|
||||
|
||||
|
||||
;----------------------- Stack and Heap Definitions ----------------------------
|
||||
|
||||
;// <h> Stack Configuration (Stack Sizes in Bytes)
|
||||
;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8>
|
||||
;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8>
|
||||
;// <o2> Abort Mode <0x0-0xFFFFFFFF:8>
|
||||
;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
|
||||
;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8>
|
||||
;// <o5> User/System Mode <0x0-0xFFFFFFFF:8>
|
||||
;// </h>
|
||||
|
||||
UND_Stack_Size EQU 512
|
||||
SVC_Stack_Size EQU 4096
|
||||
ABT_Stack_Size EQU 512
|
||||
FIQ_Stack_Size EQU 1024
|
||||
IRQ_Stack_Size EQU 1024
|
||||
USR_Stack_Size EQU 512
|
||||
|
||||
ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
|
||||
FIQ_Stack_Size + IRQ_Stack_Size)
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
|
||||
Stack_Mem SPACE USR_Stack_Size
|
||||
__initial_sp SPACE ISR_Stack_Size
|
||||
Stack_Top
|
||||
|
||||
|
||||
;// <h> Heap Configuration
|
||||
;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
|
||||
;// </h>
|
||||
|
||||
Heap_Size EQU 0x00000000
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
;----------------------- Memory Definitions ------------------------------------
|
||||
|
||||
AT91_MATRIX_BASE EQU 0xffffee00
|
||||
AT91_MATRIX_MRCR EQU (AT91_MATRIX_BASE + 0x100)
|
||||
AT91_MATRIX_RCB0 EQU 0x00000001
|
||||
AT91_MATRIX_RCB1 EQU 0x00000002
|
||||
AT91_AIC_BASE EQU 0xfffff000
|
||||
AT91_AIC_IDCR EQU 0x124
|
||||
AT91_AIC_ICCR EQU 0x128
|
||||
|
||||
;----------------------- CODE --------------------------------------------------
|
||||
|
||||
PRESERVE8
|
||||
|
||||
|
||||
; Area Definition and Entry Point
|
||||
; Startup Code must be linked first at Address at which it expects to run.
|
||||
|
||||
AREA RESET, CODE, READONLY
|
||||
ARM
|
||||
|
||||
; Exception Vectors
|
||||
; Mapped to Address 0.
|
||||
; Absolute addressing mode must be used.
|
||||
; Dummy Handlers are implemented as infinite loops which can be modified.
|
||||
|
||||
EXPORT Entry_Point
|
||||
Entry_Point
|
||||
Vectors LDR PC, Reset_Addr
|
||||
LDR PC, Undef_Addr
|
||||
LDR PC, SWI_Addr
|
||||
LDR PC, PAbt_Addr
|
||||
LDR PC, DAbt_Addr
|
||||
NOP
|
||||
LDR PC, IRQ_Addr
|
||||
LDR PC, FIQ_Addr
|
||||
|
||||
Reset_Addr DCD Reset_Handler
|
||||
Undef_Addr DCD Undef_Handler
|
||||
SWI_Addr DCD SWI_Handler
|
||||
PAbt_Addr DCD PAbt_Handler
|
||||
DAbt_Addr DCD DAbt_Handler
|
||||
DCD 0 ; Reserved Address
|
||||
IRQ_Addr DCD IRQ_Handler
|
||||
FIQ_Addr DCD FIQ_Handler
|
||||
|
||||
Undef_Handler B Undef_Handler
|
||||
SWI_Handler B SWI_Handler
|
||||
PAbt_Handler B PAbt_Handler
|
||||
;DAbt_Handler B DAbt_Handler
|
||||
FIQ_Handler B FIQ_Handler
|
||||
|
||||
;*
|
||||
;*************************************************************************
|
||||
;*
|
||||
;* Interrupt handling
|
||||
;*
|
||||
;*************************************************************************
|
||||
;*
|
||||
; DAbt Handler
|
||||
DAbt_Handler
|
||||
IMPORT rt_hw_trap_dabt
|
||||
|
||||
sub sp, sp, #72
|
||||
stmia sp, {r0 - r12} ;/* Calling r0-r12 */
|
||||
add r8, sp, #60
|
||||
stmdb r8, {sp, lr} ;/* Calling SP, LR */
|
||||
str lr, [r8, #0] ;/* Save calling PC */
|
||||
mrs r6, spsr
|
||||
str r6, [r8, #4] ;/* Save CPSR */
|
||||
str r0, [r8, #8] ;/* Save OLD_R0 */
|
||||
mov r0, sp
|
||||
|
||||
bl rt_hw_trap_dabt
|
||||
|
||||
|
||||
;##########################################
|
||||
; Reset Handler
|
||||
|
||||
EXPORT Reset_Handler
|
||||
Reset_Handler
|
||||
|
||||
|
||||
; set the cpu to SVC32 mode-----------------------------------------------------
|
||||
|
||||
MRS R0,CPSR
|
||||
BIC R0,R0,#MODEMASK
|
||||
ORR R0,R0,#SVCMODE
|
||||
MSR CPSR_cxsf,R0
|
||||
LDR R1, =AT91_AIC_BASE
|
||||
LDR R0, =0xffffffff
|
||||
STR R0, [R1, #AT91_AIC_IDCR]
|
||||
STR R0, [R1, #AT91_AIC_ICCR]
|
||||
|
||||
; remap internal ram to 0x00000000 address
|
||||
LDR R0, =AT91_MATRIX_MRCR
|
||||
LDR R1, =(AT91_MATRIX_RCB0|AT91_MATRIX_RCB1)
|
||||
STR R1, [R0]
|
||||
|
||||
|
||||
; Copy Exception Vectors to Internal RAM ---------------------------------------
|
||||
|
||||
ADR R8, Vectors ; Source
|
||||
LDR R9, =0x00 ; Destination
|
||||
LDMIA R8!, {R0-R7} ; Load Vectors
|
||||
STMIA R9!, {R0-R7} ; Store Vectors
|
||||
LDMIA R8!, {R0-R7} ; Load Handler Addresses
|
||||
STMIA R9!, {R0-R7} ; Store Handler Addresses
|
||||
|
||||
|
||||
; Setup Stack for each mode ----------------------------------------------------
|
||||
|
||||
LDR R0, =Stack_Top
|
||||
|
||||
; Enter Undefined Instruction Mode and set its Stack Pointer
|
||||
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
|
||||
MOV SP, R0
|
||||
SUB R0, R0, #UND_Stack_Size
|
||||
|
||||
; Enter Abort Mode and set its Stack Pointer
|
||||
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
|
||||
MOV SP, R0
|
||||
SUB R0, R0, #ABT_Stack_Size
|
||||
|
||||
; Enter FIQ Mode and set its Stack Pointer
|
||||
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
|
||||
MOV SP, R0
|
||||
SUB R0, R0, #FIQ_Stack_Size
|
||||
|
||||
; Enter IRQ Mode and set its Stack Pointer
|
||||
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
|
||||
MOV SP, R0
|
||||
SUB R0, R0, #IRQ_Stack_Size
|
||||
|
||||
; Enter Supervisor Mode and set its Stack Pointer
|
||||
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
|
||||
MOV SP, R0
|
||||
SUB R0, R0, #SVC_Stack_Size
|
||||
|
||||
; Enter User Mode and set its Stack Pointer
|
||||
; MSR CPSR_c, #Mode_USR
|
||||
MOV SP, R0
|
||||
SUB SL, SP, #USR_Stack_Size
|
||||
|
||||
; Enter the C code -------------------------------------------------------------
|
||||
|
||||
IMPORT __main
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
|
||||
IMPORT rt_interrupt_enter
|
||||
IMPORT rt_interrupt_leave
|
||||
IMPORT rt_thread_switch_interrupt_flag
|
||||
IMPORT rt_interrupt_from_thread
|
||||
IMPORT rt_interrupt_to_thread
|
||||
IMPORT rt_hw_trap_irq
|
||||
|
||||
IRQ_Handler PROC
|
||||
EXPORT IRQ_Handler
|
||||
STMFD sp!, {r0-r12,lr}
|
||||
BL rt_interrupt_enter
|
||||
BL rt_hw_trap_irq
|
||||
BL rt_interrupt_leave
|
||||
|
||||
; if rt_thread_switch_interrupt_flag set, jump to
|
||||
; rt_hw_context_switch_interrupt_do and don't return
|
||||
LDR r0, =rt_thread_switch_interrupt_flag
|
||||
LDR r1, [r0]
|
||||
CMP r1, #1
|
||||
BEQ rt_hw_context_switch_interrupt_do
|
||||
|
||||
LDMFD sp!, {r0-r12,lr}
|
||||
SUBS pc, lr, #4
|
||||
ENDP
|
||||
|
||||
; /*
|
||||
; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
|
||||
; */
|
||||
rt_hw_context_switch_interrupt_do PROC
|
||||
EXPORT rt_hw_context_switch_interrupt_do
|
||||
MOV r1, #0 ; clear flag
|
||||
STR r1, [r0]
|
||||
|
||||
LDMFD sp!, {r0-r12,lr}; reload saved registers
|
||||
STMFD sp!, {r0-r3} ; save r0-r3
|
||||
MOV r1, sp
|
||||
ADD sp, sp, #16 ; restore sp
|
||||
SUB r2, lr, #4 ; save old task's pc to r2
|
||||
|
||||
MRS r3, spsr ; get cpsr of interrupt thread
|
||||
|
||||
; switch to SVC mode and no interrupt
|
||||
MSR cpsr_c, #I_Bit:OR:F_Bit:OR:Mode_SVC
|
||||
|
||||
STMFD sp!, {r2} ; push old task's pc
|
||||
STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4
|
||||
MOV r4, r1 ; Special optimised code below
|
||||
MOV r5, r3
|
||||
LDMFD r4!, {r0-r3}
|
||||
STMFD sp!, {r0-r3} ; push old task's r3-r0
|
||||
STMFD sp!, {r5} ; push old task's cpsr
|
||||
MRS r4, spsr
|
||||
STMFD sp!, {r4} ; push old task's spsr
|
||||
|
||||
LDR r4, =rt_interrupt_from_thread
|
||||
LDR r5, [r4]
|
||||
STR sp, [r5] ; store sp in preempted tasks's TCB
|
||||
|
||||
LDR r6, =rt_interrupt_to_thread
|
||||
LDR r6, [r6]
|
||||
LDR sp, [r6] ; get new task's stack pointer
|
||||
|
||||
LDMFD sp!, {r4} ; pop new task's spsr
|
||||
MSR spsr_cxsf, r4
|
||||
LDMFD sp!, {r4} ; pop new task's psr
|
||||
MSR cpsr_cxsf, r4
|
||||
|
||||
LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
|
||||
ENDP
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
; User Initial Stack & Heap
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
__user_initial_stackheap
|
||||
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + USR_Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDIF
|
||||
|
||||
|
||||
END
|
||||
|
|
@ -1,185 +0,0 @@
|
|||
/*
|
||||
* File : trap.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2011-01-13 weety modified from mini2440
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
|
||||
#include "at91sam926x.h"
|
||||
|
||||
/**
|
||||
* @addtogroup AT91SAM926X
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
extern struct rt_thread *rt_current_thread;
|
||||
#ifdef RT_USING_FINSH
|
||||
extern long list_thread(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* this function will show registers of CPU
|
||||
*
|
||||
* @param regs the registers point
|
||||
*/
|
||||
|
||||
void rt_hw_show_register (struct rt_hw_register *regs)
|
||||
{
|
||||
rt_kprintf("Execption:\n");
|
||||
rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
|
||||
rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
|
||||
rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
|
||||
rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
|
||||
rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
|
||||
rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
|
||||
}
|
||||
|
||||
/**
|
||||
* When ARM7TDMI comes across an instruction which it cannot handle,
|
||||
* it takes the undefined instruction trap.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_udef(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("undefined instruction\n");
|
||||
rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
list_thread();
|
||||
#endif
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* The software interrupt instruction (SWI) is used for entering
|
||||
* Supervisor mode, usually to request a particular supervisor
|
||||
* function.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_swi(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("software interrupt\n");
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* An abort indicates that the current memory access cannot be completed,
|
||||
* which occurs during an instruction prefetch.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_pabt(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("prefetch abort\n");
|
||||
rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
list_thread();
|
||||
#endif
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* An abort indicates that the current memory access cannot be completed,
|
||||
* which occurs during a data access.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_dabt(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("data abort\n");
|
||||
rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
list_thread();
|
||||
#endif
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Normally, system will never reach here
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_resv(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_kprintf("not used\n");
|
||||
rt_hw_show_register(regs);
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
extern struct rt_irq_desc irq_desc[];
|
||||
|
||||
void rt_hw_trap_irq()
|
||||
{
|
||||
rt_isr_handler_t isr_func;
|
||||
rt_uint32_t irqstat, irq, mask;
|
||||
void *param;
|
||||
//rt_kprintf("irq interrupt request\n");
|
||||
/* get irq number */
|
||||
irq = at91_sys_read(AT91_AIC_IVR);
|
||||
/* clear pending register */
|
||||
irqstat = at91_sys_read(AT91_AIC_ISR);
|
||||
if (irqstat == 0)
|
||||
{
|
||||
rt_kprintf("No interrupt occur\n");
|
||||
at91_sys_write(AT91_AIC_EOICR, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* get interrupt service routine */
|
||||
isr_func = irq_desc[irq].handler;
|
||||
param = irq_desc[irq].param;
|
||||
|
||||
/* turn to interrupt service routine */
|
||||
isr_func(irq, param);
|
||||
at91_sys_write(AT91_AIC_EOICR, 0x55555555); //EIOCR must be write any value after interrupt, or else can't response next interrupt
|
||||
irq_desc[irq].counter ++;
|
||||
}
|
||||
|
||||
void rt_hw_trap_fiq()
|
||||
{
|
||||
rt_kprintf("fast interrupt request\n");
|
||||
}
|
||||
|
||||
/*@}*/
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -20,13 +20,14 @@
|
|||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2011-01-13 weety modified from mini2440
|
||||
* 2015-04-15 ArdaFu Add code for IAR
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#define ICACHE_MASK (rt_uint32_t)(1 << 12)
|
||||
#define DCACHE_MASK (rt_uint32_t)(1 << 2)
|
||||
#define ICACHE_MASK (rt_uint32_t)(1 << 12)
|
||||
#define DCACHE_MASK (rt_uint32_t)(1 << 2)
|
||||
|
||||
extern void machine_reset(void);
|
||||
extern void machine_shutdown(void);
|
||||
|
@ -34,70 +35,102 @@ extern void machine_shutdown(void);
|
|||
#ifdef __GNUC__
|
||||
rt_inline rt_uint32_t cp15_rd(void)
|
||||
{
|
||||
rt_uint32_t i;
|
||||
rt_uint32_t i;
|
||||
|
||||
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
|
||||
return i;
|
||||
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
|
||||
return i;
|
||||
}
|
||||
|
||||
rt_inline void cache_enable(rt_uint32_t bit)
|
||||
{
|
||||
__asm__ __volatile__( \
|
||||
"mrc p15,0,r0,c1,c0,0\n\t" \
|
||||
"orr r0,r0,%0\n\t" \
|
||||
"mcr p15,0,r0,c1,c0,0" \
|
||||
: \
|
||||
:"r" (bit) \
|
||||
:"memory");
|
||||
__asm__ __volatile__(\
|
||||
"mrc p15,0,r0,c1,c0,0\n\t" \
|
||||
"orr r0,r0,%0\n\t" \
|
||||
"mcr p15,0,r0,c1,c0,0" \
|
||||
: \
|
||||
:"r" (bit) \
|
||||
:"memory");
|
||||
}
|
||||
|
||||
rt_inline void cache_disable(rt_uint32_t bit)
|
||||
{
|
||||
__asm__ __volatile__( \
|
||||
"mrc p15,0,r0,c1,c0,0\n\t" \
|
||||
"bic r0,r0,%0\n\t" \
|
||||
"mcr p15,0,r0,c1,c0,0" \
|
||||
: \
|
||||
:"r" (bit) \
|
||||
:"memory");
|
||||
__asm__ __volatile__(\
|
||||
"mrc p15,0,r0,c1,c0,0\n\t" \
|
||||
"bic r0,r0,%0\n\t" \
|
||||
"mcr p15,0,r0,c1,c0,0" \
|
||||
: \
|
||||
:"r" (bit) \
|
||||
:"memory");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __CC_ARM
|
||||
rt_inline rt_uint32_t cp15_rd(void)
|
||||
{
|
||||
rt_uint32_t i;
|
||||
rt_uint32_t i;
|
||||
|
||||
__asm
|
||||
{
|
||||
mrc p15, 0, i, c1, c0, 0
|
||||
}
|
||||
__asm
|
||||
{
|
||||
mrc p15, 0, i, c1, c0, 0
|
||||
}
|
||||
|
||||
return i;
|
||||
return i;
|
||||
}
|
||||
|
||||
rt_inline void cache_enable(rt_uint32_t bit)
|
||||
{
|
||||
rt_uint32_t value;
|
||||
rt_uint32_t value;
|
||||
|
||||
__asm
|
||||
{
|
||||
mrc p15, 0, value, c1, c0, 0
|
||||
orr value, value, bit
|
||||
mcr p15, 0, value, c1, c0, 0
|
||||
}
|
||||
__asm
|
||||
{
|
||||
mrc p15, 0, value, c1, c0, 0
|
||||
orr value, value, bit
|
||||
mcr p15, 0, value, c1, c0, 0
|
||||
}
|
||||
}
|
||||
|
||||
rt_inline void cache_disable(rt_uint32_t bit)
|
||||
{
|
||||
rt_uint32_t value;
|
||||
rt_uint32_t value;
|
||||
|
||||
__asm
|
||||
{
|
||||
mrc p15, 0, value, c1, c0, 0
|
||||
bic value, value, bit
|
||||
mcr p15, 0, value, c1, c0, 0
|
||||
}
|
||||
__asm
|
||||
{
|
||||
mrc p15, 0, value, c1, c0, 0
|
||||
bic value, value, bit
|
||||
mcr p15, 0, value, c1, c0, 0
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __ICCARM__
|
||||
rt_inline rt_uint32_t cp15_rd(void)
|
||||
{
|
||||
rt_uint32_t i;
|
||||
|
||||
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
|
||||
return i;
|
||||
}
|
||||
|
||||
rt_inline void cache_enable(rt_uint32_t bit)
|
||||
{
|
||||
asm volatile(\
|
||||
"mrc p15,0,r0,c1,c0,0\n\t" \
|
||||
"orr r0,r0,%0\n\t" \
|
||||
"mcr p15,0,r0,c1,c0,0" \
|
||||
: \
|
||||
:"r" (bit) \
|
||||
:"memory");
|
||||
}
|
||||
|
||||
rt_inline void cache_disable(rt_uint32_t bit)
|
||||
{
|
||||
asm volatile(\
|
||||
"mrc p15,0,r0,c1,c0,0\n\t" \
|
||||
"bic r0,r0,%0\n\t" \
|
||||
"mcr p15,0,r0,c1,c0,0" \
|
||||
: \
|
||||
:"r" (bit) \
|
||||
:"memory");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -107,7 +140,7 @@ rt_inline void cache_disable(rt_uint32_t bit)
|
|||
*/
|
||||
void rt_hw_cpu_icache_enable()
|
||||
{
|
||||
cache_enable(ICACHE_MASK);
|
||||
cache_enable(ICACHE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,7 +149,7 @@ void rt_hw_cpu_icache_enable()
|
|||
*/
|
||||
void rt_hw_cpu_icache_disable()
|
||||
{
|
||||
cache_disable(ICACHE_MASK);
|
||||
cache_disable(ICACHE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,7 +158,7 @@ void rt_hw_cpu_icache_disable()
|
|||
*/
|
||||
rt_base_t rt_hw_cpu_icache_status()
|
||||
{
|
||||
return (cp15_rd() & ICACHE_MASK);
|
||||
return (cp15_rd() & ICACHE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -134,7 +167,7 @@ rt_base_t rt_hw_cpu_icache_status()
|
|||
*/
|
||||
void rt_hw_cpu_dcache_enable()
|
||||
{
|
||||
cache_enable(DCACHE_MASK);
|
||||
cache_enable(DCACHE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -143,7 +176,7 @@ void rt_hw_cpu_dcache_enable()
|
|||
*/
|
||||
void rt_hw_cpu_dcache_disable()
|
||||
{
|
||||
cache_disable(DCACHE_MASK);
|
||||
cache_disable(DCACHE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -152,7 +185,7 @@ void rt_hw_cpu_dcache_disable()
|
|||
*/
|
||||
rt_base_t rt_hw_cpu_dcache_status()
|
||||
{
|
||||
return (cp15_rd() & DCACHE_MASK);
|
||||
return (cp15_rd() & DCACHE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -161,13 +194,13 @@ rt_base_t rt_hw_cpu_dcache_status()
|
|||
*/
|
||||
void rt_hw_cpu_reset()
|
||||
{
|
||||
|
||||
rt_kprintf("Restarting system...\n");
|
||||
machine_reset();
|
||||
|
||||
while(1); /* loop forever and wait for reset to happen */
|
||||
rt_kprintf("Restarting system...\n");
|
||||
machine_reset();
|
||||
|
||||
/* 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
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,38 +26,38 @@
|
|||
|
||||
#include <rtthread.h>
|
||||
|
||||
#define CACHE_LINE_SIZE 32
|
||||
#define CACHE_LINE_SIZE 32
|
||||
|
||||
#define DESC_SEC (0x2|(1<<4))
|
||||
#define CB (3<<2) //cache_on, write_back
|
||||
#define CNB (2<<2) //cache_on, write_through
|
||||
#define NCB (1<<2) //cache_off,WR_BUF on
|
||||
#define NCNB (0<<2) //cache_off,WR_BUF off
|
||||
#define AP_RW (3<<10) //supervisor=RW, user=RW
|
||||
#define AP_RO (2<<10) //supervisor=RW, user=RO
|
||||
#define DESC_SEC (0x2|(1<<4))
|
||||
#define CB (3<<2) //cache_on, write_back
|
||||
#define CNB (2<<2) //cache_on, write_through
|
||||
#define NCB (1<<2) //cache_off,WR_BUF on
|
||||
#define NCNB (0<<2) //cache_off,WR_BUF off
|
||||
#define AP_RW (3<<10) //supervisor=RW, user=RW
|
||||
#define AP_RO (2<<10) //supervisor=RW, user=RO
|
||||
|
||||
#define DOMAIN_FAULT (0x0)
|
||||
#define DOMAIN_CHK (0x1)
|
||||
#define DOMAIN_NOTCHK (0x3)
|
||||
#define DOMAIN0 (0x0<<5)
|
||||
#define DOMAIN1 (0x1<<5)
|
||||
#define DOMAIN_FAULT (0x0)
|
||||
#define DOMAIN_CHK (0x1)
|
||||
#define DOMAIN_NOTCHK (0x3)
|
||||
#define DOMAIN0 (0x0<<5)
|
||||
#define DOMAIN1 (0x1<<5)
|
||||
|
||||
#define DOMAIN0_ATTR (DOMAIN_CHK<<0)
|
||||
#define DOMAIN1_ATTR (DOMAIN_FAULT<<2)
|
||||
#define DOMAIN0_ATTR (DOMAIN_CHK<<0)
|
||||
#define DOMAIN1_ATTR (DOMAIN_FAULT<<2)
|
||||
|
||||
#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) /* Read/Write, cache, write back */
|
||||
#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) /* Read/Write, cache, write through */
|
||||
#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */
|
||||
#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */
|
||||
#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) /* Read/Write, cache, write back */
|
||||
#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) /* Read/Write, cache, write through */
|
||||
#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */
|
||||
#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */
|
||||
|
||||
struct mem_desc {
|
||||
rt_uint32_t vaddr_start;
|
||||
rt_uint32_t vaddr_end;
|
||||
rt_uint32_t paddr_start;
|
||||
rt_uint32_t attr;
|
||||
struct mem_desc
|
||||
{
|
||||
rt_uint32_t vaddr_start;
|
||||
rt_uint32_t vaddr_end;
|
||||
rt_uint32_t paddr_start;
|
||||
rt_uint32_t attr;
|
||||
};
|
||||
|
||||
void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* File : trap.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2011-01-13 weety modified from mini2440
|
||||
* 2015-04-15 ArdaFu Split from AT91SAM9260 BSP
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
#include <interrupt.h>
|
||||
|
||||
|
||||
extern struct rt_thread *rt_current_thread;
|
||||
#ifdef RT_USING_FINSH
|
||||
extern long list_thread(void);
|
||||
#endif
|
||||
|
||||
struct rt_hw_register
|
||||
{
|
||||
rt_uint32_t r0;
|
||||
rt_uint32_t r1;
|
||||
rt_uint32_t r2;
|
||||
rt_uint32_t r3;
|
||||
rt_uint32_t r4;
|
||||
rt_uint32_t r5;
|
||||
rt_uint32_t r6;
|
||||
rt_uint32_t r7;
|
||||
rt_uint32_t r8;
|
||||
rt_uint32_t r9;
|
||||
rt_uint32_t r10;
|
||||
rt_uint32_t fp;
|
||||
rt_uint32_t ip;
|
||||
rt_uint32_t sp;
|
||||
rt_uint32_t lr;
|
||||
rt_uint32_t pc;
|
||||
rt_uint32_t cpsr;
|
||||
rt_uint32_t ORIG_r0;
|
||||
};
|
||||
|
||||
/**
|
||||
* this function will show registers of CPU
|
||||
*
|
||||
* @param regs the registers point
|
||||
*/
|
||||
|
||||
void rt_hw_show_register (struct rt_hw_register *regs)
|
||||
{
|
||||
rt_kprintf("Execption:\n");
|
||||
rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n",
|
||||
regs->r0, regs->r1, regs->r2, regs->r3);
|
||||
rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n",
|
||||
regs->r4, regs->r5, regs->r6, regs->r7);
|
||||
rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n",
|
||||
regs->r8, regs->r9, regs->r10);
|
||||
rt_kprintf("fp :0x%08x ip :0x%08x\n",
|
||||
regs->fp, regs->ip);
|
||||
rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n",
|
||||
regs->sp, regs->lr, regs->pc);
|
||||
rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
|
||||
}
|
||||
|
||||
/**
|
||||
* When ARM7TDMI comes across an instruction which it cannot handle,
|
||||
* it takes the undefined instruction trap.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_udef(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("undefined instruction\n");
|
||||
rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
list_thread();
|
||||
#endif
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* The software interrupt instruction (SWI) is used for entering
|
||||
* Supervisor mode, usually to request a particular supervisor
|
||||
* function.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_swi(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("software interrupt\n");
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* An abort indicates that the current memory access cannot be completed,
|
||||
* which occurs during an instruction prefetch.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_pabt(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("prefetch abort\n");
|
||||
rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
list_thread();
|
||||
#endif
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* An abort indicates that the current memory access cannot be completed,
|
||||
* which occurs during a data access.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_dabt(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("data abort\n");
|
||||
rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
list_thread();
|
||||
#endif
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Normally, system will never reach here
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_resv(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_kprintf("not used\n");
|
||||
rt_hw_show_register(regs);
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void rt_hw_trap_irq()
|
||||
{
|
||||
rt_isr_handler_t isr_func;
|
||||
rt_uint32_t irqstat;
|
||||
rt_uint32_t irq;
|
||||
void *param;
|
||||
extern struct rt_irq_desc irq_desc[];
|
||||
|
||||
/* get irq number */
|
||||
irqstat = rt_hw_interrupt_get_active(INT_IRQ, &irq);
|
||||
if (irqstat == 0)
|
||||
{
|
||||
rt_kprintf("No interrupt occur\n");
|
||||
rt_hw_interrupt_ack(INT_IRQ);
|
||||
return;
|
||||
}
|
||||
|
||||
/* get interrupt service routine */
|
||||
isr_func = irq_desc[irq].handler;
|
||||
param = irq_desc[irq].param;
|
||||
|
||||
/* turn to interrupt service routine */
|
||||
isr_func(irq, param);
|
||||
|
||||
rt_hw_interrupt_ack(INT_IRQ);
|
||||
irq_desc[irq].counter ++;
|
||||
}
|
||||
|
||||
void rt_hw_trap_fiq()
|
||||
{
|
||||
rt_isr_handler_t isr_func;
|
||||
rt_uint32_t irqstat;
|
||||
rt_uint32_t irq;
|
||||
void *param;
|
||||
extern struct rt_irq_desc irq_desc[];
|
||||
|
||||
/* get irq number */
|
||||
irqstat = rt_hw_interrupt_get_active(INT_FIQ, &irq);
|
||||
if (irqstat == 0)
|
||||
{
|
||||
rt_kprintf("No interrupt occur\n");
|
||||
rt_hw_interrupt_ack(INT_FIQ);
|
||||
return;
|
||||
}
|
||||
|
||||
/* get interrupt service routine */
|
||||
isr_func = irq_desc[irq].handler;
|
||||
param = irq_desc[irq].param;
|
||||
|
||||
/* turn to interrupt service routine */
|
||||
isr_func(irq, param);
|
||||
|
||||
rt_hw_interrupt_ack(INT_FIQ);
|
||||
irq_desc[irq].counter ++;
|
||||
}
|
Loading…
Reference in New Issue