blob: 2a5b951ffab073d7455752b5a1f5abb6870152b2 (
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
95
96
97
|
/*
* Copyright (c) 2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <debug.h>
#include <psci.h>
#include <realm_def.h>
#include <tftf_lib.h>
typedef void (*secondary_ep_t)(u_register_t);
static secondary_ep_t entrypoint[MAX_REC_COUNT];
static u_register_t context_id[MAX_REC_COUNT];
void realm_entrypoint(void);
void realm_payload_main(void);
void realm_cpu_off(void)
{
smc_args args = { SMC_PSCI_CPU_OFF };
tftf_smc(&args);
}
u_register_t realm_cpu_on(u_register_t mpidr, uintptr_t ep, u_register_t cxt_id)
{
smc_args args;
smc_ret_values ret_vals;
if (mpidr > MAX_REC_COUNT) {
return PSCI_E_INVALID_PARAMS;
}
if (entrypoint[mpidr] != NULL) {
return PSCI_E_ALREADY_ON;
}
args.fid = SMC_PSCI_CPU_ON;
args.arg1 = mpidr;
args.arg2 = (u_register_t)realm_entrypoint;
args.arg3 = cxt_id;
entrypoint[mpidr] = (secondary_ep_t)ep;
context_id[mpidr] = cxt_id;
ret_vals = tftf_smc(&args);
return ret_vals.ret0;
}
u_register_t realm_psci_affinity_info(u_register_t target_affinity,
uint32_t lowest_affinity_level)
{
smc_args args;
smc_ret_values ret_vals;
args.fid = SMC_PSCI_AFFINITY_INFO;
args.arg1 = target_affinity;
args.arg2 = lowest_affinity_level;
ret_vals = tftf_smc(&args);
return ret_vals.ret0;
}
u_register_t realm_psci_features(uint32_t psci_func_id)
{
smc_args args;
smc_ret_values ret_vals;
args.fid = SMC_PSCI_FEATURES;
args.arg1 = psci_func_id;
ret_vals = tftf_smc(&args);
return ret_vals.ret0;
}
void realm_secondary_entrypoint(u_register_t cxt_id)
{
u_register_t my_mpidr;
secondary_ep_t ep;
my_mpidr = read_mpidr_el1() & MPID_MASK;
ep = entrypoint[my_mpidr];
if (ep != NULL) {
entrypoint[my_mpidr] = NULL;
context_id[my_mpidr] = 0;
(ep)(context_id[my_mpidr]);
} else {
/*
* Host can execute Rec directly without CPU_ON
* from Realm, if Rec is created RUNNABLE
* Jump to main in this case.
*/
while (true) {
realm_payload_main();
}
}
realm_cpu_off();
}
|