blob: 03c2fa541eae51afc54afbca0c7c2e112ecaa19a [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>
13#include <import_sym.h>
14#include <rmm_el3_ifc.h>
15#include <sizes.h>
16#include <stdint.h>
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000017#include <string.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000018#include <xlat_contexts.h>
19#include <xlat_tables.h>
20
21IMPORT_SYM(uintptr_t, rmm_text_start, RMM_CODE_START);
22IMPORT_SYM(uintptr_t, rmm_text_end, RMM_CODE_END);
23IMPORT_SYM(uintptr_t, rmm_ro_start, RMM_RO_START);
24IMPORT_SYM(uintptr_t, rmm_ro_end, RMM_RO_END);
25IMPORT_SYM(uintptr_t, rmm_rw_start, RMM_RW_START);
26IMPORT_SYM(uintptr_t, rmm_rw_end, RMM_RW_END);
27
28/*
29 * Leave an invalid page between the end of RMM memory and the beginning
30 * of the shared buffer VA. This will help to detect any memory access
31 * underflow by RMM.
32 */
33#define RMM_SHARED_BUFFER_START (RMM_RW_END + SZ_4K)
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000034
Soby Mathewb4c6df42022-11-09 11:13:29 +000035/*
36 * Memory map REGIONS used for the RMM runtime (static mappings)
37 */
38#define RMM_CODE_SIZE (RMM_CODE_END - RMM_CODE_START)
39#define RMM_RO_SIZE (RMM_RO_END - RMM_RO_START)
40#define RMM_RW_SIZE (RMM_RW_END - RMM_RW_START)
41
42#define RMM_CODE MAP_REGION_FLAT( \
43 RMM_CODE_START, \
44 RMM_CODE_SIZE, \
45 MT_CODE | MT_REALM)
46
47#define RMM_RO MAP_REGION_FLAT( \
48 RMM_RO_START, \
49 RMM_RO_SIZE, \
50 MT_RO_DATA | MT_REALM)
51
52#define RMM_RW MAP_REGION_FLAT( \
53 RMM_RW_START, \
54 RMM_RW_SIZE, \
55 MT_RW_DATA | MT_REALM)
56
57/*
58 * Some of the fields for the RMM_SHARED region will be populated
59 * at runtime.
60 */
61#define RMM_SHARED MAP_REGION( \
62 0U, \
63 RMM_SHARED_BUFFER_START, \
64 0U, \
65 MT_RW_DATA | MT_REALM)
66
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000067/* Number of common memory mapping regions */
68#define COMMON_REGIONS (4U)
Soby Mathewb4c6df42022-11-09 11:13:29 +000069
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000070/* Total number of memory mapping regions */
71#define TOTAL_MMAP_REGIONS (COMMON_REGIONS + PLAT_CMN_EXTRA_MMAP_REGIONS)
72
73/* Memory mapping regions for the system runtime */
74static struct xlat_mmap_region static_regions[TOTAL_MMAP_REGIONS];
75
76/* Allocate the runtime translation tables */
77static uint64_t static_s1tt[XLAT_TABLE_ENTRIES * PLAT_CMN_CTX_MAX_XLAT_TABLES]
78 __aligned(XLAT_TABLES_ALIGNMENT)
79 __section("xlat_static_tables");
80
81/* Structures to hold the runtime translation context information */
82static struct xlat_ctx_tbls runtime_tbls;
83static struct xlat_ctx_cfg runtime_xlat_ctx_cfg;
84static struct xlat_ctx runtime_xlat_ctx;
Soby Mathewb4c6df42022-11-09 11:13:29 +000085
86/*
87 * Platform common cold boot setup for RMM.
88 *
89 * This function should only be invoked once during cold boot
90 * and is expected to setup architecture and platform components
91 * common for all PEs executing RMM.
92 * The xlat tables and GIC driver are initialized by this function.
93 */
94int plat_cmn_setup(unsigned long x0, unsigned long x1,
95 unsigned long x2, unsigned long x3,
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000096 struct xlat_mmap_region *plat_regions,
97 unsigned int nregions)
Soby Mathewb4c6df42022-11-09 11:13:29 +000098{
99 int ret;
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000100 unsigned int plat_offset, cmn_offset;
101
102 /* Common regions sorted by ascending VA */
103 struct xlat_mmap_region regions[COMMON_REGIONS] = {
104 RMM_CODE,
105 RMM_RO,
106 RMM_RW,
107 RMM_SHARED
108 };
109
110 if (nregions > PLAT_CMN_EXTRA_MMAP_REGIONS) {
111 return -ERANGE;
112 }
113
114 if (nregions > 0U && plat_regions == NULL) {
115 return -EINVAL;
116 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000117
118 /* Initialize the RMM <-> EL3 interface */
119 ret = rmm_el3_ifc_init(x0, x1, x2, x3, RMM_SHARED_BUFFER_START);
120 if (ret != 0) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000121 ERROR("%s (%u): Failed to initialize the RMM EL3 Interface\n",
122 __func__, __LINE__);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000123 return ret;
124 }
125
126 /* Setup the parameters of the shared area */
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000127 regions[3].base_pa = rmm_el3_ifc_get_shared_buf_pa();
128 regions[3].size = rmm_el3_ifc_get_shared_buf_size();
Soby Mathewb4c6df42022-11-09 11:13:29 +0000129
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000130 plat_offset = COMMON_REGIONS;
131 cmn_offset = 0U;
132 if (nregions > 0U) {
133 /*
134 * Combine the common memory regions with the platform ones
135 * in an array where they are sorted as per VA.
136 */
137 if (plat_regions[0].base_va < RMM_CODE_START) {
138 plat_offset = 0U;
139 cmn_offset = nregions;
140 }
141 (void)memcpy((void *)&static_regions[plat_offset],
142 (void *)&plat_regions[0U],
143 sizeof(struct xlat_mmap_region) * nregions);
144 }
145
146 (void)memcpy((void *)&static_regions[cmn_offset], (void *)&regions[0U],
147 sizeof(struct xlat_mmap_region) * COMMON_REGIONS);
148
149 ret = xlat_ctx_cfg_init(&runtime_xlat_ctx_cfg, VA_LOW_REGION,
150 &static_regions[0], nregions + COMMON_REGIONS,
151 VIRT_ADDR_SPACE_SIZE);
152
Soby Mathewb4c6df42022-11-09 11:13:29 +0000153 if (ret != 0) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000154 ERROR("%s (%u): %s (%i)\n",
155 __func__, __LINE__,
156 "Failed to initialize the xlat ctx within the xlat library ",
157 ret);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000158 return ret;
159 }
160
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000161 ret = xlat_ctx_init(&runtime_xlat_ctx, &runtime_xlat_ctx_cfg,
162 &runtime_tbls,
163 &static_s1tt[0],
164 PLAT_CMN_CTX_MAX_XLAT_TABLES);
165
Soby Mathewb4c6df42022-11-09 11:13:29 +0000166 if (ret != 0) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000167 ERROR("%s (%u): %s (%i)\n",
168 __func__, __LINE__,
169 "Failed to create the xlat ctx within the xlat library ",
170 ret);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000171 return ret;
172 }
173
174 /* Read supported GIC virtualization features and init GIC variables */
175 gic_get_virt_features();
176
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000177 /* Perform coold boot initialization of the slot buffer mechanism */
178 return slot_buf_coldboot_init();
Soby Mathewb4c6df42022-11-09 11:13:29 +0000179}
180
181/*
182 * Local PE common platform setup for RMM.
183 *
184 * This function will only be invoked during
185 * warm boot and is expected to setup architecture and platform
186 * components local to a PE executing RMM.
187 */
188int plat_cmn_warmboot_setup(void)
189{
190 int ret;
191
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000192 /* Setup the MMU cfg for the low region (runtime context) */
Soby Mathewb4c6df42022-11-09 11:13:29 +0000193 ret = xlat_arch_setup_mmu_cfg(&runtime_xlat_ctx);
194 if (ret != 0) {
195 ERROR("%s (%u): Failed to setup xlat tables for CPU[%u]\n",
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000196 __func__, __LINE__, my_cpuid());
Soby Mathewb4c6df42022-11-09 11:13:29 +0000197 return ret;
198 }
199
200 /* Setup the MMU cfg for the slot buffer context (high region) */
201 slot_buf_setup_xlat();
202
203 VERBOSE("xlat tables configured for CPU[%u]\n", my_cpuid());
204 return 0;
205}