mirror of
https://github.com/micropython/micropython.git
synced 2026-01-06 20:20:14 +01:00
Allowing to use e.g. the Adafruit bootloaders with MicroPython. The .uf2 file is created in addition to the .bin and .hex files allowing to use the latter ones without the bootloader for debugging and testing. Changes: - Set the location of the ISR Vector and .text segment to 0x6000C000 and 0x6000C400. - Reserve an area at the start of ITCM for a copy of the interrupt vector table and copy the table on reset to this place. - Extend `machine.bootloader()` by setting the magic number to enable the bootloader on reset. - Create a .uf2 file which skips the segments below 0x6000C000. The bootloader has to be installed as a preparation step using the board specific methods, but then the firmware's .uf2 file version can be installed using the bootloader. The bootloader can be invoked with: - double reset - calling machine.bootloader() - Using the touch1200 method Double reset is hard to achieve on MIMXRT boards, since there is no clean reset pin. Some MIMXRT boards provide it by switching the power. Some boards are excluded from the .uf2 build: - MIMXRT1050_EVK: The uf2 bootloader is built for the QSPI version of the board. MicroPython supports the Hyperflash version. - MIMXRT1176_EVK: No support for this board yet, but it should be possible. Signed-off-by: robert-hh <robert@hammelrath.com>
196 lines
6.1 KiB
ArmAsm
196 lines
6.1 KiB
ArmAsm
/* ------------------------------------------------------------------------- */
|
|
/* */
|
|
/* Copyright 1997-2016 Freescale Semiconductor, Inc. */
|
|
/* Copyright 2016-2019 NXP */
|
|
/* All rights reserved. */
|
|
/* */
|
|
/* SPDX-License-Identifier: BSD-3-Clause */
|
|
/*****************************************************************************/
|
|
/* Version: GCC for ARM Embedded Processors */
|
|
/*****************************************************************************/
|
|
.syntax unified
|
|
.arch armv7-m
|
|
|
|
#include"flexram_config.s"
|
|
|
|
|
|
/* Reset Handler */
|
|
|
|
.thumb_func
|
|
.align 2
|
|
.globl Reset_Handler
|
|
.type Reset_Handler, %function
|
|
Reset_Handler:
|
|
cpsid i /* Mask interrupts */
|
|
.equ VTOR, 0xE000ED08
|
|
ldr r0, =VTOR
|
|
ldr r1, =__isr_vector
|
|
str r1, [r0]
|
|
ldr r2, [r1]
|
|
msr msp, r2
|
|
|
|
/* Reconfigure the memory map, which must match the setting of the linker script */
|
|
dsb
|
|
isb
|
|
ldr r0, =__iomux_gpr17_adr /* load IOMUXC_GPR17 register address to R0 */
|
|
ldr r1, =__iomux_gpr17_value /* move FlexRAM configuration value to R1 */
|
|
str r1,[r0] /* store FLEXRAM configuration value to IOMUXC_GPR17 */
|
|
dsb
|
|
isb
|
|
#if defined MIMXRT117x_SERIES
|
|
ldr r0, =__iomux_gpr18_adr /* load IOMUXC_GPR18 register address to R0 */
|
|
ldr r1, =__iomux_gpr18_value /* move FlexRAM configuration value to R1 */
|
|
str r1,[r0] /* store FLEXRAM configuration value to IOMUXC_GPR18 */
|
|
dsb
|
|
isb
|
|
#endif
|
|
ldr r0, =__iomux_gpr16_adr /* load IOMUXC_GPR16 register address to R0 */
|
|
ldr r1,[r0] /* load IOMUXC_GPR16 register value to R1 */
|
|
orr r1, r1, #4 /* set corresponding FLEXRAM_BANK_CFG_SEL bit */
|
|
str r1,[r0] /* store the value to IOMUXC_GPR16 (FLEXRAM_BANK_CFG_SEL = '1') */
|
|
dsb
|
|
isb
|
|
|
|
#ifndef __NO_SYSTEM_INIT
|
|
ldr r0,=SystemInit
|
|
blx r0
|
|
#endif
|
|
/* Loop to copy data from read only memory to RAM. The ranges
|
|
* of copy from/to are specified by following symbols evaluated in
|
|
* linker script.
|
|
* __etext: End of code section, i.e., begin of data sections to copy from.
|
|
* __data_start__/__data_end__: RAM address range that data should be
|
|
* __noncachedata_start__/__noncachedata_end__ : non-cacheable region
|
|
* __ram_function_start__/__ram_function_end__ : ramfunction region
|
|
* copied to. Both must be aligned to 4 bytes boundary. */
|
|
|
|
/* Copy the ISR Vector table to the start of ITCM to be available when the
|
|
.uf2 bootloader is used */
|
|
|
|
ldr r1, = __Vectors
|
|
ldr r2, = __Vectors_RAM
|
|
movs r3, 1024
|
|
|
|
.LC_ISR:
|
|
subs r3, #4
|
|
ldr r0, [r1, r3]
|
|
str r0, [r2, r3]
|
|
bgt .LC_ISR
|
|
|
|
ldr r1, =__etext
|
|
ldr r2, =__data_start__
|
|
ldr r3, =__data_end__
|
|
|
|
#ifdef __PERFORMANCE_IMPLEMENTATION
|
|
/* Here are two copies of loop implementations. First one favors performance
|
|
* and the second one favors code size. Default uses the second one.
|
|
* Define macro "__PERFORMANCE_IMPLEMENTATION" in project to use the first one */
|
|
subs r3, r2
|
|
ble .LC1
|
|
.LC0:
|
|
subs r3, #4
|
|
ldr r0, [r1, r3]
|
|
str r0, [r2, r3]
|
|
bgt .LC0
|
|
.LC1:
|
|
#else /* code size implementation */
|
|
.LC0:
|
|
cmp r2, r3
|
|
ittt lt
|
|
ldrlt r0, [r1], #4
|
|
strlt r0, [r2], #4
|
|
blt .LC0
|
|
#endif
|
|
#ifdef __STARTUP_INITIALIZE_RAMFUNCTION
|
|
ldr r2, =__ram_function_start__
|
|
ldr r3, =__ram_function_end__
|
|
#ifdef __PERFORMANCE_IMPLEMENTATION
|
|
/* Here are two copies of loop implementations. First one favors performance
|
|
* and the second one favors code size. Default uses the second one.
|
|
* Define macro "__PERFORMANCE_IMPLEMENTATION" in project to use the first one */
|
|
subs r3, r2
|
|
ble .LC_ramfunc_copy_end
|
|
.LC_ramfunc_copy_start:
|
|
subs r3, #4
|
|
ldr r0, [r1, r3]
|
|
str r0, [r2, r3]
|
|
bgt .LC_ramfunc_copy_start
|
|
.LC_ramfunc_copy_end:
|
|
#else /* code size implementation */
|
|
.LC_ramfunc_copy_start:
|
|
cmp r2, r3
|
|
ittt lt
|
|
ldrlt r0, [r1], #4
|
|
strlt r0, [r2], #4
|
|
blt .LC_ramfunc_copy_start
|
|
#endif
|
|
#endif /* __STARTUP_INITIALIZE_RAMFUNCTION */
|
|
#ifdef __STARTUP_INITIALIZE_NONCACHEDATA
|
|
ldr r2, =__noncachedata_start__
|
|
ldr r3, =__noncachedata_init_end__
|
|
#ifdef __PERFORMANCE_IMPLEMENTATION
|
|
/* Here are two copies of loop implementations. First one favors performance
|
|
* and the second one favors code size. Default uses the second one.
|
|
* Define macro "__PERFORMANCE_IMPLEMENTATION" in project to use the first one */
|
|
subs r3, r2
|
|
ble .LC3
|
|
.LC2:
|
|
subs r3, #4
|
|
ldr r0, [r1, r3]
|
|
str r0, [r2, r3]
|
|
bgt .LC2
|
|
.LC3:
|
|
#else /* code size implementation */
|
|
.LC2:
|
|
cmp r2, r3
|
|
ittt lt
|
|
ldrlt r0, [r1], #4
|
|
strlt r0, [r2], #4
|
|
blt .LC2
|
|
#endif
|
|
/* zero inited ncache section initialization */
|
|
ldr r3, =__noncachedata_end__
|
|
movs r0,0
|
|
.LC4:
|
|
cmp r2,r3
|
|
itt lt
|
|
strlt r0,[r2],#4
|
|
blt .LC4
|
|
#endif /* __STARTUP_INITIALIZE_NONCACHEDATA */
|
|
|
|
#ifdef __STARTUP_CLEAR_BSS
|
|
/* This part of work usually is done in C library startup code. Otherwise,
|
|
* define this macro to enable it in this startup.
|
|
*
|
|
* Loop to zero out BSS section, which uses following symbols
|
|
* in linker script:
|
|
* __bss_start__: start of BSS section. Must align to 4
|
|
* __bss_end__: end of BSS section. Must align to 4
|
|
*/
|
|
ldr r1, =__bss_start__
|
|
ldr r2, =__bss_end__
|
|
|
|
movs r0, 0
|
|
.LC5:
|
|
cmp r1, r2
|
|
itt lt
|
|
strlt r0, [r1], #4
|
|
blt .LC5
|
|
#endif /* __STARTUP_CLEAR_BSS */
|
|
|
|
cpsie i /* Unmask interrupts */
|
|
#ifndef __START
|
|
#define __START _start
|
|
#endif
|
|
#ifndef __ATOLLIC__
|
|
ldr r0,=__START
|
|
blx r0
|
|
#else
|
|
ldr r0,=__libc_init_array
|
|
blx r0
|
|
ldr r0,=main
|
|
bx r0
|
|
#endif
|
|
.pool
|
|
.size Reset_Handler, . - Reset_Handler
|