User Tools

Site Tools


doc:recipes:debrick.ath79.using.jtag

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.

  • telnet console - for linux or PuTTY console - for Windows.
  • ath79.cfg - config. file for the OpenOCD program and your target device (config. file must be copied to OpenOCD your installation folder as the /usr/local/share/openocd/scripts/target/ath79.cfg).
  • backup.bin - conditional bootloader or other fragment of SPI-flash memory data you want to restore.

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.

  • After we make and install the OpenOCD program, ath79.cfg config. file must be copied to your OpenOCD installation folder as the /usr/local/share/openocd/scripts/target/ath79.cfg
  • Connect JTAG to the PC and router (router must be turned OFF).
  • After that turn ON your bricked router.
  • Run OpenOCD with next parameters:
    sudo openocd -f interface/parport.cfg -f target/ath79.cfg -c "adapter_khz 6000"
    If you use a different JTAG adapter, parport.cfg name of interface should be changed to the appropriate name of the configuration file for your JTAG adapter. Of course, you have to pre-build OpenOCD program with support this interface.

Working with the program OpenOCD

  • Once we have turned ON the router, our target is to detect ID 0x00000001 (standard Atheros CPU identifier):
    ubuntu@ubuntu:~$ 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
    Info : JTAG tap: ath79.cpu tap/device found: 0x00000001 (mfg: 0x000 (<invalid>), part: 0x0000, ver: 0x0)
    Info : accepting 'telnet' connection on tcp/4444
    If you could not identify the ID at once, try to go to the next step and enter "reset" in the telnet console. If the program still does not identify the CPU ID, check the JTAG connection cable for possible errors, as the cause of a problem may lie in the length of the cable used.
  • If everything is successful, run in new shell telnet console or PuTTY at address 127.0.0.1 and port 4444, after connecting to the console should display input prompt:
    ubuntu@ubuntu:~$ telnet localhost 4444
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    Open On-Chip Debugger
    > 
    • Next, enter the commands:
      > reset
      JTAG tap: ath79.cpu tap/device found: 0x00000001 (mfg: 0x000 (<invalid>), part: 0x0000, ver: 0x0)
      > 
      This command does not affect the state of the processor, because we do not use RST pin. However, the command once again detects the ID and state of the processor.


      > halt      
      ath79.cpu: target state: halted
      target halted in MIPS32 mode due to debug-request, pc: 0xbfc03860
      > 
      This command puts the processor from the state "running" to the state "halted" - in this state, the processor receives commands from operator.


      > reset init
      JTAG tap: ath79.cpu tap/device found: 0x00000001 (mfg: 0x000 (<invalid>), part: 0x0000, ver: 0x0)
      ath79.cpu: target state: halted
      target halted in MIPS32 mode due to debug-request, pc: 0xbfc03860
      > 
      Initializing the main script in the ath79.cfg configuration file. In this case, the script commands sent a group of commands (enclosed in braces) for the event reset init.


      > flash probe 0
      read_flash_id: 16311c
      Found flash device 'eon en25f32' (ID 0x0016311c)
      flash 'ath79' found at 0xbf000000
      > 
      Probing the flash. Detects flash memory identifier, if the flash-chip is not supported by the driver, there will be written.


      > flash info 0
      #0 : ath79 at 0xbf000000, size 0x00400000, buswidth 0, chipwidth 0
      	#  0: 0x00000000 (0x10000 64kB) protected
      	#  1: 0x00010000 (0x10000 64kB) protected
      	#  2: 0x00020000 (0x10000 64kB) protected
      	#  3: 0x00030000 (0x10000 64kB) protected
      	#  4: 0x00040000 (0x10000 64kB) protected
      	#  5: 0x00050000 (0x10000 64kB) protected
      	#  6: 0x00060000 (0x10000 64kB) protected
      	#  7: 0x00070000 (0x10000 64kB) protected
      	#  8: 0x00080000 (0x10000 64kB) protected
      	#  9: 0x00090000 (0x10000 64kB) protected
      	# 10: 0x000a0000 (0x10000 64kB) protected
      	# 11: 0x000b0000 (0x10000 64kB) protected
      	# 12: 0x000c0000 (0x10000 64kB) protected
      	# 13: 0x000d0000 (0x10000 64kB) protected
      	# 14: 0x000e0000 (0x10000 64kB) protected
      	# 15: 0x000f0000 (0x10000 64kB) protected
      	# 16: 0x00100000 (0x10000 64kB) protected
      	# 17: 0x00110000 (0x10000 64kB) protected
      	# 18: 0x00120000 (0x10000 64kB) protected
      	# 19: 0x00130000 (0x10000 64kB) protected
      	# 20: 0x00140000 (0x10000 64kB) protected
      	# 21: 0x00150000 (0x10000 64kB) protected
      	# 22: 0x00160000 (0x10000 64kB) protected
      	# 23: 0x00170000 (0x10000 64kB) protected
      	# 24: 0x00180000 (0x10000 64kB) protected
      	# 25: 0x00190000 (0x10000 64kB) protected
      	# 26: 0x001a0000 (0x10000 64kB) protected
      	# 27: 0x001b0000 (0x10000 64kB) protected
      	# 28: 0x001c0000 (0x10000 64kB) protected
      	# 29: 0x001d0000 (0x10000 64kB) protected
      	# 30: 0x001e0000 (0x10000 64kB) protected
      	# 31: 0x001f0000 (0x10000 64kB) protected
      	# 32: 0x00200000 (0x10000 64kB) protected
      	# 33: 0x00210000 (0x10000 64kB) protected
      	# 34: 0x00220000 (0x10000 64kB) protected
      	# 35: 0x00230000 (0x10000 64kB) protected
      	# 36: 0x00240000 (0x10000 64kB) protected
      	# 37: 0x00250000 (0x10000 64kB) protected
      	# 38: 0x00260000 (0x10000 64kB) protected
      	# 39: 0x00270000 (0x10000 64kB) protected
      	# 40: 0x00280000 (0x10000 64kB) protected
      	# 41: 0x00290000 (0x10000 64kB) protected
      	# 42: 0x002a0000 (0x10000 64kB) protected
      	# 43: 0x002b0000 (0x10000 64kB) protected
      	# 44: 0x002c0000 (0x10000 64kB) protected
      	# 45: 0x002d0000 (0x10000 64kB) protected
      	# 46: 0x002e0000 (0x10000 64kB) protected
      	# 47: 0x002f0000 (0x10000 64kB) protected
      	# 48: 0x00300000 (0x10000 64kB) protected
      	# 49: 0x00310000 (0x10000 64kB) protected
      	# 50: 0x00320000 (0x10000 64kB) protected
      	# 51: 0x00330000 (0x10000 64kB) protected
      	# 52: 0x00340000 (0x10000 64kB) protected
      	# 53: 0x00350000 (0x10000 64kB) protected
      	# 54: 0x00360000 (0x10000 64kB) protected
      	# 55: 0x00370000 (0x10000 64kB) protected
      	# 56: 0x00380000 (0x10000 64kB) protected
      	# 57: 0x00390000 (0x10000 64kB) protected
      	# 58: 0x003a0000 (0x10000 64kB) protected
      	# 59: 0x003b0000 (0x10000 64kB) protected
      	# 60: 0x003c0000 (0x10000 64kB) protected
      	# 61: 0x003d0000 (0x10000 64kB) protected
      	# 62: 0x003e0000 (0x10000 64kB) protected
      	# 63: 0x003f0000 (0x10000 64kB) protected
      
      SMI flash information:
        Device 'eon en25f32' (ID 0x0016311c)
      
      > 
      Where first two sectors (#0,#1) is uboot and last sector (#63) is art partition (for 4MByte flash and TP-LINK platform).


      > dump_image uboot.bin 0x9f000000 0x20000  
      dumped 131072 bytes in 88.281433s (1.450 KiB/s)
      > dump_image art.bin 0x9f3f0000 0x10000    
      dumped 65536 bytes in 47.600506s (1.345 KiB/s)
      > 
      Buckup uboot and art partition.


      > flash write_image unlock uboot.bin 0xbf000000
      auto unlock enabled
      writing 256 bytes to flash page @0x00000000
      writing 256 bytes to flash page @0x00000100
      writing 256 bytes to flash page @0x00000200
      writing 256 bytes to flash page @0x00000300
      writing 256 bytes to flash page @0x00000400
      writing 256 bytes to flash page @0x00000500
      ...
      writing 256 bytes to flash page @0x0001ef00
      writing 256 bytes to flash page @0x0001f000
      writing 256 bytes to flash page @0x0001fb00
      writing 256 bytes to flash page @0x0001fc00
      writing 256 bytes to flash page @0x0001fd00
      writing 256 bytes to flash page @0x0001fe00
      wrote 131072 bytes from file uboot.bin in 1968.353027s (0.065 KiB/s)
      Writing flash at base (bank) flash address.
      Note: This is not very high Write speed because I use the old JTAG adapter (500KHz).

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

doc/recipes/debrick.ath79.using.jtag.txt · Last modified: 2017/06/03 00:03 by Dioptimizer