blob: c01e9ee730169200d87f9ceab6370a0700c1e6ba [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
6#include <arch_helpers.h>
7#include <assert.h>
8#include <buffer.h>
9#include <cpuid.h>
10#include <debug.h>
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000011#include <errno.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000012#include <gic.h>
Soby Mathew26727ea2023-03-06 13:26:50 +000013#include <plat_cmn_arch.h>
AlexeiFedorovee2fc822023-10-31 14:54:39 +000014#include <plat_common.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000015#include <rmm_el3_ifc.h>
16#include <sizes.h>
17#include <stdint.h>
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000018#include <string.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000019#include <xlat_contexts.h>
Mate Toth-Pal7f5b27d2023-08-08 13:49:19 +020020#include <xlat_high_va.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000021#include <xlat_tables.h>
22
Soby Mathew26727ea2023-03-06 13:26:50 +000023
24IMPORT_SYM(uintptr_t, rmm_text_start, RMM_CODE_START);
25IMPORT_SYM(uintptr_t, rmm_text_end, RMM_CODE_END);
26IMPORT_SYM(uintptr_t, rmm_ro_start, RMM_RO_START);
27IMPORT_SYM(uintptr_t, rmm_ro_end, RMM_RO_END);
28IMPORT_SYM(uintptr_t, rmm_rw_start, RMM_RW_START);
29IMPORT_SYM(uintptr_t, rmm_rw_end, RMM_RW_END);
30
Soby Mathewb4c6df42022-11-09 11:13:29 +000031/*
32 * Memory map REGIONS used for the RMM runtime (static mappings)
33 */
34#define RMM_CODE_SIZE (RMM_CODE_END - RMM_CODE_START)
35#define RMM_RO_SIZE (RMM_RO_END - RMM_RO_START)
36#define RMM_RW_SIZE (RMM_RW_END - RMM_RW_START)
37
38#define RMM_CODE MAP_REGION_FLAT( \
39 RMM_CODE_START, \
40 RMM_CODE_SIZE, \
AlexeiFedorov3f5d6272023-10-23 16:27:37 +010041 (MT_CODE | MT_REALM))
Soby Mathewb4c6df42022-11-09 11:13:29 +000042
43#define RMM_RO MAP_REGION_FLAT( \
44 RMM_RO_START, \
45 RMM_RO_SIZE, \
AlexeiFedorov3f5d6272023-10-23 16:27:37 +010046 (MT_RO_DATA | MT_REALM))
Soby Mathewb4c6df42022-11-09 11:13:29 +000047
48#define RMM_RW MAP_REGION_FLAT( \
49 RMM_RW_START, \
50 RMM_RW_SIZE, \
AlexeiFedorov3f5d6272023-10-23 16:27:37 +010051 (MT_RW_DATA | MT_REALM))
Soby Mathewb4c6df42022-11-09 11:13:29 +000052
53/*
Soby Mathew26727ea2023-03-06 13:26:50 +000054 * Leave an invalid page between the end of RMM memory and the beginning
55 * of the shared buffer VA. This will help to detect any memory access
56 * underflow by RMM.
57 */
58#define RMM_SHARED_BUFFER_START (RMM_RW_END + SZ_4K)
59
60/*
Soby Mathewb4c6df42022-11-09 11:13:29 +000061 * Some of the fields for the RMM_SHARED region will be populated
62 * at runtime.
63 */
64#define RMM_SHARED MAP_REGION( \
65 0U, \
66 RMM_SHARED_BUFFER_START, \
67 0U, \
AlexeiFedorov3f5d6272023-10-23 16:27:37 +010068 (MT_RW_DATA | MT_REALM))
Soby Mathewb4c6df42022-11-09 11:13:29 +000069
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000070/* Number of common memory mapping regions */
71#define COMMON_REGIONS (4U)
Soby Mathewb4c6df42022-11-09 11:13:29 +000072
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000073/* Total number of memory mapping regions */
74#define TOTAL_MMAP_REGIONS (COMMON_REGIONS + PLAT_CMN_EXTRA_MMAP_REGIONS)
75
76/* Memory mapping regions for the system runtime */
77static struct xlat_mmap_region static_regions[TOTAL_MMAP_REGIONS];
78
Javier Almansa Sobrino765a3162023-04-27 17:42:58 +010079/*
80 * Allocate the runtime translation tables.
81 * Although a base table at level -1 when FEAT_LPA2 is enabled only has
82 * 16 entries, all tables are allocated a page for simplicity.
83 */
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000084static uint64_t static_s1tt[XLAT_TABLE_ENTRIES * PLAT_CMN_CTX_MAX_XLAT_TABLES]
85 __aligned(XLAT_TABLES_ALIGNMENT)
86 __section("xlat_static_tables");
87
88/* Structures to hold the runtime translation context information */
89static struct xlat_ctx_tbls runtime_tbls;
90static struct xlat_ctx_cfg runtime_xlat_ctx_cfg;
91static struct xlat_ctx runtime_xlat_ctx;
Soby Mathewb4c6df42022-11-09 11:13:29 +000092
93/*
94 * Platform common cold boot setup for RMM.
95 *
96 * This function should only be invoked once during cold boot
97 * and is expected to setup architecture and platform components
Soby Mathew26727ea2023-03-06 13:26:50 +000098 * common for all PEs executing RMM. The rmm_el3_ifc, the xlat tables
99 * and GIC driver are initialized by this function.
Soby Mathewb4c6df42022-11-09 11:13:29 +0000100 */
101int plat_cmn_setup(unsigned long x0, unsigned long x1,
102 unsigned long x2, unsigned long x3,
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000103 struct xlat_mmap_region *plat_regions,
104 unsigned int nregions)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000105{
106 int ret;
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000107 unsigned int plat_offset, cmn_offset;
108
109 /* Common regions sorted by ascending VA */
110 struct xlat_mmap_region regions[COMMON_REGIONS] = {
111 RMM_CODE,
112 RMM_RO,
113 RMM_RW,
114 RMM_SHARED
115 };
116
117 if (nregions > PLAT_CMN_EXTRA_MMAP_REGIONS) {
118 return -ERANGE;
119 }
120
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100121 if ((nregions != 0U) && (plat_regions == NULL)) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000122 return -EINVAL;
123 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000124
Soby Mathew26727ea2023-03-06 13:26:50 +0000125 /* Initialize the RMM <-> EL3 interface */
126 ret = rmm_el3_ifc_init(x0, x1, x2, x3, get_shared_buf_va(x3));
127 if (ret != 0) {
128 ERROR("%s (%u): Failed to initialize the RMM EL3 Interface\n",
129 __func__, __LINE__);
130 return ret;
131 }
132
Soby Mathewb4c6df42022-11-09 11:13:29 +0000133 /* Setup the parameters of the shared area */
Soby Mathew26727ea2023-03-06 13:26:50 +0000134 regions[3].base_pa = get_shared_buf_pa();
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000135 regions[3].size = rmm_el3_ifc_get_shared_buf_size();
Soby Mathewb4c6df42022-11-09 11:13:29 +0000136
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000137 plat_offset = COMMON_REGIONS;
138 cmn_offset = 0U;
139 if (nregions > 0U) {
140 /*
141 * Combine the common memory regions with the platform ones
142 * in an array where they are sorted as per VA.
143 */
144 if (plat_regions[0].base_va < RMM_CODE_START) {
145 plat_offset = 0U;
146 cmn_offset = nregions;
147 }
148 (void)memcpy((void *)&static_regions[plat_offset],
149 (void *)&plat_regions[0U],
150 sizeof(struct xlat_mmap_region) * nregions);
151 }
152
153 (void)memcpy((void *)&static_regions[cmn_offset], (void *)&regions[0U],
154 sizeof(struct xlat_mmap_region) * COMMON_REGIONS);
155
156 ret = xlat_ctx_cfg_init(&runtime_xlat_ctx_cfg, VA_LOW_REGION,
157 &static_regions[0], nregions + COMMON_REGIONS,
158 VIRT_ADDR_SPACE_SIZE);
159
Soby Mathewb4c6df42022-11-09 11:13:29 +0000160 if (ret != 0) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000161 ERROR("%s (%u): %s (%i)\n",
162 __func__, __LINE__,
163 "Failed to initialize the xlat ctx within the xlat library ",
164 ret);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000165 return ret;
166 }
167
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000168 ret = xlat_ctx_init(&runtime_xlat_ctx, &runtime_xlat_ctx_cfg,
169 &runtime_tbls,
170 &static_s1tt[0],
171 PLAT_CMN_CTX_MAX_XLAT_TABLES);
172
Soby Mathewb4c6df42022-11-09 11:13:29 +0000173 if (ret != 0) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000174 ERROR("%s (%u): %s (%i)\n",
175 __func__, __LINE__,
176 "Failed to create the xlat ctx within the xlat library ",
177 ret);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000178 return ret;
179 }
180
181 /* Read supported GIC virtualization features and init GIC variables */
182 gic_get_virt_features();
183
Mate Toth-Pal7f5b27d2023-08-08 13:49:19 +0200184 return 0;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000185}
186
187/*
188 * Local PE common platform setup for RMM.
189 *
190 * This function will only be invoked during
191 * warm boot and is expected to setup architecture and platform
192 * components local to a PE executing RMM.
193 */
194int plat_cmn_warmboot_setup(void)
195{
196 int ret;
197
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000198 /* Setup the MMU cfg for the low region (runtime context) */
Soby Mathewb4c6df42022-11-09 11:13:29 +0000199 ret = xlat_arch_setup_mmu_cfg(&runtime_xlat_ctx);
200 if (ret != 0) {
201 ERROR("%s (%u): Failed to setup xlat tables for CPU[%u]\n",
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000202 __func__, __LINE__, my_cpuid());
Soby Mathewb4c6df42022-11-09 11:13:29 +0000203 return ret;
204 }
205
Mate Toth-Pal7f5b27d2023-08-08 13:49:19 +0200206 /* Perform warm boot initialization of the high VA region */
207 ret = xlat_high_va_setup();
208 if (ret != 0) {
209 ERROR("%s (%u): Failed to setup high VA for CPU[%u]\n",
210 __func__, __LINE__, my_cpuid());
211 return ret;
212 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000213
214 VERBOSE("xlat tables configured for CPU[%u]\n", my_cpuid());
215 return 0;
216}