openocd/tcl/target/ls1088a.cfg
Sean Anderson d1278660af target: ls1088a: Add service processor
Normally the service processor is not necessary for debugging. However,
if you are using the hard-coded RCW or your boot source is otherwise
corrupt, then the general purpose processors will never be released from
hold-off. This will cause GDB to become confused if it tries to attach,
since they will appear to be running arm32 processors. To deal with
this, we can release the CPUs manually with the BRRL register. This
register cannot be written to from the axi target, so we need to do it
from the service processor target. This involves halting the service
processor, modifying the register, and then resuming it again. We try
and determine what state the service processor was in to avoid resuming
it if it was already halted.

The reset vector for the general purpose processors is determined by the
boot logation pointer registers in the device configuration unit.
Normally these are set using pre-boot initialization commands, but if
they are not set then they default to 0. This will cause the CPU to
almost immediately hit an illegal instruction. This is fine because we
will almost certainly want to attach to the processor and load a program
anyway.

I considered adding this as an event handler for either gdb-attach or
reset-init. However, this command shouldn't be necessary most of the
time, and so I don't think we should run it automatically.

Signed-off-by: Sean Anderson <sean.anderson@seco.com>
Change-Id: I1b725292d8a11274d03af5313dc83678e10e944c
Reviewed-on: https://review.openocd.org/c/openocd/+/6850
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
2022-02-26 15:36:16 +00:00

75 lines
2.0 KiB
INI

# SPDX-License-Identifier: GPL-2.0-or-later
# NXP LS1088A
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME ls1088a
}
if { [info exists DAP_TAPID] } {
set _DAP_TAPID $DAP_TAPID
} else {
set _DAP_TAPID 0x5ba00477
}
jtag newtap $_CHIPNAME dap -irlen 4 -expected-id $_DAP_TAPID
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap
target create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 1
set _CPU_BASE 0x81000000
set _CPU_STRIDE 0x100000
set _CPU_DBGOFF 0x10000
set _CPU_CTIOFF 0x20000
set _TARGETS {}
for {set i 0} {$i < 8} {incr i} {
set _BASE [expr {$_CPU_BASE + $_CPU_STRIDE * $i}]
cti create $_CHIPNAME.cti$i -dap $_CHIPNAME.dap -ap-num 0 \
-baseaddr [expr {$_BASE + $_CPU_CTIOFF}]
target create $_CHIPNAME.cpu$i aarch64 -dap $_CHIPNAME.dap \
-cti $_CHIPNAME.cti$i -dbgbase [expr {$_BASE + $_CPU_DBGOFF}] \
{*}[expr {$i ? "-coreid $i" : "-rtos hwthread" }]
lappend _TARGETS $_CHIPNAME.cpu$i
}
target smp {*}$_TARGETS
# Service processor
target create $_CHIPNAME.sp cortex_a -dap $_CHIPNAME.dap -ap-num 0 -dbgbase 0x80138000
# Normally you will not need to call this, but if you are using the hard-coded
# Reset Configuration Word (RCW) you will need to call this manually. The CPU's
# reset vector is 0, and the boot ROM at that location contains ARMv7-A 32-bit
# instructions. This will cause the CPU to almost immediately execute an
# illegal instruction.
#
# This code is idempotent; releasing a released CPU has no effect, although it
# will halt/resume the service processor.
add_help_text release_cpu "Release a cpu which is held off"
proc release_cpu {cpu} {
set RST_BRRL 0x1e60060
set old [target current]
targets $::_CHIPNAME.sp
set not_halted [string compare halted [$::_CHIPNAME.sp curstate]]
if {$not_halted} {
halt
}
# Release the cpu; it will start executing something bogus
mem2array regs 32 $RST_BRRL 1
mww $RST_BRRL [expr {$regs(0) | 1 << $cpu}]
if {$not_halted} {
resume
}
targets $old
}
targets $_CHIPNAME.cpu0
# Seems to work OK in testing
adapter speed 10000