blob: 93664cda91398dafc67de88d24299d76aa01231e [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>
Mate Toth-Pal833bf632023-02-27 13:33:58 +010013#include <plat_import_sym.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000014#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
Soby Mathewb4c6df42022-11-09 11:13:29 +000021/*
22 * Memory map REGIONS used for the RMM runtime (static mappings)
23 */
24#define RMM_CODE_SIZE (RMM_CODE_END - RMM_CODE_START)
25#define RMM_RO_SIZE (RMM_RO_END - RMM_RO_START)
26#define RMM_RW_SIZE (RMM_RW_END - RMM_RW_START)
27
28#define RMM_CODE MAP_REGION_FLAT( \
29 RMM_CODE_START, \
30 RMM_CODE_SIZE, \
31 MT_CODE | MT_REALM)
32
33#define RMM_RO MAP_REGION_FLAT( \
34 RMM_RO_START, \
35 RMM_RO_SIZE, \
36 MT_RO_DATA | MT_REALM)
37
38#define RMM_RW MAP_REGION_FLAT( \
39 RMM_RW_START, \
40 RMM_RW_SIZE, \
41 MT_RW_DATA | MT_REALM)
42
43/*
44 * Some of the fields for the RMM_SHARED region will be populated
45 * at runtime.
46 */
47#define RMM_SHARED MAP_REGION( \
48 0U, \
49 RMM_SHARED_BUFFER_START, \
50 0U, \
51 MT_RW_DATA | MT_REALM)
52
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000053/* Number of common memory mapping regions */
54#define COMMON_REGIONS (4U)
Soby Mathewb4c6df42022-11-09 11:13:29 +000055
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000056/* Total number of memory mapping regions */
57#define TOTAL_MMAP_REGIONS (COMMON_REGIONS + PLAT_CMN_EXTRA_MMAP_REGIONS)
58
59/* Memory mapping regions for the system runtime */
60static struct xlat_mmap_region static_regions[TOTAL_MMAP_REGIONS];
61
62/* Allocate the runtime translation tables */
63static uint64_t static_s1tt[XLAT_TABLE_ENTRIES * PLAT_CMN_CTX_MAX_XLAT_TABLES]
64 __aligned(XLAT_TABLES_ALIGNMENT)
65 __section("xlat_static_tables");
66
67/* Structures to hold the runtime translation context information */
68static struct xlat_ctx_tbls runtime_tbls;
69static struct xlat_ctx_cfg runtime_xlat_ctx_cfg;
70static struct xlat_ctx runtime_xlat_ctx;
Soby Mathewb4c6df42022-11-09 11:13:29 +000071
72/*
73 * Platform common cold boot setup for RMM.
74 *
75 * This function should only be invoked once during cold boot
76 * and is expected to setup architecture and platform components
77 * common for all PEs executing RMM.
78 * The xlat tables and GIC driver are initialized by this function.
79 */
80int plat_cmn_setup(unsigned long x0, unsigned long x1,
81 unsigned long x2, unsigned long x3,
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000082 struct xlat_mmap_region *plat_regions,
83 unsigned int nregions)
Soby Mathewb4c6df42022-11-09 11:13:29 +000084{
85 int ret;
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000086 unsigned int plat_offset, cmn_offset;
87
Mate Toth-Pal833bf632023-02-27 13:33:58 +010088 (void)x0;
89 (void)x1;
90 (void)x2;
91 (void)x3;
92
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +000093 /* Common regions sorted by ascending VA */
94 struct xlat_mmap_region regions[COMMON_REGIONS] = {
95 RMM_CODE,
96 RMM_RO,
97 RMM_RW,
98 RMM_SHARED
99 };
100
101 if (nregions > PLAT_CMN_EXTRA_MMAP_REGIONS) {
102 return -ERANGE;
103 }
104
105 if (nregions > 0U && plat_regions == NULL) {
106 return -EINVAL;
107 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000108
Soby Mathewb4c6df42022-11-09 11:13:29 +0000109 /* Setup the parameters of the shared area */
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000110 regions[3].base_pa = rmm_el3_ifc_get_shared_buf_pa();
111 regions[3].size = rmm_el3_ifc_get_shared_buf_size();
Soby Mathewb4c6df42022-11-09 11:13:29 +0000112
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000113 plat_offset = COMMON_REGIONS;
114 cmn_offset = 0U;
115 if (nregions > 0U) {
116 /*
117 * Combine the common memory regions with the platform ones
118 * in an array where they are sorted as per VA.
119 */
120 if (plat_regions[0].base_va < RMM_CODE_START) {
121 plat_offset = 0U;
122 cmn_offset = nregions;
123 }
124 (void)memcpy((void *)&static_regions[plat_offset],
125 (void *)&plat_regions[0U],
126 sizeof(struct xlat_mmap_region) * nregions);
127 }
128
129 (void)memcpy((void *)&static_regions[cmn_offset], (void *)&regions[0U],
130 sizeof(struct xlat_mmap_region) * COMMON_REGIONS);
131
132 ret = xlat_ctx_cfg_init(&runtime_xlat_ctx_cfg, VA_LOW_REGION,
133 &static_regions[0], nregions + COMMON_REGIONS,
134 VIRT_ADDR_SPACE_SIZE);
135
Soby Mathewb4c6df42022-11-09 11:13:29 +0000136 if (ret != 0) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000137 ERROR("%s (%u): %s (%i)\n",
138 __func__, __LINE__,
139 "Failed to initialize the xlat ctx within the xlat library ",
140 ret);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000141 return ret;
142 }
143
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000144 ret = xlat_ctx_init(&runtime_xlat_ctx, &runtime_xlat_ctx_cfg,
145 &runtime_tbls,
146 &static_s1tt[0],
147 PLAT_CMN_CTX_MAX_XLAT_TABLES);
148
Soby Mathewb4c6df42022-11-09 11:13:29 +0000149 if (ret != 0) {
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000150 ERROR("%s (%u): %s (%i)\n",
151 __func__, __LINE__,
152 "Failed to create the xlat ctx within the xlat library ",
153 ret);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000154 return ret;
155 }
156
157 /* Read supported GIC virtualization features and init GIC variables */
158 gic_get_virt_features();
159
Javier Almansa Sobrinoed932592023-01-24 12:50:41 +0000160 /* Perform coold boot initialization of the slot buffer mechanism */
161 return slot_buf_coldboot_init();
Soby Mathewb4c6df42022-11-09 11:13:29 +0000162}
163
164/*
165 * Local PE common platform setup for RMM.
166 *
167 * This function will only be invoked during
168 * warm boot and is expected to setup architecture and platform
169 * components local to a PE executing RMM.
170 */
171int plat_cmn_warmboot_setup(void)
172{
173 int ret;
174
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000175 /* Setup the MMU cfg for the low region (runtime context) */
Soby Mathewb4c6df42022-11-09 11:13:29 +0000176 ret = xlat_arch_setup_mmu_cfg(&runtime_xlat_ctx);
177 if (ret != 0) {
178 ERROR("%s (%u): Failed to setup xlat tables for CPU[%u]\n",
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000179 __func__, __LINE__, my_cpuid());
Soby Mathewb4c6df42022-11-09 11:13:29 +0000180 return ret;
181 }
182
183 /* Setup the MMU cfg for the slot buffer context (high region) */
184 slot_buf_setup_xlat();
185
186 VERBOSE("xlat tables configured for CPU[%u]\n", my_cpuid());
187 return 0;
188}