From c6fcdc24ac1dea40d8ae3cbc57e918c54395429e Mon Sep 17 00:00:00 2001 From: Watson Zeng Date: Mon, 5 Jul 2021 16:28:56 +0800 Subject: [PATCH] arch: arc: update ARConnect ICD select mask when new cpu come online The ARConnect Inter-core Debug Unit (ICD) provides additional debug assist features in multi-core scenarios. It's useful to halt other cores when one core is halted. Before we program ICD in master core(core 0) initial stage, add all cores to mask. so we need to make sure other slave cores have launched and in running mode before we enable ICD in master core. If we launch master core first, then launch slave cores by master core conditionally, in this scenario, it's not OK. Let's update arc connect debug (ARConnect ICD) select mask when new slave core come online by slave core self, instead of use hardcoded select mask. Signed-off-by: Watson Zeng --- arch/arc/core/arc_smp.c | 44 ++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/arch/arc/core/arc_smp.c b/arch/arc/core/arc_smp.c index 51224ec657e..00c0a062e5c 100644 --- a/arch/arc/core/arc_smp.c +++ b/arch/arc/core/arc_smp.c @@ -66,12 +66,40 @@ void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, } } +#ifdef CONFIG_SMP +static void arc_connect_debug_mask_update(int cpu_num) +{ + uint32_t core_mask = 1 << cpu_num; + + core_mask |= z_arc_connect_debug_select_read(); + z_arc_connect_debug_select_set(core_mask); + /* Debugger halts cores at all conditions: + * ARC_CONNECT_CMD_DEBUG_MASK_H: Core global halt. + * ARC_CONNECT_CMD_DEBUG_MASK_AH: Actionpoint halt. + * ARC_CONNECT_CMD_DEBUG_MASK_BH: Software breakpoint halt. + * ARC_CONNECT_CMD_DEBUG_MASK_SH: Self halt. + */ + z_arc_connect_debug_mask_set(core_mask, (ARC_CONNECT_CMD_DEBUG_MASK_SH + | ARC_CONNECT_CMD_DEBUG_MASK_BH | ARC_CONNECT_CMD_DEBUG_MASK_AH + | ARC_CONNECT_CMD_DEBUG_MASK_H)); +} +#endif + /* the C entry of slave cores */ void z_arc_slave_start(int cpu_num) { arch_cpustart_t fn; #ifdef CONFIG_SMP + struct arc_connect_bcr bcr; + + bcr.val = z_arc_v2_aux_reg_read(_ARC_V2_CONNECT_BCR); + + if (bcr.dbg) { + /* configure inter-core debug unit if available */ + arc_connect_debug_mask_update(cpu_num); + } + z_irq_setup(); z_arc_connect_ici_clear(); @@ -117,6 +145,11 @@ static int arc_smp_init(const struct device *dev) bcr.val = z_arc_v2_aux_reg_read(_ARC_V2_CONNECT_BCR); + if (bcr.dbg) { + /* configure inter-core debug unit if available */ + arc_connect_debug_mask_update(0); + } + if (bcr.ipi) { /* register ici interrupt, just need master core to register once */ z_arc_connect_ici_clear(); @@ -130,17 +163,6 @@ static int arc_smp_init(const struct device *dev) return -ENODEV; } - if (bcr.dbg) { - /* configure inter-core debug unit if available */ - uint32_t core_mask = (1 << CONFIG_MP_NUM_CPUS) - 1; - z_arc_connect_debug_select_set(core_mask); - /* Debugger halt cores at conditions */ - z_arc_connect_debug_mask_set(core_mask, (ARC_CONNECT_CMD_DEBUG_MASK_SH - | ARC_CONNECT_CMD_DEBUG_MASK_BH | ARC_CONNECT_CMD_DEBUG_MASK_AH - | ARC_CONNECT_CMD_DEBUG_MASK_H)); - - } - if (bcr.gfrc) { /* global free running count init */ z_arc_connect_gfrc_enable();