This is an automated email from Gerrit. "Tomas Vanek <van...@fbl.cz>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8449
-- gerrit commit e8873f562b16b51661b2f3afabe05f541e8bfe89 Author: Tomas Vanek <van...@fbl.cz> Date: Sun Aug 11 15:03:05 2024 +0200 tcl/target/rp2350: universal config with architecture switching blocked Tcl variable USE_CORE selects what cores are debugged. Signed-off-by: Tomas Vanek <van...@fbl.cz> Change-Id: I56fe1aa94304bdfd1ec98bba57cc3fa792a35f69 diff --git a/tcl/target/rp2350.cfg b/tcl/target/rp2350.cfg new file mode 100644 index 0000000000..3c544885ac --- /dev/null +++ b/tcl/target/rp2350.cfg @@ -0,0 +1,424 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# RP2350 is a microcontroller with dual Cortex-M33 cores or dual Hazard3 RISC-V cores. +# https://www.raspberrypi.com/documentation/microcontrollers/rp2350.html + +transport select swd + +source [find target/swj-dp.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME rp2350 +} + +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x10000 +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + set _CPUTAPID 0x00040927 +} + +# Set to '1' to start rescue mode +if { [info exists RESCUE] } { + set _RESCUE $RESCUE +} else { + set _RESCUE 0 +} + +# Set to 'cm0' or 'cm1' for Cortex-M33 single core configuration +# To keep compatibility with RP2040 aliases '0' and '1' are provided for Cortex-M33 cores +# Use 'rv0' or 'rv1' for RISC-V single core configuration +# List more for a multicore configuration +if { [info exists USE_CORE] } { + set _USE_CORE $USE_CORE +} else { + # defaults to both Cortex-M33 cores + set _USE_CORE { cm0 cm1 } +} + +swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID + +if { [info exists SWD_MULTIDROP] } { + dap create $_CHIPNAME.dap -adiv6 -chain-position $_CHIPNAME.cpu -dp-id 0x0040927 -instance-id 0 +} else { + dap create $_CHIPNAME.dap -adiv6 -chain-position $_CHIPNAME.cpu +} + +# Cortex-M33 core 0 +if { [lsearch $_USE_CORE cm0] >= 0 || [lsearch $_USE_CORE 0] >= 0 } { + set _TARGETNAME_CM0 $_CHIPNAME.cm0 + set _TARGETNAME_0 $_TARGETNAME_CM0 +} + +# RISC-V core 0 +if { [lsearch $_USE_CORE rv0] >= 0 } { + set _TARGETNAME_RV0 $_CHIPNAME.rv0 + if { ![info exists _TARGETNAME_0] } { + set _TARGETNAME_0 $_TARGETNAME_RV0 + } +} + +# Cortex-M33 core 1 +if { [lsearch $_USE_CORE cm1] >= 0 || [lsearch $_USE_CORE 1] >= 0 } { + set _TARGETNAME_CM1 $_CHIPNAME.cm1 + set _TARGETNAME_1 $_TARGETNAME_CM1 +} + +# RISC-V core 1 +if { [lsearch $_USE_CORE rv1] >= 0 } { + set _TARGETNAME_RV1 $_CHIPNAME.rv1 + if { ![info exists _TARGETNAME_1] } { + set _TARGETNAME_1 $_TARGETNAME_RV1 + } +} + + +if { [info exists _TARGETNAME_CM0] } { + target create $_TARGETNAME_CM0 cortex_m -dap $_CHIPNAME.dap -ap-num 0x2000 + # srst does not exist; use SYSRESETREQ to perform a soft reset + $_TARGETNAME_CM0 cortex_m reset_config sysresetreq + + # After a rescue reset the cache requires invalidate to allow SPI flash + # reads from the XIP cached mapping area + $_TARGETNAME_CM0 configure -event reset-init { rp2xxx rom_api_call 0 FC } + +# $_TARGETNAME_CM0 configure -event check-availability "_cm_available_examine $_TARGETNAME_CM0 $_CHIPNAME.dap 0" +} + +if { [info exists _TARGETNAME_RV0] } { + target create $_TARGETNAME_RV0 riscv -dap $_CHIPNAME.dap -ap-num 0xa000 -coreid 0 + $_TARGETNAME_RV0 riscv set_enable_virt2phys off + + # Workaround for stray IO_QSPI: GPIO_QSPI_SD1_CTRL: INOVER bit in RISC-V BOOTSEL + $_TARGETNAME_RV0 configure -event reset-init { mww 0x4003002c 0 } + + if { [info exists _TARGETNAME_CM0] } { +# $_TARGETNAME_RV0 configure -event become-unavailable "rp2xxx _switch_target $_TARGETNAME_RV0 $_TARGETNAME_CM0" +# $_TARGETNAME_RV0 configure -event become-available \ +# "_conditional_examine_switch $_TARGETNAME_CM0 $_TARGETNAME_RV0" + + # just for setting after init when the event become-available is not fired + $_TARGETNAME_RV0 configure -event examine-end "rp2xxx _switch_target $_TARGETNAME_CM0 $_TARGETNAME_RV0" + } else { +# $_TARGETNAME_RV0 configure -event become-available "_conditional_examine $_TARGETNAME_RV0" + } +} + +if { [info exists _TARGETNAME_CM1] } { + target create $_TARGETNAME_CM1 cortex_m -dap $_CHIPNAME.dap -ap-num 0x4000 + $_TARGETNAME_CM1 cortex_m reset_config sysresetreq + +# $_TARGETNAME_CM1 configure -event check-availability "_cm_available_examine $_TARGETNAME_CM1 $_CHIPNAME.dap 4" +} + +if { [info exists _TARGETNAME_RV1] } { + target create $_TARGETNAME_RV1 riscv -dap $_CHIPNAME.dap -ap-num 0xa000 -coreid 1 + $_TARGETNAME_RV1 riscv set_enable_virt2phys off + +# $_TARGETNAME_RV1 configure -event become-available "_conditional_examine $_TARGETNAME_RV1" +} + +if { [info exists USE_SMP] } { + set _USE_SMP $USE_SMP +} elseif { [info exists _TARGETNAME_CM0] == [info exists _TARGETNAME_CM1] + && [info exists _TARGETNAME_RV0] == [info exists _TARGETNAME_RV1] } { + set _USE_SMP 1 +} else { + set _USE_SMP 0 +} +if { $_USE_SMP } { + if { [info exists _TARGETNAME_CM0] && [info exists _TARGETNAME_CM1] } { + $_TARGETNAME_CM0 configure -rtos hwthread + $_TARGETNAME_CM1 configure -rtos hwthread + target smp $_TARGETNAME_CM0 $_TARGETNAME_CM1 + } + if { [info exists _TARGETNAME_RV0] && [info exists _TARGETNAME_RV1] } { + $_TARGETNAME_RV0 configure -rtos hwthread + $_TARGETNAME_RV1 configure -rtos hwthread + target smp $_TARGETNAME_RV0 $_TARGETNAME_RV1 + } +} + +if { [info exists _TARGETNAME_0] } { + set _FLASH_TARGET $_TARGETNAME_0 +} +if { ![info exists _FLASH_TARGET] && [info exists _TARGETNAME_1] } { + set _FLASH_TARGET $_TARGETNAME_1 + if { [info exists _TARGETNAME_CM1] && [info exists _TARGETNAME_RV1] } { + echo "Info : $_CHIPNAME.flash will be handled by $_TARGETNAME_1 without switching" + } +} +if { [info exists _FLASH_TARGET] } { + $_FLASH_TARGET configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE + if { [info exists _TARGETNAME_CM0] && [info exists _TARGETNAME_RV0] } { + $_TARGETNAME_RV0 configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE + echo "Info : $_CHIPNAME.flash will be handled by the active one of $_FLASH_TARGET and $_TARGETNAME_RV0 cores" + } + set _FLASHNAME $_CHIPNAME.flash + set _FLASHSIZE 0x00400000 + flash bank $_FLASHNAME rp2040_flash 0x10000000 $_FLASHSIZE 0 0 $_FLASH_TARGET +} + +if { [info exists _TARGETNAME_1] } { + # Alias to ensure gdb connecting to core 1 gets the correct memory map + flash bank $_CHIPNAME.alias virtual 0x10000000 0 0 0 $_TARGETNAME_1 $_FLASHNAME +} + +if { [info exists _TARGETNAME_0] } { + # Select core 0 + targets $_TARGETNAME_0 +} + +# Cold reset resets everything except DP +proc cold_reset { { __CHIPNAME "" } } { + if { $__CHIPNAME == "" } { + global _CHIPNAME + set __CHIPNAME $_CHIPNAME + } + poll off + # set CDBGRSTREQ (and keep set CSYSPWRUPREQ and CDBGPWRUPREQ) + $__CHIPNAME.dap dpreg 4 0x54000000 + set dpstat [$__CHIPNAME.dap dpreg 4] + if { [expr { $dpstat & 0xcc000000 }] != 0xcc000000 } { + echo "Warn : dpstat_reset failed, DP STAT $dpstat" + } + $__CHIPNAME.dap dpreg 4 0x50000000 + dap init + poll on +} + +# Rescue reset resets everything except DP and RP_AP +# Both Cortex-M33 cores stop in bootrom +proc rescue_reset { { __CHIPNAME "" } } { + if { $__CHIPNAME == "" } { + global _CHIPNAME + set __CHIPNAME $_CHIPNAME + } + poll off + # set bit RESCUE_RESTART in RP_AP: CTRL register + $__CHIPNAME.dap apreg 0x80000 0 0x80000000 + $__CHIPNAME.dap apreg 0x80000 0 0 + dap init + poll on + if { [lsearch [target names] $__CHIPNAME.cm0] < 0 } { + echo "Info : restart OpenOCD with 'set USE_CORE { cm0 cm1 }' to debug after rescue" + } +} + +if { $_RESCUE } { + init + rescue_reset +} + +proc _conditional_examine { target } { + if {![$target was_examined]} { + $target arp_examine + } +} + +proc _conditional_examine_switch { old_target new_target } { + if {[$new_target was_examined]} { + rp2xxx _switch_target $old_target $new_target + } else { + $new_target arp_examine + } +} + +proc _cm_present { dap romtable_ptr } { + expr { [$dap apreg 0 $romtable_ptr] & 1 } +} + +proc _cm_available_examine { target dap romtable_ptr } { + if { [_cm_present $dap $romtable_ptr] } { + # examine after switch if not yet examined + _conditional_examine $target + return "available" + } else { + return "unavailable" + } +} + +proc target_present { target } { + set dap [$target cget -dap] + if { [$target cget -type] == "riscv" } { + # Reading availability from DM requires to select particular core. + # Use negated presence of Cortex-M33 core instead. + switch [$target cget -coreid] { + 0 { return [expr { ![_cm_present $dap 0] }]} + 1 { return [expr { ![_cm_present $dap 4] }]} + default { echo "Error: unexpected core id"; return 0 } + } + } else { + switch [format 0x%x [$target cget -ap-num]] { + 0x2000 { return [_cm_present $dap 0] } + 0x4000 { return [_cm_present $dap 4] } + default { echo "Error: unexpected AP num"; return 0 } + } + } +} + +proc ocd_process_reset_inner { MODE } { + set targets [target names] + + # If this target must be halted... + switch $MODE { + halt - + init { + set halt 1 + } + run { + set halt 0 + } + default { + return -code error "Invalid mode: $MODE, must be one of: halt, init, or run"; + } + } + + # Target event handlers *might* change which TAPs are enabled + # or disabled, so we fire all of them. But don't issue any + # target "arp_*" commands, which may issue JTAG transactions, + # unless we know the underlying TAP is active. + # + # NOTE: ARP == "Advanced Reset Process" ... "advanced" is + # relative to a previous restrictive scheme + + foreach t $targets { + # New event script. + $t invoke-event reset-start + } + + # Use TRST or TMS/TCK operations to reset all the tap controllers. + # TAP reset events get reported; they might enable some taps. + init_reset $MODE + + # Examine all targets on enabled taps. + foreach t $targets { + if {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} { + if {[target_present $t]} { + $t invoke-event examine-start + set err [catch "$t arp_examine"] + if { $err } { + $t invoke-event examine-fail + } else { + $t invoke-event examine-end + } + } + } + } + + # Assert SRST, and report the pre/post events. + # Note: no target sees SRST before "pre" or after "post". + foreach t $targets { + $t invoke-event reset-assert-pre + } + foreach t $targets { + # C code needs to know if we expect to 'halt' + if {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} { + if {[target_present $t]} { + $t arp_reset assert $halt + } + } + } + foreach t $targets { + $t invoke-event reset-assert-post + } + + # Now de-assert SRST, and report the pre/post events. + # Note: no target sees !SRST before "pre" or after "post". + foreach t $targets { + $t invoke-event reset-deassert-pre + } + foreach t $targets { + # Again, de-assert code needs to know if we 'halt' + if {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} { + if {[target_present $t]} { + $t arp_reset deassert $halt + } + } + } + foreach t $targets { + $t invoke-event reset-deassert-post + } + + # Pass 1 - Now wait for any halt (requested as part of reset + # assert/deassert) to happen. Ideally it takes effect without + # first executing any instructions. + if { $halt } { + foreach t $targets { + if {[using_jtag] && ![jtag tapisenabled [$t cget -chain-position]]} { + continue + } + if {![target_present $t]} { + continue + } + + if { ![$t was_examined] } { + # don't wait for targets where examination is deferred + # they can not be halted anyway at this point + if { [$t examine_deferred] } { + continue + } + # try to re-examine or target state will be unknown + $t invoke-event examine-start + set err [catch "$t arp_examine"] + if { $err } { + $t invoke-event examine-fail + return -code error [format "TARGET: %s - Not examined" $t] + } else { + $t invoke-event examine-end + } + } + + # Wait up to 1 second for target to halt. Why 1sec? Cause + # the JTAG tap reset signal might be hooked to a slow + # resistor/capacitor circuit - and it might take a while + # to charge + + # Catch, but ignore any errors. + catch { $t arp_waitstate halted 1000 } + + # Did we succeed? + set s [$t curstate] + + if { $s != "halted" } { + return -code error [format "TARGET: %s - Not halted" $t] + } + } + } + + #Pass 2 - if needed "init" + if { $MODE == "init" } { + foreach t $targets { + if {[using_jtag] && ![jtag tapisenabled [$t cget -chain-position]]} { + continue + } + if {![target_present $t]} { + continue + } + + # don't wait for targets where examination is deferred + # they can not be halted anyway at this point + if { ![$t was_examined] && [$t examine_deferred] } { + continue + } + + set err [catch "$t arp_waitstate halted 5000"] + # Did it halt? + if { $err == 0 } { + $t invoke-event reset-init + } + } + } + + foreach t $targets { + $t invoke-event reset-end + } +} + --