Table of Contents

Debrick ath79 using JTAG

Since with this commit and this fix now OpenOCD program support SPI driver for ATH79 SoCs.

This means, that you do NOT need to patch the OpenOCD program for support the ath79-spi driver. However, you may need to change the /openocd/src/flash/nor/spi.c source file for support your NOR-flash chip with specific JEDEC ID.

Supported SoCs: AR71xx, AR91xx, AR724x, AR93xx, QCA95xx.

Unlike the method with initializing a processor and memory - this method is more functional because You do not need to look for special registers for a specific SoC. The OpenOCD program will be use the SPI-chip directly. Therefore, this method is good for the recovery of data on flash with any processor of the ath79 family where there is → JTAG port.

Pinout EJTAG v3.1 port on ath79 looks like this:

EJTAG on DIR-615 Ex EJTAG on TL-WR1043ND
ASCII tl-wr1043nd_serial.jpg

Using nSRST (RST) pin - in the case of damage the bootloader this pin is optional. Even more, on the Atheros SoC, it not only resets SoC also it resets the TAP controller.
In the case your bootloader is not damaged the JTAG on router may not work at all, because during the boot process, in the bootloader, JTAG can be disabled and configured for GPIOs or other stuff.
Limit only in that, does support your NOR-flash chip by OpenOCD program or not. If not - you can manual add support of your NOR-flash chip in program at the stage of compiling the program.

How to Build

For build the program I use Linux (Ubuntu) and this guide or this guide:

sudo apt-get update
sudo apt-get install libtool automake libusb-1.0 git
git clone git://openocd.git.sourceforge.net/gitroot/openocd/openocd
cd ~/openocd
git pull
./bootstrap

Note: I use a short version of the packages installation for Ubuntu to support OpenOCD because I only need the parallel port.

The next step configures support of program OpenOCD specific interfaces, for more help, see “./configure -help” option.
Most likely you will need to use other options for your JTAG-interface. For example, I'll use (Wiggler parallel port JTAG adapter) and here my options:

./configure --enable-maintainer-mode --disable-werror --disable-shared --enable-parport --enable-parport_ppdev

Note: Besides in my case, I compile with “--disable-werror” option because I have Warning messages, otherwise it will be have error at the stage of compiling the program.

Before we make and install the program, what you should do next is located in the file /openocd/src/flash/nor/spi.c of source - you must find name of your NOR-flash chip in this list. If your chip not listed, then go to this point, okay, now make it:

make
sudo make install


Supported NOR-flash chips by default (02.06.17)

	...
	/* name, erase_cmd, chip_erase_cmd, device_id, pagesize, sectorsize, size_in_bytes */
	FLASH_ID("st m25p05",      0xd8, 0xc7, 0x00102020, 0x80,  0x8000,  0x10000),
	FLASH_ID("st m25p10",      0xd8, 0xc7, 0x00112020, 0x80,  0x8000,  0x20000),
	FLASH_ID("st m25p20",      0xd8, 0xc7, 0x00122020, 0x100, 0x10000, 0x40000),
	FLASH_ID("st m25p40",      0xd8, 0xc7, 0x00132020, 0x100, 0x10000, 0x80000),
	FLASH_ID("st m25p80",      0xd8, 0xc7, 0x00142020, 0x100, 0x10000, 0x100000),
	FLASH_ID("st m25p16",      0xd8, 0xc7, 0x00152020, 0x100, 0x10000, 0x200000),
	FLASH_ID("st m25p32",      0xd8, 0xc7, 0x00162020, 0x100, 0x10000, 0x400000),
	FLASH_ID("st m25p64",      0xd8, 0xc7, 0x00172020, 0x100, 0x10000, 0x800000),
	FLASH_ID("st m25p128",     0xd8, 0xc7, 0x00182020, 0x100, 0x40000, 0x1000000),
	FLASH_ID("st m45pe10",     0xd8, 0xd8, 0x00114020, 0x100, 0x10000, 0x20000),
	FLASH_ID("st m45pe20",     0xd8, 0xd8, 0x00124020, 0x100, 0x10000, 0x40000),
	FLASH_ID("st m45pe40",     0xd8, 0xd8, 0x00134020, 0x100, 0x10000, 0x80000),
	FLASH_ID("st m45pe80",     0xd8, 0xd8, 0x00144020, 0x100, 0x10000, 0x100000),
	FLASH_ID("sp s25fl004",    0xd8, 0xc7, 0x00120201, 0x100, 0x10000, 0x80000),
	FLASH_ID("sp s25fl008",    0xd8, 0xc7, 0x00130201, 0x100, 0x10000, 0x100000),
	FLASH_ID("sp s25fl016",    0xd8, 0xc7, 0x00140201, 0x100, 0x10000, 0x200000),
	FLASH_ID("sp s25fl116k",   0xd8, 0xc7, 0x00154001, 0x100, 0x10000, 0x200000),
	FLASH_ID("sp s25fl032",    0xd8, 0xc7, 0x00150201, 0x100, 0x10000, 0x400000),
	FLASH_ID("sp s25fl132k",   0xd8, 0xc7, 0x00164001, 0x100, 0x10000, 0x400000),
	FLASH_ID("sp s25fl064",    0xd8, 0xc7, 0x00160201, 0x100, 0x10000, 0x800000),
	FLASH_ID("sp s25fl164k",   0xd8, 0xc7, 0x00174001, 0x100, 0x10000, 0x800000),
	FLASH_ID("sp s25fl128",    0xd8, 0xc7, 0x00182001, 0x100, 0x10000, 0x1000000),
	FLASH_ID("sp s25fl256",    0xd8, 0xc7, 0x00190201, 0x100, 0x10000, 0x2000000),
	FLASH_ID("atmel 25f512",   0x52, 0xc7, 0x0065001f, 0x80,  0x8000,  0x10000),
	FLASH_ID("atmel 25f1024",  0x52, 0x62, 0x0060001f, 0x100, 0x8000,  0x20000),
	FLASH_ID("atmel 25f2048",  0x52, 0x62, 0x0063001f, 0x100, 0x10000, 0x40000),
	FLASH_ID("atmel 25f4096",  0x52, 0x62, 0x0064001f, 0x100, 0x10000, 0x80000),
	FLASH_ID("atmel 25fs040",  0xd7, 0xc7, 0x0004661f, 0x100, 0x10000, 0x80000),
	FLASH_ID("mac 25l512",     0xd8, 0xc7, 0x001020c2, 0x010, 0x10000, 0x10000),
	FLASH_ID("mac 25l1005",    0xd8, 0xc7, 0x001120c2, 0x010, 0x10000, 0x20000),
	FLASH_ID("mac 25l2005",    0xd8, 0xc7, 0x001220c2, 0x010, 0x10000, 0x40000),
	FLASH_ID("mac 25l4005",    0xd8, 0xc7, 0x001320c2, 0x010, 0x10000, 0x80000),
	FLASH_ID("mac 25l8005",    0xd8, 0xc7, 0x001420c2, 0x010, 0x10000, 0x100000),
	FLASH_ID("mac 25l1605",    0xd8, 0xc7, 0x001520c2, 0x100, 0x10000, 0x200000),
	FLASH_ID("mac 25l3205",    0xd8, 0xc7, 0x001620c2, 0x100, 0x10000, 0x400000),
	FLASH_ID("mac 25l6405",    0xd8, 0xc7, 0x001720c2, 0x100, 0x10000, 0x800000),
	FLASH_ID("micron n25q064", 0xd8, 0xc7, 0x0017ba20, 0x100, 0x10000, 0x800000),
	FLASH_ID("micron n25q128", 0xd8, 0xc7, 0x0018ba20, 0x100, 0x10000, 0x1000000),
	FLASH_ID("win w25q80bv",   0xd8, 0xc7, 0x001440ef, 0x100, 0x10000, 0x100000),
	FLASH_ID("win w25q32fv",   0xd8, 0xc7, 0x001640ef, 0x100, 0x10000, 0x400000),
	FLASH_ID("win w25q32dw",   0xd8, 0xc7, 0x001660ef, 0x100, 0x10000, 0x400000),
	FLASH_ID("win w25q64cv",   0xd8, 0xc7, 0x001740ef, 0x100, 0x10000, 0x800000),
	FLASH_ID("win w25q128fv",  0xd8, 0xc7, 0x001840ef, 0x100, 0x10000, 0x1000000),
	FLASH_ID("gd gd25q20",     0x20, 0xc7, 0x00c84012, 0x100, 0x1000,  0x80000),
	FLASH_ID("gd gd25q16c",    0xd8, 0xc7, 0x001540c8, 0x100, 0x10000, 0x200000),
	FLASH_ID("gd gd25q32c",    0xd8, 0xc7, 0x001640c8, 0x100, 0x10000, 0x400000),
	FLASH_ID("gd gd25q128c",   0xd8, 0xc7, 0x001840c8, 0x100, 0x10000, 0x1000000),
	FLASH_ID(NULL,             0,    0,	   0,          0,     0,       0)

Also you can manual add your not listed NOR-flash chip in /openocd/src/flash/nor/spi.c file of OpenOCD sources.
Note: That JEDEC ID here in the reversed byte (big-endian) ordering format (for example: 0x001840ef = 0xef401800).

Using OpenOCD

This part includes a list of programs that will be needed in the process of debugging and recovery through the JTAG interface. Also, this section contains a list of used OpenOCD commands and configuration file for ATH79 SoC's.

Used commands in OpenOCD

reset

The example presented in this section, the command is only used as - identify the ID and state of the processor, not more.


halt

Put the processor in debug state (receiving commands from operator).


reset init

After running this command, the script will be executed for this event (enclosed in braces), which is in the config. file (send commands to the processor).


dump_image <filename> <starting address in memory or flash-chip> <size>

This command saves a dump of the memory/flash-chip to the file. Command can be executed before initialize the CPU and memory. To read the flash memory, use the address 0x9f000000


flash write_image unlock <filename> <starting address in flash-chip>

This command starts writing flash-chip from file at starting address.


ath79.cfg

# Atheros ATH79 MIPS SoC.
# tested on AP83 and AP99 reference board
#
# source: https://forum.openwrt.org/viewtopic.php?pid=297299#p297299

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

if { [info exists ENDIAN] } {
   set _ENDIAN $ENDIAN
} else {
   set _ENDIAN big
}

if { [info exists CPUTAPID] } {
   set _CPUTAPID $CPUTAPID
} else {
   set _CPUTAPID 0x00000001
}

jtag_ntrst_assert_width 200
jtag_ntrst_delay 1

reset_config trst_only

jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID

set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME mips_m4k -endian $_ENDIAN -chain-position $_TARGETNAME

$_TARGETNAME configure -event reset-init {
	# disable flash remap
	mww 0xbf000004 0x43
}

# serial SPI capable flash
# flash bank <driver> <base> <size> <chip_width> <bus_width>
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME ath79 0xbf000000 0x01000000 0 0 $_TARGETNAME

Recovery example

Recovery the bootloader u-boot and art section, on the AR7241 SoC in the Ubuntu operating system. If you need, in the same way, additionally, it is possible to flash the firmware image or fully flash-chip - fullflash.

Working with the program OpenOCD

Problems

Unknown flash device

> flash probe 0
read_flash_id: 16311c
Unknown flash device (ID 0x0016311c)
in procedure 'flash'
> 

Solution: You can add manual support for your flash-chip by editing /openocd/src/flash/nor/spi.c file of OpenOCD sources.

Read datasheet for your SPI NOR flash-chip(search by name of flash on package), in datasheet you can find necessary registers for the driver. Or copy it from other driver.
Note: That JEDEC ID here in the reversed byte (big-endian) ordering format (for example: 0x0016311c = 0x1c311600).

Error: JTAG scan chain interrogation failed: all ones

ubuntu@ubuntu:~/openocd$ sudo openocd -f interface/parport.cfg -f target/ath79.cfg -c "adapter_khz 6000"
Open On-Chip Debugger 0.10.0-dev-00247-g73b676c-dirty (2016-03-12-07:52)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Warn : Adapter driver 'parport' did not declare which transports it allows; assuming legacy JTAG-only
Info : only one transport option; autoselect 'jtag'
parport port = 0x0
jtag_ntrst_assert_width: 200
jtag_ntrst_delay: 1
trst_only separate trst_push_pull
adapter speed: 6000 kHz
Info : clock speed 500 kHz
Error: JTAG scan chain interrogation failed: all ones
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway...
Error: ath79.cpu: IR capture error; saw 0x1f not 0x01
Warn : Bypassing JTAG setup events due to errors

Solution: Check the JTAG connection cable for possible errors, Check TDO signal

When TDO is connected to the JTAG adapter the signal must return to 3.3V in rest. Optionally add a 10kΩ pullup resistor to 3V3 (between pins TDO and VCC 3V3).

Forum discussion and source

https://forum.openwrt.org/viewtopic.php?id=34993