blob: 21d78b7c6648c92d6ca9017c403c1faf564137f1 [file] [log] [blame]
Julian Hallf31da8e2023-01-17 10:10:29 +00001// SPDX-License-Identifier: BSD-3-Clause
2/*
Imre Kisefadd3a2024-06-28 14:15:57 +02003 * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
Julian Hallf31da8e2023-01-17 10:10:29 +00004 */
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;
Imre Kisefadd3a2024-06-28 14:15:57 +020048 struct update_agent *update_agent = NULL;
Julian Hallf31da8e2023-01-17 10:10:29 +000049 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
Imre Kisefadd3a2024-06-28 14:15:57 +020092 update_agent = update_agent_init(HARD_CODED_BOOT_INDEX, direct_fw_inspector_inspect,
93 &fw_store);
94 if (!update_agent) {
Julian Hallf31da8e2023-01-17 10:10:29 +000095 EMSG("Failed to init update agent");
96 goto fatal_error;
97 }
98
99 /* Initialise the FWU service provider */
Imre Kisefadd3a2024-06-28 14:15:57 +0200100 service_iface = fwu_provider_init(&service_provider, update_agent);
Julian Hallf31da8e2023-01-17 10:10:29 +0000101
102 if (!service_iface) {
103 EMSG("Failed to init service provider");
104 goto fatal_error;
105 }
106
Gyorgy Szing3c446242023-03-31 01:53:15 +0200107 fwu_provider_register_serializer(&service_provider, TS_RPC_ENCODING_PACKED_C,
108 packedc_fwu_provider_serializer_instance());
Julian Hallf31da8e2023-01-17 10:10:29 +0000109
Julian Hallf31da8e2023-01-17 10:10:29 +0000110 /* Associate service interface with FFA call endpoint */
Imre Kis2a0d0e62023-07-04 18:00:53 +0200111 rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 1, 16);
112 if (rpc_status != RPC_SUCCESS) {
113 EMSG("Failed to initialize RPC endpoint: %d", rpc_status);
114 goto fatal_error;
115 }
116
117 rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, service_iface);
118 if (rpc_status != RPC_SUCCESS) {
119 EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
120 goto fatal_error;
121 }
Julian Hallf31da8e2023-01-17 10:10:29 +0000122
123 /* End of boot phase */
124 result = sp_msg_wait(&req_msg);
125 if (result != SP_RESULT_OK) {
126 EMSG("Failed to send message wait %d", result);
127 goto fatal_error;
128 }
129
130 while (1) {
Imre Kis2a0d0e62023-07-04 18:00:53 +0200131 ts_rpc_endpoint_sp_receive(&rpc_endpoint, &req_msg, &resp_msg);
Julian Hallf31da8e2023-01-17 10:10:29 +0000132
133 result = sp_msg_send_direct_resp(&resp_msg, &req_msg);
134 if (result != SP_RESULT_OK) {
135 EMSG("Failed to send direct response %d", result);
136 result = sp_msg_wait(&req_msg);
137 if (result != SP_RESULT_OK) {
138 EMSG("Failed to send message wait %d", result);
139 goto fatal_error;
140 }
141 }
142 }
143
144fatal_error:
145 /* SP is not viable */
146 EMSG("FWU SP error");
Gyorgy Szing3c446242023-03-31 01:53:15 +0200147 while (1) {
148 }
Julian Hallf31da8e2023-01-17 10:10:29 +0000149}
150
151void sp_interrupt_handler(uint32_t interrupt_id)
152{
153 (void)interrupt_id;
154}
155
Balint Dobszayac721da2024-07-02 16:33:59 +0200156ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
157{
158 (void)vm_id;
159 (void)handle;
160
161 return FFA_OK;
162}
163
164ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
165{
166 (void)vm_id;
167 (void)handle;
168
169 return FFA_OK;
170}
171
Julian Hallf31da8e2023-01-17 10:10:29 +0000172static bool sp_init(uint16_t *own_id)
173{
Julian Hallf31da8e2023-01-17 10:10:29 +0000174 static uint8_t tx_buffer[4096] __aligned(4096);
175 static uint8_t rx_buffer[4096] __aligned(4096);
176
Gyorgy Szing3c446242023-03-31 01:53:15 +0200177 sp_result sp_res = sp_rxtx_buffer_map(tx_buffer, rx_buffer, sizeof(rx_buffer));
Julian Hallf31da8e2023-01-17 10:10:29 +0000178 if (sp_res != SP_RESULT_OK) {
179 EMSG("Failed to map RXTX buffers: %d", sp_res);
180 return false;
181 }
182
183 sp_res = sp_discovery_own_id_get(own_id);
184 if (sp_res != SP_RESULT_OK) {
185 EMSG("Failed to query own ID: %d", sp_res);
186 return false;
187 }
188
189 return true;
190}
191
192static bool configure_for_platform(void)
193{
194 struct uuid_octets device_uuids[FWU_SP_MAX_STORAGE_DEVICES];
195 size_t num_storage_devices = 0;
196
Gyorgy Szing3c446242023-03-31 01:53:15 +0200197 int status =
198 volume_factory_init(device_uuids, FWU_SP_MAX_STORAGE_DEVICES, &num_storage_devices);
Julian Hallf31da8e2023-01-17 10:10:29 +0000199
200 if (status) {
Julian Hallf31da8e2023-01-17 10:10:29 +0000201 EMSG("Failed to init volume factory: %d", status);
202 return false;
203 }
204
205 status = fwu_configure(device_uuids, num_storage_devices);
206
207 if (status) {
Julian Hallf31da8e2023-01-17 10:10:29 +0000208 EMSG("Failed to setup FWU configuration: %d", status);
209 return false;
210 }
211
212 return true;
213}
214
215const struct metadata_serializer *select_metadata_serializer(unsigned int version)
216{
217 if (version == 1)
218 return metadata_serializer_v1();
219
220 if (version == 2)
221 return metadata_serializer_v2();
222
223 return NULL;
224}