blob: 098653240fba6acb40b97d747d237941e0e76f0b [file] [log] [blame]
/*
* Copyright (c) 2018, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <events.h>
#include <plat_topology.h>
#include <platform.h>
#include <power_management.h>
#include <psci.h>
#include <test_helpers.h>
#include <tftf_lib.h>
static event_t cpu_has_entered_test[PLATFORM_CORE_COUNT];
/*
* Test entry point function for non-lead CPUs.
* Specified by the lead CPU when bringing up other CPUs.
*/
static test_result_t non_lead_cpu_fn(void)
{
unsigned int mpid = read_mpidr_el1() & MPID_MASK;
unsigned int core_pos = platform_get_core_pos(mpid);
/* Signal to the lead CPU that the calling CPU has entered the test */
tftf_send_event(&cpu_has_entered_test[core_pos]);
return TEST_RESULT_SUCCESS;
}
/*
* @Test_Aim@ Template code for a test running on multiple CPUs.
*
* This "test" powers on all CPUs on the platform and report test success.
* The function test_template_multi_core() runs on the lead CPU only.
* The test entrypoint for other CPUs is non_lead_cpu_fn(), as specified when
* bringing them up.
*
* This "test" is skipped on single-core platforms. If an error occurs during
* the bring-up of non-lead CPUs, it is skipped as well. Otherwise, this test
* always returns success.
*/
test_result_t test_template_multi_core(void)
{
unsigned int lead_mpid;
unsigned int cpu_mpid, cpu_node;
unsigned int core_pos;
int psci_ret;
lead_mpid = read_mpidr_el1() & MPID_MASK;
SKIP_TEST_IF_LESS_THAN_N_CPUS(2);
/* Power on all CPUs */
for_each_cpu(cpu_node) {
cpu_mpid = tftf_get_mpidr_from_node(cpu_node);
/* Skip lead CPU as it is already powered on */
if (cpu_mpid == lead_mpid)
continue;
psci_ret = tftf_cpu_on(cpu_mpid, (uintptr_t) non_lead_cpu_fn, 0);
if (psci_ret != PSCI_E_SUCCESS) {
tftf_testcase_printf(
"Failed to power on CPU 0x%x (%d)\n",
cpu_mpid, psci_ret);
return TEST_RESULT_SKIPPED;
}
}
/* Wait for non-lead CPUs to enter the test */
for_each_cpu(cpu_node) {
cpu_mpid = tftf_get_mpidr_from_node(cpu_node);
/* Skip lead CPU */
if (cpu_mpid == lead_mpid)
continue;
core_pos = platform_get_core_pos(cpu_mpid);
tftf_wait_for_event(&cpu_has_entered_test[core_pos]);
}
return TEST_RESULT_SUCCESS;
}