blob: c9bf4b13660d261bea657210cc5fc007831c6bf2 [file] [log] [blame]
Julian Hallf31da8e2023-01-17 10:10:29 +00001// SPDX-License-Identifier: BSD-3-Clause
2/*
3 * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
4 */
5
6#include <stddef.h>
Julian Hallf31da8e2023-01-17 10:10:29 +00007
Balint Dobszay550ce872022-12-15 15:28:40 +01008#include "common/crc32/crc32.h"
Gyorgy Szing3c446242023-03-31 01:53:15 +02009#include "config/loader/sp/sp_config_loader.h"
10#include "config/ramstore/config_ramstore.h"
11#include "media/volume/factory/volume_factory.h"
12#include "protocols/rpc/common/packed-c/status.h"
Imre Kis2a0d0e62023-07-04 18:00:53 +020013#include "components/rpc/common/endpoint/rpc_service_interface.h"
14#include "components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.h"
Gyorgy Szing3c446242023-03-31 01:53:15 +020015#include "service/fwu/agent/update_agent.h"
16#include "service/fwu/config/fwu_configure.h"
17#include "service/fwu/fw_store/banked/bank_scheme.h"
18#include "service/fwu/fw_store/banked/banked_fw_store.h"
19#include "service/fwu/fw_store/banked/metadata_serializer/v1/metadata_serializer_v1.h"
20#include "service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.h"
21#include "service/fwu/inspector/direct/direct_fw_inspector.h"
22#include "service/fwu/provider/fwu_provider.h"
23#include "service/fwu/provider/serializer/packed-c/packedc_fwu_provider_serializer.h"
24#include "sp_api.h"
25#include "sp_discovery.h"
26#include "sp_messaging.h"
27#include "sp_rxtx.h"
28#include "trace.h"
Julian Hallf31da8e2023-01-17 10:10:29 +000029
30/* Set default limit on the number of storage devices to update */
31#ifndef FWU_SP_MAX_STORAGE_DEVICES
Gyorgy Szing3c446242023-03-31 01:53:15 +020032#define FWU_SP_MAX_STORAGE_DEVICES (1)
Julian Hallf31da8e2023-01-17 10:10:29 +000033#endif
34
35/* Parameters that should be passed forward by the bootloader */
Gyorgy Szing3c446242023-03-31 01:53:15 +020036#define HARD_CODED_BOOT_INDEX (0)
37#define HARD_CODED_METADATA_VER (2)
Julian Hallf31da8e2023-01-17 10:10:29 +000038
39static bool sp_init(uint16_t *own_sp_id);
40static bool configure_for_platform(void);
41const struct metadata_serializer *select_metadata_serializer(unsigned int version);
42
Balint Dobszay4f9d8e32023-04-13 13:55:08 +020043void __noreturn sp_main(union ffa_boot_info *boot_info)
Julian Hallf31da8e2023-01-17 10:10:29 +000044{
Imre Kis2a0d0e62023-07-04 18:00:53 +020045 struct ts_rpc_endpoint_sp rpc_endpoint = { 0 };
Julian Hallf31da8e2023-01-17 10:10:29 +000046 struct fwu_provider service_provider = { 0 };
Imre Kis2a0d0e62023-07-04 18:00:53 +020047 struct rpc_service_interface *service_iface = NULL;
Julian Hallf31da8e2023-01-17 10:10:29 +000048 struct update_agent update_agent = { 0 };
49 struct fw_store fw_store = { 0 };
50 struct sp_msg req_msg = { 0 };
51 struct sp_msg resp_msg = { 0 };
52 uint16_t own_id = 0;
53 sp_result result = SP_RESULT_INTERNAL_ERROR;
Imre Kis2a0d0e62023-07-04 18:00:53 +020054 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
Julian Hallf31da8e2023-01-17 10:10:29 +000055
56 /* Boot phase */
57 if (!sp_init(&own_id)) {
58 EMSG("Failed to init SP");
59 goto fatal_error;
60 }
61
62 config_ramstore_init();
63
Balint Dobszay4f9d8e32023-04-13 13:55:08 +020064 if (!sp_config_load(boot_info)) {
Julian Hallf31da8e2023-01-17 10:10:29 +000065 EMSG("Failed to load SP config");
66 goto fatal_error;
67 }
68
Balint Dobszay550ce872022-12-15 15:28:40 +010069 crc32_init();
70
Julian Hallf31da8e2023-01-17 10:10:29 +000071 /* Configuration - discovers required volumes and installers */
72 if (!configure_for_platform()) {
73 EMSG("Failed to configure for platform");
74 goto fatal_error;
75 }
76
77 /* Select FWU metadata serializer for compatibility with bootloader */
78 const struct metadata_serializer *serializer =
79 select_metadata_serializer(HARD_CODED_METADATA_VER);
80
81 if (!serializer) {
82 EMSG("Unsupported FWU metadata version");
83 goto fatal_error;
84 }
85
86 /* Initialise fw store */
87 if (banked_fw_store_init(&fw_store, serializer)) {
88 EMSG("Failed to init fw store");
89 goto fatal_error;
90 }
91
Gyorgy Szing3c446242023-03-31 01:53:15 +020092 if (update_agent_init(&update_agent, HARD_CODED_BOOT_INDEX, direct_fw_inspector_inspect,
93 &fw_store)) {
Julian Hallf31da8e2023-01-17 10:10:29 +000094 EMSG("Failed to init update agent");
95 goto fatal_error;
96 }
97
98 /* Initialise the FWU service provider */
Gyorgy Szing3c446242023-03-31 01:53:15 +020099 service_iface = fwu_provider_init(&service_provider, &update_agent);
Julian Hallf31da8e2023-01-17 10:10:29 +0000100
101 if (!service_iface) {
102 EMSG("Failed to init service provider");
103 goto fatal_error;
104 }
105
Gyorgy Szing3c446242023-03-31 01:53:15 +0200106 fwu_provider_register_serializer(&service_provider, TS_RPC_ENCODING_PACKED_C,
107 packedc_fwu_provider_serializer_instance());
Julian Hallf31da8e2023-01-17 10:10:29 +0000108
Julian Hallf31da8e2023-01-17 10:10:29 +0000109 /* Associate service interface with FFA call endpoint */
Imre Kis2a0d0e62023-07-04 18:00:53 +0200110 rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 1, 16);
111 if (rpc_status != RPC_SUCCESS) {
112 EMSG("Failed to initialize RPC endpoint: %d", rpc_status);
113 goto fatal_error;
114 }
115
116 rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, service_iface);
117 if (rpc_status != RPC_SUCCESS) {
118 EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
119 goto fatal_error;
120 }
Julian Hallf31da8e2023-01-17 10:10:29 +0000121
122 /* End of boot phase */
123 result = sp_msg_wait(&req_msg);
124 if (result != SP_RESULT_OK) {
125 EMSG("Failed to send message wait %d", result);
126 goto fatal_error;
127 }
128
129 while (1) {
Imre Kis2a0d0e62023-07-04 18:00:53 +0200130 ts_rpc_endpoint_sp_receive(&rpc_endpoint, &req_msg, &resp_msg);
Julian Hallf31da8e2023-01-17 10:10:29 +0000131
132 result = sp_msg_send_direct_resp(&resp_msg, &req_msg);
133 if (result != SP_RESULT_OK) {
134 EMSG("Failed to send direct response %d", result);
135 result = sp_msg_wait(&req_msg);
136 if (result != SP_RESULT_OK) {
137 EMSG("Failed to send message wait %d", result);
138 goto fatal_error;
139 }
140 }
141 }
142
143fatal_error:
144 /* SP is not viable */
145 EMSG("FWU SP error");
Gyorgy Szing3c446242023-03-31 01:53:15 +0200146 while (1) {
147 }
Julian Hallf31da8e2023-01-17 10:10:29 +0000148}
149
150void sp_interrupt_handler(uint32_t interrupt_id)
151{
152 (void)interrupt_id;
153}
154
Balint Dobszayac721da2024-07-02 16:33:59 +0200155ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
156{
157 (void)vm_id;
158 (void)handle;
159
160 return FFA_OK;
161}
162
163ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
164{
165 (void)vm_id;
166 (void)handle;
167
168 return FFA_OK;
169}
170
Julian Hallf31da8e2023-01-17 10:10:29 +0000171static bool sp_init(uint16_t *own_id)
172{
Julian Hallf31da8e2023-01-17 10:10:29 +0000173 static uint8_t tx_buffer[4096] __aligned(4096);
174 static uint8_t rx_buffer[4096] __aligned(4096);
175
Gyorgy Szing3c446242023-03-31 01:53:15 +0200176 sp_result sp_res = sp_rxtx_buffer_map(tx_buffer, rx_buffer, sizeof(rx_buffer));
Julian Hallf31da8e2023-01-17 10:10:29 +0000177 if (sp_res != SP_RESULT_OK) {
178 EMSG("Failed to map RXTX buffers: %d", sp_res);
179 return false;
180 }
181
182 sp_res = sp_discovery_own_id_get(own_id);
183 if (sp_res != SP_RESULT_OK) {
184 EMSG("Failed to query own ID: %d", sp_res);
185 return false;
186 }
187
188 return true;
189}
190
191static bool configure_for_platform(void)
192{
193 struct uuid_octets device_uuids[FWU_SP_MAX_STORAGE_DEVICES];
194 size_t num_storage_devices = 0;
195
Gyorgy Szing3c446242023-03-31 01:53:15 +0200196 int status =
197 volume_factory_init(device_uuids, FWU_SP_MAX_STORAGE_DEVICES, &num_storage_devices);
Julian Hallf31da8e2023-01-17 10:10:29 +0000198
199 if (status) {
Julian Hallf31da8e2023-01-17 10:10:29 +0000200 EMSG("Failed to init volume factory: %d", status);
201 return false;
202 }
203
204 status = fwu_configure(device_uuids, num_storage_devices);
205
206 if (status) {
Julian Hallf31da8e2023-01-17 10:10:29 +0000207 EMSG("Failed to setup FWU configuration: %d", status);
208 return false;
209 }
210
211 return true;
212}
213
214const struct metadata_serializer *select_metadata_serializer(unsigned int version)
215{
216 if (version == 1)
217 return metadata_serializer_v1();
218
219 if (version == 2)
220 return metadata_serializer_v2();
221
222 return NULL;
223}