Import xPack OpenOCD 0.12.0-7 and GNU Make 4.4.1 from x86_64-w64-mingw32.

This commit is contained in:
2026-09-14 16:20:05 +08:00
parent 2b73c30a9d
commit 534c017e0f
1133 changed files with 74341 additions and 0 deletions
@@ -0,0 +1,115 @@
# SPDX-License-Identifier: GPL-2.0-or-later
echo "\n\nFirmware recovery helpers"
echo "Use -c firmware_help to get help\n"
set known_boards {
"asus-rt-n16 ASUS RT-N16"
"asus-rt-n66u ASUS RT-N66U"
"linksys-wag200g Linksys WAG200G"
"linksys-wrt54gl Linksys WRT54GL v1.1"
"netgear-dg834v3 Netgear DG834G v3"
"tp-link_tl-mr3020 TP-LINK TL-MR3020"
"bt-homehubv1 BT HomeHub v1"
}
proc firmware_help { } {
echo "
Your OpenOCD command should look like this:
openocd -f interface/<jtag adapter>.cfg -f tools/firmware-recovery.tcl -c \"<commands>*; shutdown\"
Where:
<jtag adapter> is one of the supported devices, e.g. ftdi/jtagkey2
<commands> are firmware-recovery commands separated by semicolon
Supported commands:
firmware_help get this help
list_boards list known boards and exit
board <name> select board you work with
list_partitions list partitions of the currently selected board
dump_part <name> <filename> save partition's contents to a file
erase_part <name> erase the given partition
flash_part <name> <filename> erase, flash and verify the given partition
ram_boot <filename> load binary file to RAM and run it
adapter speed <freq> set JTAG clock frequency in kHz
For example, to clear nvram and reflash CFE on an RT-N16 using TUMPA, run:
openocd -f interface/ftdi/tumpa.cfg -f tools/firmware-recovery.tcl \\
-c \"board asus-rt-n16; erase_part nvram; flash_part CFE cfe-n16.bin; shutdown\"
\n\n"
shutdown
}
# set default, can be overridden later
adapter speed 1000
proc get_partition { name } {
global partition_list
dict get $partition_list $name
}
proc partition_desc { name } { lindex [get_partition $name] 0 }
proc partition_start { name } { lindex [get_partition $name] 1 }
proc partition_size { name } { lindex [get_partition $name] 2 }
proc list_boards { } {
global known_boards
echo "List of the supported boards:\n"
echo "Board name\t\tDescription"
echo "-----------------------------------"
foreach i $known_boards {
echo $i
}
echo "\n\n"
}
proc board { name } {
script [find board/$name.cfg]
}
proc list_partitions { } {
global partition_list
set fstr "%-16s%-14s%-14s%s"
echo "\nThe currently selected board is known to have these partitions:\n"
echo [format $fstr Name Start Size Description]
echo "-------------------------------------------------------"
for {set i 0} {$i < [llength $partition_list]} {incr i 2} {
set key [lindex $partition_list $i]
echo [format $fstr $key [partition_start $key] [partition_size $key] [partition_desc $key]]
}
echo "\n\n"
}
# Magic to work with any targets, including semi-functional
proc prepare_target { } {
init
catch {halt}
catch {reset init}
catch {halt}
}
proc dump_part { name filename } {
prepare_target
dump_image $filename [partition_start $name] [partition_size $name]
}
proc erase_part { name } {
prepare_target
flash erase_address [partition_start $name] [partition_size $name]
}
proc flash_part { name filename } {
prepare_target
flash write_image erase $filename [partition_start $name] bin
echo "Verifying:"
verify_image $filename [partition_start $name]
}
proc ram_boot { filename } {
global ram_boot_address
prepare_target
load_image $filename $ram_boot_address bin
resume $ram_boot_address
}
echo ""
@@ -0,0 +1,191 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Algorithms by Michael Barr, released into public domain
# Ported to OpenOCD by Shane Volpe, additional fixes by Paul Fertser
set CPU_MAX_ADDRESS 0xFFFFFFFF
source [find bitsbytes.tcl]
source [find memory.tcl]
proc runAllMemTests { baseAddress nBytes } {
memTestDataBus $baseAddress
memTestAddressBus $baseAddress $nBytes
memTestDevice $baseAddress $nBytes
}
#***********************************************************************************
# *
# * Function: memTestDataBus()
# *
# * Description: Test the data bus wiring in a memory region by
# * performing a walking 1's test at a fixed address
# * within that region. The address (and hence the
# * memory region) is selected by the caller.
# * Ported from:
# * http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C
# * Notes:
# *
# * Returns: Empty string if the test succeeds.
# * A non-zero result is the first pattern that failed.
# *
#***********************************************************************************
proc memTestDataBus { address } {
echo "Running memTestDataBus"
for {set i 0} {$i < 32} {incr i} {
# Shift bit
set pattern [expr {1 << $i}]
# Write pattern to memory
memwrite32 $address $pattern
# Read pattern from memory
set data [memread32 $address]
if {$data != $pattern} {
echo "FAILED DATABUS: Address: $address, Pattern: $pattern, Returned: $data"
return $pattern
}
}
}
#***********************************************************************************
# *
# * Function: memTestAddressBus()
# *
# * Description: Perform a walking 1's test on the relevant bits
# * of the address and check for aliasing. This test
# * will find single-bit address failures such as stuck
# * -high, stuck-low, and shorted pins. The base address
# * and size of the region are selected by the caller.
# * Ported from:
# * http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C
# *
# * Notes: For best results, the selected base address should
# * have enough LSB 0's to guarantee single address bit
# * changes. For example, to test a 64-Kbyte region,
# * select a base address on a 64-Kbyte boundary. Also,
# * select the region size as a power-of-two--if at all
# * possible.
# *
# * Returns: Empty string if the test succeeds.
# * A non-zero result is the first address at which an
# * aliasing problem was uncovered. By examining the
# * contents of memory, it may be possible to gather
# * additional information about the problem.
# *
#***********************************************************************************
proc memTestAddressBus { baseAddress nBytes } {
set addressMask [expr {$nBytes - 1}]
set pattern 0xAAAAAAAA
set antipattern 0x55555555
echo "Running memTestAddressBus"
echo "addressMask: [convertToHex $addressMask]"
echo "memTestAddressBus: Writing the default pattern at each of the power-of-two offsets..."
for {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}] } {
set addr [expr {$baseAddress + $offset}]
memwrite32 $addr $pattern
}
echo "memTestAddressBus: Checking for address bits stuck high..."
memwrite32 $baseAddress $antipattern
for {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}]} {
set addr [expr {$baseAddress + $offset}]
set data [memread32 $addr]
if {$data != $pattern} {
echo "FAILED DATA_ADDR_BUS_SHIGH: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]"
return $pattern
}
}
echo "memTestAddressBus: Checking for address bits stuck low or shorted..."
memwrite32 $baseAddress $pattern
for {set testOffset 32} {[expr {$testOffset & $addressMask}] != 0} {set testOffset [expr {$testOffset << 1}] } {
set addr [expr {$baseAddress + $testOffset}]
memwrite32 $addr $antipattern
set data [memread32 $baseAddress]
if {$data != $pattern} {
echo "FAILED DATA_ADDR_BUS_SLOW: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]"
return $pattern
}
for {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}]} {
set addr [expr {$baseAddress + $offset}]
set data [memread32 $baseAddress]
if {(($data != $pattern) && ($offset != $testOffset))} {
echo "FAILED DATA_ADDR_BUS_SLOW2: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset], testOffset [convertToHex $testOffset]"
return $pattern
}
}
set addr [expr {$baseAddress + $testOffset}]
memwrite32 $addr $pattern
}
}
#***********************************************************************************
# *
# * Function: memTestDevice()
# *
# * Description: Test the integrity of a physical memory device by
# * performing an increment/decrement test over the
# * entire region. In the process every storage bit
# * in the device is tested as zero and as one. The
# * base address and the size of the region are
# * selected by the caller.
# * Ported from:
# * http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C
# * Notes:
# *
# * Returns: Empty string if the test succeeds.
# * A non-zero result is the first address at which an
# * incorrect value was read back. By examining the
# * contents of memory, it may be possible to gather
# * additional information about the problem.
# *
#***********************************************************************************
proc memTestDevice { baseAddress nBytes } {
echo "Running memTestDevice"
echo "memTestDevice: Filling memory with a known pattern..."
for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {
memwrite32 [expr {$baseAddress + $offset}] $pattern
}
echo "memTestDevice: Checking each location and inverting it for the second pass..."
for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {
set addr [expr {$baseAddress + $offset}]
set data [memread32 $addr]
if {$data != $pattern} {
echo "FAILED memTestDevice_pattern: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset]"
return $pattern
}
set antiPattern [expr {~$pattern}]
memwrite32 [expr {$baseAddress + $offset}] $antiPattern
}
echo "memTestDevice: Checking each location for the inverted pattern and zeroing it..."
for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {
set antiPattern [expr {~$pattern & ((1<<32) - 1)}]
set addr [expr {$baseAddress + $offset}]
set data [memread32 $addr]
set dataHex [convertToHex $data]
set antiPatternHex [convertToHex $antiPattern]
if {$dataHex != $antiPatternHex} {
echo "FAILED memTestDevice_antipattern: Address: [convertToHex $addr], antiPattern: $antiPatternHex, Returned: $dataHex, offset: $offset"
return $pattern
}
}
}
proc convertToHex { value } {
format 0x%08x $value
}
@@ -0,0 +1,50 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Description:
# Measure the CPU clock frequency of an ARM Cortex-M based device.
#
# Return:
# The CPU clock frequency in Hz. A negative value indicates that the loop
# counter was saturated.
#
# Note:
# You may need to adapt the number of cycles for your device.
#
add_help_text cortex_m_test_cpu_speed "Measure the CPU clock frequency of an ARM Cortex-M based device"
add_usage_text cortex_m_test_cpu_speed {address [timeout [cycles_per_loop]]}
proc cortex_m_test_cpu_speed { address { timeout 200 } { cycles_per_loop 4 } } {
set loop_counter_start 0xffffffff
halt
# Backup registers and memory.
set backup_regs [get_reg -force {pc r0 xpsr}]
set backup_mem [read_memory $address 16 3]
# We place the following code at the given address to measure the
# CPU clock frequency:
#
# 3801: subs r0, #1
# d1fd: bne #-2
# e7fe: b #-4
write_memory $address 16 {0x3801 0xd1fd 0xe7fe}
set_reg "pc $address r0 $loop_counter_start"
resume
sleep $timeout
halt
# Get the loop counter value from register r0.
set loop_counter_end [dict values [get_reg r0]]
set loop_counter_diff [expr {$loop_counter_start - $loop_counter_end}]
# Restore registers and memory.
set_reg $backup_regs
write_memory $address 16 $backup_mem
if { [expr {$loop_counter_end == 0}] } {
return -1
}
return [expr {double($loop_counter_diff) * $cycles_per_loop / $timeout * 1000}]
}