xref: /rk3399_ARM-atf/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c (revision 24804eeb334e17a34f7e755eda420cd83079f40b)
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