This is an automated email from Gerrit. "Artemiy Volkov <arte...@synopsys.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8117
-- gerrit commit 8ff251367be11e3399cc5334edbbe4a1da6fdbc5 Author: Evgeniy Didin <di...@synopsys.com> Date: Tue Jul 28 15:26:03 2020 +0300 target/arc: implement basic SMP support This patch adds support for SMP targets in arc_poll(), arc_halt(), and arc_resume(), which is just enough to be able to use arc-openocd for simple program execution ('load_image' followed by 'resume $addr') in SMP mode. Other SMP-aware functionality (e.g. breakpoints, single-stepping, gdb support) is left to be implemented in the future. This has been previously committed to the Zephyr project's openocd repo[1], and currently allows us to run nightly testsuite runs on real HW with arc-openocd as the program runner. Included in this patch are also snps_hsdk_smp.cfg configuration files for the ARCv2 HSDK boards, which are functionally equivalent to their snps_hsdk.cfg counterparts except for the SMP target registration at the end. [1] https://github.com/zephyrproject-rtos/openocd/pull/25 Change-Id: I04bef83b51dd1e5daee01b9c0392da5f16106468 Signed-off-by: Evgeniy Didin <di...@synopsys.com> Signed-off-by: Stephanos Ioannidis <r...@stephanos.io> Signed-off-by: Artemiy Volkov <arte...@synopsys.com> diff --git a/src/target/arc.c b/src/target/arc.c index 72e4d918de..4299ccd1ed 100644 --- a/src/target/arc.c +++ b/src/target/arc.c @@ -13,10 +13,9 @@ #include "config.h" #endif +#include <target/smp.h> #include "arc.h" - - /* * ARC architecture specific details. * @@ -57,6 +56,10 @@ static int arc_unset_breakpoint(struct target *target, static int arc_set_breakpoint(struct target *target, struct breakpoint *breakpoint); static int arc_single_step_core(struct target *target); +static int arc_halt(struct target *target); +static int arc_poll(struct target *target); +static int arc_resume(struct target *target, int current, target_addr_t address, + int handle_breakpoints, int debug_execution); void arc_reg_data_type_add(struct target *target, struct arc_reg_data_type *data_type) @@ -778,6 +781,31 @@ static int arc_exit_debug(struct target *target) return ERROR_OK; } +static int arc_halt_smp(struct target *target) +{ + int retval = ERROR_OK; + struct target_list *head; + + foreach_smp_target(head, target->smp_targets) { + int ret; + struct target *curr = head->target; + if (curr != target && curr->state != TARGET_HALTED + && target_was_examined(curr)) { + /* avoid recursion in arc_halt() */ + curr->smp = 0; + ret = arc_halt(curr); + if (ret != ERROR_OK) { + LOG_ERROR("smp halt failed coreid: %" PRId32 " error code: %d", + curr->coreid, ret); + retval = ret; + } + curr->smp = 1; + } + } + + return retval; +} + static int arc_halt(struct target *target) { uint32_t value, irq_state; @@ -785,6 +813,9 @@ static int arc_halt(struct target *target) LOG_DEBUG("target->state: %s", target_state_name(target)); + if (target->smp) + CHECK_RETVAL(arc_halt_smp(target)); + if (target->state == TARGET_HALTED) { LOG_DEBUG("target was already halted"); return ERROR_OK; @@ -1035,6 +1066,32 @@ static int arc_debug_entry(struct target *target) return ERROR_OK; } +static int arc_poll_smp(struct target *target) +{ + struct target_list *head; + int retval = ERROR_OK; + + foreach_smp_target(head, target->smp_targets) { + int ret; + struct target *curr = head->target; + + if (curr != target && curr->state != TARGET_HALTED + && target_was_examined(curr)) { + /* avoid recursion in arc_poll() */ + curr->smp = 0; + ret = arc_poll(curr); + if (ret != ERROR_OK) { + LOG_ERROR("smp poll failed coreid: %" PRId32 " error code: %d", + curr->coreid, ret); + retval = ret; + } + curr->smp = 1; + } + } + + return retval; +} + static int arc_poll(struct target *target) { uint32_t status, value; @@ -1062,6 +1119,10 @@ static int arc_poll(struct target *target) if (target->state == TARGET_RUNNING) CHECK_RETVAL(arc_debug_entry(target)); target->state = TARGET_HALTED; + + if (target->smp) + CHECK_RETVAL(arc_poll_smp(target)); + CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED)); } else { LOG_DEBUG("Discrepancy of STATUS32[0] HALT bit and ARC_JTAG_STAT_RU, " @@ -1271,6 +1332,30 @@ static int arc_enable_interrupts(struct target *target, int enable) return ERROR_OK; } +static int arc_resume_smp(struct target *target, int current, target_addr_t address, + int handle_breakpoints, int debug_execution) +{ + int retval = ERROR_OK; + struct target_list *head; + foreach_smp_target(head, target->smp_targets) { + int ret; + struct target *curr = head->target; + if (curr != target && curr->state != TARGET_RUNNING + && target_was_examined(curr)) { + /* avoid recursion in arc_resume() */ + curr->smp = 0; + ret = arc_resume(curr, current, address, handle_breakpoints, debug_execution); + if (ret != ERROR_OK) { + LOG_ERROR("smp resume failed coreid: %" PRId32 " error code: %d", + curr->coreid, ret); + retval = ret; + } + curr->smp = 1; + } + } + return retval; +} + static int arc_resume(struct target *target, int current, target_addr_t address, int handle_breakpoints, int debug_execution) { @@ -1299,6 +1384,10 @@ static int arc_resume(struct target *target, int current, target_addr_t address, CHECK_RETVAL(arc_enable_watchpoints(target)); } + if (target->smp) + CHECK_RETVAL(arc_resume_smp(target, current, address, + handle_breakpoints, debug_execution)); + /* current = 1: continue on current PC, otherwise continue at <address> */ if (!current) { target_buffer_set_u32(target, pc->value, address); @@ -1350,7 +1439,7 @@ static int arc_resume(struct target *target, int current, target_addr_t address, CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, &value)); value &= ~SET_CORE_HALT_BIT; /* clear the HALT bit */ CHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, value)); - LOG_DEBUG("Core started to run"); + LOG_DEBUG("Core %s started to run", target_name(target)); /* registers are now invalid */ register_cache_invalidate(arc->core_and_aux_cache); diff --git a/tcl/board/snps_hsdk_smp.cfg b/tcl/board/snps_hsdk_smp.cfg new file mode 100644 index 0000000000..bfcc427210 --- /dev/null +++ b/tcl/board/snps_hsdk_smp.cfg @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Copyright (C) 2019, 2020 Synopsys, Inc. +# Anton Kolesov <anton.kole...@synopsys.com> +# Didin Evgeniy <di...@synopsys.com> + +# Synopsys DesignWare ARC AXS103 Software Development Platform (HS38 cores) +# + +# Configure JTAG cable +# SDP has built-in FT2232 chip, which is similar to Digilent HS-1, except that +# it uses channel B for JTAG, instead of channel A. +source [find interface/ftdi/snps_sdp.cfg] +adapter speed 10000 + +# ARCs supports only JTAG. +transport select jtag + +# Configure SoC +source [find target/snps_hsdk_smp.cfg] + +# Initialize +init +reset halt + diff --git a/tcl/target/snps_hsdk_smp.cfg b/tcl/target/snps_hsdk_smp.cfg new file mode 100644 index 0000000000..96a818c1ef --- /dev/null +++ b/tcl/target/snps_hsdk_smp.cfg @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Copyright (C) 2019,2020,2023 Synopsys, Inc. +# Anton Kolesov <anton.kole...@synopsys.com> +# Didin Evgeniy <di...@synopsys.com> +# Artemiy Volkov <arte...@synopsys.com> + +# +# HS Development Kit SoC. +# +# Contains quad-core ARC HS38. +# + +source [find cpu/arc/hs.tcl] + +# CHIPNAME will be used to choose core family (600, 700 or EM). As far as +# OpenOCD is concerned EM and HS are identical. +set _CHIPNAME arc-em + +# Set up global variables and a cpu description generation routine. +# +set _coreid 0 +set _dbgbase [expr {$_coreid << 13}] +set _smp_targets "" + +proc setup_cpu {core_index expected_id} { + global _coreid + global _dbgbase + global _smp_targets + global _CHIPNAME + + set _TARGETNAME $_CHIPNAME.cpu$core_index + + jtag newtap $_CHIPNAME cpu$core_index -irlen 4 -ircapture 0x1 -expected-id $expected_id + + target create $_TARGETNAME arcv2 -chain-position $_TARGETNAME + $_TARGETNAME configure -coreid $_coreid + $_TARGETNAME configure -dbgbase $_dbgbase + # Flush L2$. + $_TARGETNAME configure -event reset-assert "arc_hs_reset $_TARGETNAME" + + arc_hs_init_regs + + # Enable L2 cache support for core 4. + $_TARGETNAME arc cache l2 auto 1 + + set _smp_targets "$_smp_targets $_TARGETNAME" + set _coreid [expr {$_coreid + 1}] + set _dbgbase [expr {$_coreid << 13}] +} + +# OpenOCD discovers JTAG TAPs in reverse order. + +setup_cpu 4 0x200c24b1 +setup_cpu 3 0x200824b1 +setup_cpu 2 0x200424b1 +setup_cpu 1 0x200024b1 + +eval "target smp $_smp_targets" --