Recently came up with solution to use cheap chinese ST Link v2 clone JTAG adapter with MIPS CPUs, for which even supplier claimed it doesn't support MIPS (and indeed it doesn't, at least not with ST firmware and software). Support for this clone known as Baite has been added to dirtyjtag firmware which can be run with urjtag software, and from some testing it seems functional, except for missing/untested low level commands.
Since these commands are not needed for OpenOCD as the software communicates directly with SPI flash chip, I've decided to try to make it work.
As a result, here is tutorial on how to flash this Baite adapter and use it to recover Archcer C7 v1 router that had broken u-boot flashed, it is likely this will work for v2 and v3 versions, possibly for v4 and v5 but these use newer QCA956X socs and I'm not sure they even have JTAG headers on board.
Download Versaloon firmware (md5 ed4f8fee72e27a4297248d572c784583) for the adapter and flash it to the device following this procedure:
Get USB-UART adapter, in this case CP2102 was used and connect it to Baite as shown in the photo.
Plug in the USB-UART adapter to your PC and flash Versaloon firmware by issuing these commands:
Important: Do not plug in Baite adapter to USB port at this point!
stm32flash -k /dev/ttyUSB0
stm32flash -u /dev/ttyUSB0
stm32flash -o /dev/ttyUSB0
stm32flash -w Versaloon-STM32F103C8_Baite.bin -v /dev/ttyUSB0
Note: this was done on ubuntu 16.04.6, other OS may recognize USB-UART different than ttyUSB0, -k and -u parameters disable flash read/write protection, -o erases flash and -w writes firmware to it
Disconnect the USB-UART adapter from Baite and verify that the new firmware is running properly by plugging in Baite to your PC. lsusb should display 0483:a038 STMicroelectronics ID.
Disconnect Baite from PC and proceed with JTAG connection to the router. You need to connect 5 pins to the board: TCK, TMS, TDI, TDO and GND.
Wiring schematics:
Next plug in Baite to your PC, and short CS pin of the SPI flash chip on router to one of the router's GND pins. Power on router and remove the object used to short CS pin after few seconds (when ethernet LEDs go off)
Now run the actual debug program, OpenOCD:
openocd -f interface/vsllink.cfg -f target/ath79.cfg
It should display the following content:
Open On-Chip Debugger 0.10.0+dev-00916-g42cee46 (2019-06-20-15:01)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
jtag
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : Versaloon(0x22)by Simon(compiled on Jun 21 2019)
Info : USB_TO_XXX abilities: 0x00000008:0x00000083:0xC0000007
Info : clock speed 100 kHz
Info : JTAG tap: ath79.cpu tap/device found: 0x00000001 (mfg: 0x000 (<invalid>), part: 0x0000, ver: 0x0)
Info : Listening on port 3333 for gdb connections
Now open telnet session in another terminal and issue reset command to verifiy things are working:
telnet 127.0.0.1 4444
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Open On-Chip Debugger
> reset
JTAG tap: ath79.cpu tap/device found: 0x00000001 (mfg: 0x000 (<invalid>), part: 0x0000, ver: 0x0)
Issue halt command to enter debug mode:
> halt
MIPS32 with MIPS16 support implemented
target halted in MIPS32 mode due to debug-request, pc: 0xbfc005ec
Issue reset-init command to disable flash remap:
> reset init
JTAG tap: ath79.cpu tap/device found: 0x00000001 (mfg: 0x000 (<invalid>), part: 0x0000, ver: 0x0)
target halted in MIPS32 mode due to debug-request, pc: 0xbfc005ec
Try to detect SPI flash chip:
> flash probe 0
Found flash device 'win w25q64fv/jv' (ID 0x001740ef)
flash 'ath79' found at 0xbf000000
Show more info about SPI flash chip:
> flash info 0
#0 : ath79 at 0xbf000000, size 0x00800000, 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
# 64: 0x00400000 (0x10000 64kB) protected
# 65: 0x00410000 (0x10000 64kB) protected
# 66: 0x00420000 (0x10000 64kB) protected
# 67: 0x00430000 (0x10000 64kB) protected
# 68: 0x00440000 (0x10000 64kB) protected
# 69: 0x00450000 (0x10000 64kB) protected
# 70: 0x00460000 (0x10000 64kB) protected
# 71: 0x00470000 (0x10000 64kB) protected
# 72: 0x00480000 (0x10000 64kB) protected
# 73: 0x00490000 (0x10000 64kB) protected
# 74: 0x004a0000 (0x10000 64kB) protected
# 75: 0x004b0000 (0x10000 64kB) protected
# 76: 0x004c0000 (0x10000 64kB) protected
# 77: 0x004d0000 (0x10000 64kB) protected
# 78: 0x004e0000 (0x10000 64kB) protected
# 79: 0x004f0000 (0x10000 64kB) protected
# 80: 0x00500000 (0x10000 64kB) protected
# 81: 0x00510000 (0x10000 64kB) protected
# 82: 0x00520000 (0x10000 64kB) protected
# 83: 0x00530000 (0x10000 64kB) protected
# 84: 0x00540000 (0x10000 64kB) protected
# 85: 0x00550000 (0x10000 64kB) protected
# 86: 0x00560000 (0x10000 64kB) protected
# 87: 0x00570000 (0x10000 64kB) protected
# 88: 0x00580000 (0x10000 64kB) protected
# 89: 0x00590000 (0x10000 64kB) protected
# 90: 0x005a0000 (0x10000 64kB) protected
# 91: 0x005b0000 (0x10000 64kB) protected
# 92: 0x005c0000 (0x10000 64kB) protected
# 93: 0x005d0000 (0x10000 64kB) protected
# 94: 0x005e0000 (0x10000 64kB) protected
# 95: 0x005f0000 (0x10000 64kB) protected
# 96: 0x00600000 (0x10000 64kB) protected
# 97: 0x00610000 (0x10000 64kB) protected
# 98: 0x00620000 (0x10000 64kB) protected
# 99: 0x00630000 (0x10000 64kB) protected
#100: 0x00640000 (0x10000 64kB) protected
#101: 0x00650000 (0x10000 64kB) protected
#102: 0x00660000 (0x10000 64kB) protected
#103: 0x00670000 (0x10000 64kB) protected
#104: 0x00680000 (0x10000 64kB) protected
#105: 0x00690000 (0x10000 64kB) protected
#106: 0x006a0000 (0x10000 64kB) protected
#107: 0x006b0000 (0x10000 64kB) protected
#108: 0x006c0000 (0x10000 64kB) protected
#109: 0x006d0000 (0x10000 64kB) protected
#110: 0x006e0000 (0x10000 64kB) protected
#111: 0x006f0000 (0x10000 64kB) protected
#112: 0x00700000 (0x10000 64kB) protected
#113: 0x00710000 (0x10000 64kB) protected
#114: 0x00720000 (0x10000 64kB) protected
#115: 0x00730000 (0x10000 64kB) protected
#116: 0x00740000 (0x10000 64kB) protected
#117: 0x00750000 (0x10000 64kB) protected
#118: 0x00760000 (0x10000 64kB) protected
#119: 0x00770000 (0x10000 64kB) protected
#120: 0x00780000 (0x10000 64kB) protected
#121: 0x00790000 (0x10000 64kB) protected
#122: 0x007a0000 (0x10000 64kB) protected
#123: 0x007b0000 (0x10000 64kB) protected
#124: 0x007c0000 (0x10000 64kB) protected
#125: 0x007d0000 (0x10000 64kB) protected
#126: 0x007e0000 (0x10000 64kB) protected
#127: 0x007f0000 (0x10000 64kB) protected
ATH79 flash information:
Device 'win w25q64fv/jv' (ID 0x001740ef)
Saving previously written u-boot area content:
> dump_image ubootbad.bin 0x9f000000 0x20000
dumped 131072 bytes in 404.372253s (0.317 KiB/s)
Remove protection from u-boot blocks in SPI flash:
> flash protect 0 0 1 off
cleared protection for sectors 0 through 1 on flash bank 0
Erase u-boot section on the flash before writing new u-boot:
> flash erase_sector 0 0 1
erased sectors 0 through 1 on flash bank 0 in 2.167238s
Write working u-boot image to the SPI flash chip:
> flash write_image uboot.bin 0xbf000000
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 @0x0001fc00
writing 256 bytes to flash page @0x0001fd00
writing 256 bytes to flash page @0x0001fe00
wrote 131072 bytes from file uboot.bin in 7880.783203s (0.016 KiB/s)
Now your router has restored working u-boot in the SPI flash chip, power it off, disconnect the Baite adapter, power it back on and let it boot or reflash firmware/art using tftp-serial method.
Troubleshooting:
If you get this error on openocd starting
Open On-Chip Debugger 0.10.0+dev-00916-g42cee46 (2019-06-20-15:01)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
jtag
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : Versaloon(0x22)by Simon(compiled on Jun 21 2019)
Error: (null) command 0x00 failed with 0x7f
Error: Fail to initialize usbtoxxx.
it's because versaloon have some bugs. Simply run again:
openocd -f interface/vsllink.cfg -f target/ath79.cfg
If dumping image exits to prompt
> dump_image boot.bin 0x9f000000 0x20000
>
it may indicate problems with JTAG wiring (unconfirmed) or bug in openocd (i've compiled master version, you can try older/stable openocd release) First several attempts to read flash this way worked for me, even with adapter khz 150, but later it always failed (no matter if set khz to 1, 10 ,50, 80 or 100), sometimes it managed to read part of flash and then the process was interrupted. Slow flash reading still works, e.g: flash read_bank 0 blk1 0x00010000 0x10000
update: adapter speeds tested thoroughly, at 300khz connection is not possible, lowered to 270khz and so far more than 10 read/write cycles completed without any data coruption (no failed attempts). at this rate it takes 3m40s to read 128KB of u-boot data and about 45 min to write (modified u-boot from @pepe2k), or somewhat less than 1h30m if writing tplink u-boot
Note: When u-boot is partially damaged (but still no output on serial console) it is required to pull CS pin of the SPI flash to GND, in order to enter JTAG mode. When u-boot is completely erased, or damaged from the first sector in flash then CS pin remains low on bootstrap (after initial transition from high to low) and it is not required to short GND pin to CS for JTAG to work.