diff options
Diffstat (limited to 'boot_loader/bl_startup_ccs.s')
| -rw-r--r-- | boot_loader/bl_startup_ccs.s | 645 |
1 files changed, 645 insertions, 0 deletions
diff --git a/boot_loader/bl_startup_ccs.s b/boot_loader/bl_startup_ccs.s new file mode 100644 index 0000000..8bfa96b --- /dev/null +++ b/boot_loader/bl_startup_ccs.s @@ -0,0 +1,645 @@ +;;*****************************************************************************
+;;
+;; bl_startup_ccs.s - Boot loader startup code for Code Composer Studio
+;;
+;; Copyright (c) 2009-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 Tiva Firmware Development Package.
+;;
+;;*****************************************************************************
+
+;;*****************************************************************************
+;;
+;; Include the boot loader configuration options.
+;;
+;;*****************************************************************************
+ .cdecls C, NOLIST, WARN
+ %{
+ #include "inc/hw_nvic.h"
+ #include "inc/hw_sysctl.h"
+ #include "bl_config.h"
+ %}
+
+;;*****************************************************************************
+;;
+;; Export symbols from this file that are used elsewhere
+;;
+;;*****************************************************************************
+ .global ResetISR, Delay, Vectors
+
+;;*****************************************************************************
+;;
+;; Create the stack and put it in a section
+;;
+;;*****************************************************************************
+ .global __stack
+__stack:.usect ".stack", STACK_SIZE * 4, 8
+
+;;*****************************************************************************
+;;
+;; Put the assembler into the correct configuration.
+;;
+;;*****************************************************************************
+ .thumb
+
+;;*****************************************************************************
+;;
+;; This portion of the file goes into interrupt vectors section
+;;
+;;*****************************************************************************
+ .sect ".intvecs"
+
+;;*****************************************************************************
+;;
+;; The minimal vector table for a Cortex-M3 processor.
+;;
+;;*****************************************************************************
+Vectors:
+ .ref __STACK_TOP
+ .word __STACK_TOP ;; Offset 00: Initial stack pointer
+ .word ResetISR - 0x20000000 ;; Offset 04: Reset handler
+ .word NmiSR - 0x20000000 ;; Offset 08: NMI handler
+ .word FaultISR - 0x20000000 ;; Offset 0C: Hard fault handler
+ .word IntDefaultHandler ;; Offset 10: MPU fault handler
+ .word IntDefaultHandler ;; Offset 14: Bus fault handler
+ .word IntDefaultHandler ;; Offset 18: Usage fault handler
+ .word 0 ;; Offset 1C: Reserved
+ .word 0 ;; Offset 20: Reserved
+ .word 0 ;; Offset 24: Reserved
+ .word 0 ;; Offset 28: Reserved
+ .word UpdateHandler - 0x20000000 ;; Offset 2C: SVCall handler
+ .word IntDefaultHandler ;; Offset 30: Debug monitor handler
+ .word 0 ;; Offset 34: Reserved
+ .word IntDefaultHandler ;; Offset 38: PendSV handler
+ .if $$defined(ENET_ENABLE_UPDATE)
+ .ref SysTickIntHandler
+ .word SysTickIntHandler ;; Offset 3C: SysTick handler
+ .else
+ .word IntDefaultHandler ;; Offset 3C: SysTick handler
+ .endif
+ .if $$defined(UART_ENABLE_UPDATE) & $$defined(UART_AUTOBAUD)
+ .ref GPIOIntHandler
+ .word GPIOIntHandler ;; Offset 40: GPIO port A handler
+ .else
+ .word IntDefaultHandler ;; Offset 40: GPIO port A handler
+ .endif
+ .if ($$defined(USB_ENABLE_UPDATE) | (APP_START_ADDRESS != VTABLE_START_ADDRESS))
+ .word IntDefaultHandler ;; Offset 44: GPIO Port B
+ .word IntDefaultHandler ;; Offset 48: GPIO Port C
+ .word IntDefaultHandler ;; Offset 4C: GPIO Port D
+ .word IntDefaultHandler ;; Offset 50: GPIO Port E
+ .word IntDefaultHandler ;; Offset 54: UART0 Rx and Tx
+ .word IntDefaultHandler ;; Offset 58: UART1 Rx and Tx
+ .word IntDefaultHandler ;; Offset 5C: SSI0 Rx and Tx
+ .word IntDefaultHandler ;; Offset 60: I2C0 Master and Slave
+ .word IntDefaultHandler ;; Offset 64: PWM Fault
+ .word IntDefaultHandler ;; Offset 68: PWM Generator 0
+ .word IntDefaultHandler ;; Offset 6C: PWM Generator 1
+ .word IntDefaultHandler ;; Offset 70: PWM Generator 2
+ .word IntDefaultHandler ;; Offset 74: Quadrature Encoder 0
+ .word IntDefaultHandler ;; Offset 78: ADC Sequence 0
+ .word IntDefaultHandler ;; Offset 7C: ADC Sequence 1
+ .word IntDefaultHandler ;; Offset 80: ADC Sequence 2
+ .word IntDefaultHandler ;; Offset 84: ADC Sequence 3
+ .word IntDefaultHandler ;; Offset 88: Watchdog timer
+ .word IntDefaultHandler ;; Offset 8C: Timer 0 subtimer A
+ .word IntDefaultHandler ;; Offset 90: Timer 0 subtimer B
+ .word IntDefaultHandler ;; Offset 94: Timer 1 subtimer A
+ .word IntDefaultHandler ;; Offset 98: Timer 1 subtimer B
+ .word IntDefaultHandler ;; Offset 9C: Timer 2 subtimer A
+ .word IntDefaultHandler ;; Offset A0: Timer 2 subtimer B
+ .word IntDefaultHandler ;; Offset A4: Analog Comparator 0
+ .word IntDefaultHandler ;; Offset A8: Analog Comparator 1
+ .word IntDefaultHandler ;; Offset AC: Analog Comparator 2
+ .word IntDefaultHandler ;; Offset B0: System Control
+ .word IntDefaultHandler ;; Offset B4: FLASH Control
+ .endif
+ .if ($$defined(USB_ENABLE_UPDATE) | (APP_START_ADDRESS != VTABLE_START_ADDRESS))
+ .word IntDefaultHandler ;; Offset B8: GPIO Port F
+ .word IntDefaultHandler ;; Offset BC: GPIO Port G
+ .word IntDefaultHandler ;; Offset C0: GPIO Port H
+ .word IntDefaultHandler ;; Offset C4: UART2 Rx and Tx
+ .word IntDefaultHandler ;; Offset C8: SSI1 Rx and Tx
+ .word IntDefaultHandler ;; Offset CC: Timer 3 subtimer A
+ .word IntDefaultHandler ;; Offset D0: Timer 3 subtimer B
+ .word IntDefaultHandler ;; Offset D4: I2C1 Master and Slave
+ .word IntDefaultHandler ;; Offset D8: Quadrature Encoder 1
+ .word IntDefaultHandler ;; Offset DC: CAN0
+ .word IntDefaultHandler ;; Offset E0: CAN1
+ .word IntDefaultHandler ;; Offset E4: CAN2
+ .word IntDefaultHandler ;; Offset E8: Ethernet
+ .word IntDefaultHandler ;; Offset EC: Hibernation module
+ .if $$defined(USB_ENABLE_UPDATE)
+ .ref USB0DeviceIntHandler
+ .word USB0DeviceIntHandler ;; Offset F0: USB 0 Controller
+ .else
+ .word IntDefaultHandler ;; Offset F0: USB 0 Controller
+ .endif
+ .endif
+
+;;*****************************************************************************
+;;
+;; This portion of the file goes into the text section.
+;;
+;;*****************************************************************************
+ .text
+
+;;*****************************************************************************
+;;
+;; Initialize the processor by copying the boot loader from flash to SRAM, zero
+;; filling the .bss section, and moving the vector table to the beginning of
+;; SRAM. The return address is modified to point to the SRAM copy of the boot
+;; loader instead of the flash copy, resulting in a branch to the copy now in
+;; SRAM.
+;;
+;;*****************************************************************************
+ .ref bss_run
+bss_start .word bss_run
+ .ref __STACK_TOP
+bss_end .word __STACK_TOP
+
+ .thumbfunc ProcessorInit
+ProcessorInit: .asmfunc
+ ;;
+ ;; Copy the code image from flash to SRAM.
+ ;;
+ movs r0, #0x0000
+ movs r1, #0x0000
+ movt r1, #0x2000
+ ldr r2, bss_start
+copy_loop:
+ ldr r3, [r0], #4
+ str r3, [r1], #4
+ cmp r1, r2
+ blt copy_loop
+
+ ;;
+ ;; Zero fill the .bss section.
+ ;;
+ movs r0, #0x0000
+ ldr r2, bss_end
+zero_loop:
+ str r0, [r1], #4
+ cmp r1, r2
+ blt zero_loop
+
+ ;;
+ ;; Set the vector table pointer to the beginning of SRAM.
+ ;;
+ movw r0, #(NVIC_VTABLE & 0xffff)
+ movt r0, #(NVIC_VTABLE >> 16)
+ movs r1, #0x0000
+ movt r1, #0x2000
+ str r1, [r0]
+
+ ;;
+ ;; Set the return address to the code just copied into SRAM.
+ ;;
+ orr lr, lr, #0x20000000
+
+ ;;
+ ;; Return to the caller.
+ ;;
+ bx lr
+ .endasmfunc
+
+;;*****************************************************************************
+;;
+;; The reset handler, which gets called when the processor starts.
+;;
+;;*****************************************************************************
+ .thumbfunc ResetISR
+ResetISR: .asmfunc
+ ;;
+ ;; Enable the floating-point unit. This must be done here in case any
+ ;; later C functions use floating point. Note that some toolchains will
+ ;; use the FPU registers for general workspace even if no explicit floating
+ ;; point data types are in use.
+ ;;
+ movw r0, #0xED88
+ movt r0, #0xE000
+ ldr r1, [r0]
+ orr r1, r1, #0x00F00000
+ str r1, [r0]
+
+ ;;
+ ;; Initialize the processor.
+ ;;
+ bl ProcessorInit
+
+ ;;
+ ;; Call the user-supplied low level hardware initialization function
+ ;; if provided.
+ ;;
+ .if $$defined(BL_HW_INIT_FN_HOOK)
+ .ref BL_HW_INIT_FN_HOOK
+ bl BL_HW_INIT_FN_HOOK
+ .endif
+
+ ;;
+ ;; See if an update should be performed.
+ ;;
+ .ref CheckForceUpdate
+ bl CheckForceUpdate
+ cbz r0, CallApplication
+
+ ;;
+ ;; Configure the microcontroller.
+ ;;
+ .thumbfunc EnterBootLoader
+EnterBootLoader:
+ .if $$defined(ENET_ENABLE_UPDATE)
+ .ref ConfigureEnet
+ bl ConfigureEnet
+ .elseif $$defined(CAN_ENABLE_UPDATE)
+ .ref ConfigureCAN
+ bl ConfigureCAN
+ .elseif $$defined(USB_ENABLE_UPDATE)
+ .ref ConfigureUSB
+ bl ConfigureUSB
+ .else
+ .ref ConfigureDevice
+ bl ConfigureDevice
+ .endif
+
+ ;;
+ ;; Call the user-supplied initialization function if provided.
+ ;;
+ .if $$defined(BL_INIT_FN_HOOK)
+ .ref BL_INIT_FN_HOOK
+ bl BL_INIT_FN_HOOK
+ .endif
+
+ ;;
+ ;; Branch to the update handler.
+ ;;
+ .if $$defined(ENET_ENABLE_UPDATE)
+ .ref UpdateBOOTP
+ b UpdateBOOTP
+ .elseif $$defined(CAN_ENABLE_UPDATE)
+ .ref UpdaterCAN
+ b UpdaterCAN
+ .elseif $$defined(USB_ENABLE_UPDATE)
+ .ref UpdaterUSB
+ b UpdaterUSB
+ .else
+ .ref Updater
+ b Updater
+ .endif
+ .endasmfunc
+
+ ;;
+ ;; This is a second symbol to allow starting the application from the boot
+ ;; loader the linker may not like the perceived jump.
+ ;;
+ .global StartApplication
+ .thumbfunc StartApplication
+StartApplication:
+ ;;
+ ;; Call the application via the reset handler in its vector table. Load
+ ;; the address of the application vector table.
+ ;;
+ .thumbfunc CallApplication
+CallApplication: .asmfunc
+ ;;
+ ;; Copy the application's vector table to the target address if necessary.
+ ;; Note that incorrect boot loader configuration could cause this to
+ ;; corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start
+ ;; of SRAM) is safe since this will use the same memory that the boot loader
+ ;; already uses for its vector table. Great care will have to be taken if
+ ;; other addresses are to be used.
+ ;;
+ .if (APP_START_ADDRESS != VTABLE_START_ADDRESS)
+ movw r0, #(VTABLE_START_ADDRESS & 0xffff)
+ .if (VTABLE_START_ADDRESS > 0xffff)
+ movt r0, #(VTABLE_START_ADDRESS >> 16)
+ .endif
+ movw r1, #(APP_START_ADDRESS & 0xffff)
+ .if (APP_START_ADDRESS > 0xffff)
+ movt r1, #(APP_START_ADDRESS >> 16)
+ .endif
+
+ ;;
+ ;; Calculate the end address of the vector table assuming that it has the
+ ;; maximum possible number of vectors. We don't know how many the app has
+ ;; populated so this is the safest approach though it may copy some non
+ ;; vector data if the app table is smaller than the maximum.
+ ;;
+ movw r2, #(70 * 4)
+ adds r2, r2, r0
+VectorCopyLoop:
+ ldr r3, [r1], #4
+ str r3, [r0], #4
+ cmp r0, r2
+ blt VectorCopyLoop
+ .endif
+
+ ;;
+ ;; Set the application's vector table start address. Typically this is the
+ ;; application start address but in some cases an application may relocate
+ ;; this so we can't assume that these two addresses are equal.
+ ;;
+ movw r0, #(VTABLE_START_ADDRESS & 0xffff)
+ .if (VTABLE_START_ADDRESS > 0xffff)
+ movt r0, #(VTABLE_START_ADDRESS >> 16)
+ .endif
+ movw r1, #(NVIC_VTABLE & 0xffff)
+ movt r1, #(NVIC_VTABLE >> 16)
+ str r0, [r1]
+
+ ;;
+ ;; Load the stack pointer from the application's vector table.
+ ;;
+ .if (APP_START_ADDRESS != VTABLE_START_ADDRESS)
+ movw r0, #(APP_START_ADDRESS & 0xffff)
+ .if (APP_START_ADDRESS > 0xffff)
+ movt r0, #(APP_START_ADDRESS >> 16)
+ .endif
+ .endif
+ ldr sp, [r0]
+
+ ;;
+ ;; Load the initial PC from the application's vector table and branch to
+ ;; the application's entry point.
+ ;;
+ ldr r0, [r0, #4]
+ bx r0
+ .endasmfunc
+
+;;*****************************************************************************
+;;
+;; The update handler, which gets called when the application would like to
+;; start an update.
+;;
+;;*****************************************************************************
+ .thumbfunc UpdateHandler
+UpdateHandler: .asmfunc
+ ;;
+ ;; Initialize the processor.
+ ;;
+ bl ProcessorInit
+
+ ;;
+ ;; Load the stack pointer from the vector table.
+ ;;
+ movs r0, #0x0000
+ ldr sp, [r0]
+
+ ;;
+ ;; Call the user-supplied low level hardware initialization function
+ ;; if provided.
+ ;;
+ .if $$defined(BL_HW_INIT_FN_HOOK)
+ bl BL_HW_INIT_FN_HOOK
+ .endif
+
+ ;;
+ ;; Call the user-supplied re-initialization function if provided.
+ ;;
+ .if $$defined(BL_REINIT_FN_HOOK)
+ .ref BL_REINIT_FN_HOOK
+ bl BL_REINIT_FN_HOOK
+ .endif
+
+ ;;
+ ;; Branch to the update handler.
+ ;;
+ .if $$defined(ENET_ENABLE_UPDATE)
+ b UpdateBOOTP
+ .elseif $$defined(CAN_ENABLE_UPDATE)
+ .ref AppUpdaterCAN
+ b AppUpdaterCAN
+ .elseif $$defined(USB_ENABLE_UPDATE)
+ .ref AppUpdaterUSB
+ b AppUpdaterUSB
+ .else
+ b Updater
+ .endif
+ .endasmfunc
+
+;;*****************************************************************************
+;;
+;; The NMI handler.
+;;
+;;*****************************************************************************
+ .thumbfunc NmiSR
+NmiSR: .asmfunc
+ .if $$defined(ENABLE_MOSCFAIL_HANDLER)
+ ;;
+ ;; Grab the fault frame from the stack (the stack will be cleared by the
+ ;; processor initialization that follows).
+ ;;
+ ldm sp, {r4-r11}
+ mov r12, lr
+
+ ;;
+ ;; Initialize the processor.
+ ;;
+ bl ProcessorInit
+
+ ;;
+ ;; Restore the stack frame.
+ ;;
+ mov lr, r12
+ stm sp, {r4-r11}
+
+ ;;
+ ;; Save the link register.
+ ;;
+ mov r9, lr
+
+ ;;
+ ;; Call the user-supplied low level hardware initialization function
+ ;; if provided.
+ ;;
+ .if $$defined(BL_HW_INIT_FN_HOOK)
+ bl BL_HW_INIT_FN_HOOK
+ .endif
+
+ ;;
+ ;; See if an update should be performed.
+ ;;
+ bl CheckForceUpdate
+ cbz r0, EnterApplication
+
+ ;;
+ ;; Clear the MOSCFAIL bit in RESC.
+ ;;
+ movw r0, #(SYSCTL_RESC & 0xffff)
+ movt r0, #(SYSCTL_RESC >> 16)
+ ldr r1, [r0]
+ bic r1, r1, #SYSCTL_RESC_MOSCFAIL
+ str r1, [r0]
+
+ ;;
+ ;; Fix up the PC on the stack so that the boot pin check is bypassed
+ ;; (since it has already been performed).
+ ;;
+ ldr r0, =EnterBootLoader
+ bic r0, #0x00000001
+ str r0, [sp, #0x18]
+
+ ;;
+ ;; Return from the NMI handler. This will then start execution of the
+ ;; boot loader.
+ ;;
+ bx r9
+
+ ;;
+ ;; Restore the link register.
+ ;;
+EnterApplication:
+ mov lr, r9
+
+ ;;
+ ;; Copy the application's vector table to the target address if necessary.
+ ;; Note that incorrect boot loader configuration could cause this to
+ ;; corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start
+ ;; of SRAM) is safe since this will use the same memory that the boot loader
+ ;; already uses for its vector table. Great care will have to be taken if
+ ;; other addresses are to be used.
+ ;;
+ .if (APP_START_ADDRESS != VTABLE_START_ADDRESS)
+ movw r0, #(VTABLE_START_ADDRESS & 0xffff)
+ .if (VTABLE_START_ADDRESS > 0xffff)
+ movt r0, #(VTABLE_START_ADDRESS >> 16)
+ .endif
+ movw r1, #(APP_START_ADDRESS & 0xffff)
+ .if (APP_START_ADDRESS > 0xffff)
+ movt r1, #(APP_START_ADDRESS >> 16)
+ .endif
+
+ ;;
+ ;; Calculate the end address of the vector table assuming that it has the
+ ;; maximum possible number of vectors. We don't know how many the app has
+ ;; populated so this is the safest approach though it may copy some non
+ ;; vector data if the app table is smaller than the maximum.
+ ;;
+ movw r2, #(70 * 4)
+ adds r2, r2, r0
+VectorCopyLoop2:
+ ldr r3, [r1], #4
+ str r3, [r0], #4
+ cmp r0, r2
+ blt VectorCopyLoop2
+ .endif
+
+ ;;
+ ;; Set the application's vector table start address. Typically this is the
+ ;; application start address but in some cases an application may relocate
+ ;; this so we can't assume that these two addresses are equal.
+ ;;
+ movw r0, #(VTABLE_START_ADDRESS & 0xffff)
+ .if (VTABLE_START_ADDRESS > 0xffff)
+ movt r0, #(VTABLE_START_ADDRESS >> 16)
+ .endif
+ movw r1, #(NVIC_VTABLE & 0xffff)
+ movt r1, #(NVIC_VTABLE >> 16)
+ str r0, [r1]
+
+ ;;
+ ;; Remove the NMI stack frame from the boot loader's stack.
+ ;;
+ ldmia sp, {r4-r11}
+
+ ;;
+ ;; Get the application's stack pointer.
+ ;;
+ .if (APP_START_ADDRESS != VTABLE_START_ADDRESS)
+ movw r0, #(APP_START_ADDRESS & 0xffff)
+ .if (APP_START_ADDRESS > 0xffff)
+ movt r0, #(APP_START_ADDRESS >> 16)
+ .endif
+ .endif
+ ldr sp, [r0, #0x00]
+
+ ;;
+ ;; Fix up the NMI stack frame's return address to be the reset handler of
+ ;; the application.
+ ;;
+ ldr r10, [r0, #0x04]
+ bic r10, #0x00000001
+
+ ;;
+ ;; Store the NMI stack frame onto the application's stack.
+ ;;
+ stmdb sp!, {r4-r11}
+
+ ;;
+ ;; Branch to the application's NMI handler.
+ ;;
+ ldr r0, [r0, #0x08]
+ bx r0
+ .else
+ ;;
+ ;; Loop forever since there is nothing that we can do about a NMI.
+ ;;
+ b NmiSR
+ .endif
+ .endasmfunc
+
+;;*****************************************************************************
+;;
+;; The hard fault handler.
+;;
+;;*****************************************************************************
+ .thumbfunc FaultISR
+FaultISR: .asmfunc
+ ;;
+ ;; Loop forever since there is nothing that we can do about a hard fault.
+ ;;
+ b FaultISR
+ .endasmfunc
+
+;;*****************************************************************************
+;;
+;; The default interrupt handler.
+;;
+;;*****************************************************************************
+ .thumbfunc IntDefaultHandler
+IntDefaultHandler: .asmfunc
+ ;;
+ ;; Loop forever since there is nothing that we can do about an unexpected
+ ;; interrupt.
+ ;;
+ b IntDefaultHandler
+ .endasmfunc
+
+;;*****************************************************************************
+;;
+;; Provides a small delay. The loop below takes 3 cycles/loop.
+;;
+;;*****************************************************************************
+; .globl Delay
+ .thumbfunc Delay
+Delay: .asmfunc
+ subs r0, #1
+ bne Delay
+ bx lr
+ .endasmfunc
+
+ .thumbfunc _c_int00
+ .global _c_int00
+_c_int00: .asmfunc
+ b ResetISR
+
+;;*****************************************************************************
+;;
+;; This is the end of the file.
+;;
+;;*****************************************************************************
+ .end
|
