January 20, 2025

Antminer S9 board - U-boot, going deeper with JTAG

We have built U-boot from source.
We have put BOOT.BIN with the spl onto an SD card.

We boot it, but see no serial output.

Time for JTAG

I have learned that it doesn't matter if we start this executable at 0 or 0x44 since address 0 holds a jump to 0x44 anyway. Here is what I see when I use JTAG to halt the processor:
halt
zynq.cpu0: MPIDR level2 0, cluster 0, core 0, multi core, no SMT
target halted in Thumb state due to debug-request, current mode: Supervisor
cpsr: 0x400001f3 pc: 0xfffff934
MMU: disabled, D-Cache: disabled, I-Cache: enabled

I examine memory at the start of OCM, and things are as expected:

mdw 0 32
0x00000000: ea00000f e59ff014 e59ff014 e59ff014 e59ff014 e59ff014 e59ff014 e59ff014
0x00000020: 00000040 00000040 00000040 00000040 00000040 00000040 00000040 deadbeef
0x00000040: eafffffe ea000012 e10f0000 e200101f e331001a 13c0001f 13800013 e38000c0
0x00000060: e129f000 ee110f10 e3c00a02 ee010f10 e59f0084 ee0c0f10 eb000006 eb00001d

arm disassemble 0 32
0x00000000  000f ea00	b	#0x44
0x00000004  f014 e59f	ldr	pc, [pc, #0x14]
0x00000008  f014 e59f	ldr	pc, [pc, #0x14]
0x0000000c  f014 e59f	ldr	pc, [pc, #0x14]
0x00000010  f014 e59f	ldr	pc, [pc, #0x14]
0x00000014  f014 e59f	ldr	pc, [pc, #0x14]
0x00000018  f014 e59f	ldr	pc, [pc, #0x14]
0x0000001c  f014 e59f	ldr	pc, [pc, #0x14]
0x00000020  0040 0000	andeq	r0, r0, r0, asr #32
0x00000024  0040 0000	andeq	r0, r0, r0, asr #32
0x00000028  0040 0000	andeq	r0, r0, r0, asr #32
0x0000002c  0040 0000	andeq	r0, r0, r0, asr #32
0x00000030  0040 0000	andeq	r0, r0, r0, asr #32
0x00000034  0040 0000	andeq	r0, r0, r0, asr #32
0x00000038  0040 0000	andeq	r0, r0, r0, asr #32
0x0000003c  beef dead	cdple	p14, #0xa, c11, c13, c15, #7
0x00000040  fffe eaff	b	#0x40
0x00000044  0012 ea00	b	#0x94

0x00000048  0000 e10f	mrs	r0, apsr
0x0000004c  101f e200	and	r1, r0, #0x1f
0x00000050  001a e331	teq	r1, #0x1a
0x00000054  001f 13c0	bicne	r0, r0, #0x1f
0x00000058  0013 1380	orrne	r0, r0, #0x13
0x0000005c  00c0 e380	orr	r0, r0, #0xc0
0x00000060  f000 e129	msr	cpsr_fc, r0
0x00000064  0f10 ee11	mrc	p15, #0, r0, c1, c0, #0
0x00000068  0a02 e3c0	bic	r0, r0, #0x2000
0x0000006c  0f10 ee01	mcr	p15, #0, r0, c1, c0, #0
.....
arm disassemble 0x94 32
0x00000094  ffeb eaff	b	#0x48
0x00000098  0000 e3a0	mov	r0, #0
0x0000009c  0f17 ee08	mcr	p15, #0, r0, c8, c7, #0
0x000000a0  0f15 ee07	mcr	p15, #0, r0, c7, c5, #0
0x000000a4  0fd5 ee07	mcr	p15, #0, r0, c7, c5, #6
0x000000a8  f04f f57f	dsb	sy
0x000000ac  f06f f57f	isb	sy
We can see that there is nothing wrong with starting at address 0, as that will just branch to 0x44 anyway. My objdump generated disassembly was incomplete and misleading. Also notice that 0x44 branches to 0x94, which branches to 0x48, which seems to start the show.

Note the spin loop at 0x40 that all of the vectors take you to. Next I try this:

resume 0x44
halt
target halted in ARM state due to debug-request, current mode: Abort
cpsr: 0x40000197 pc: 0x00000040
MMU: disabled, D-Cache: disabled, I-Cache: enabled
Data fault registers        DFSR: 00000001, DFAR: 78000023
Instruction fault registers IFSR: 00000000, IFAR: 00000000
Well, look at that. Now it has made its way to the spin loop at 0x40
Now I try this:
> resume 0x94
> halt
target halted in Thumb state due to debug-request, current mode: Supervisor
cpsr: 0x400001b3 pc: 0xfffffd86
MMU: disabled, D-Cache: disabled, I-Cache: enabled
> resume 0x94
> halt
target halted in ARM state due to debug-request, current mode: Undefined instruction
cpsr: 0x4000019b pc: 0x00000040
MMU: disabled, D-Cache: disabled, I-Cache: enabled
It seems to be a crap shoot whether it goes to the 0x40 spin loop to die or transitions the Thumb mode running in the last page (0xfffffxxx).

Source for the startup code is in arch/arm/cpu/armv7/start.S

Dig deeper using JTAG

We should be able to set a breakpoint at "main" using:
bp 0x4e0
But it doesn't work. Time to start reading, starting with my own old notes which have useful links. Also useful are these articles: They spend a lot of time on hardware details of the JTAG signals, but they have nice collections of links at the end of the articles.

Probably what I need to do, now that I have my feet wet with OpenOCD is to read the official PDF manual. It is 233 pages. I'll also note that you do OpenOCD scripting with Tcl.


Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org