1 /*
2 * Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <common/debug.h>
8 #include <drivers/arm/gic600_multichip.h>
9 #include <drivers/arm/mhu.h>
10 #include <drivers/arm/rse_comms.h>
11 #include <plat/arm/common/plat_arm.h>
12 #include <plat/common/platform.h>
13 #include <platform_def.h>
14 #include <nrd_plat.h>
15 #include <rdv3_mhuv3.h>
16 #include <rdv3_rse_comms.h>
17
plat_arm_nrd_get_platform_id(void)18 unsigned int plat_arm_nrd_get_platform_id(void)
19 {
20 return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET) &
21 SID_SYSTEM_ID_PART_NUM_MASK;
22 }
23
plat_arm_nrd_get_config_id(void)24 unsigned int plat_arm_nrd_get_config_id(void)
25 {
26 return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
27 }
28
plat_arm_nrd_get_multi_chip_mode(void)29 unsigned int plat_arm_nrd_get_multi_chip_mode(void)
30 {
31 return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
32 SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
33 }
34
35 /*
36 * Get a pointer to the RMM-EL3 shared buffer and return it
37 * through the pointer passed as parameter.
38 *
39 * This function returns the size of the shared buffer.
40 */
plat_rmmd_get_el3_rmm_shared_mem(uintptr_t * shared)41 size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
42 {
43 *shared = (uintptr_t)RMM_SHARED_BASE;
44
45 return (size_t)RMM_SHARED_SIZE;
46 }
47
48 /*
49 * Calculate checksum of 64-bit words @buffer with @size length
50 */
checksum_calc(uint64_t * buffer,size_t size)51 static uint64_t checksum_calc(uint64_t *buffer, size_t size)
52 {
53 uint64_t sum = 0UL;
54
55 assert(((uintptr_t)buffer & (sizeof(uint64_t) - 1UL)) == 0UL);
56 assert((size & (sizeof(uint64_t) - 1UL)) == 0UL);
57
58 for (unsigned long i = 0UL; i < (size / sizeof(uint64_t)); i++) {
59 sum += buffer[i];
60 }
61
62 return sum;
63 }
64
plat_rmmd_load_manifest(struct rmm_manifest * manifest)65 int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
66 {
67 uint64_t checksum, num_banks, num_consoles;
68 struct memory_bank *bank_ptr;
69 struct console_info *console_ptr;
70
71 assert(manifest != NULL);
72
73 /* DRAM Bank-1 and Bank-2 */
74 num_banks = 2;
75 assert(num_banks <= ARM_DRAM_NUM_BANKS);
76
77 /* Set number of consoles */
78 num_consoles = NRD_CSS_RMM_CONSOLE_COUNT;
79
80 manifest->version = RMMD_MANIFEST_VERSION;
81 manifest->padding = 0U; /* RES0 */
82 manifest->plat_data = (uintptr_t)NULL;
83 manifest->plat_dram.num_banks = num_banks;
84 manifest->plat_console.num_consoles = num_consoles;
85
86 /*
87 * Boot Manifest structure illustration, with two dram banks and
88 * a single console.
89 *
90 * +----------------------------------------+
91 * | offset | field | comment |
92 * +--------+----------------+--------------+
93 * | 0 | version | 0x00000003 |
94 * +--------+----------------+--------------+
95 * | 4 | padding | 0x00000000 |
96 * +--------+----------------+--------------+
97 * | 8 | plat_data | NULL |
98 * +--------+----------------+--------------+
99 * | 16 | num_banks | |
100 * +--------+----------------+ |
101 * | 24 | banks | plat_dram |
102 * +--------+----------------+ |
103 * | 32 | checksum | |
104 * +--------+----------------+--------------+
105 * | 40 | num_consoles | |
106 * +--------+----------------+ |
107 * | 48 | consoles | plat_console |
108 * +--------+----------------+ |
109 * | 56 | checksum | |
110 * +--------+----------------+--------------+
111 * | 64 | base 0 | |
112 * +--------+----------------+ bank[0] |
113 * | 72 | size 0 | |
114 * +--------+----------------+--------------+
115 * | 80 | base 1 | |
116 * +--------+----------------+ bank[1] |
117 * | 88 | size 1 | |
118 * +--------+----------------+--------------+
119 * | 96 | base | |
120 * +--------+----------------+ |
121 * | 104 | map_pages | |
122 * +--------+----------------+ |
123 * | 112 | name | |
124 * +--------+----------------+ consoles[0] |
125 * | 120 | clk_in_hz | |
126 * +--------+----------------+ |
127 * | 128 | baud_rate | |
128 * +--------+----------------+ |
129 * | 136 | flags | |
130 * +--------+----------------+--------------+
131 */
132
133 bank_ptr = (struct memory_bank *)
134 (((uintptr_t)manifest) + sizeof(*manifest));
135 console_ptr = (struct console_info *)
136 ((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
137
138 manifest->plat_dram.banks = bank_ptr;
139 manifest->plat_console.consoles = console_ptr;
140
141 /* Ensure the manifest is not larger than the shared buffer */
142 assert((sizeof(struct rmm_manifest) +
143 (sizeof(struct console_info) *
144 manifest->plat_console.num_consoles) +
145 (sizeof(struct memory_bank) * manifest->plat_dram.num_banks))
146 <= ARM_EL3_RMM_SHARED_SIZE);
147
148 /* Calculate checksum of plat_dram structure */
149 checksum = num_banks + (uint64_t)bank_ptr;
150
151 /* Store FVP DRAM banks data in Boot Manifest */
152 bank_ptr[0].base = ARM_NS_DRAM1_BASE;
153 bank_ptr[0].size = ARM_NS_DRAM1_SIZE;
154
155 bank_ptr[1].base = ARM_DRAM2_BASE;
156 bank_ptr[1].size = ARM_DRAM2_SIZE;
157
158 /* Update checksum */
159 checksum += checksum_calc((uint64_t *)bank_ptr,
160 sizeof(struct memory_bank) * num_banks);
161
162 /* Checksum must be 0 */
163 manifest->plat_dram.checksum = ~checksum + 1UL;
164
165 /* Calculate the checksum of the plat_consoles structure */
166 checksum = num_consoles + (uint64_t)console_ptr;
167
168 /* Zero out the console info struct */
169 (void)memset((void *)console_ptr, '\0',
170 sizeof(struct console_info) * num_consoles);
171
172 console_ptr[0].map_pages = 1UL;
173 console_ptr[0].base = NRD_CSS_RMM_CONSOLE_BASE;
174 console_ptr[0].clk_in_hz = NRD_CSS_RMM_CONSOLE_CLK_IN_HZ;
175 console_ptr[0].baud_rate = NRD_CSS_RMM_CONSOLE_BAUD;
176
177 (void)strlcpy(console_ptr[0].name, NRD_CSS_RMM_CONSOLE_NAME,
178 sizeof(console_ptr[0].name));
179
180 /* Update checksum */
181 checksum += checksum_calc((uint64_t *)console_ptr,
182 sizeof(struct console_info) * num_consoles);
183
184 /* Checksum must be 0 */
185 manifest->plat_console.checksum = ~checksum + 1UL;
186
187 return 0;
188 }
189
190 /*
191 * Update encryption key associated with @mecid.
192 */
plat_rmmd_mecid_key_update(uint16_t mecid,unsigned int reason)193 int plat_rmmd_mecid_key_update(uint16_t mecid, unsigned int reason)
194 {
195 /*
196 * RDV3 does not support FEAT_MEC.
197 * This empty hook is for compilation to succeed.
198 */
199 return 0;
200 }
201
plat_rse_comms_init(void)202 int plat_rse_comms_init(void)
203 {
204 struct mhu_addr mhu_addresses;
205
206 /* Get sender and receiver frames for AP-RSE communication */
207 mhu_v3_get_secure_device_base(&mhu_addresses.sender_base, true);
208 mhu_v3_get_secure_device_base(&mhu_addresses.receiver_base, false);
209
210 VERBOSE("Initializing the rse_comms now\n");
211 /* Initialize the communication channel between AP and RSE */
212 return rse_mbx_init(&mhu_addresses);
213 }
214
plat_spmd_handle_group0_interrupt(uint32_t intid)215 int plat_spmd_handle_group0_interrupt(uint32_t intid)
216 {
217 /*
218 * As of now, there are no sources of Group0 secure interrupt enabled
219 * for FVP.
220 */
221 (void)intid;
222 return -1;
223 }
224