blob: bd9aad34be9a758af8a43fc56cb4419f47831fad [file] [log] [blame]
/* Copyright (c) 2022 Intel Corporation.
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/ztest.h>
#include "tests.h"
/* Experimentally 10ms is enough time to get the second CPU to run on
* all known platforms.
*/
#define CPU_START_DELAY 10000
/* IPIs happen much faster than CPU startup */
#define CPU_IPI_DELAY 250
BUILD_ASSERT(CONFIG_SMP);
BUILD_ASSERT(CONFIG_SMP_BOOT_DELAY);
#define STACKSZ 2048
char stack[STACKSZ];
volatile bool mp_flag;
struct k_thread cpu_thr;
K_THREAD_STACK_DEFINE(thr_stack, STACKSZ);
extern void z_smp_start_cpu(int id);
static void thread_fn(void *a, void *b, void *c)
{
int cpuid = (int) a;
zassert_true(cpuid == 0 || cpuid == arch_curr_cpu()->id,
"running on wrong cpu");
mp_flag = true;
}
/* Needless to say: since this is starting the SMP CPUs, it needs to
* be the first test run!
*/
ZTEST(intel_adsp_boot, test_1st_smp_boot_delay)
{
unsigned int num_cpus = arch_num_cpus();
if (arch_num_cpus() < 2) {
ztest_test_skip();
}
for (int i = 1; i < num_cpus; i++) {
printk("Launch cpu%d\n", i);
mp_flag = false;
k_thread_create(&cpu_thr, thr_stack, K_THREAD_STACK_SIZEOF(thr_stack),
thread_fn, (void *)i, NULL, NULL,
0, 0, K_FOREVER);
k_thread_cpu_mask_clear(&cpu_thr);
k_thread_cpu_mask_enable(&cpu_thr, i);
k_thread_start(&cpu_thr);
/* Make sure that thread has not run (because the cpu is halted) */
k_busy_wait(CPU_START_DELAY);
zassert_false(mp_flag, "cpu %d must not be running yet", i);
/* Start the second CPU */
z_smp_start_cpu(i);
/* Verify the thread ran */
k_busy_wait(CPU_START_DELAY);
zassert_true(mp_flag, "cpu %d did not start", i);
k_thread_abort(&cpu_thr);
}
}
ZTEST(intel_adsp_boot, test_3rd_post_boot_ipi)
{
if (arch_num_cpus() < 2) {
ztest_test_skip();
}
/* Spawn the same thread to do the same thing, but this time
* expect that the thread is going to run synchronously on
* another CPU as soon as its created. Intended to test
* whether IPIs were correctly set up on the runtime-launched
* CPU.
*/
mp_flag = false;
k_thread_create(&cpu_thr, thr_stack, K_THREAD_STACK_SIZEOF(thr_stack),
thread_fn, (void *)0, NULL, NULL,
1, 0, K_NO_WAIT);
k_busy_wait(CPU_IPI_DELAY);
zassert_true(mp_flag, "cpu did not start thread via IPI");
}