Belkin RT3200/Linksys E8450 WiFi AX discussion

I have made it further in my attempt to recover one of my devices. I can now get the uboot running in memory through openocd and jtag interface. And I can run the tftpboot command to load the two image files. But if I power cycle the device it goes back to the beginning as if nothing was flashed.

Below are details. I'm sure this will get long so apologies but want to be complete in case someone else may want the info.

I'm using raspberry pi zero W with the headers I soldered in. Then I wire-wrapped to the following raspberry pi gpio/pin and soldered the other end to the jtag interface pins on the RT3200.

signal, rpi gpio number, rpi header pin number, RT3200 jtag pin number
TRST, 7, 26, 3
TDI, 10, 19, 5
TMS, 8, 24, 7
TCK, 11, 23, 9
TDO, 9, 21, 13
SRST, 24, 18, 15
GND, NA, 6, 20

I compiled openocd like this:

cd /usr/src
curl -L http://github.com/mtk-openwrt/openocd-scripts/archive/main.tar.gz | tar zxf -
#to make match Daniel's locations:
mv openocd-scripts-main mtk-openocd-scripts

git clone https://repo.or.cz/openocd.git
cd openocd
#curl https://raw.githubusercontent.com/mtk-openwrt/openocd-scripts/main/patch/0001-armv8-do-not-read-ESR_EL3-in-AArch32-state.patch | git am

cat /usr/src/mtk-openocd-scripts/patch/0001-armv8-do-not-read-ESR_EL3-in-AArch32-state.patch | git am
cat /usr/src/mtk-openocd-scripts/patch/0002-target-aarch64-enable-disable-mmu-new-commands.patch | git am

apt install build-essential git autoconf libtool make pkg-config libusb-1.0-0 libusb-1.0-0-dev tcl
./bootstrap |tee -i my_bootstrap.log
./configure --enable-sysfsgpio --enable-bcm2835gpio |tee -i my_configure.log
make -j 2 |tee -i my_make.log

Then once built, I ran the following to start openocd:

./src/openocd -f openocd.cfg -f /usr/src/mtk-openocd-scripts/mt7622/mt7622.cfg

Here is the content of my openocd.cfg file (which was modified from openocd tcl/interface/raspberrypi-native.cfg file):

# SPDX-License-Identifier: GPL-2.0-or-later

# Config for Raspberry Pi used as a bitbang adapter.
# https://www.raspberrypi.com/documentation/computers/raspberry-pi.html

# Supports all models with 40-pin or 26-pin GPIO connector up to Raspberry Pi 4 
B
# also supports Raspberry Pi Zero, Zero W and Zero 2 W.

# Adapter speed calibration is computed from cpufreq/scaling_max_freq.
# Adjusts automatically if CPU is overclocked.

adapter driver bcm2835gpio
adapter speed 50

proc read_file { name } {
        if {[catch {open $name r} fd]} {
                return ""
        }
        set result [read $fd]
        close $fd
        return $result
}

proc measure_clock {} {
        set result [exec vcgencmd measure_clock arm]
        set clock_hz [lindex [split $result "="] 1]
        expr { $clock_hz / 1000 }
}

proc get_max_cpu_clock { default } {
        set clock [read_file /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq]
        if { $clock > 100000 } {
                return $clock
        }

        # cpufreq not available. As the last resort try Broadcom's proprietary utility
        if {![catch measure_clock clock] && $clock > 100000} {
                return $clock
        }

        echo "WARNING: Host CPU clock unknown."
        echo "WARNING: Using the highest possible value $default kHz as a safe default."
        echo "WARNING: Expect JTAG/SWD clock significantly slower than requested."

        return $default
}

set compat [read_file /proc/device-tree/compatible]
set clocks_per_timing_loop 4

if {[string match *bcm2711* $compat]} {
        set speed_offset 52
} elseif {[string match *bcm2837* $compat] || [string match *bcm2710* $compat]} {
        set speed_offset 34
} elseif {[string match *bcm2836* $compat] || [string match *bcm2709* $compat]} {
        set speed_offset 36
} elseif {[string match *bcm2835* $compat] || [string match *bcm2708* $compat]} {
        set clocks_per_timing_loop 6
        set speed_offset 32
} else {
        set speed_offset 32
        echo "WARNING: Unknown type of the host SoC. Expect JTAG/SWD clock slower than requested."
}

set clock [get_max_cpu_clock 2000000]
set speed_coeff [expr { $clock / $clocks_per_timing_loop }]

# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET
# The coefficients depend on system clock and CPU frequency scaling.
bcm2835gpio speed_coeffs $speed_coeff $speed_offset

source raspberrypi-gpio-connector.cfg

#https://forum.openwrt.org/t/need-help-with-a-bricked-linksys-e8450/144836/16
adapter speed 10000
transport select jtag
#ftdi_tdo_sample_edge falling

#adapter srst delay 750
#jtag_ntrst_assert_width 100
#jtag_ntrst_delay 50

#reset_config trst_and_srst separate srst_gates_jtag srst_open_drain

# reset_config trst_only

# reset_config srst_only srst_push_pull

# or if you have both connected,
reset_config trst_and_srst srst_push_pull

Here is the content of my modified version of raspberrypi-gpio-connector.cfg file:

# SPDX-License-Identifier: GPL-2.0-or-later

#
# Config for Raspberry Pi GPIO header
#
# This is best used with a fast enough buffer but also
# is suitable for direct connection if the target voltage
# matches RPi's 3.3V and the cable is short enough.
#
# Do not forget the GND connection, e.g. pin 20 of the GPIO header.
#

# GPIO 25 (pin 22) previously used for TMS/SWDIO is pulled-down by default.
# The JTAG/SWD specification requires pull-up at the target board
# for either signal. Connecting the signal pulled-up on the target
# to the pull-down on the adapter is not a good idea.
# GPIO 8 is pulled-up by default.
echo "Warn : TMS/SWDIO moved to GPIO 8 (pin 24). Check the wiring please!"

# Each of the JTAG lines need a gpio number set: tck tms tdi tdo
# Header pin numbers: 23 24 19 21
adapter gpio tck -chip 0 11
adapter gpio tms -chip 0 8
adapter gpio tdi -chip 0 10
adapter gpio tdo -chip 0 9

# Each of the SWD lines need a gpio number set: swclk swdio
# Header pin numbers: 23 24
adapter gpio swclk -chip 0 11
adapter gpio swdio -chip 0 8

# If you define trst or srst, use appropriate reset_config
# Header pin numbers: TRST - 26, SRST - 18

adapter gpio trst -chip 0 7
# reset_config trst_only

adapter gpio srst -chip 0 24
# reset_config srst_only srst_push_pull

# or if you have both connected,
reset_config trst_and_srst srst_push_pull

Here is the content of the mt7622.cfg file (unmodified from mtk-openwrt):

#
# The MediaTek MT7622 is a highly integrated wireless network router SoC for
# for high wireless performance, home entertainment and home automation.
#
# Product page:
# https://www.mediatek.com/products/homenetworking/mt7622
#
# Specifications:
# - Dual-core ARM Cortex-A53 MPCoreTM @ 1.35GHz
# − 32KB L1 I-Cache and 32KB L1 D-Cache
# − 512KB unified L2 Cache
# − NEON/FPU
#

if { [info exists CHIPNAME] } {
    set _CHIPNAME $CHIPNAME
} else {
    set _CHIPNAME mt7622
}

if { [info exists DAP_TAPID] } {
   set _DAP_TAPID $DAP_TAPID
} else {
   set _DAP_TAPID 0x4ba00477
}

set _COREBASE {0x80810000 0x80910000}
set _CTIBASE  {0x80820000 0x80920000}
set _CORES 2

# declare the one JTAG tap to access the DAP
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -ignore-version -enable
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu

# declare the main application cores
set _TARGETNAME $_CHIPNAME.cpu
set _smp_command ""

for { set _core 0 } { $_core < $_CORES } { incr _core 1 } {

    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [lindex $_CTIBASE $_core] -ap-num 1

    set _command "target create ${_TARGETNAME}$_core aarch64 \
                         -dap $_CHIPNAME.dap -coreid $_core \
                         -cti cti$_core -dbgbase [lindex $_COREBASE $_core]"

    if { $_core != 0 } {
        # non-boot core examination may fail
        set _command "$_command -defer-examine"
        set _smp_command "$_smp_command ${_TARGETNAME}$_core"
    } else {
        set _smp_command "target smp ${_TARGETNAME}$_core"
    }

    eval $_command
}

eval $_smp_command

targets ${_TARGETNAME}0

Then in another window, start the telnet session:

telnet localhost 4444

Here are the commands I used in the telnet session. They are mainly from /usr/src/mtk-openocd-scripts/mt7622/readme.txt file:

halt
mww 0x10212000 0x22000000
mt7622.cpu0 configure -work-area-phys 0x101000 -work-area-size 8096

set cp [aarch64 mrc 15 0 1 0 0]
#Had to change expr syntax due to jimtcl 0.81 change included in openocd:
set cp [expr {$cp & ~1}]
aarch64 mcr 15 0 1 0 0 $cp

reg cpsr

reg cpsr 0x1d3

load_image /usr/src/mtk-openocd-scripts/mt7622/switch_mode_32_64.bin 0x100000 bin
load_image /usr/src/mtk-openocd-scripts/mt7622/aarch64_stall.bin 0x100100 bin
reg pc 0x100000
resume

halt
load_image /usr/src/mtk-openocd-scripts/mt7622/bl2-1c.bin 0x201000 bin
reg pc 0x201000
resume

halt
load_image /usr/src/mtk-openocd-scripts/mt7622/fip-snand-no-bmt.bin 0x40020000 bin
mww 0x100200 1
resume

Here is copy/paste of the telnet session output which looks like it worked:

root@raspberrypi:~# telnet localhost 4444
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> halt
> set cp [aarch64 mrc 15 0 1 0 0]
0xc50838
> set cp [expr {$cp & ~1}]
12912696
> aarch64 mcr 15 0 1 0 0 $cp
> reg cpsr
cpsr (/32): 0x600001f3
> poll
target halted in Thumb state due to debug-request, current mode: Supervisor
cpsr: 0x600001f3 pc: 0x0000b9d8
MMU: disabled, D-Cache: disabled, I-Cache: disabled
background polling: on
TAP: mt7622.cpu (enabled)
> reg cpsr 0x1d3
cpsr (/32): 0x000001d3
> poll
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x000001d3 pc: 0x0000b9d8
MMU: disabled, D-Cache: disabled, I-Cache: disabled
background polling: on
TAP: mt7622.cpu (enabled)
> load_image /usr/src/mtk-openocd-scripts/mt7622/switch_mode_32_64.bin 0x100000 bin
68 bytes written at address 0x00100000
downloaded 68 bytes in 0.009850s (6.742 KiB/s)
> load_image /usr/src/mtk-openocd-scripts/mt7622/aarch64_stall.bin 0x100100 bin
4 bytes written at address 0x00100100
downloaded 4 bytes in 0.006032s (0.648 KiB/s)
> reg pc 0x100000
pc (/64): 0x0000000000100000
> resume
mt7622.cpu0: Timeout waiting for resumex

> halt
mt7622.cpu0 halted in AArch64 state due to debug-request, current mode: EL3H
cpsr: 0x000003cd pc: 0x100100
MMU: disabled, D-Cache: disabled, I-Cache: disabled
> load_image /usr/src/mtk-openocd-scripts/mt7622/bl2-1c.bin 0x201000 bin
46133 bytes written at address 0x00201000
downloaded 46133 bytes in 0.356745s (126.286 KiB/s)
> reg pc 0x201000
pc (/64): 0x0000000000201000
> resume
> halt
mt7622.cpu0 halted in AArch64 state due to debug-request, current mode: EL3T
cpsr: 0x200002cc pc: 0x207d38
MMU: disabled, D-Cache: disabled, I-Cache: enabled
> load_image /usr/src/mtk-openocd-scripts/mt7622/fip-snand-no-bmt.bin 0x40020000 bin
616606 bytes written at address 0x40020000
downloaded 616606 bytes in 3.993011s (150.802 KiB/s)
> mww 0x100200 1
> resume

And the serial output looks like it works to get to the uboot prompt:

F0: 102B 0000
F1: 5000 1006
F3: 4000 0036
F5: 480A 0031
F5: 480A 0031
00: 1005 0000
F1: 5000 1006
F3: 4000 0036
F5: 480A 0031
F5: 480A 0031
01: 102A 0001
02: 1005 0000
BP: 0000 00C0 [0001]
T0: 0000 0350 [000F]
System halt!

NOTICE:  BL2: v2.4(release):516c195bf-dirty
NOTICE:  BL2: Built : 18:53:46, Feb  2 2021
INFO:    BL2: Doing platform setup
INFO:    PMIC: MediaTek MT6380 E3
INFO:    EMI: DRAMC calibration done
INFO:    EMI: Rank size auto detect
INFO:    EMI: Rank size: 0x20000000
INFO:    EMI: complex R/W mem test passed
INFO:    BL2: Loading image id 3
INFO:    Loading image id=3 at address 0x43001000
INFO:    Image id=3 loaded: 0x43001000 - 0x4300c0dd
INFO:    BL2: Loading image id 5
INFO:    Loading image id=5 at address 0x41e00000
INFO:    Image id=5 loaded: 0x41e00000 - 0x41e8b739
NOTICE:  BL2: Booting BL31
INFO:    Entry point address = 0x43001000
INFO:    SPSR = 0x3cd
INFO:    Secondary bootloader is AArch64
NOTICE:  BL31: v2.4(release):638b6e19e
NOTICE:  BL31: Built : 10:17:31, Feb 25 2021
INFO:    ARM GICv2 driver initialized
INFO:    BL31: Initializing runtime services
INFO:    BL31: Preparing for EL3 exit to normal world
INFO:    Entry point address = 0x41e00000
INFO:    SPSR = 0x3c9
serial_mtk serial@11002000: pinctrl_select_state_full: uclass_get_device_by_phandle_id: err=-19


U-Boot 2021.04-rc3-gdc001ffc7d-dirty (Mar 05 2021 - 17:10:16 +0800)

CPU:   MediaTek MT7622
Model: mt7622-rfb
DRAM:  256 MiB
WDT:   Started with servicing (60s timeout)
MMC:   mmc@11230000: 0, mmc@11240000: 1
In:    serial@11002000
Out:   serial@11002000
Err:   serial@11002000
Net:
Warning: ethernet@1b100000 (eth0) using random MAC address - ae:54:c2:5d:13:d1
eth0: ethernet@1b100000
MT7622>

If I run the tftpboot to load the two files and it looks like works:

MT7622> tftpboot openwrt_recovery.itb
Using ethernet@1b100000 device
TFTP from server 192.168.1.2; our IP address is 192.168.1.1
Filename 'openwrt_recovery.itb'.
Load address: 0x4007ff28
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ###############################################################
         6.7 MiB/s
done
Bytes transferred = 7602176 (740000 hex)

MT7622> tftpboot openwrt_sysupgrade.itb
Using ethernet@1b100000 device
TFTP from server 192.168.1.2; our IP address is 192.168.1.1
Filename 'openwrt_sysupgrade.itb'.
Load address: 0x4007ff28
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ######################
         6.8 MiB/s
done
Bytes transferred = 9863475 (968133 hex)
MT7622>

BTW - the file names above were shortened when i put them on the tftp server so it was easier for me to type into the serial console. The original files I used were:

openwrt-23.05.0-mediatek-mt7622-linksys_e8450-ubi-initramfs-recovery.itb

openwrt-23.05.0-mediatek-mt7622-linksys_e8450-ubi-squashfs-sysupgrade.itb

But if I power cycle, it doesn't work. It comes back to "System halt!" or the "failed to load BL2" message again.

Is there anything else I can check from the uboot menu to see if the flash chip is working? I'm new to this and have experimented with some commands but nothing seems to show a working SPI flash chip.

MT7622> sf read
No SPI flash selected. Please run `sf probe'


MT7622> sf probe
spi frequency: 46666653 Hz
jedec_spi_nor spi-flash@0: unrecognized JEDEC id bytes: ff, e5, 71
Failed to initialize SPI flash at 0:0 (error -2)

MT7622> bdinfo
boot_params = 0x0000000040000100
DRAM bank   = 0x0000000000000000
-> start    = 0x0000000040000000
-> size     = 0x0000000010000000
flashstart  = 0x0000000000000000
flashsize   = 0x0000000000000000
flashoffset = 0x0000000000000000
baudrate    = 115200 bps
relocaddr   = 0x000000004ff5c000
reloc off   = 0x000000000e15c000
Build       = 64-bit
current eth = ethernet@1b100000
ethaddr     = (not set)
IP addr     = 192.168.1.1
fdt_blob    = 0x000000004f7fd3e0
new_fdt     = 0x000000004f7fd3e0
fdt_size    = 0x00000000000029c0
lmb_dump_all:
    memory.cnt             = 0x1
    memory.size            = 0x0
    memory.reg[0x0].base   = 0x40000000
                   .size   = 0x10000000

    reserved.cnt           = 0x1
    reserved.size          = 0x0
    reserved.reg[0x0].base = 0x4f7fb8e0
                     .size = 0x804720
arch_number = 0x0000000000000000
TLB addr    = 0x000000004fff0000
irq_sp      = 0x000000004f7fd3d0
sp start    = 0x000000004f7fd3d0
Early malloc usage: 5b0 / 4000

Thanks,
Jason