blob: 719da8534d22cc8c3542a89dac3b6644f83605c1 [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
Mate Toth-Pal0da58112024-01-10 11:49:58 +01006#ifndef CBMC
7
Mate Toth-Palbbb816d2024-08-01 10:41:35 +02008#include <app_header.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +00009#include <arch_helpers.h>
10#include <assert.h>
11#include <buffer.h>
12#include <cpuid.h>
13#include <debug.h>
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000014#include <errno.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000015#include <gic.h>
Soby Mathew26727ea2023-03-06 13:26:50 +000016#include <plat_cmn_arch.h>
AlexeiFedorovee2fc822023-10-31 14:54:39 +000017#include <plat_common.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000018#include <rmm_el3_ifc.h>
19#include <sizes.h>
20#include <stdint.h>
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000021#include <string.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000022#include <xlat_contexts.h>
Mate Toth-Pal7f5b27d2023-08-08 13:49:19 +020023#include <xlat_high_va.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000024#include <xlat_tables.h>
25
Soby Mathew26727ea2023-03-06 13:26:50 +000026
27IMPORT_SYM(uintptr_t, rmm_text_start, RMM_CODE_START);
28IMPORT_SYM(uintptr_t, rmm_text_end, RMM_CODE_END);
29IMPORT_SYM(uintptr_t, rmm_ro_start, RMM_RO_START);
30IMPORT_SYM(uintptr_t, rmm_ro_end, RMM_RO_END);
31IMPORT_SYM(uintptr_t, rmm_rw_start, RMM_RW_START);
32IMPORT_SYM(uintptr_t, rmm_rw_end, RMM_RW_END);
33
Soby Mathewb4c6df42022-11-09 11:13:29 +000034/*
35 * Memory map REGIONS used for the RMM runtime (static mappings)
36 */
37#define RMM_CODE_SIZE (RMM_CODE_END - RMM_CODE_START)
38#define RMM_RO_SIZE (RMM_RO_END - RMM_RO_START)
39#define RMM_RW_SIZE (RMM_RW_END - RMM_RW_START)
40
Mate Toth-Palbbb816d2024-08-01 10:41:35 +020041/* Map the application binary data as RO. This is necessary so that the RMM can
42 * simply access the app header structures. Execution is not enabled as RMM is
43 * never intended to run app code in EL2. Write is not enabled as data pages
44 * might only be written from EL0, and for that purpose a separate mapping is
45 * created.
46 */
47#if APP_COUNT != 0
48#define RMM_APP MAP_REGION_FLAT( \
49 0, \
50 0, \
51 (MT_RO_DATA | MT_REALM))
52#endif
53
Soby Mathewb4c6df42022-11-09 11:13:29 +000054#define RMM_CODE MAP_REGION_FLAT( \
55 RMM_CODE_START, \
56 RMM_CODE_SIZE, \
AlexeiFedorov3f5d6272023-10-23 16:27:37 +010057 (MT_CODE | MT_REALM))
Soby Mathewb4c6df42022-11-09 11:13:29 +000058
59#define RMM_RO MAP_REGION_FLAT( \
60 RMM_RO_START, \
61 RMM_RO_SIZE, \
AlexeiFedorov3f5d6272023-10-23 16:27:37 +010062 (MT_RO_DATA | MT_REALM))
Soby Mathewb4c6df42022-11-09 11:13:29 +000063
64#define RMM_RW MAP_REGION_FLAT( \
65 RMM_RW_START, \
66 RMM_RW_SIZE, \
AlexeiFedorov3f5d6272023-10-23 16:27:37 +010067 (MT_RW_DATA | MT_REALM))
Soby Mathewb4c6df42022-11-09 11:13:29 +000068
69/*
Soby Mathew26727ea2023-03-06 13:26:50 +000070 * Leave an invalid page between the end of RMM memory and the beginning
71 * of the shared buffer VA. This will help to detect any memory access
72 * underflow by RMM.
73 */
74#define RMM_SHARED_BUFFER_START (RMM_RW_END + SZ_4K)
75
76/*
Soby Mathewb4c6df42022-11-09 11:13:29 +000077 * Some of the fields for the RMM_SHARED region will be populated
78 * at runtime.
79 */
80#define RMM_SHARED MAP_REGION( \
81 0U, \
82 RMM_SHARED_BUFFER_START, \
83 0U, \
AlexeiFedorov3f5d6272023-10-23 16:27:37 +010084 (MT_RW_DATA | MT_REALM))
Soby Mathewb4c6df42022-11-09 11:13:29 +000085
Soby Mathew9dcdb152024-02-27 15:15:28 +000086/* RMM supports only a single console */
87#define RMM_CSL MAP_REGION_FLAT( \
88 0, \
89 0, \
90 (MT_DEVICE | MT_RW | MT_REALM))
91
Mate Toth-Palbbb816d2024-08-01 10:41:35 +020092
93#if APP_COUNT == 0
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000094/* Number of common memory mapping regions */
95#define COMMON_REGIONS (4U)
Mate Toth-Palbbb816d2024-08-01 10:41:35 +020096#define REGION_RMM_SHARED_IDX 3
97#else
98/* Number of common memory mapping regions */
99#define COMMON_REGIONS (5U)
100#define REGION_RMM_APP_IDX 0
101#define REGION_RMM_SHARED_IDX 4
102#endif
Soby Mathewb4c6df42022-11-09 11:13:29 +0000103
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000104/* Total number of memory mapping regions */
105#define TOTAL_MMAP_REGIONS (COMMON_REGIONS + PLAT_CMN_EXTRA_MMAP_REGIONS)
106
107/* Memory mapping regions for the system runtime */
108static struct xlat_mmap_region static_regions[TOTAL_MMAP_REGIONS];
109
Javier Almansa Sobrino765a3162023-04-27 17:42:58 +0100110/*
111 * Allocate the runtime translation tables.
112 * Although a base table at level -1 when FEAT_LPA2 is enabled only has
113 * 16 entries, all tables are allocated a page for simplicity.
114 */
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000115static uint64_t static_s1tt[XLAT_TABLE_ENTRIES * PLAT_CMN_CTX_MAX_XLAT_TABLES]
116 __aligned(XLAT_TABLES_ALIGNMENT)
117 __section("xlat_static_tables");
118
119/* Structures to hold the runtime translation context information */
120static struct xlat_ctx_tbls runtime_tbls;
121static struct xlat_ctx_cfg runtime_xlat_ctx_cfg;
122static struct xlat_ctx runtime_xlat_ctx;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000123
Soby Mathew9dcdb152024-02-27 15:15:28 +0000124int plat_cmn_init_el3_ifc(unsigned long x0, unsigned long x1,
125 unsigned long x2, unsigned long x3)
126{
127 /* Initialize the RMM <-> EL3 interface */
128 return rmm_el3_ifc_init(x0, x1, x2, x3, get_shared_buf_va(x3));
129}
130
Soby Mathewb4c6df42022-11-09 11:13:29 +0000131/*
132 * Platform common cold boot setup for RMM.
133 *
134 * This function should only be invoked once during cold boot
135 * and is expected to setup architecture and platform components
Soby Mathew26727ea2023-03-06 13:26:50 +0000136 * common for all PEs executing RMM. The rmm_el3_ifc, the xlat tables
137 * and GIC driver are initialized by this function.
Soby Mathewb4c6df42022-11-09 11:13:29 +0000138 */
Soby Mathew9dcdb152024-02-27 15:15:28 +0000139int plat_cmn_setup(struct xlat_mmap_region *plat_regions,
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000140 unsigned int nregions)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000141{
142 int ret;
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000143 unsigned int plat_offset, cmn_offset;
Mate Toth-Palbbb816d2024-08-01 10:41:35 +0200144#if APP_COUNT != 0
145 uint64_t rmm_img_start = app_get_rmm_start();
146#endif
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000147
148 /* Common regions sorted by ascending VA */
149 struct xlat_mmap_region regions[COMMON_REGIONS] = {
Mate Toth-Palbbb816d2024-08-01 10:41:35 +0200150#if APP_COUNT != 0
151 RMM_APP,
152#endif
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000153 RMM_CODE,
154 RMM_RO,
155 RMM_RW,
156 RMM_SHARED
157 };
158
159 if (nregions > PLAT_CMN_EXTRA_MMAP_REGIONS) {
160 return -ERANGE;
161 }
162
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100163 if ((nregions != 0U) && (plat_regions == NULL)) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000164 return -EINVAL;
165 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000166
Mate Toth-Palbbb816d2024-08-01 10:41:35 +0200167#if APP_COUNT != 0
168 /* setup the parameters for the application binary data */
169 regions[REGION_RMM_APP_IDX].base_pa = rmm_img_start;
170 regions[REGION_RMM_APP_IDX].base_va = rmm_img_start;
171 regions[REGION_RMM_APP_IDX].size = RMM_CODE_START - rmm_img_start;
172#endif
173
Soby Mathewb4c6df42022-11-09 11:13:29 +0000174 /* Setup the parameters of the shared area */
Mate Toth-Palbbb816d2024-08-01 10:41:35 +0200175 regions[REGION_RMM_SHARED_IDX].base_pa = get_shared_buf_pa();
176 regions[REGION_RMM_SHARED_IDX].size = rmm_el3_ifc_get_shared_buf_size();
Soby Mathewb4c6df42022-11-09 11:13:29 +0000177
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000178 plat_offset = COMMON_REGIONS;
179 cmn_offset = 0U;
Soby Mathew9dcdb152024-02-27 15:15:28 +0000180 if (nregions != 0U) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000181 /*
182 * Combine the common memory regions with the platform ones
183 * in an array where they are sorted as per VA.
184 */
185 if (plat_regions[0].base_va < RMM_CODE_START) {
186 plat_offset = 0U;
187 cmn_offset = nregions;
188 }
189 (void)memcpy((void *)&static_regions[plat_offset],
190 (void *)&plat_regions[0U],
191 sizeof(struct xlat_mmap_region) * nregions);
192 }
193
194 (void)memcpy((void *)&static_regions[cmn_offset], (void *)&regions[0U],
195 sizeof(struct xlat_mmap_region) * COMMON_REGIONS);
196
197 ret = xlat_ctx_cfg_init(&runtime_xlat_ctx_cfg, VA_LOW_REGION,
198 &static_regions[0], nregions + COMMON_REGIONS,
Soby Mathew92b886f2024-04-30 10:17:44 +0100199 PLAT_CMN_VIRT_ADDR_SPACE_SIZE);
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000200
Soby Mathewb4c6df42022-11-09 11:13:29 +0000201 if (ret != 0) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000202 ERROR("%s (%u): %s (%i)\n",
203 __func__, __LINE__,
204 "Failed to initialize the xlat ctx within the xlat library ",
205 ret);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000206 return ret;
207 }
208
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000209 ret = xlat_ctx_init(&runtime_xlat_ctx, &runtime_xlat_ctx_cfg,
210 &runtime_tbls,
211 &static_s1tt[0],
212 PLAT_CMN_CTX_MAX_XLAT_TABLES);
213
Soby Mathewb4c6df42022-11-09 11:13:29 +0000214 if (ret != 0) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000215 ERROR("%s (%u): %s (%i)\n",
216 __func__, __LINE__,
217 "Failed to create the xlat ctx within the xlat library ",
218 ret);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000219 return ret;
220 }
221
222 /* Read supported GIC virtualization features and init GIC variables */
223 gic_get_virt_features();
224
Mate Toth-Pal7f5b27d2023-08-08 13:49:19 +0200225 return 0;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000226}
227
228/*
229 * Local PE common platform setup for RMM.
230 *
231 * This function will only be invoked during
232 * warm boot and is expected to setup architecture and platform
233 * components local to a PE executing RMM.
234 */
235int plat_cmn_warmboot_setup(void)
236{
237 int ret;
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +0200238 struct xlat_mmu_cfg mmu_config;
239
Soby Mathewb4c6df42022-11-09 11:13:29 +0000240
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000241 /* Setup the MMU cfg for the low region (runtime context) */
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +0200242 ret = xlat_arch_setup_mmu_cfg(&runtime_xlat_ctx, &mmu_config);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000243 if (ret != 0) {
244 ERROR("%s (%u): Failed to setup xlat tables for CPU[%u]\n",
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000245 __func__, __LINE__, my_cpuid());
Soby Mathewb4c6df42022-11-09 11:13:29 +0000246 return ret;
247 }
248
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +0200249 xlat_arch_write_mmu_cfg(&mmu_config);
250
Mate Toth-Pal7f5b27d2023-08-08 13:49:19 +0200251 /* Perform warm boot initialization of the high VA region */
252 ret = xlat_high_va_setup();
253 if (ret != 0) {
254 ERROR("%s (%u): Failed to setup high VA for CPU[%u]\n",
255 __func__, __LINE__, my_cpuid());
256 return ret;
257 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000258
259 VERBOSE("xlat tables configured for CPU[%u]\n", my_cpuid());
260 return 0;
261}
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100262
263#endif /* CBMC */