blob: 471507a14e8d8d9c38cfe92495039afd38ca0d5d [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
Soby Mathewb4c6df42022-11-09 11:13:29 +00008#include <arch_helpers.h>
9#include <assert.h>
10#include <buffer.h>
11#include <cpuid.h>
12#include <debug.h>
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000013#include <errno.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000014#include <gic.h>
Soby Mathew26727ea2023-03-06 13:26:50 +000015#include <plat_cmn_arch.h>
AlexeiFedorovee2fc822023-10-31 14:54:39 +000016#include <plat_common.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000017#include <rmm_el3_ifc.h>
18#include <sizes.h>
19#include <stdint.h>
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000020#include <string.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000021#include <xlat_contexts.h>
Mate Toth-Pal7f5b27d2023-08-08 13:49:19 +020022#include <xlat_high_va.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000023#include <xlat_tables.h>
24
Soby Mathew26727ea2023-03-06 13:26:50 +000025
26IMPORT_SYM(uintptr_t, rmm_text_start, RMM_CODE_START);
27IMPORT_SYM(uintptr_t, rmm_text_end, RMM_CODE_END);
28IMPORT_SYM(uintptr_t, rmm_ro_start, RMM_RO_START);
29IMPORT_SYM(uintptr_t, rmm_ro_end, RMM_RO_END);
30IMPORT_SYM(uintptr_t, rmm_rw_start, RMM_RW_START);
31IMPORT_SYM(uintptr_t, rmm_rw_end, RMM_RW_END);
32
Soby Mathewb4c6df42022-11-09 11:13:29 +000033/*
34 * Memory map REGIONS used for the RMM runtime (static mappings)
35 */
36#define RMM_CODE_SIZE (RMM_CODE_END - RMM_CODE_START)
37#define RMM_RO_SIZE (RMM_RO_END - RMM_RO_START)
38#define RMM_RW_SIZE (RMM_RW_END - RMM_RW_START)
39
40#define RMM_CODE MAP_REGION_FLAT( \
41 RMM_CODE_START, \
42 RMM_CODE_SIZE, \
AlexeiFedorov3f5d6272023-10-23 16:27:37 +010043 (MT_CODE | MT_REALM))
Soby Mathewb4c6df42022-11-09 11:13:29 +000044
45#define RMM_RO MAP_REGION_FLAT( \
46 RMM_RO_START, \
47 RMM_RO_SIZE, \
AlexeiFedorov3f5d6272023-10-23 16:27:37 +010048 (MT_RO_DATA | MT_REALM))
Soby Mathewb4c6df42022-11-09 11:13:29 +000049
50#define RMM_RW MAP_REGION_FLAT( \
51 RMM_RW_START, \
52 RMM_RW_SIZE, \
AlexeiFedorov3f5d6272023-10-23 16:27:37 +010053 (MT_RW_DATA | MT_REALM))
Soby Mathewb4c6df42022-11-09 11:13:29 +000054
55/*
Soby Mathew26727ea2023-03-06 13:26:50 +000056 * Leave an invalid page between the end of RMM memory and the beginning
57 * of the shared buffer VA. This will help to detect any memory access
58 * underflow by RMM.
59 */
60#define RMM_SHARED_BUFFER_START (RMM_RW_END + SZ_4K)
61
62/*
Soby Mathewb4c6df42022-11-09 11:13:29 +000063 * Some of the fields for the RMM_SHARED region will be populated
64 * at runtime.
65 */
66#define RMM_SHARED MAP_REGION( \
67 0U, \
68 RMM_SHARED_BUFFER_START, \
69 0U, \
AlexeiFedorov3f5d6272023-10-23 16:27:37 +010070 (MT_RW_DATA | MT_REALM))
Soby Mathewb4c6df42022-11-09 11:13:29 +000071
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000072/* Number of common memory mapping regions */
73#define COMMON_REGIONS (4U)
Soby Mathewb4c6df42022-11-09 11:13:29 +000074
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000075/* Total number of memory mapping regions */
76#define TOTAL_MMAP_REGIONS (COMMON_REGIONS + PLAT_CMN_EXTRA_MMAP_REGIONS)
77
78/* Memory mapping regions for the system runtime */
79static struct xlat_mmap_region static_regions[TOTAL_MMAP_REGIONS];
80
Javier Almansa Sobrino765a3162023-04-27 17:42:58 +010081/*
82 * Allocate the runtime translation tables.
83 * Although a base table at level -1 when FEAT_LPA2 is enabled only has
84 * 16 entries, all tables are allocated a page for simplicity.
85 */
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000086static uint64_t static_s1tt[XLAT_TABLE_ENTRIES * PLAT_CMN_CTX_MAX_XLAT_TABLES]
87 __aligned(XLAT_TABLES_ALIGNMENT)
88 __section("xlat_static_tables");
89
90/* Structures to hold the runtime translation context information */
91static struct xlat_ctx_tbls runtime_tbls;
92static struct xlat_ctx_cfg runtime_xlat_ctx_cfg;
93static struct xlat_ctx runtime_xlat_ctx;
Soby Mathewb4c6df42022-11-09 11:13:29 +000094
95/*
96 * Platform common cold boot setup for RMM.
97 *
98 * This function should only be invoked once during cold boot
99 * and is expected to setup architecture and platform components
Soby Mathew26727ea2023-03-06 13:26:50 +0000100 * common for all PEs executing RMM. The rmm_el3_ifc, the xlat tables
101 * and GIC driver are initialized by this function.
Soby Mathewb4c6df42022-11-09 11:13:29 +0000102 */
103int plat_cmn_setup(unsigned long x0, unsigned long x1,
104 unsigned long x2, unsigned long x3,
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000105 struct xlat_mmap_region *plat_regions,
106 unsigned int nregions)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000107{
108 int ret;
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000109 unsigned int plat_offset, cmn_offset;
110
111 /* Common regions sorted by ascending VA */
112 struct xlat_mmap_region regions[COMMON_REGIONS] = {
113 RMM_CODE,
114 RMM_RO,
115 RMM_RW,
116 RMM_SHARED
117 };
118
119 if (nregions > PLAT_CMN_EXTRA_MMAP_REGIONS) {
120 return -ERANGE;
121 }
122
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100123 if ((nregions != 0U) && (plat_regions == NULL)) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000124 return -EINVAL;
125 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000126
Soby Mathew26727ea2023-03-06 13:26:50 +0000127 /* Initialize the RMM <-> EL3 interface */
128 ret = rmm_el3_ifc_init(x0, x1, x2, x3, get_shared_buf_va(x3));
129 if (ret != 0) {
130 ERROR("%s (%u): Failed to initialize the RMM EL3 Interface\n",
131 __func__, __LINE__);
132 return ret;
133 }
134
Soby Mathewb4c6df42022-11-09 11:13:29 +0000135 /* Setup the parameters of the shared area */
Soby Mathew26727ea2023-03-06 13:26:50 +0000136 regions[3].base_pa = get_shared_buf_pa();
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000137 regions[3].size = rmm_el3_ifc_get_shared_buf_size();
Soby Mathewb4c6df42022-11-09 11:13:29 +0000138
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000139 plat_offset = COMMON_REGIONS;
140 cmn_offset = 0U;
141 if (nregions > 0U) {
142 /*
143 * Combine the common memory regions with the platform ones
144 * in an array where they are sorted as per VA.
145 */
146 if (plat_regions[0].base_va < RMM_CODE_START) {
147 plat_offset = 0U;
148 cmn_offset = nregions;
149 }
150 (void)memcpy((void *)&static_regions[plat_offset],
151 (void *)&plat_regions[0U],
152 sizeof(struct xlat_mmap_region) * nregions);
153 }
154
155 (void)memcpy((void *)&static_regions[cmn_offset], (void *)&regions[0U],
156 sizeof(struct xlat_mmap_region) * COMMON_REGIONS);
157
158 ret = xlat_ctx_cfg_init(&runtime_xlat_ctx_cfg, VA_LOW_REGION,
159 &static_regions[0], nregions + COMMON_REGIONS,
160 VIRT_ADDR_SPACE_SIZE);
161
Soby Mathewb4c6df42022-11-09 11:13:29 +0000162 if (ret != 0) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000163 ERROR("%s (%u): %s (%i)\n",
164 __func__, __LINE__,
165 "Failed to initialize the xlat ctx within the xlat library ",
166 ret);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000167 return ret;
168 }
169
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000170 ret = xlat_ctx_init(&runtime_xlat_ctx, &runtime_xlat_ctx_cfg,
171 &runtime_tbls,
172 &static_s1tt[0],
173 PLAT_CMN_CTX_MAX_XLAT_TABLES);
174
Soby Mathewb4c6df42022-11-09 11:13:29 +0000175 if (ret != 0) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000176 ERROR("%s (%u): %s (%i)\n",
177 __func__, __LINE__,
178 "Failed to create the xlat ctx within the xlat library ",
179 ret);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000180 return ret;
181 }
182
183 /* Read supported GIC virtualization features and init GIC variables */
184 gic_get_virt_features();
185
Mate Toth-Pal7f5b27d2023-08-08 13:49:19 +0200186 return 0;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000187}
188
189/*
190 * Local PE common platform setup for RMM.
191 *
192 * This function will only be invoked during
193 * warm boot and is expected to setup architecture and platform
194 * components local to a PE executing RMM.
195 */
196int plat_cmn_warmboot_setup(void)
197{
198 int ret;
199
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000200 /* Setup the MMU cfg for the low region (runtime context) */
Soby Mathewb4c6df42022-11-09 11:13:29 +0000201 ret = xlat_arch_setup_mmu_cfg(&runtime_xlat_ctx);
202 if (ret != 0) {
203 ERROR("%s (%u): Failed to setup xlat tables for CPU[%u]\n",
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000204 __func__, __LINE__, my_cpuid());
Soby Mathewb4c6df42022-11-09 11:13:29 +0000205 return ret;
206 }
207
Mate Toth-Pal7f5b27d2023-08-08 13:49:19 +0200208 /* Perform warm boot initialization of the high VA region */
209 ret = xlat_high_va_setup();
210 if (ret != 0) {
211 ERROR("%s (%u): Failed to setup high VA for CPU[%u]\n",
212 __func__, __LINE__, my_cpuid());
213 return ret;
214 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000215
216 VERBOSE("xlat tables configured for CPU[%u]\n", my_cpuid());
217 return 0;
218}
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100219
220#endif /* CBMC */