D.2.5. Debug handler firmware support

The code in Example D.1 is an example of a reset handler that enables hot-debug when it is included in your target firmware, and you are using Multi-ICE Version 2.1 or later.

Example D.1. Example hot-debug firmware

reset_handler_start
        ; The reset handler must first check whether this is a debug exception,
        ; or a real RESET event.
        ; NOTE: r13 is the only safe scratch register to use:
        ;
        ;   - for a RESET, any register can be used
        ;
        ;   - for a debug exception, r13 = r13_dbg, and using r13 prevents
        ;     the application registers from being corrupted before the 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.
        ALIGN   32      ; Align code to a cache line boundary (32 byte aligned).
dbg_handler_stub
        ; First save the state of the IC enable/disable bit in r14_dbg[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 instruction fetches
        ; have completed before continuing.
        ;
        ; The invalidate cache line function serves as a synchronization
        ; operation, and that is why it is used here. The target line is some
        ; scratch address in memory, reserved at the end of this code.
        ADR     r13, line2
        MCR     p15, 0, r13, c7, c5, 1
        ; Invalidate the BTB.
        ;
        ; Make sure that the downloaded vector table does not hit one of the
        ; application’s branches that is cached in the BTB, and therefore
        ; branch to the wrong place.
        MCR     p15, 0, r13, c7, c5, 6
        ; Now, send a ‘ready for download’ message to the debugger, indicating
        ; that the debugger can begin the download.
        ;
        ; NOTE: ‘ready for download’ = 0x00B00000.
TXloop
        MRC     p14, 0, r15, c14, c0, 0 ; First ensure TX register is available,
        BVS     TXloop                  ; looping if it is not.
        MOV     r13, #0x00B00000        ; Create ‘ready for download’ message,
        MCR     p14, 0, r13, c8, c0, 0  ; and write it to the TX register
        ; Wait for the debugger to indicate that the download is complete.
RXloop
        MRC     p14, 0, r15, c14, c0, 0 ; Wait for data from the debugger in
        BPL     RXloop                  ; the RX register, looping if none.
        ; 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 that
        ; it had at the start of the debug handler stub.
        ;
        ; NOTE: the state of the IC must be restored before reading the RX
        ; register, because r13 is the only usable scratch register.
        MRC     p15, 0, r13, c1, c0, 0
        ; First, check r14_dbg[0] to see if the IC was enabled or disabled.
        TST     r14, #0x1
        ; If the IC was previously disabled, then disable it now.
        ;
        ; (Otherwise, there is no need to change the state, because the IC is
        ; already enabled.)
        BICEQ   r13, r13, #0x1000
        MRC     p15, 0, r13, c1, c0, 0
        ; Now r13 can be used to read the RX register and get the target
        ; address to branch to.
        MRC     p14, 0, r13, c9, c0, 0 ; Read the RX register, and
        MOV     pc, r13                ; branch to the downloaded address.
        ; Scratch memory space used by the invalidate IC line function above.
        ALIGN   32                     ; Make sure it starts at a cache line
                                       ; boundary, so nothing else is affected.
line2
        SPACE   32                     ; Allocate 32 bytes of zeroed memory.

There are several restrictions to debug handlers:

Copyright © 1998-2002 ARM Limited. All rights reserved.ARM DUI 0048F
Non-Confidential