/* * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By * downloading, copying, installing or using the software you agree to * this license. If you do not agree to this license, do not download, * install, copy or use the software. * * Intel Open Source License * * Copyright (c) 2002 Intel 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 following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS * CONTRIBUTORS 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. * * */ /* * * Authors: Phil Buonadonna,David Gay * Date last modified: $Revision$ * */ .equ ARM_CPSR_MODE_MASK,(0x0000001F) .equ ARM_CPSR_INT_MASK,(0x000000C0) .equ ARM_CPSR_COND_MASK,(0xF8000000) .equ ARM_CPSR_MODE_USR,(0x10) .equ ARM_CPSR_MODE_FIQ,(0x11) .equ ARM_CPSR_MODE_IRQ,(0x12) .equ ARM_CPSR_MODE_SVC,(0x13) .equ ARM_CPSR_MODE_ABT,(0x17) .equ ARM_CPSR_MODE_UND,(0x1B) .equ ARM_CPSR_MODE_SYS,(0x1F) .equ ARM_CPSR_BIT_N,(0x80000000) .equ ARM_CPSR_BIT_Z,(0x40000000) .equ ARM_CPSR_BIT_C,(0x20000000) .equ ARM_CPSR_BIT_V,(0x10000000) .equ ARM_CPSR_BIT_Q,(0x08000000) .equ ARM_CPSR_BIT_I,(0x00000080) .equ ARM_CPSR_BIT_F,(0x00000040) .equ ARM_CPRS_BIT_T,(0x00000020) .equ _TOS_STACK_SIZE,(0x400) @ TinyOS Exception stack sizes .equ _TOS_ISRAM_PHYSBASE,(0x5C000000) @ Internal SRAM on PXA27X .text .globl start start: mrs r0, CPSR bic r0, r0, #ARM_CPSR_MODE_MASK orr r0, r0, #(ARM_CPSR_MODE_SVC | ARM_CPSR_INT_MASK) msr cpsr_cf, r0 /* Initialize the stack pointers for all modes */ mov r0,#_TOS_ISRAM_PHYSBASE ldr r2, =(256*1024 - 4) @ and go to the last slot (256K - 4) add r2,r2,r0 mov r0, #ARM_CPSR_MODE_ABT msr CPSR_c, R0 mov sp, r2 sub r2, r2, #_TOS_STACK_SIZE mov r0, #ARM_CPSR_MODE_UND msr CPSR_c, R0 mov sp, r2 sub r2, r2, #_TOS_STACK_SIZE mov r0, #ARM_CPSR_MODE_FIQ msr CPSR_c, R0 mov sp, r2 sub r2, r2, #_TOS_STACK_SIZE mov r0, #ARM_CPSR_MODE_IRQ msr CPSR_c, R0 mov sp, r2 sub r2, r2, #(_TOS_STACK_SIZE * 2) mov r0, #ARM_CPSR_MODE_SVC msr CPSR_c, R0 mov sp, r2 /* copy data */ ldr r0, =__data_load_start ldr r1, =__data_load_end ldr r2, =__data_start .Lcopy: cmp r0, r1 beq .Lcopydone ldrb r3, [r0], #1 strb r3, [r2], #1 b .Lcopy .Lcopydone: /* clear bss */ ldr r0, =__bss_start__ ldr r1, =__bss_end__ mov r2, #0 .Lclear: cmp r0, r1 beq .Lcleardone strb r2, [r0], #1 b .Lclear .Lcleardone: mov r0, #0 /* argc? */ mov r1, #0 /* argv? */ bl main .L1: nop b .L1 @if we receive and interrupt that we don't handle, behavior will depend on whether we're in release or not .ifdef RELEASE @reboot...assumes that we started out in supervisor mode..and that we'll be returning hplarmv_undef: movs PC, #0 hplarmv_swi: movs PC, #0 hplarmv_pabort: movs PC, #0 hplarmv_dabort: movs PC, #0 hplarmv_reserved: movs PC, #0 hplarmv_irq: movs PC, #0 hplarmv_fiq: movs PC, #0 .else @infinite loop so that we can detect what happened with a debugger @in future, we'll want to blink specific LED patter or something for the USER...or perhaps blue light of death hplarmv_undef: b hplarmv_undef hplarmv_swi: b hplarmv_swi hplarmv_pabort: b hplarmv_pabort hplarmv_dabort: b hplarmv_dabort hplarmv_reserved: b hplarmv_reserved hplarmv_irq: b hplarmv_irq hplarmv_fiq: b hplarmv_fiq .endif reset_handler_start: @ reset handler should first check whether this is a debug exception @ or a real RESET event. @ NOTE: r13 is only safe register to use. @ - For RESET, donÆt really care about which register is used @ - For debug exception, r13=DBG_r13, prevents application registers @ - from being corrupted, before debug handler can save. mrs r13, cpsr and r13, r13, #0x1f cmp r13, #0x15 @ are we in DBG mode? beq dbg_handler_stub @ if so, go to the dbg handler stub mov r13, #0x8000001c @ otherwise, enable debug, set MOE bits mcr p14, 0, r13, c10, c0, 0 @ and continue with the reset handler @ normal reset handler initialization follows code here, @ or branch to the reset handler. b start .align 5 @ align code to a cache line boundary. dbg_handler_stub: @ First save the state of the IC enable/disable bit in DBG_LR[0]. mrc p15, 0, r13, c1, c0, 0 and r13, r13, #0x1000 orr r14, r14, r13, lsr #12 @ Next, enable the IC. mrc p15, 0, r13, c1, c0, 0 orr r13, r13, #0x1000 mcr p15, 0, r13, c1, c0, 0 @ do a sync operation to ensure all outstanding instr fetches have @ completed before continuing. The invalidate cache line function @ serves as a synchronization operation, thatÆs why it is used @ here. The target line is some scratch address in memory. adr r13, line2 mcr p15, 0, r13, c7, c5, 1 @ invalidate BTB. make sure downloaded vector table does not hit one of @ the applicationÆs branches cached in the BTB, branch to the wrong place mcr p15, 0, r13, c7, c5, 6 @ Now, send æready for downloadÆ message to debugger, indicating debugger @ can begin the download. æready for downloadÆ = 0x00B00000. TXloop: mrc p14, 0, r15, c14, c0, 0 @ first make sure TX reg. is available bvs TXloop mov r13, #0x00B00000 mcr p14, 0, r13, c8, c0, 0 @ now write to TX @ Wait for debugger to indicate that the download is complete. RXloop: mrc p14, 0, r15, c14, c0, 0 @ spin in loop waiting for data from the bpl RXloop @ debugger in RX. @ before reading the RX register to get the address to branch to, restore @ the state of the IC (saved in DBG_r14[0]) to the value it have at the @ start of the debug handler stub. Also, note it must be restored before @ reading the RX register because of limited scratch registers (r13) mrc p15, 0, r13, c1, c0, 0 @ First, check DBG_LR[0] to see if the IC was enabled or disabled tst r14, #0x1 @ Then, if it was previously disabled, then disable it now, otherwise, @ thereÆs no need to change the state, because its already enabled. biceq r13, r13, #0x1000 mcr p15, 0, r13, c1, c0, 0 @ Restore the link register value bic r14, r14, #0x1 @ Now r13 can be used to read RX and get the target address to branch to. mrc p14, 0, r13, c9, c0, 0 @ Read RX and mov pc, r13 @ branch to downloaded address. @ scratch memory space used by the invalidate IC line function above. .align 5 @ make sure it starts at a cache line @ boundary, so nothing else is affected line2: .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .weak hplarmv_undef, hplarmv_swi, hplarmv_pabort, hplarmv_dabort, hplarmv_reserved, hplarmv_irq, hplarmv_fiq .section .vectors b reset_handler_start b hplarmv_undef b hplarmv_swi b hplarmv_pabort b hplarmv_dabort b hplarmv_reserved b hplarmv_irq b hplarmv_fiq .end