<commit_before>/*
 * Copyright (c) 2019 Synopsys.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief codes required for ARC smp support
 *
 */
#include <device.h>
#include <kernel.h>
#include <kernel_structs.h>
#include <ksched.h>
#include <soc.h>
#include <init.h>


#ifndef IRQ_ICI
#define IRQ_ICI 19
#endif

#define ARCV2_ICI_IRQ_PRIORITY 1

static void sched_ipi_handler(void *unused)
{
	ARG_UNUSED(unused);

	z_arc_connect_ici_clear();
	z_sched_ipi();
}

/**
 * @brief Check whether need to do thread switch in isr context
 *
 * @details u64_t is used to let compiler use (r0, r1) as return register.
 *  use register r0 and register r1 as return value, r0 has
 *  new thread, r1 has old thread. If r0 == 0, it means no thread switch.
 */
u64_t z_arc_smp_switch_in_isr(void)
{
	u64_t ret = 0;
	u32_t new_thread;
	u32_t old_thread;

	if (!_current_cpu->swap_ok) {
		return 0;
	}

	old_thread = (u32_t)_current;

	new_thread = (u32_t)z_get_next_ready_thread();

	if (new_thread != old_thread) {
		_current_cpu->swap_ok = 0;
		((struct k_thread *)new_thread)->base.cpu =
				arch_curr_cpu()->id;
		_current = (struct k_thread *) new_thread;
		ret = new_thread | ((u64_t)(old_thread) << 32);
	}

	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)
{
	u32_t i;

	/* broadcast sched_ipi request to all cores
	 * if the target is current core, hardware will ignore it
	 */
	for (i = 0; i < CONFIG_MP_NUM_CPUS; i++) {
		z_arc_connect_ici_generate(i);
	}
}<commit_msg>arch: arc: necessary fixes after normal idle is used for SMP<commit_after>/*
 * Copyright (c) 2019 Synopsys.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief codes required for ARC smp support
 *
 */
#include <device.h>
#include <kernel.h>
#include <kernel_structs.h>
#include <ksched.h>
#include <soc.h>
#include <init.h>


#ifndef IRQ_ICI
#define IRQ_ICI 19
#endif

#define ARCV2_ICI_IRQ_PRIORITY 1

static void sched_ipi_handler(void *unused)
{
	ARG_UNUSED(unused);

	z_arc_connect_ici_clear();
	z_sched_ipi();
}

/**
 * @brief Check whether need to do thread switch in isr context
 *
 * @details u64_t is used to let compiler use (r0, r1) as return register.
 *  use register r0 and register r1 as return value, r0 has
 *  new thread, r1 has old thread. If r0 == 0, it means no thread switch.
 */
u64_t z_arc_smp_switch_in_isr(void)
{
	u64_t ret = 0;
	u32_t new_thread;
	u32_t old_thread;

	old_thread = (u32_t)_current;

	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
		_current_cpu->swap_ok = 0;
		((struct k_thread *)new_thread)->base.cpu =
				arch_curr_cpu()->id;
		_current = (struct k_thread *) new_thread;
		ret = new_thread | ((u64_t)(old_thread) << 32);
	}

	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)
{
	u32_t i;

	/* broadcast sched_ipi request to other cores
	 * if the target is current core, hardware will ignore it
	 */
	for (i = 0; i < CONFIG_MP_NUM_CPUS; i++) {
		z_arc_connect_ici_generate(i);
	}
}
{'fraction_non_alphanumeric': 0.1168207681365576, 'fraction_numerical': 0.016536273115220483, 'mean_word_length': 4.217996289424861, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2936435', 'n_tokens_mistral': 2310, 'n_tokens_neox': 2200, 'n_words': 599}