📄 vectors.s
字号:
//****************************************************************************//// VECTORS.S - Code for all the exception vectors of the ARM processor.//// Copyright (c) 1998,1999,2000,2001 Cirrus Logic, Inc.////****************************************************************************#include "../asmdefs.h"#include "../hwport.h"#include "../hwdefs.h"//****************************************************************************//// Zero-initialized read/write data area.////**************************************************************************** _BSS_//****************************************************************************//// Memory buffers to contain the stacks for the various processor modes which// we will be using.////****************************************************************************SVCStack _LABEL_#ifdef gcc _SPACE_ 0x800#else _SPACE_ 0x400#endifSVCStackEnd _LABEL_IRQStack _LABEL_ _SPACE_ 0x200IRQStackEnd _LABEL_FIQStack _LABEL_ _SPACE_ 0x10FIQStackEnd _LABEL_//****************************************************************************//// The following variable contains a set of flags that indicate various// conditions/requests within the system.////**************************************************************************** _EXPORT_ ulSystemFlagsulSystemFlags _LABEL_ _WORD_ 0//****************************************************************************//// The following contains the address of the first free word of internal SRAM.////**************************************************************************** _EXPORT_ ulEndOfRAMulEndOfRAM _LABEL_ _WORD_ 0//****************************************************************************//// Read-only code area.////**************************************************************************** _TEXT_//****************************************************************************//// The ARM vector table. This must reside at location 0x00000000 in the ARM's// address space. When the ARM takes an exception, it changes the program// counter to one of the first eight addresses in memory. Each vector has only// one instruction, so we use that instruction to branch to the handler for the// vector.////**************************************************************************** _ENTRY_vectortable _LABEL_ b ResetHandler b UndefHandler b SWIHandler b PAbortHandler b DAbortHandler b UnusedHandler b IRQHandler b FIQHandler//****************************************************************************//// Immediately following the ARM vector table is a structure that describes// the software image. It has the following definition://// struct// {// //// // The memory address of this structure in the eyes of the linker.// //// unsigned long ulBaseAddress;//// //// // The length of the program image.// //// unsigned long ulLength;//// //// // The hardware ID of the device on which this software image runs.// //// unsigned long ulHardwareID;//// //// // The CRC of the program image.// //// unsigned long ulCRC32;// };//// The ulLength and ulCRC32 fields are filled in by the package program.////**************************************************************************** _WORD_ . _WORD_ 0 _WORD_ HardwareID _WORD_ 0//****************************************************************************//// ResetHandler is the startup code to be used when the ARM processor first// starts executing after a reset. This is responsible for setting up the// device, configuring the MMU, and launching the actual application.////****************************************************************************ResetHandler _LABEL_ // // Put the ARM processor into IRQ mode. // ldr r0, =0x000000d2 msr cpsr_cf, r0 // // Set up the stack pointer for IRQ mode. // ldr r13, =IRQStackEnd // // Put the ARM processor into FIQ mode. // ldr r0, =0x000000d1 msr cpsr_cf, r0 // // Initialize the values of the FIQ mode banked registers. // ldr r8, =0x00000000 ldr r9, =0x00000000 ldr r10, =0x00000000 ldr r11, =0x00000000 ldr r12, =0x00000000 // // Set up the stack pointer for FIQ mode. // ldr r13, =FIQStackEnd // // Put the ARM processor into SVC mode. // ldr r0, =0x000000d3 msr cpsr_cf, r0 // // Set up the stack pointer. // ldr r13, =SVCStackEnd // // Set up the MMU. Start by flushing the cache and TLB. // ldr r0, =0x00000000 mcr _CP15_, 0, r0, _CR7_, _CR7_ mcr _CP15_, 0, r0, _CR8_, _CR7_ // // Set user mode access for all 16 domains. // ldr r0, =0x55555555 mcr _CP15_, 0, r0, _CR3_, _CR0_ // // Tell the MMU where to find the page table. // _IMPORT_ PageTable ldr r0, =PageTable mcr _CP15_, 0, r0, _CR2_, _CR0_ // // Turn on the ROM protection in the MMU. // ldr r0, =0x00000270 mcr _CP15_, 0, r0, _CR1_, _CR0_ // // Enable the MMU. // orr r0, r0, _CONST_ 0x0000000d mcr _CP15_, 0, r0, _CR1_, _CR0_ // // There should always be two NOP instructions following the enable or // disable of the MMU. // nop nop // // Load pointers to the EP7209 internal registers. // ldr r0, =HwBaseAddress add r1, r0, _CONST_ 0x00001000 add r2, r0, _CONST_ 0x00002000 // // If the system was reset by nPOR, then program the real time clock with // the default system time (Nov 30, 1999 @ 9:49am). // ldr r3, [r0, _CONST_ HwStatus] tst r3, _CONST_ HwStatusColdStartFlag ldrne r3, =0x38439d8c strne r3, [r0, _CONST_ HwRtcData] // // Clear the startup reason flags. // str r0, [r0, _CONST_ HwStartFlagClear] // // Disable all the interrupt sources except for the USB interrupt and the // timer 1 interrupt. // ldr r3, =HwIrqTimer1 str r3, [r0, _CONST_ HwIntMask] ldr r3, =0x00000000 str r3, [r1, _CONST_ (HwIntMask2 - 0x1000)] str r3, [r2, _CONST_ (HwIntMask3 - 0x2000)] // // Program the memory configuration register to properly access the // peripherals on the board. // ldr r3, [r0, _CONST_ HwStatus] and r3, r3, _CONST_ HwStatusBootWidthMask cmp r3, _CONST_ HwStatusBootWidth16 ldreq r3, =(HwMemConfig1_Value | 0x01010100) ldrne r3, =HwMemConfig1_Value str r3, [r0, _CONST_ HwMemConfig1] ldreq r3, =(HwMemConfig2_Value | 0x00000101) ldrne r3, =HwMemConfig2_Value str r3, [r0, _CONST_ HwMemConfig2] // // Program the system control registers. Enable the first serial port, set // the processor clock rate to 74MHz, and select prescale mode for timer 1. // ldr r3, =HwControl1_Value str r3, [r0, _CONST_ HwControl] ldr r3, =HwControl2_Value str r3, [r1, _CONST_ (HwControl2 - 0x1000)] ldr r3, =HwControl3_Value str r3, [r2, _CONST_ (HwControl3 - 0x2000)] // // Set the divisor for timer 1 such that it generates an interrupt every // 5ms. // ldr r3, =0x0000000a str r3, [r0, _CONST_ HwTimer1Data] // // Set the direction of the GPIO pins. // ldr r3, =HwPortABCD_DefaultDir str r3, [r0, _CONST_ HwDdrABCD] ldr r3, =HwPortE_DefaultDir str r3, [r0, _CONST_ HwDdrE] // // Set the initial state of the GPIO pins. // ldr r3, =HwPortABCD_DefaultValue str r3, [r0, _CONST_ HwPortABCD] ldr r3, =HwPortE_DefaultValue str r3, [r0, _CONST_ HwPortE] // // Copy the read-write data block from ROM to RAM. // _IMPORT_ _ROLIMIT_ _IMPORT_ _RWBASE_ _IMPORT_ _ZIBASE_ ldr r0, =_ROLIMIT_ ldr r1, =_RWBASE_ ldr r2, =_ZIBASE_copy_rw _LABEL_ cmp r1, r2 ldrne r3, [r0], _CONST_ 4 strne r3, [r1], _CONST_ 4 bne copy_rw // // Fill the zero initialized data block in RAM with zeros. // _IMPORT_ _RWLIMIT_ ldr r2, =_RWLIMIT_ ldr r3, =0x00000000zero _LABEL_ cmp r1, r2 strne r3, [r1], _CONST_ 4 bne zero // // Initialize the value of ulEndOfRAM. // ldr r0, =ulEndOfRAM str r1, [r0] // // We've completed the setup of the processor, peripherals, and program // data, so enable the IRQ and FIQ interrupts. // mrs r0, cpsr bic r0, r0, _CONST_ 0x000000c0 msr cpsr_cf, r0 // // Initialize the remainder of the hardware/software environment required // by the player. // _IMPORT_ initialize bl initialize // // Branch to the actual program. We set the link register to zero so that // if the program does happen to return, we will re-initialize the system. // ldr lr, =0x00000000 _IMPORT_ entry b entry // // Tell the assembler to put in-line data here. // _LTORG_//****************************************************************************//// The following is a handler for several of the ARM exception vectors://// 1) The undefined instruction handler. This is called when an// instruction reaches the execute stage of the ARM pipeline, but is// not an instruction which is recognized by the ARM processor.// 2) The instruction pre-fetch abort handler. This is called when an// instruction reaches the execute state of the ARM pipeline, but the// pre-fetch of the instruction failed due to a MMU error.// 3) The data abort handler. This is called when a load or store// instruction is executed and the memory access failed due to a MMU// error.// 4) The unused handler. This is a legacy vector which is no longer used// on ARM7 processors and therefore will (should) never be called.//// In the event that we enter any of these exception vectors, we shutdown down// the player as best we can and branch back to the reset handler (so that we// start over with hopefully a clean slate).////****************************************************************************UndefHandler _LABEL_PAbortHandler _LABEL_DAbortHandler _LABEL_UnusedHandler _LABEL_ // // Put the ARM processor into SVC mode and disable interrupts. // ldr r0, =0x000000d3 msr cpsr_cf, r0 // // Disable the USB controller. // _IMPORT_ USBDisable bl USBDisable // // Disable the MMU. // mov r0, _CONST_ 0x00000070 mcr _CP15_, 0, r0, _CR1_, _CR0_ // // There should always be two NOP instructions following the enable or // disable of the MMU. // nop nop // // Flush the cache and TLB. // ldr r0, =0x00000000 mcr _CP15_, 0, r0, _CR7_, _CR7_ mcr _CP15_, 0, r0, _CR8_, _CR7_ // // Branch back to the reset handler. // b ResetHandler//****************************************************************************//// The software interrupt handler. We do not support any SWIs, so simply// return to the caller.////****************************************************************************SWIHandler _LABEL_ movs pc, lr//****************************************************************************//// The IRQ interrupt handler. This is called when the IRQ line going into the// ARM processor goes high, indicating an external device is requesting the// attention of the processor.//// We handle the USB interrupt, the timer interrupt for timer1, and the// interrupts for SmartMedia if they exist.////****************************************************************************IRQHandler _LABEL_ // // Save r0 through r3 to the stack. // stmdb r13!, {r0-r3} // // Load r0 with a pointer to the EP7209 internal registers. // ldr r0, =HwBaseAddress // // Read the interrupt status register to see which interrupts are asserted. // Use the value of the interrupt mask register to mask off asserted // interrupts which are currently masked out so that we do not service // them. // ldr r1, [r0, _CONST_ HwIntStatus] ldr r2, [r0, _CONST_ HwIntMask] and r1, r1, r2 // // See if timer1 caused the interrupt. // tst r1, _CONST_ HwIrqTimer1 beq timer1_done // // See if we should call the output processing code. // ldr r2, =ulSystemFlags ldr r2, [r2] tst r2, _CONST_ 8 beq output_done // // Save r0, r1, r12 and r14 to the stack. // stmdb r13!, {r0, r1, r12, r14} //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -