📄 vectors.s
字号:
// #========================================================================// #// # vectors.S// #// # ARM exception vectors// #// #========================================================================// ####COPYRIGHTBEGIN####// // -------------------------------------------// The contents of this file are subject to the Cygnus eCos Public License// Version 1.0 (the "License"); you may not use this file except in// compliance with the License. You may obtain a copy of the License at// http://sourceware.cygnus.com/ecos// // Software distributed under the License is distributed on an "AS IS"// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the// License for the specific language governing rights and limitations under// the License.// // The Original Code is eCos - Embedded Cygnus Operating System, released// September 30, 1998.// // The Initial Developer of the Original Code is Cygnus. Portions created// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved.// -------------------------------------------// // ####COPYRIGHTEND####// #========================================================================// ######DESCRIPTIONBEGIN####// #// # Author(s): nickg, gthomas// # Contributors: nickg, gthomas// # Date: 1999-02-20// # Purpose: ARM exception vectors// # Description: This file defines the code placed into the exception// # vectors. It also contains the first level default VSRs// # that save and restore state for both exceptions and// # interrupts.// #// #####DESCRIPTIONEND####// #// #========================================================================#include <pkgconf/hal.h>#include <pkgconf/hal_arm.h>#ifdef CYGPKG_KERNEL // no CDL yet#include <pkgconf/kernel.h>#else# undef CYGFUN_HAL_COMMON_KERNEL_SUPPORT#endif#include <cyg/hal/hal_platform_setup.h>#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS// The CDL should enforce this#undef CYGHWR_HAL_ARM_DUMP_EXCEPTIONS#endif#include "arm.inc"#define FUNC_START(name) \ .globl _name; \_name: #define PTR(name) \.##name: .word name .file "vectors.S"//==========================================================================// Hardware exception vectors.// This entire section will be copied to location 0x0000 at startup time.// .section ".vectors","ax" .global __exception_handlers__exception_handlers: ldr pc,.reset_vector // 0x00 ldr pc,.undefined_instruction // 0x04 ldr pc,.software_interrupt // 0x08 start && software int ldr pc,.abort_prefetch // 0x0C ldr pc,.abort_data // 0x10 .word 0 // unused ldr pc,.IRQ // 0x18 ldr pc,.FIQ // 0x1C// The layout of these pointers should match the vector table above since// they are copied in pairs. .global vectorsvectors:PTR(reset_vector)PTR(undefined_instruction)PTR(software_interrupt)PTR(abort_prefetch)PTR(abort_data) .word 0PTR(IRQ)PTR(FIQ)PTR(start) .text // Startup code which will get the machine into supervisor mode .global reset_vector .type reset_vector,functionreset_vector:#if defined(CYG_HAL_STARTUP_RAM) && \ !defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) mrs r7,cpsr // move back to IRQ mode and r7,r7,#CPSR_MODE_BITS cmp r7,#CPSR_SUPERVISOR_MODE beq start#endif PLATFORM_SETUP1 // Early stage platform initialization // see <cyg/hal/hal_platform_setup.h> mov r0,#0 // move vectors ldr r1,.__exception_handlers ldr r2,[r1,#0x04] // undefined instruction str r2,[r0,#0x04] ldr r2,[r1,#0x24] str r2,[r0,#0x24] ldr r2,[r1,#0x08] // software interrupt str r2,[r0,#0x08] ldr r2,[r1,#0x40] str r2,[r0,#0x28] swi // switch to supervisor mode// =========================================================================// Real startup code. We jump here from the reset vector to set up the world. .globl startstart: #if defined(CYG_HAL_STARTUP_RAM) && \ !defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)// If we get restarted, hang here to avoid corrupting memory ldr r0,.init_flag ldr r1,[r0]1: cmp r1,#0 bne 1b ldr r1,init_done str r1,[r0]#endif // Reset software interrupt pointer mov r0,#0 // move vectors ldr r1,.__exception_handlers#if defined(CYG_HAL_STARTUP_RAM) && \ !defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) cmp r7,#CPSR_SUPERVISOR_MODE beq 10f#endif ldr r2,[r1,#0x28] // software interrupt str r2,[r0,#0x28]10: ldr r2,[r1,#0x18] // IRQ str r2,[r0,#0x18] ldr r2,[r1,#0x38] str r2,[r0,#0x38] ldr r2,[r1,#0x1C] // FIQ str r2,[r0,#0x1C] ldr r2,[r1,#0x3C] str r2,[r0,#0x3C] ldr r2,[r1,#0x0C] // abort (prefetch) str r2,[r0,#0x0C] ldr r2,[r1,#0x2C] str r2,[r0,#0x2C] ldr r2,[r1,#0x10] // abort (data) str r2,[r0,#0x10] ldr r2,[r1,#0x30] str r2,[r0,#0x30]#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_STUBS) // Relocate [copy] data from ROM to RAM ldr r3,.__rom_data_start ldr r4,.__ram_data_start ldr r5,.__ram_data_end cmp r4,r5 // jump if no data to move beq 2f sub r3,r3,#4 // loop adjustments sub r4,r4,#41: ldr r0,[r3,#4]! // copy info str r0,[r4,#4]! cmp r4,r5 bne 1b2:#endif // initialize interrupt/exception environments ldr sp,.__startup_stack mov r0,#(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_IRQ_MODE) msr cpsr,r0 ldr sp,.__exception_stack mov r0,#(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_UNDEF_MODE) msr cpsr,r0 ldr sp,.__exception_stack // initialize CPSR (machine state register) mov r0,#(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SUPERVISOR_MODE) msr cpsr,r0 // Note: some functions in LIBGCC1 will cause a "restore from SPSR"!! msr spsr,r0 // initialize stack ldr sp,.__startup_stack // clear BSS ldr r1,.__bss_start ldr r2,.__bss_end mov r0,#0 cmp r1,r2 beq 2f sub r1,r1,#41: str r0,[r1,#4]! cmp r1,r2 bne 1b2: // Call platform specific hardware initialization bl hal_hardware_init // Run through static constructors bl cyg_hal_invoke_constructors#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS bl initialize_stub#endif // This starts up the eCos kernel bl cyg_start_start_hang: b _start_hanginit_done: .long 0xDEADB00B//// Exception handlers// Assmumption: get here from a Supervisor context [mode]//undefined_instruction: ldr sp,.__undef_exception_stack // get good stack sub lr,lr,#4 // PC at time of interrupt stmfd sp!,{r0,fp,ip,lr} mrs r0,spsr stmfd sp!,{r0} mov ip,sp // save SP which will vanish with // mode switch mrs r0,cpsr // switch to Supervisor Mode bic r0,r0,#CPSR_MODE_BITS orr r0,r0,#CPSR_SUPERVISOR_MODE msr cpsr,r0 // sp,lr are now old values mov fp,sp#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS ldr sp,.__GDB_stack cmp fp,sp // already on GDB stack? bhi 10f ldr r0,.__GDB_stack_base cmp fp,r0 bls 10f // no - switch to GDB stack // (already in sp) mov sp,fp // yes - no switch10:#endif sub sp,sp,#ARMREG_SIZE // make space for frame stmea sp,{r0-r10,fp} // save immediately visible registers ldmfd ip,{r0-r4} // saved registers str r0,[sp,#armreg_cpsr] // CPSR at time of interrupt str r1,[sp,#armreg_r0] // saved R0 str r2,[sp,#armreg_fp] // saved FP str r3,[sp,#armreg_ip] // saved IP str r4,[sp,#armreg_pc] // PC at time of interrupt str lr,[sp,#armreg_lr] // LR at time of interrupt add r0,ip,#ARMREG_SIZE str fp,[sp,#armreg_sp] // SP at time of interrupt#ifdef CYGHWR_HAL_ARM_DUMP_EXCEPTIONS mov r0,sp bl undefined_instruction#endif mov v1,#CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION b call_exception_handlersoftware_interrupt: ldr sp,.__startup_stack // get good stack sub lr,lr,#4 // PC at time of interrupt stmfd sp!,{r0,ip,lr} mrs r0,spsr stmfd sp!,{r0} mov ip,sp // save SP which will vanish with // mode switch mrs r0,cpsr // switch to Supervisor Mode bic r0,r0,#CPSR_MODE_BITS orr r0,r0,#CPSR_SUPERVISOR_MODE msr cpsr,r0 // sp,lr are now old values mov ip,sp ldr sp,.__startup_stack // get good stack sub sp,sp,#ARMREG_SIZE+16 // make space for frame stmea sp,{r0-r10,fp} // save immediately visible registers ldmfd ip,{r0-r3} // saved registers str r0,[sp,#armreg_cpsr] // CPSR at time of interrupt str r1,[sp,#armreg_r0] // saved R0 str r2,[sp,#armreg_ip] // saved IP str r3,[sp,#armreg_pc] // PC at time of interrupt str lr,[sp,#armreg_lr] // LR at time of interrupt add r0,ip,#ARMREG_SIZE str r0,[sp,#armreg_sp] // SP at time of interrupt#ifdef CYGHWR_HAL_ARM_DUMP_EXCEPTIONS mov r0,sp bl software_interrupt#endif mov v1,#CYGNUM_HAL_EXCEPTION_INTERRUPT b call_exception_handlerabort_prefetch: ldr sp,.__undef_exception_stack // get good stack sub lr,lr,#4 // PC at time of interrupt stmfd sp!,{r0,fp,ip,lr} mrs r0,spsr stmfd sp!,{r0} mov ip,sp // save SP which will vanish with // mode switch mrs r0,cpsr // switch to Supervisor Mode bic r0,r0,#CPSR_MODE_BITS orr r0,r0,#CPSR_SUPERVISOR_MODE msr cpsr,r0 // sp,lr are now old values mov fp,sp#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS ldr sp,.__GDB_stack cmp fp,sp // already on GDB stack? bhi 10f ldr r0,.__GDB_stack_base cmp fp,r0 bls 10f // no - switch to GDB stack // (already in sp) mov sp,fp // yes - no switch10:#endif sub sp,sp,#ARMREG_SIZE // make space for frame stmea sp,{r0-r10,fp} // save immediately visible registers ldmfd ip,{r0-r4} // saved registers str r0,[sp,#armreg_cpsr] // CPSR at time of interrupt str r1,[sp,#armreg_r0] // saved R0 str r2,[sp,#armreg_fp] // saved FP str r3,[sp,#armreg_ip] // saved IP str r4,[sp,#armreg_pc] // PC at time of interrupt str lr,[sp,#armreg_lr] // LR at time of interrupt add r0,ip,#ARMREG_SIZE str fp,[sp,#armreg_sp] // SP at time of interrupt#ifdef CYGHWR_HAL_ARM_DUMP_EXCEPTIONS mov r0,sp bl abort_prefetch#endif mov v1,#CYGNUM_HAL_EXCEPTION_CODE_ACCESS b call_exception_handlerabort_data: ldr sp,.__undef_exception_stack // get good stack sub lr,lr,#4 // PC at time of interrupt stmfd sp!,{r0,fp,ip,lr} mrs r0,spsr stmfd sp!,{r0} mov ip,sp // save SP which will vanish with // mode switch mrs r0,cpsr // switch to Supervisor Mode bic r0,r0,#CPSR_MODE_BITS orr r0,r0,#CPSR_SUPERVISOR_MODE msr cpsr,r0 // sp,lr are now old values mov fp,sp#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS ldr sp,.__GDB_stack cmp fp,sp // already on GDB stack? bhi 10f ldr r0,.__GDB_stack_base cmp fp,r0 bls 10f // no - switch to GDB stack // (already in sp) mov sp,fp // yes - no switch10:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -