blob: a6d691412856d8369988031c2e1c0d3bcf71610e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
/*
* Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <psci.h>
#include <smccc.h>
#include <tftf_lib.h>
#include <test_helpers.h>
#include <power_management.h>
/* Generic function to call System OFF SMC */
static test_result_t test_cpu_system_off(void)
{
u_register_t curr_mpid = read_mpidr_el1() & MPID_MASK;
u_register_t mpid;
unsigned int cpu_node;
smc_args args = { SMC_PSCI_SYSTEM_OFF };
/* Wait for all other CPU's to turn off */
for_each_cpu(cpu_node) {
mpid = tftf_get_mpidr_from_node(cpu_node);
/* Skip current CPU */
if (mpid == curr_mpid)
continue;
while (tftf_psci_affinity_info(mpid,
MPIDR_AFFLVL0) != PSCI_STATE_OFF) {
}
}
INFO("System off from CPU MPID 0x%lx\n", curr_mpid);
tftf_notify_reboot();
tftf_smc(&args);
/* The PSCI SYSTEM_OFF call is not supposed to return */
tftf_testcase_printf("System didn't shutdown properly\n");
return TEST_RESULT_FAIL;
}
/*
* @Test_Aim@ Validate the SYSTEM_OFF call.
* Test SUCCESS in case of system shutdown.
* Test FAIL in case of execution not terminated.
*/
test_result_t test_system_off(void)
{
if (tftf_is_rebooted() == 1) {
/* Successfully resumed from SYSTEM_OFF */
return TEST_RESULT_SUCCESS;
}
return test_cpu_system_off();
}
/*
* @Test_Aim@ Validate the SYSTEM_OFF call on CPU other than lead CPU
* Test SUCCESS in case of system shutdown.
* Test FAIL in case of execution not terminated.
*/
test_result_t test_system_off_cpu_other_than_lead(void)
{
u_register_t lead_mpid = read_mpidr_el1() & MPID_MASK;
u_register_t cpu_mpid;
int psci_ret;
SKIP_TEST_IF_LESS_THAN_N_CPUS(2);
if (tftf_is_rebooted() == 1) {
/* Successfully resumed from SYSTEM_OFF */
return TEST_RESULT_SUCCESS;
}
/* Power ON another CPU, other than the lead CPU */
cpu_mpid = tftf_find_random_cpu_other_than(lead_mpid);
VERBOSE("CPU to be turned on MPID: 0x%lx\n", cpu_mpid);
psci_ret = tftf_cpu_on(cpu_mpid,
(uintptr_t)test_cpu_system_off,
0);
if (psci_ret != PSCI_E_SUCCESS) {
tftf_testcase_printf("Failed to power on CPU 0x%lx (%d)\n",
cpu_mpid, psci_ret);
return TEST_RESULT_FAIL;
}
/* Power down the lead CPU */
INFO("Lead CPU to be turned off MPID: 0x%lx\n", lead_mpid);
tftf_cpu_off();
/* Test should not reach here */
return TEST_RESULT_FAIL;
}
|