blob: 19444cc37ce46eeb3139a7579c1eede27fe5c0c8 [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>
11#include <gic.h>
12#include <import_sym.h>
13#include <rmm_el3_ifc.h>
14#include <sizes.h>
15#include <stdint.h>
16#include <xlat_contexts.h>
17#include <xlat_tables.h>
18
19IMPORT_SYM(uintptr_t, rmm_text_start, RMM_CODE_START);
20IMPORT_SYM(uintptr_t, rmm_text_end, RMM_CODE_END);
21IMPORT_SYM(uintptr_t, rmm_ro_start, RMM_RO_START);
22IMPORT_SYM(uintptr_t, rmm_ro_end, RMM_RO_END);
23IMPORT_SYM(uintptr_t, rmm_rw_start, RMM_RW_START);
24IMPORT_SYM(uintptr_t, rmm_rw_end, RMM_RW_END);
25
26/*
27 * Leave an invalid page between the end of RMM memory and the beginning
28 * of the shared buffer VA. This will help to detect any memory access
29 * underflow by RMM.
30 */
31#define RMM_SHARED_BUFFER_START (RMM_RW_END + SZ_4K)
32/*
33 * Memory map REGIONS used for the RMM runtime (static mappings)
34 */
35#define RMM_CODE_SIZE (RMM_CODE_END - RMM_CODE_START)
36#define RMM_RO_SIZE (RMM_RO_END - RMM_RO_START)
37#define RMM_RW_SIZE (RMM_RW_END - RMM_RW_START)
38
39#define RMM_CODE MAP_REGION_FLAT( \
40 RMM_CODE_START, \
41 RMM_CODE_SIZE, \
42 MT_CODE | MT_REALM)
43
44#define RMM_RO MAP_REGION_FLAT( \
45 RMM_RO_START, \
46 RMM_RO_SIZE, \
47 MT_RO_DATA | MT_REALM)
48
49#define RMM_RW MAP_REGION_FLAT( \
50 RMM_RW_START, \
51 RMM_RW_SIZE, \
52 MT_RW_DATA | MT_REALM)
53
54/*
55 * Some of the fields for the RMM_SHARED region will be populated
56 * at runtime.
57 */
58#define RMM_SHARED MAP_REGION( \
59 0U, \
60 RMM_SHARED_BUFFER_START, \
61 0U, \
62 MT_RW_DATA | MT_REALM)
63
64
65XLAT_REGISTER_CONTEXT(runtime, VA_LOW_REGION, PLAT_CMN_MAX_MMAP_REGIONS,
66 PLAT_CMN_CTX_MAX_XLAT_TABLES,
67 VIRT_ADDR_SPACE_SIZE,
68 "xlat_static_tables");
69
70/*
71 * Platform common cold boot setup for RMM.
72 *
73 * This function should only be invoked once during cold boot
74 * and is expected to setup architecture and platform components
75 * common for all PEs executing RMM.
76 * The xlat tables and GIC driver are initialized by this function.
77 */
78int plat_cmn_setup(unsigned long x0, unsigned long x1,
79 unsigned long x2, unsigned long x3,
80 struct xlat_mmap_region *plat_regions)
81{
82 int ret;
83
84 /* Initialize the RMM <-> EL3 interface */
85 ret = rmm_el3_ifc_init(x0, x1, x2, x3, RMM_SHARED_BUFFER_START);
86 if (ret != 0) {
87 ERROR("%s (%u): Failed to initialized RMM EL3 Interface\n",
AlexeiFedorov7c5001a2022-12-14 13:22:33 +000088 __func__, __LINE__);
Soby Mathewb4c6df42022-11-09 11:13:29 +000089 return ret;
90 }
91
92 /*
93 * xlat library might modify the memory mappings
94 * to optimize it, so don't make this constant.
95 */
96 struct xlat_mmap_region runtime_regions[] = {
97 RMM_CODE,
98 RMM_RO,
99 RMM_RW,
100 RMM_SHARED,
101 {0}
102 };
103
104 assert(plat_regions != NULL);
105
106 ret = xlat_mmap_add_ctx(&runtime_xlat_ctx, plat_regions, false);
107 if (ret != 0) {
108 ERROR("%s (%u): Failed to add platform regions to xlat mapping\n",
109 __func__, __LINE__);
110 return ret;
111 }
112
113 /* Setup the parameters of the shared area */
114 runtime_regions[3].base_pa = rmm_el3_ifc_get_shared_buf_pa();
115 runtime_regions[3].size = rmm_el3_ifc_get_shared_buf_size();
116
117 ret = xlat_mmap_add_ctx(&runtime_xlat_ctx, runtime_regions, true);
118 if (ret != 0) {
119 ERROR("%s (%u): Failed to add RMM common regions to xlat mapping\n",
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000120 __func__, __LINE__);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000121 return ret;
122 }
123
124 ret = xlat_init_tables_ctx(&runtime_xlat_ctx);
125 if (ret != 0) {
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000126 ERROR("%s (%u): xlat initialization failed\n",
127 __func__, __LINE__);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000128 return ret;
129 }
130
131 /* Read supported GIC virtualization features and init GIC variables */
132 gic_get_virt_features();
133
134 return 0;
135}
136
137/*
138 * Local PE common platform setup for RMM.
139 *
140 * This function will only be invoked during
141 * warm boot and is expected to setup architecture and platform
142 * components local to a PE executing RMM.
143 */
144int plat_cmn_warmboot_setup(void)
145{
146 int ret;
147
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000148 /* Setup the MMU cfg for the low region (runtime context) */
Soby Mathewb4c6df42022-11-09 11:13:29 +0000149 ret = xlat_arch_setup_mmu_cfg(&runtime_xlat_ctx);
150 if (ret != 0) {
151 ERROR("%s (%u): Failed to setup xlat tables for CPU[%u]\n",
AlexeiFedorov7c5001a2022-12-14 13:22:33 +0000152 __func__, __LINE__, my_cpuid());
Soby Mathewb4c6df42022-11-09 11:13:29 +0000153 return ret;
154 }
155
156 /* Setup the MMU cfg for the slot buffer context (high region) */
157 slot_buf_setup_xlat();
158
159 VERBOSE("xlat tables configured for CPU[%u]\n", my_cpuid());
160 return 0;
161}