April 30, 2024

A hobos guide to OpenOCD, part 2

A note in passing. There is a document "IEEE 1149.1" that gives a myriad of details about JTAG.

Another note (to myself) my files for this are in /u1/Projects/OpenOCD.

Part 1 gave a general introduction to OpenOCD, along with mixed results using Versaloon as a JTAG adapter. I spent a day building a cable adapter for my Segger J-link clone that allows me to connect its 20 pin cable to the 14 pin JTAG connector on my Ebaz board with a Xilinx Zynq chip.

Just launching OpenOCD, I see these messages:

Warn : An adapter speed is not selected in the init scripts. OpenOCD will try to run the adapter at the low speed (100 kHz)
Warn : To remove this warnings and achieve reasonable communication speed with the target, set "adapter speed" or "jtag_rclk" in the init scripts.
Info : J-Link ARM V8 compiled Nov 28 2014 13:44:46
Info : Hardware version: 8.00
Info : VTarget = 3.338 V
Info : clock speed 100 kHz
Warn : There are no enabled taps.  AUTO PROBING MIGHT NOT WORK!!
Info : JTAG tap: auto0.tap tap/device found: 0x13722093 (mfg: 0x049 (Xilinx), part: 0x3722, ver: 0x1)
Info : JTAG tap: auto1.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)
Warn : AUTO auto0.tap - use "jtag newtap auto0 tap -irlen 2 -expected-id 0x13722093"
Warn : AUTO auto1.tap - use "jtag newtap auto1 tap -irlen 2 -expected-id 0x4ba00477"
So, OpenOCD detects two JTAG "tap"s, one by Xilinx (probably the FPGA or PL part of the Zynq), and another by ARM (probably the dual core ARM processor).

Among the files in /usr/share/openocd I found /usr/share/openocd/scripts/target/zynq_7000.cfg. I made a copy of this, commenting out the portions related to the FPGA (PL) part of the Zynq chip leaving me with this:

jtag newtap zynq_pl bs -irlen 6 -ircapture 0x1 -irmask 0x03 \
    -expected-id 0x23727093 \
    -expected-id 0x13722093 \
    -expected-id 0x03727093 \
    -expected-id 0x03736093

jtag newtap zynq cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4ba00477

dap create zynq.dap -chain-position zynq.cpu

target create zynq.cpu0 cortex_a -dap zynq.dap \
    -coreid 0 -dbgbase 0x80090000
target create zynq.cpu1 cortex_a -dap zynq.dap \
    -coreid 1 -dbgbase 0x80092000
Then I type this command:
openocd -f /usr/share/openocd/scripts/interface/jlink.cfg -c "transport select jtag" -f z1.cfg
Open On-Chip Debugger 0.12.0
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Warn : An adapter speed is not selected in the init scripts. OpenOCD will try to run the adapter at the low speed (100 kHz)
Warn : To remove this warnings and achieve reasonable communication speed with the target, set "adapter speed" or "jtag_rclk" in the init scripts.
Info : J-Link ARM V8 compiled Nov 28 2014 13:44:46
Info : Hardware version: 8.00
Info : VTarget = 3.338 V
Info : clock speed 100 kHz
Info : JTAG tap: zynq_pl.bs tap/device found: 0x13722093 (mfg: 0x049 (Xilinx), part: 0x3722, ver: 0x1)
Info : JTAG tap: zynq.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)
Info : zynq.cpu0: hardware has 6 breakpoints, 4 watchpoints
Info : zynq.cpu1: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for zynq.cpu0 on 3333
Info : Listening on port 3333 for gdb connections
Info : starting gdb server for zynq.cpu1 on 3334
Info : Listening on port 3334 for gdb connections
This is real progress. I am not sure whether my previous difficulties were related to bugs in Versaloon or whether I had somehow gotten the Zynq into a bad mood by giving "newtap" commands out of order, but this gives us the results we are looking for. I'll also note that we can stop and then restart openocd without confusion. The thing to do now is to take some time to inspect what we have done in some detail.

A look at JTAG "TAP"s

A TAP is a "test access port" and these are the heart of JTAG. As the OpenOCD manual says, "Setting up the TAPs is the core task of your configuration files." A TAP has a data register (DR) and an index register (IR). For some reason the size of the IR can be a mystery to be solved. As you can see above, the "irlen" for the FPGA tap is 6, whereas the "irlen" for the CPU tap on the Zynq is 4. Somebody worked all of this out for the Zynq and put it into the file I tripped across.

For the time being, I intend to ignore the TAP for the FPGA (PL). But it is important to configure it via a newtap command (and in the proper order) or things will get confused. There is plenty more about all of this in Section 10 of the OpenOCD manual.

The important and exciting thing for our purposes is that we have a TAP configured for the ARM processor pair, with the name "zynq.cpu".

Now we need a DAP

There seems to be potential for confusion here. There is also something called "DAP" that seems to be an alternative to JTAG that is implmented by some devices. ARM documents talk about a "JTAG debug port" and that seems to be what OpenOCD calls a DAP. Searching on this led me to these interesting articles: Specifying a DAP is simple once we have out TAP configured:
dap create zynq.dap -chain-position zynq.cpu
The main point of a DAP is to then define debug targets, which are what GDB will be looking for.

Debug targets

These are created as follows:
target create zynq.cpu0 cortex_a -dap zynq.dap -coreid 0 -dbgbase 0x80090000
target create zynq.cpu1 cortex_a -dap zynq.dap -coreid 1 -dbgbase 0x80092000
Where do the "dbgbase" values come from? At this point, who knows?
The command "targets" now shows us:
> targets
    TargetName         Type       Endian TapName            State
--  ------------------ ---------- ------ ------------------ ------------
 0  zynq.cpu0          cortex_a   little zynq.cpu           running
 1* zynq.cpu1          cortex_a   little zynq.cpu           running
And there are our two cores. The type (cortex_a) indicates an ARMv7-A core with an MMU. The asterisk next to core 1 indicates that it is the current target, and this is probably not what we want. There is a "target" command with a multitude of options.
We can switch the current target like this:
> targets zynq.cpu0
> targets
    TargetName         Type       Endian TapName            State
--  ------------------ ---------- ------ ------------------ ------------
 0* zynq.cpu0          cortex_a   little zynq.cpu           running
 1  zynq.cpu1          cortex_a   little zynq.cpu           running

What are these cores doing?

Well, right this moment, they are running linux on my Ebaz board and I can get to a bash shell via the uart. If I had a network cable connected, I could undoubtedly connect via ssh. We can do this:
> halt
DSCR_DTR_RX_FULL, dscr 0x4b08e003
zynq.cpu0: MPIDR level2 0, cluster 0, core 0, multi core, no SMT
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x00030093 pc: 0xc0116288
MMU: enabled, D-Cache: enabled, I-Cache: enabled
> targets
    TargetName         Type       Endian TapName            State
--  ------------------ ---------- ------ ------------------ ------------
 0* zynq.cpu0          cortex_a   little zynq.cpu           halted
 1  zynq.cpu1          cortex_a   little zynq.cpu           running

> resume
Note that this only halts core 0 (the current target). Once we type "resume" we are back to running linux as though nothing ever happened.

I reboot linux, then type "d" to get to the U-boot prompt. I can type "targets 1" to switch to core 1. It scolds me, but does what I want.

> targets 1
use 'zynq.cpu1' as target identifier, not '1'
> targets
    TargetName         Type       Endian TapName            State
--  ------------------ ---------- ------ ------------------ ------------
 0  zynq.cpu0          cortex_a   little zynq.cpu           running
 1* zynq.cpu1          cortex_a   little zynq.cpu           running

> halt
zynq.cpu1: MPIDR level2 0, cluster 0, core 1, multi core, no SMT
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x000001d3 pc: 0xffffff34
MMU: disabled, D-Cache: disabled, I-Cache: disabled
> arm disassemble 0xffffff00 64
0xffffff00  0004 f800	.byte	0x04, 0x00, 0x00, 0xf8
0xffffff04  767b 0000	andeq	r7, r0, fp, ror r6
0xffffff08  0000 0000	andeq	r0, r0, r0
0xffffff0c  0000 0000	andeq	r0, r0, r0
0xffffff10  0000 0000	andeq	r0, r0, r0
0xffffff14  0000 0000	andeq	r0, r0, r0
0xffffff18  0004 0000	andeq	r0, r0, r4
0xffffff1c  0000 0000	andeq	r0, r0, r0
0xffffff20  f04f f57f	dsb	sy
0xffffff24  f002 e320	wfe
0xffffff28  fffc eaff	b	#0xffffff20
0xffffff2c  f04f f57f	dsb	sy
0xffffff30  f002 e320	wfe
0xffffff34  000f e3e0	mvn	r0, #0xf
0xffffff38  e000 e590	ldr	lr, [r0]
0xffffff3c  00d4 e37e	cmn	lr, #0xd4
0xffffff40  fff9 0aff	beq	#0xffffff2c
0xffffff44  0f15 ee07	mcr	p15, #0, r0, c7, c5, #0
0xffffff48  0fd5 ee07	mcr	p15, #0, r0, c7, c5, #6
0xffffff4c  0f17 ee08	mcr	p15, #0, r0, c8, c7, #0
0xffffff50  4000 e3a0	mov	r4, #0
0xffffff54  4f10 ee01	mcr	p15, #0, r4, c1, c0, #0
0xffffff58  ff1e e12f	bx	lr
0xffffff5c  0000 0000	andeq	r0, r0, r0
0xffffff60  0000 0000	andeq	r0, r0, r0

0xfffffff0  ff2c ffff	.byte	0x2c, 0xff, 0xff, 0xff
So, there you have it. Core 1 "parked" in a typical wait loop in OCM (on chip memory). And with core 1 halted, U-Boot still stays running just fine via Core 0.

What does this code do? The mvn instruction loads and flips all the bits, so it would yield 0xfffffff0 in r0. It would then read from this address and compare to the negative of 0xd4 (which is .... 0xffffff2c just as we see stored there).

If this value changes, we fall out of the loop and after performing some processor state fiddling we jump (via bx lr) to the address placed there. This all makes sense.

ARM debugging

How much can we do with OpenOCD and when should we switch to using gdb?

We have hardware breakpoints (via the "bp" command") and can look at all the ARM registers (more than you would imagine) using the "reg" command.

The reset command

At this point this simply doesn't work. I get this:
> reset halt
JTAG tap: zynq_pl.bs tap/device found: 0x13722093 (mfg: 0x049 (Xilinx), part: 0x3722, ver: 0x1)
JTAG tap: zynq.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)
zynq.cpu0: how to reset?
I think it is a bug that it asks "how to reset?" given that I told it "reset halt". The bug is simply the message that makes you think you typed something wrong, whereas in fact it actually has a hardware issue. It should say "unable to reset" perhaps.

Maybe this can be fixed by some reset configuration, but I am well aware that the Ebaz does not provide any reset signals on the JTAG connector and this may be the root of this issue.

Breakpoints

bp addr len - set a breakpoint
rbp addr -- remove breakpoint at address
rbp all -- remove all breakpoints
Why do breakpoints have a length? I do this to set a breakpoint. U-boot is running.
halt
bp 0x200 4
resume
Then I type the command "reset" to U-boot. It performs a reset and the breakpoint endures. This looks promising:
zynq.cpu0: hardware has 6 breakpoints, 4 watchpoints
> bp
IVA breakpoint: 0x00000200, 0x4, 0x0b
The acronym "IVA" is an ARM thing standing for "instruction virtual address". No luck so far. I am hoping of course to get a breakpoint to catch the bootrom code running. Apparently this was a sw breakpoing by default.

So let's try again, but now set hardware breakpoints:

> rbp all
> bp 0x200 8 hw
breakpoint set at 0x00000200
> bp 0x1200 8 hw
breakpoint set at 0x00001200
> bp 0x2200 8 hw
breakpoint set at 0x00002200
> bp 0xffff0200 8 hw
breakpoint set at 0xffff0200
> bp
Breakpoint(IVA): 0x00000200, 0x8, 0
Breakpoint(IVA): 0x00001200, 0x8, 1
Breakpoint(IVA): 0x00002200, 0x8, 2
Breakpoint(IVA): 0xffff0200, 0x8, 3
> resume
Then we type reset to U-boot and get:
target halted in ARM state due to breakpoint, current mode: IRQ
cpsr: 0x600001d2 pc: 0x00000200
MMU: disabled, D-Cache: disabled, I-Cache: disabled
Aha, now that seems more like it.
Now I do this:
> arm disassemble 0 256
0x00000000  0049 ea00	b	#0x12c
0x00000004  0025 ea00	b	#0xa0
0x00000008  002b ea00	b	#0xbc
0x0000000c  003b ea00	b	#0x100
0x00000010  0032 ea00	b	#0xe0
0x00000014  f000 e320	nop
0x00000018  0000 ea00	b	#0x20
0x0000001c  000f ea00	b	#0x60
0x00000020  500f e92d	push	{r0, r1, r2, r3, ip, lr}
0x00000024  0b10 ed2d	vpush	{d0, d1, d2, d3, d4, d5, d6, d7}
0x00000028  0b20 ed6d	vpush	{d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
0x0000002c  1a10 eef1	vmrs	r1, fpscr
0x00000030  1004 e52d	str	r1, [sp, #-4]!
0x00000034  1a10 eef8	vmrs	r1, fpexc
0x00000038  1004 e52d	str	r1, [sp, #-4]!
0x0000003c  2125 eb00	bl	#0x84d8
0x00000040  1004 e49d	pop	{r1}
0x00000044  1a10 eee8	vmsr	fpexc, r1
0x00000048  1004 e49d	pop	{r1}
0x0000004c  1a10 eee1	vmsr	fpscr, r1
0x00000050  0b20 ecfd	vpop	{d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
0x00000054  0b10 ecbd	vpop	{d0, d1, d2, d3, d4, d5, d6, d7}
0x00000058  500f e8bd	pop	{r0, r1, r2, r3, ip, lr}
0x0000005c  f004 e25e	subs	pc, lr, #4
0x00000060  500f e92d	push	{r0, r1, r2, r3, ip, lr}
0x00000064  0b10 ed2d	vpush	{d0, d1, d2, d3, d4, d5, d6, d7}
0x00000068  0b20 ed6d	vpush	{d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
0x0000006c  1a10 eef1	vmrs	r1, fpscr
0x00000070  1004 e52d	str	r1, [sp, #-4]!
0x00000074  1a10 eef8	vmrs	r1, fpexc
0x00000078  1004 e52d	str	r1, [sp, #-4]!
0x0000007c  2110 eb00	bl	#0x84c4
0x00000080  1004 e49d	pop	{r1}
0x00000084  1a10 eee8	vmsr	fpexc, r1
0x00000088  1004 e49d	pop	{r1}
0x0000008c  1a10 eee1	vmsr	fpscr, r1
0x00000090  0b20 ecfd	vpop	{d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
0x00000094  0b10 ecbd	vpop	{d0, d1, d2, d3, d4, d5, d6, d7}
0x00000098  500f e8bd	pop	{r0, r1, r2, r3, ip, lr}
0x0000009c  f004 e25e	subs	pc, lr, #4
0x000000a0  500f e92d	push	{r0, r1, r2, r3, ip, lr}
0x000000a4  0074 e59f	ldr	r0, [pc, #0x74]
0x000000a8  1004 e24e	sub	r1, lr, #4
0x000000ac  1000 e580	str	r1, [r0]
0x000000b0  210d eb00	bl	#0x84ec
0x000000b4  500f e8bd	pop	{r0, r1, r2, r3, ip, lr}
0x000000b8  f00e e1b0	movs	pc, lr
0x000000bc  500f e92d	push	{r0, r1, r2, r3, ip, lr}
0x000000c0  0020 e310	tst	r0, #0x20
0x000000c4  00b2 115e	ldrhne	r0, [lr, #-2]
0x000000c8  0cff 13c0	bicne	r0, r0, #0xff00
0x000000cc  0004 051e	ldreq	r0, [lr, #-4]
0x000000d0  04ff 03c0	biceq	r0, r0, #0xff000000
0x000000d4  2109 eb00	bl	#0x8500
0x000000d8  500f e8bd	pop	{r0, r1, r2, r3, ip, lr}
0x000000dc  f00e e1b0	movs	pc, lr
0x000000e0  f04f f57f	dsb	sy
0x000000e4  500f e92d	push	{r0, r1, r2, r3, ip, lr}
0x000000e8  0034 e59f	ldr	r0, [pc, #0x34]
0x000000ec  1008 e24e	sub	r1, lr, #8
0x000000f0  1000 e580	str	r1, [r0]
0x000000f4  2106 eb00	bl	#0x8514
0x000000f8  500f e8bd	pop	{r0, r1, r2, r3, ip, lr}
0x000000fc  f008 e25e	subs	pc, lr, #8
0x00000100  f04f f57f	dsb	sy
0x00000104  500f e92d	push	{r0, r1, r2, r3, ip, lr}
0x00000108  0018 e59f	ldr	r0, [pc, #0x18]
0x0000010c  1004 e24e	sub	r1, lr, #4
0x00000110  1000 e580	str	r1, [r0]
0x00000114  2103 eb00	bl	#0x8528
0x00000118  500f e8bd	pop	{r0, r1, r2, r3, ip, lr}
0x0000011c  f004 e25e	subs	pc, lr, #4
0x00000120  0cf4 0002	strdeq	r0, r1, [r2], -r4
0x00000124  0cfc 0002	strdeq	r0, r1, [r2], -ip
0x00000128  0cf8 0002	strdeq	r0, r1, [r2], -r8
0x0000012c  1fb0 ee10	mrc	p15, #0, r1, c0, c0, #5
0x00000130  100f e201	and	r1, r1, #0xf
0x00000134  0000 e351	cmp	r1, #0
0x00000138  0001 0a00	beq	#0x144
0x0000013c  f002 e320	wfe
0x00000140  fffd eaff	b	#0x13c
0x00000144  030c e59f	ldr	r0, [pc, #0x30c]
0x00000148  1000 e590	ldr	r1, [r0]
0x0000014c  1080 e211	ands	r1, r1, #0x80
0x00000150  0009 0a00	beq	#0x17c
0x00000154  0300 e59f	ldr	r0, [pc, #0x300]
0x00000158  1300 e59f	ldr	r1, [pc, #0x300]
0x0000015c  1000 e580	str	r1, [r0]
0x00000160  02fc e59f	ldr	r0, [pc, #0x2fc]
0x00000164  1000 e590	ldr	r1, [r0]
0x00000168  1022 e381	orr	r1, r1, #0x22
0x0000016c  1000 e580	str	r1, [r0]
0x00000170  02f0 e59f	ldr	r0, [pc, #0x2f0]
0x00000174  12f0 e59f	ldr	r1, [pc, #0x2f0]
0x00000178  1000 e580	str	r1, [r0]
0x0000017c  0f10 ee10	mrc	p15, #0, r0, c0, c0, #0
0x00000180  560f e200	and	r5, r0, #0xf00000
0x00000184  600f e200	and	r6, r0, #0xf
0x00000188  6825 e186	orr	r6, r6, r5, lsr #16
0x0000018c  0022 e356	cmp	r6, #0x22
0x00000190  af30 de1f	mrcle	p15, #0, sl, c15, c0, #1
0x00000194  a010 d38a	orrle	sl, sl, #0x10
0x00000198  af30 de0f	mcrle	p15, #0, sl, c15, c0, #1
0x0000019c  0602 e335	teq	r5, #0x200000
0x000001a0  af30 0e1f	mrceq	p15, #0, sl, c15, c0, #1
0x000001a4  a040 038a	orreq	sl, sl, #0x40
0x000001a8  af30 0e0f	mcreq	p15, #0, sl, c15, c0, #1
0x000001ac  02bc e59f	ldr	r0, [pc, #0x2bc]
0x000001b0  0f10 ee0c	mcr	p15, #0, r0, c12, c0, #0
0x000001b4  72b8 e59f	ldr	r7, [pc, #0x2b8]
0x000001b8  62b8 e59f	ldr	r6, [pc, #0x2b8]
0x000001bc  6000 e587	str	r6, [r7]
0x000001c0  0000 e3a0	mov	r0, #0
0x000001c4  0f17 ee08	mcr	p15, #0, r0, c8, c7, #0
0x000001c8  0f15 ee07	mcr	p15, #0, r0, c7, c5, #0
0x000001cc  0fd5 ee07	mcr	p15, #0, r0, c7, c5, #6
0x000001d0  007c eb00	bl	#0x3c8
0x000001d4  0f10 ee11	mrc	p15, #0, r0, c1, c0, #0
0x000001d8  0001 e3c0	bic	r0, r0, #1
0x000001dc  0f10 ee01	mcr	p15, #0, r0, c1, c0, #0
0x000001e0  0000 e10f	mrs	r0, apsr
0x000001e4  101f e3e0	mvn	r1, #0x1f
0x000001e8  2000 e001	and	r2, r1, r0
0x000001ec  2012 e382	orr	r2, r2, #0x12
0x000001f0  f002 e129	msr	cpsr_fc, r2
0x000001f4  d280 e59f	ldr	sp, [pc, #0x280]
0x000001f8  2c02 e3c2	bic	r2, r2, #0x200
0x000001fc  f002 e16f	msr	spsr_fsxc, r2
0x00000200  0000 e10f	mrs	r0, apsr
0x00000204  101f e3e0	mvn	r1, #0x1f
0x00000208  2000 e001	and	r2, r1, r0
0x0000020c  2013 e382	orr	r2, r2, #0x13
0x00000210  f002 e129	msr	cpsr_fc, r2
0x00000214  d264 e59f	ldr	sp, [pc, #0x264]
0x00000218  2c02 e3c2	bic	r2, r2, #0x200
0x0000021c  f002 e16f	msr	spsr_fsxc, r2
0x00000220  0000 e10f	mrs	r0, apsr
0x00000224  101f e3e0	mvn	r1, #0x1f
0x00000228  2000 e001	and	r2, r1, r0
0x0000022c  2017 e382	orr	r2, r2, #0x17
0x00000230  f002 e129	msr	cpsr_fc, r2
0x00000234  d248 e59f	ldr	sp, [pc, #0x248]
0x00000238  2c02 e3c2	bic	r2, r2, #0x200
0x0000023c  f002 e16f	msr	spsr_fsxc, r2
0x00000240  0000 e10f	mrs	r0, apsr
0x00000244  101f e3e0	mvn	r1, #0x1f
0x00000248  2000 e001	and	r2, r1, r0
0x0000024c  2011 e382	orr	r2, r2, #0x11
0x00000250  f002 e129	msr	cpsr_fc, r2
0x00000254  d22c e59f	ldr	sp, [pc, #0x22c]
0x00000258  2c02 e3c2	bic	r2, r2, #0x200
0x0000025c  f002 e16f	msr	spsr_fsxc, r2
0x00000260  0000 e10f	mrs	r0, apsr
0x00000264  101f e3e0	mvn	r1, #0x1f
0x00000268  2000 e001	and	r2, r1, r0
0x0000026c  201b e382	orr	r2, r2, #0x1b
0x00000270  f002 e129	msr	cpsr_fc, r2
0x00000274  d210 e59f	ldr	sp, [pc, #0x210]
0x00000278  2c02 e3c2	bic	r2, r2, #0x200
0x0000027c  f002 e16f	msr	spsr_fsxc, r2
0x00000280  0000 e10f	mrs	r0, apsr
0x00000284  101f e3e0	mvn	r1, #0x1f
0x00000288  2000 e001	and	r2, r1, r0
0x0000028c  201f e382	orr	r2, r2, #0x1f
0x00000290  f002 e129	msr	cpsr_fc, r2
0x00000294  d1f4 e59f	ldr	sp, [pc, #0x1f4]
0x00000298  71f4 e59f	ldr	r7, [pc, #0x1f4]
0x0000029c  0000 e597	ldr	r0, [r7]
0x000002a0  0001 e380	orr	r0, r0, #1
0x000002a4  0000 e587	str	r0, [r7]
0x000002a8  01e8 e59f	ldr	r0, [pc, #0x1e8]
0x000002ac  005b e380	orr	r0, r0, #0x5b
0x000002b0  0f10 ee02	mcr	p15, #0, r0, c2, c0, #0
0x000002b4  0000 e3e0	mvn	r0, #0
0x000002b8  0f10 ee03	mcr	p15, #0, r0, c3, c0, #0
0x000002bc  01d8 e59f	ldr	r0, [pc, #0x1d8]
0x000002c0  0f10 ee01	mcr	p15, #0, r0, c1, c0, #0
0x000002c4  f04f f57f	dsb	sy
0x000002c8  f06f f57f	isb	sy
0x000002cc  0f30 ee11	mrc	p15, #0, r0, c1, c0, #1
0x000002d0  0040 e380	orr	r0, r0, #0x40
0x000002d4  0001 e380	orr	r0, r0, #1
0x000002d8  0f30 ee01	mcr	p15, #0, r0, c1, c0, #1
0x000002dc  01bc e59f	ldr	r0, [pc, #0x1bc]
0x000002e0  1000 e3a0	mov	r1, #0
0x000002e4  1000 e580	str	r1, [r0]
0x000002e8  01b4 e59f	ldr	r0, [pc, #0x1b4]
0x000002ec  1000 e590	ldr	r1, [r0]
0x000002f0  21b0 e59f	ldr	r2, [pc, #0x1b0]
0x000002f4  1002 e181	orr	r1, r1, r2
0x000002f8  1000 e580	str	r1, [r0]
0x000002fc  01a8 e59f	ldr	r0, [pc, #0x1a8]
0x00000300  11a8 e59f	ldr	r1, [pc, #0x1a8]
0x00000304  1000 e580	str	r1, [r0]
0x00000308  01a4 e59f	ldr	r0, [pc, #0x1a4]
0x0000030c  11a4 e59f	ldr	r1, [pc, #0x1a4]
0x00000310  1000 e580	str	r1, [r0]
0x00000314  01a0 e59f	ldr	r0, [pc, #0x1a0]
0x00000318  2158 e59f	ldr	r2, [pc, #0x158]
0x0000031c  2000 e580	str	r2, [r0]
0x00000320  0198 e59f	ldr	r0, [pc, #0x198]
0x00000324  1000 e590	ldr	r1, [r0]
0x00000328  0000 e351	cmp	r1, #0
0x0000032c  fffc 1aff	bne	#0x324
0x00000330  018c e59f	ldr	r0, [pc, #0x18c]
0x00000334  1000 e590	ldr	r1, [r0]
0x00000338  0188 e59f	ldr	r0, [pc, #0x188]
0x0000033c  1000 e580	str	r1, [r0]
0x00000340  0114 e59f	ldr	r0, [pc, #0x114]
0x00000344  1114 e59f	ldr	r1, [pc, #0x114]
0x00000348  1000 e580	str	r1, [r0]
0x0000034c  0178 e59f	ldr	r0, [pc, #0x178]
0x00000350  1178 e59f	ldr	r1, [pc, #0x178]
0x00000354  1000 e580	str	r1, [r0]
0x00000358  0108 e59f	ldr	r0, [pc, #0x108]
0x0000035c  1108 e59f	ldr	r1, [pc, #0x108]
0x00000360  1000 e580	str	r1, [r0]
0x00000364  0134 e59f	ldr	r0, [pc, #0x134]
0x00000368  1000 e590	ldr	r1, [r0]
0x0000036c  2001 e3a0	mov	r2, #1
0x00000370  1002 e181	orr	r1, r1, r2
0x00000374  1000 e580	str	r1, [r0]
0x00000378  0000 e1a0	mov	r0, r0
0x0000037c  1f50 ee11	mrc	p15, #0, r1, c1, c0, #2
0x00000380  160f e381	orr	r1, r1, #0xf00000
0x00000384  1f50 ee01	mcr	p15, #0, r1, c1, c0, #2
0x00000388  1a10 eef8	vmrs	r1, fpexc
0x0000038c  1101 e381	orr	r1, r1, #0x40000000
0x00000390  1a10 eee8	vmsr	fpexc, r1
0x00000394  0f10 ee11	mrc	p15, #0, r0, c1, c0, #0
0x00000398  0b02 e380	orr	r0, r0, #0x800
0x0000039c  0f10 ee01	mcr	p15, #0, r0, c1, c0, #0
0x000003a0  0f30 ee11	mrc	p15, #0, r0, c1, c0, #1
0x000003a4  0004 e380	orr	r0, r0, #4
0x000003a8  0002 e380	orr	r0, r0, #2
0x000003ac  0f30 ee01	mcr	p15, #0, r0, c1, c0, #1
0x000003b0  0000 e10f	mrs	r0, apsr
0x000003b4  0c01 e3c0	bic	r0, r0, #0x100
0x000003b8  f000 e12e	msr	cpsr_fsx, r0
0x000003bc  2063 ea00	b	#0x8550
0x000003c0  0000 e000	and	r0, r0, r0
0x000003c4  fffe eaff	b	#0x3c4
0x000003c8  0f30 ee30	mrc	p15, #1, r0, c0, c0, #1
0x000003cc  3407 e210	ands	r3, r0, #0x7000000
0x000003d0  3ba3 e1a0	lsr	r3, r3, #0x17
0x000003d4  001a 0a00	beq	#0x444
0x000003d8  a000 e3a0	mov	sl, #0
0x000003dc  20aa e08a	add	r2, sl, sl, lsr #1
0x000003e0  1230 e1a0	lsr	r1, r0, r2
0x000003e4  1007 e201	and	r1, r1, #7
0x000003e8  0002 e351	cmp	r1, #2
0x000003ec  0011 ba00	blt	#0x438
0x000003f0  af10 ee40	mcr	p15, #2, sl, c0, c0, #0
0x000003f4  f06f f57f	isb	sy
0x000003f8  1f10 ee30	mrc	p15, #1, r1, c0, c0, #0
0x000003fc  2007 e201	and	r2, r1, #7
As a sanity check, I resume, cycle power, then interrupt U-boot so it doesn't boot to linux, then do this:
halt
> arm disassemble 0 20
0x00000000  0000 e59f	ldr	r0, [pc]
0x00000004  ff10 e12f	bx	r0
0x00000008  1400 0012	andseq	r1, r2, r0, lsl #8
0x0000000c  aecb aeb8	cdpge	p14, #0xb, c10, c8, c11, #6
0x00000010  bcb8 9e9d	mrcls	p12, #4, fp, c13, c8, #5
0x00000014  181a baeb	blt	#0xffac6084
0x00000018  fffc 9e2d	mcrls	p15, #1, pc, c13, c12, #7
0x0000001c  86db b6ec	usatlt	r8, #0xc, fp, asr #0xd
0x00000020  bd98 fdae	stc2	p13, c11, [lr, #0x260]!
This is clearly different that what we had before. Only the first two lines actually look like code. No need for in-depth analysis, but this somewhat confirms that our breakpoints did catch bootrom code running and that we did dump bootrom contents. Maybe.
Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org