blob: bef4759d089d4f8647c4676e0891cefcd4930ebc [file] [log] [blame]
Javier Almansa Sobrinoc4ad5b02022-07-05 19:05:14 +01001/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
6#include <gic.h>
7#include <host_defs.h>
8#include <host_utils.h>
9#include <platform_api.h>
10#include <rmm_el3_ifc.h>
11#include <xlat_tables.h>
12
13/* Implemented in init.c and needed here */
14void rmm_warmboot_main(void);
15void rmm_main(void);
16
17/*
18 * Define and set the Boot Interface arguments.
19 */
20#define RMM_EL3_IFC_ABI_VERSION (RMM_EL3_IFC_SUPPORTED_VERSION)
21#define RMM_EL3_MAX_CPUS (MAX_CPUS)
22
23static unsigned char el3_rmm_shared_buffer[PAGE_SIZE] __aligned(PAGE_SIZE);
24
25/*
26 * Create a basic boot manifest.
27 */
28static struct rmm_core_manifest *boot_manifest =
29 (struct rmm_core_manifest *)el3_rmm_shared_buffer;
30
31/*
32 * Performs some initialization needed before RMM can be run, such as
33 * setting up callbacks for sysreg access.
34 */
35static void setup_sysreg_and_boot_manifest(void)
36{
37 /*
38 * Initialize ID_AA64MMFR0_EL1 with a physical address
39 * range of 18 bits
40 */
41 (void)host_util_set_default_sysreg_cb("id_aa64mmfr0_el1",
42 INPLACE(ID_AA64MMFR0_EL1_PARANGE, 5UL));
43
44 /*
45 * Initialize ICH_VTR_EL2 with 6 preemption bits.
46 * (PREbits is equal number of preemption bits minus one)
47 */
48 (void)host_util_set_default_sysreg_cb("ich_vtr_el2",
49 INPLACE(ICH_VTR_EL2_PRE_BITS, 5UL));
50
51 /* Used to hold CPU Id. Reset to CPUid 0. */
52 (void)host_util_set_default_sysreg_cb("tpidr_el2", 0UL);
53
54 (void)host_util_set_default_sysreg_cb("sctlr_el2", 0UL);
55
56 /* Initialize the boot manifest */
57 boot_manifest->version = RMM_EL3_IFC_SUPPORTED_VERSION;
58 boot_manifest->plat_data = (uintptr_t)NULL;
59}
60
61/*
62 * Function to emulate the turn on of the MMU for the fake_host architecture.
63 */
64static void enable_fake_mmu(void)
65{
66 write_sctlr_el2(SCTLR_EL2_WXN | SCTLR_EL2_M);
67}
68
69static void start_primary_pe(void)
70{
71 host_util_set_cpuid(0U);
72
73 /* Early setup the CpuId into tpidr_el2 */
74 write_tpidr_el2(0U);
75
76 plat_setup(0UL,
77 RMM_EL3_IFC_ABI_VERSION,
78 RMM_EL3_MAX_CPUS,
79 (uintptr_t)&el3_rmm_shared_buffer);
80
81 /*
82 * Enable the MMU. This is needed as some initialization code
83 * called by rmm_main() asserts that the mmu is enabled.
84 */
85 enable_fake_mmu();
86
87 /*
88 * rmm_main() finishhes the warmboot path.
89 *
90 * Note: It is expected that the attestation init will fail.
91 */
92 rmm_main();
93}
94
95static void start_secondary_pe(unsigned int cpuid)
96{
97 host_util_set_cpuid(cpuid);
98
99 /*
100 * Early setup the CpuId into tpidr_el2 for each secondary.
101 */
102 write_tpidr_el2(cpuid);
103
104 plat_warmboot_setup(0UL,
105 RMM_EL3_IFC_ABI_VERSION,
106 RMM_EL3_MAX_CPUS,
107 (uintptr_t)&el3_rmm_shared_buffer);
108
109 /*
110 * Enable the MMU. This is needed to avoid assertions during boot up
111 * that would otherwise occur if the MMU is disabled.
112 */
113 enable_fake_mmu();
114
115 /*
116 * Finalize the warmboot path.
117 * This enables the slot buffer mechanism.
118 */
119 rmm_warmboot_main();
120}
121
122void test_helper_rmm_start(bool secondaries)
123{
124 static bool initialized;
125
126 if (initialized == false) {
127 /* Enable RMM and setup basic structures for each test. */
128 setup_sysreg_and_boot_manifest();
129
130 /* bringup primary CPU */
131 start_primary_pe();
132
133 if (secondaries) {
134 for (unsigned int i = 1U; i < RMM_EL3_MAX_CPUS; i++) {
135 start_secondary_pe(i);
136 }
137 host_util_set_cpuid(0U);
138 }
139 initialized = true;
140 }
141}
142
143unsigned int test_helper_get_nr_granules(void)
144{
145 return HOST_NR_GRANULES;
146}