blob: bdf50af34faed943c764acc42c2b730a98bcdd7f [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
Soby Mathew9dcdb152024-02-27 15:15:28 +000072/* RMM supports only a single console */
73#define RMM_CSL MAP_REGION_FLAT( \
74 0, \
75 0, \
76 (MT_DEVICE | MT_RW | MT_REALM))
77
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000078/* Number of common memory mapping regions */
79#define COMMON_REGIONS (4U)
Soby Mathewb4c6df42022-11-09 11:13:29 +000080
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000081/* Total number of memory mapping regions */
82#define TOTAL_MMAP_REGIONS (COMMON_REGIONS + PLAT_CMN_EXTRA_MMAP_REGIONS)
83
84/* Memory mapping regions for the system runtime */
85static struct xlat_mmap_region static_regions[TOTAL_MMAP_REGIONS];
86
Javier Almansa Sobrino765a3162023-04-27 17:42:58 +010087/*
88 * Allocate the runtime translation tables.
89 * Although a base table at level -1 when FEAT_LPA2 is enabled only has
90 * 16 entries, all tables are allocated a page for simplicity.
91 */
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000092static uint64_t static_s1tt[XLAT_TABLE_ENTRIES * PLAT_CMN_CTX_MAX_XLAT_TABLES]
93 __aligned(XLAT_TABLES_ALIGNMENT)
94 __section("xlat_static_tables");
95
96/* Structures to hold the runtime translation context information */
97static struct xlat_ctx_tbls runtime_tbls;
98static struct xlat_ctx_cfg runtime_xlat_ctx_cfg;
99static struct xlat_ctx runtime_xlat_ctx;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000100
Soby Mathew9dcdb152024-02-27 15:15:28 +0000101int plat_cmn_init_el3_ifc(unsigned long x0, unsigned long x1,
102 unsigned long x2, unsigned long x3)
103{
104 /* Initialize the RMM <-> EL3 interface */
105 return rmm_el3_ifc_init(x0, x1, x2, x3, get_shared_buf_va(x3));
106}
107
Soby Mathewb4c6df42022-11-09 11:13:29 +0000108/*
109 * Platform common cold boot setup for RMM.
110 *
111 * This function should only be invoked once during cold boot
112 * and is expected to setup architecture and platform components
Soby Mathew26727ea2023-03-06 13:26:50 +0000113 * common for all PEs executing RMM. The rmm_el3_ifc, the xlat tables
114 * and GIC driver are initialized by this function.
Soby Mathewb4c6df42022-11-09 11:13:29 +0000115 */
Soby Mathew9dcdb152024-02-27 15:15:28 +0000116int plat_cmn_setup(struct xlat_mmap_region *plat_regions,
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000117 unsigned int nregions)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000118{
119 int ret;
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000120 unsigned int plat_offset, cmn_offset;
121
122 /* Common regions sorted by ascending VA */
123 struct xlat_mmap_region regions[COMMON_REGIONS] = {
124 RMM_CODE,
125 RMM_RO,
126 RMM_RW,
127 RMM_SHARED
128 };
129
130 if (nregions > PLAT_CMN_EXTRA_MMAP_REGIONS) {
131 return -ERANGE;
132 }
133
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100134 if ((nregions != 0U) && (plat_regions == NULL)) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000135 return -EINVAL;
136 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000137
Soby Mathewb4c6df42022-11-09 11:13:29 +0000138 /* Setup the parameters of the shared area */
Soby Mathew26727ea2023-03-06 13:26:50 +0000139 regions[3].base_pa = get_shared_buf_pa();
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000140 regions[3].size = rmm_el3_ifc_get_shared_buf_size();
Soby Mathewb4c6df42022-11-09 11:13:29 +0000141
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000142 plat_offset = COMMON_REGIONS;
143 cmn_offset = 0U;
Soby Mathew9dcdb152024-02-27 15:15:28 +0000144 if (nregions != 0U) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000145 /*
146 * Combine the common memory regions with the platform ones
147 * in an array where they are sorted as per VA.
148 */
149 if (plat_regions[0].base_va < RMM_CODE_START) {
150 plat_offset = 0U;
151 cmn_offset = nregions;
152 }
153 (void)memcpy((void *)&static_regions[plat_offset],
154 (void *)&plat_regions[0U],
155 sizeof(struct xlat_mmap_region) * nregions);
156 }
157
158 (void)memcpy((void *)&static_regions[cmn_offset], (void *)&regions[0U],
159 sizeof(struct xlat_mmap_region) * COMMON_REGIONS);
160
161 ret = xlat_ctx_cfg_init(&runtime_xlat_ctx_cfg, VA_LOW_REGION,
162 &static_regions[0], nregions + COMMON_REGIONS,
163 VIRT_ADDR_SPACE_SIZE);
164
Soby Mathewb4c6df42022-11-09 11:13:29 +0000165 if (ret != 0) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000166 ERROR("%s (%u): %s (%i)\n",
167 __func__, __LINE__,
168 "Failed to initialize the xlat ctx within the xlat library ",
169 ret);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000170 return ret;
171 }
172
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000173 ret = xlat_ctx_init(&runtime_xlat_ctx, &runtime_xlat_ctx_cfg,
174 &runtime_tbls,
175 &static_s1tt[0],
176 PLAT_CMN_CTX_MAX_XLAT_TABLES);
177
Soby Mathewb4c6df42022-11-09 11:13:29 +0000178 if (ret != 0) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000179 ERROR("%s (%u): %s (%i)\n",
180 __func__, __LINE__,
181 "Failed to create the xlat ctx within the xlat library ",
182 ret);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000183 return ret;
184 }
185
186 /* Read supported GIC virtualization features and init GIC variables */
187 gic_get_virt_features();
188
Mate Toth-Pal7f5b27d2023-08-08 13:49:19 +0200189 return 0;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000190}
191
192/*
193 * Local PE common platform setup for RMM.
194 *
195 * This function will only be invoked during
196 * warm boot and is expected to setup architecture and platform
197 * components local to a PE executing RMM.
198 */
199int plat_cmn_warmboot_setup(void)
200{
201 int ret;
202
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000203 /* Setup the MMU cfg for the low region (runtime context) */
Soby Mathewb4c6df42022-11-09 11:13:29 +0000204 ret = xlat_arch_setup_mmu_cfg(&runtime_xlat_ctx);
205 if (ret != 0) {
206 ERROR("%s (%u): Failed to setup xlat tables for CPU[%u]\n",
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000207 __func__, __LINE__, my_cpuid());
Soby Mathewb4c6df42022-11-09 11:13:29 +0000208 return ret;
209 }
210
Mate Toth-Pal7f5b27d2023-08-08 13:49:19 +0200211 /* Perform warm boot initialization of the high VA region */
212 ret = xlat_high_va_setup();
213 if (ret != 0) {
214 ERROR("%s (%u): Failed to setup high VA for CPU[%u]\n",
215 __func__, __LINE__, my_cpuid());
216 return ret;
217 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000218
219 VERBOSE("xlat tables configured for CPU[%u]\n", my_cpuid());
220 return 0;
221}
Mate Toth-Pal0da58112024-01-10 11:49:58 +0100222
223#endif /* CBMC */