arch: arc: split codes for SMP and codes for multicore

reported by #19599, this commit splits the codes for Zephyr SMP
and codes for ARC mulicore.

Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
This commit is contained in:
Wayne Ren 2019-10-14 22:29:19 +08:00 committed by Andrew Boie
parent efc00b5612
commit 63d3828fa3
3 changed files with 68 additions and 59 deletions

View file

@ -26,7 +26,7 @@ zephyr_library_sources_if_kconfig(irq_offload.c)
zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.S)
zephyr_library_sources_ifdef(CONFIG_ARC_CONNECT arc_connect.c)
zephyr_library_sources_ifdef(CONFIG_SMP arc_smp.c)
zephyr_library_sources_ifdef(CONFIG_ARC_CONNECT arc_smp.c)
add_subdirectory_ifdef(CONFIG_ARC_CORE_MPU mpu)
add_subdirectory_ifdef(CONFIG_ARC_SECURE_FIRMWARE secureshield)

View file

@ -6,7 +6,7 @@
/**
* @file
* @brief codes required for ARC smp support
* @brief codes required for ARC multicore and Zephyr smp support
*
*/
#include <device.h>
@ -23,6 +23,69 @@
#define ARCV2_ICI_IRQ_PRIORITY 1
volatile struct {
void (*fn)(int, void*);
void *arg;
} arc_cpu_init[CONFIG_MP_NUM_CPUS];
/*
* arc_cpu_wake_flag is used to sync up master core and slave cores
* Slave core will spin for arc_cpu_wake_flag until master core sets
* it to the core id of slave core. Then, slave core clears it to notify
* master core that it's waken
*
*/
volatile u32_t arc_cpu_wake_flag;
volatile char *arc_cpu_sp;
/*
* _curr_cpu is used to record the struct of _cpu_t of each cpu.
* for efficient usage in assembly
*/
volatile _cpu_t *_curr_cpu[CONFIG_MP_NUM_CPUS];
/* Called from Zephyr initialization */
void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz,
void (*fn)(int, void *), void *arg)
{
_curr_cpu[cpu_num] = &(_kernel.cpus[cpu_num]);
arc_cpu_init[cpu_num].fn = fn;
arc_cpu_init[cpu_num].arg = arg;
/* set the initial sp of target sp through arc_cpu_sp
* arc_cpu_wake_flag will protect arc_cpu_sp that
* only one slave cpu can read it per time
*/
arc_cpu_sp = Z_THREAD_STACK_BUFFER(stack) + sz;
arc_cpu_wake_flag = cpu_num;
/* wait slave cpu to start */
while (arc_cpu_wake_flag != 0) {
;
}
}
/* the C entry of slave cores */
void z_arc_slave_start(int cpu_num)
{
void (*fn)(int, void*);
#ifdef CONFIG_SMP
z_icache_setup();
z_irq_setup();
z_irq_priority_set(IRQ_ICI, ARCV2_ICI_IRQ_PRIORITY, 0);
irq_enable(IRQ_ICI);
#endif
/* call the function set by arch_start_cpu */
fn = arc_cpu_init[cpu_num].fn;
fn(cpu_num, arc_cpu_init[cpu_num].arg);
}
#ifdef CONFIG_SMP
static void sched_ipi_handler(void *unused)
{
ARG_UNUSED(unused);
@ -49,7 +112,6 @@ u64_t z_arc_smp_switch_in_isr(void)
new_thread = (u32_t)z_get_next_ready_thread();
if (new_thread != old_thread) {
/* should check whether new_thread to relace old_thread */
#ifdef CONFIG_TIMESLICING
z_reset_time_slice();
#endif
@ -63,58 +125,6 @@ u64_t z_arc_smp_switch_in_isr(void)
return ret;
}
volatile struct {
void (*fn)(int, void*);
void *arg;
} arc_cpu_init[CONFIG_MP_NUM_CPUS];
/*
* arc_cpu_wake_flag is used to sync up master core and slave cores
* Slave core will spin for arc_cpu_wake_flag until master core sets
* it to the core id of slave core. Then, slave core clears it to notify
* master core that it's waken
*
*/
volatile u32_t arc_cpu_wake_flag;
/*
* _curr_cpu is used to record the struct of _cpu_t of each cpu.
* for efficient usage in assembly
*/
volatile _cpu_t *_curr_cpu[CONFIG_MP_NUM_CPUS];
/* Called from Zephyr initialization */
void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz,
void (*fn)(int, void *), void *arg)
{
_curr_cpu[cpu_num] = &(_kernel.cpus[cpu_num]);
arc_cpu_init[cpu_num].fn = fn;
arc_cpu_init[cpu_num].arg = arg;
arc_cpu_wake_flag = cpu_num;
/* wait slave cpu to start */
while (arc_cpu_wake_flag != 0) {
;
}
}
/* the C entry of slave cores */
void z_arc_slave_start(int cpu_num)
{
void (*fn)(int, void*);
z_icache_setup();
z_irq_setup();
z_irq_priority_set(IRQ_ICI, ARCV2_ICI_IRQ_PRIORITY, 0);
irq_enable(IRQ_ICI);
/* call the function set by arch_start_cpu */
fn = arc_cpu_init[cpu_num].fn;
fn(cpu_num, arc_cpu_init[cpu_num].arg);
}
/* arch implementation of sched_ipi */
void arch_sched_ipi(void)
{
@ -170,3 +180,4 @@ static int arc_smp_init(struct device *dev)
}
SYS_INIT(arc_smp_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
#endif

View file

@ -126,7 +126,7 @@ done_cache_invalidate:
jl @_sys_resume_from_deep_sleep
#endif
#ifdef CONFIG_SMP
#if CONFIG_MP_NUM_CPUS > 1
_get_cpu_id r0
breq r0, 0, _master_core_startup
@ -137,12 +137,10 @@ _slave_core_wait:
ld r1, [arc_cpu_wake_flag]
brne r0, r1, _slave_core_wait
ld sp, [arc_cpu_sp]
/* signal master core that slave core runs */
st 0, [arc_cpu_wake_flag]
/* get sp set by master core */
_get_curr_cpu_irq_stack sp
#if defined(CONFIG_ARC_FIRQ_STACK)
jl z_arc_firq_stack_set
#endif