| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- if { [info exists CHIPNAME] } {
- set _CHIPNAME $CHIPNAME
- } else {
- set _CHIPNAME imxrt
- }
- source [find mem_helper.tcl]
- # ---------------------------------------------- Auxiliary functions for accessing i.MXRT registers ----------------------------------------------
- # SBMR2: Bit 25..24:
- # BOOT_MODE[1:0]: 00b - Boot From Fuses
- # 01b - Serial Downloader
- # 10b - Internal Boot
- # 11b - Reserved
- proc get_boot_mode {} {
- set SRC_SBMR2 [ mrw 0x400F801C ]
- set bootmode [expr ($SRC_SBMR2 & 0x03000000) >> 24 ]
- return $bootmode
- }
- # Boot Device: 0000b - Serial NOR boot via FlexSPI
- # 001xb - SD boot via uSDHC
- # 10xxb - eMMC/MMC boot via uSDHC
- # 01xxb - SLC NAND boot via SEMC
- # 0001b - Parallel NOR boot via SEMC
- # 11xxb - Serial NAND boot via FlexSPI
- proc get_boot_device {} {
- set SRC_SBMR1 [ mrw 0x400F8004 ]
- set bootdevice [expr ($SRC_SBMR1 & 0x000000F0) >> 4 ]
- return $bootdevice
- }
- proc get_reset_vector {} {
- global FLASH_MEMORY_BASE
- set MAX_FLASH_MEMORY_SIZE 0x10000000
-
- set vector_table_addr [ mrw [expr $FLASH_MEMORY_BASE + 0x1004 ] ]
- if { ($vector_table_addr < $FLASH_MEMORY_BASE) || ($vector_table_addr > ($FLASH_MEMORY_BASE + $MAX_FLASH_MEMORY_SIZE)) } {
- echo "Invalid vector table address: $vector_table_addr"
- return 0
- }
-
- set reset_vector [ mrw [expr $vector_table_addr + 4] ]
- return $reset_vector
- }
- # ------------------------------------------------------------------------------------------------------------------------------------------------
- set RESET_INTO_BOOT_ROM 0
- #The regular "reset halt" command on i.MXRT will stop the chip at the internal entry point in the boot ROM.
- #At this point the internal bootloader has not initialized the peripherals set.
- #So normally, we want to instead let the bootloader run and stop when it invokes the entry point of the main program.
- #The 'reset_into_boot_rom' command controls this behavior.
- #Usage: reset_into_boot_rom 0/1
- proc reset_into_boot_rom { flag } {
- global RESET_INTO_BOOT_ROM
- set RESET_INTO_BOOT_ROM $flag
- if { $flag } {
- echo "'reset halt' will now try to stop in the boot ROM"
- } else {
- echo "'reset halt' will now try to stop at the entry point in FLASH"
- }
-
- return ""
- }
- set FLASH_MEMORY_BASE 0x60000000
- proc init_reset { mode } {
- global RESET_INTO_BOOT_ROM
- global PENDING_ENTRY_POINT_ADDRESS
- set PENDING_ENTRY_POINT_ADDRESS 0
-
- if { ($mode eq "run") || $RESET_INTO_BOOT_ROM } {
- return
- }
-
- halt
- wait_halt 1000
-
- set bootmode [ get_boot_mode ]
- set bootdev [ get_boot_device ]
-
- if { $bootmode != 2 } {
- echo "Cannot reset into entry when boot mode is $bootmode"
- return
- }
-
- if { $bootdev != 0 } {
- echo "Cannot reset into entry when boot device is $bootdev"
- return
- }
-
- set entry_point [ get_reset_vector ]
-
- if { $entry_point == 0 } {
- echo "Cannot locate the reset vector in FLASH memory. Make sure FLASH is not empty and FlexSPI is initialized."
- return
- }
-
- set PENDING_ENTRY_POINT_ADDRESS $entry_point
- }
- #
- # Only SWD and SPD supported
- #
- source [find target/swj-dp.tcl]
- if { [info exists CPUTAPID] } {
- set _CPU_SWD_TAPID $CPUTAPID
- } else {
- set _CPU_SWD_TAPID 0x0BD11477
- }
- swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_SWD_TAPID
- dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
- set _TARGETNAME $_CHIPNAME.cpu
- target create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap
- if { [info exists WORKAREASIZE] } {
- set _WORKAREASIZE $WORKAREASIZE
- } else {
- set _WORKAREASIZE 0x4000
- }
- $_TARGETNAME configure -work-area-phys 0x20200000 \
- -work-area-size $_WORKAREASIZE \
- -work-area-backup 0
-
- $_TARGETNAME configure -event reset-deassert-post {
- global PENDING_ENTRY_POINT_ADDRESS
- set halt_timeout 1000
-
- if { $PENDING_ENTRY_POINT_ADDRESS } {
- wait_halt $halt_timeout
-
- set entry_point_hex [ format "0x%X" $PENDING_ENTRY_POINT_ADDRESS ]
- echo "Found entry point at $entry_point_hex. Setting a temporary breakpoint and resetting..."
- bp $entry_point_hex 2 hw
- resume
- wait_halt $halt_timeout
- rbp $entry_point_hex
- }
- }
- #Using SRST on i.MXRT devices will not get the chip to halt. Doing a system reset on the ARM Cortex level instead works as expected
- cortex_m reset_config sysresetreq
- reset_config none
- #To support FLASH programming on i.MXRT, download the FLASH plugin from https://github.com/sysprogs/flash_drivers and adjust/uncomment the line below:
- #flash bank imxrt plugin $FLASH_MEMORY_BASE 0 0 0 0 flash/IMXRT1050_HyperFLASH_ROMAPI.elf
|