blob: 475d03c9cd4dda1b193e483df690213971fea8d8 [file] [log] [blame] [edit]
# Usage:
# openocd -f openocd-optimus.cfg
# (in another window:)
# telnet localhost 4444
#
# Note: this stops working as soon as Linux boots. I think the MMU breaks it,
# perhaps.
#
source [find interface/olimex-arm-usb-tiny-h.cfg]
# Addresses and header offsets for the uLoader and loader (barebox).
# Unsigned uLoaders, and both unsigned and signed loaders (bareboxes) have
# headers which must be skipped when loading images via JTAG. Signed uLoaders
# are only used on devices which have their JTAG locked anyway, so are
# irrelevant here.
#
# Note that there is also a legacy form of unsigned barebox which has no
# header. This is not directly supported by this script, but you can just
# change the header size here to 0x0.
global IRAM_ADDR LOAD_ADDR ULOADER_UNSIGNED_HEADER_SIZE BAREBOX_HEADER_SIZE
set IRAM_ADDR 0x83000000
set LOAD_ADDR 0x01000000
set ULOADER_UNSIGNED_HEADER_SIZE 0x38
set BAREBOX_HEADER_SIZE 0x10
reset_config trst_and_srst
adapter_khz 1000
# Called automatically at initialization time.
# This function will reset the board, so that even if you're in Linux already
# (which seems to stop JTAG from working) openocd can take over.
proc init_reset { mode } {
echo "In init_reset($mode)..."
if { $mode == "startup" } {
echo "startup mode"
jtag_reset 1 1
sleep 1
jtag_reset 0 1
sleep 1
runtest 50
jtag arp_init-reset
jtag_reset 0 0
} else {
c2k.cpu mww phys 0x904b0000 2
}
echo "init_reset done"
}
proc jtag_init {} {
init_reset startup
}
# the mindspeed c2k "data access port" via jtag.
jtag newtap c2k dap \
-expected-id 0x4ba00477 \
-irlen 4 \
-ircapture 0x1 \
-irmask 0xf
# the mindspeed c2k's ARM core, via the dap.
# If you have a newer version of openocd, you might need to change
# "cortex_a8" -> "cortex_a"
# NOTE(apenwarr): 0x80110000 is a magic number copied from another config file.
# But it's the only one that works. I would have thought the control
# registers would be in the normal 0x9xxxxxxx register space but that doesn't
# work at all.
target create c2k.cpu cortex_a8 \
-chain-position c2k.dap \
-coreid 0 \
-dbgbase 0x80110000
# TODO(apenwarr): this supposedly speeds up flash access, but it's scary.
# IRAM_ADDR is the mindspeed CPU's IRAM (internal SRAM) used for booting.
# That's the only RAM that will work before configuring the DRAM, ie.
# super early after reset. Maybe we should just add some code here to
# configure the DRAM though.
# c2k.cpu configure \
# -work-area-phys $IRAM_ADDR \
# -work-area-size 65536
# This function lets us reset the CPU without resetting the jtag interface
# and disrupting our communications.
c2k.cpu configure -event reset-assert {
c2k.cpu mww phys 0x904b0000 2
}
# Our NOR flash connected via the EXT bus.
# NOTE(apenwarr): I think the flash driver is buggy.
# Reprogramming the flash seems to only work sometimes. I suggest not
# using it; just load a replacement bootloader into RAM instead and use
# that for reflashing.
flash bank nor0 cfi 0xc0000000 0x04000000 2 2 c2k.cpu
# TODO(apenwarr): we'd have to add a new driver in order to flash NAND.
# That's probably more work than it's worth.
# nand device nand0 orion c2k.cpu 0xcfff0000
# Usage: uloader uloader.bin
# Reboots the box and loads uloader.bin into the IRAM, then prepares it to
# run. use 'resume' to actually let it run.
proc uloader { filename } {
global IRAM_ADDR ULOADER_UNSIGNED_HEADER_SIZE
reset halt
echo "Loading uloader $filename into IRAM..."
load_image $filename [expr $IRAM_ADDR - $ULOADER_UNSIGNED_HEADER_SIZE]
step $IRAM_ADDR
echo "Load completed; stopped at first instruction."
}
proc _run_uloader {} {
global LOAD_ADDR
echo "Letting uloader run..."
bp $LOAD_ADDR 8 hw
resume
echo "resumed..."
wait_halt
rbp $LOAD_ADDR
echo "uloader finished."
echo ""
}
proc _loader { filename } {
global LOAD_ADDR BAREBOX_HEADER_SIZE
echo "Loading loader $filename into DRAM..."
load_image $filename [expr $LOAD_ADDR - $BAREBOX_HEADER_SIZE]
# NOTE(apenwarr): note sure why, but 'resume' sometimes fails to resume here.
# It might have some kind of interaction with the (should be deleted)
# hardware breakpoint. step followed by resume works more reliably.
step $LOAD_ADDR
echo "Load completed; stopped at first instruction."
}
# Usage: loader barebox.bin
# Reboots the box, lets the default uloader execute, then loads the given
# barebox into DRAM and prepares it to run. Use 'resume' to actually let
# it run.
proc loader { filename } {
# TODO(apenwarr): Use a post-reset hook to set DRAM timings; skip uloader.
reset halt
_run_uloader
_loader $filename
}
# Usage: loaders uloader.bin barebox.bin
# Reboots the box, loads uloader.bin into IRAM, lets it execute until
# it tries to run barebox (presumably after configuring DRAM and GPIOs),
# then halts the processor so it can load our own copy of barebox.bin
# into DRAM, then runs that. This should allow one-step recovery from
# a completely bricked device.
#
# This prepares the second barebox to run, but doesn't run it. Use 'resume'
# to actually let it run.
proc loaders { file1 file2 } {
# TODO(apenwarr): Use a post-reset hook to set DRAM timings; skip uloader.
uloader $file1
_run_uloader
_loader $file2
}
echo "config finished."