blob: e3e0544042f463a5f03e70aa44067f5c286d65c1 [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
155static bool sp_init(uint16_t *own_id)
156{
Julian Hallf31da8e2023-01-17 10:10:29 +0000157 static uint8_t tx_buffer[4096] __aligned(4096);
158 static uint8_t rx_buffer[4096] __aligned(4096);
159
Gyorgy Szing3c446242023-03-31 01:53:15 +0200160 sp_result sp_res = sp_rxtx_buffer_map(tx_buffer, rx_buffer, sizeof(rx_buffer));
Julian Hallf31da8e2023-01-17 10:10:29 +0000161 if (sp_res != SP_RESULT_OK) {
162 EMSG("Failed to map RXTX buffers: %d", sp_res);
163 return false;
164 }
165
166 sp_res = sp_discovery_own_id_get(own_id);
167 if (sp_res != SP_RESULT_OK) {
168 EMSG("Failed to query own ID: %d", sp_res);
169 return false;
170 }
171
172 return true;
173}
174
175static bool configure_for_platform(void)
176{
177 struct uuid_octets device_uuids[FWU_SP_MAX_STORAGE_DEVICES];
178 size_t num_storage_devices = 0;
179
Gyorgy Szing3c446242023-03-31 01:53:15 +0200180 int status =
181 volume_factory_init(device_uuids, FWU_SP_MAX_STORAGE_DEVICES, &num_storage_devices);
Julian Hallf31da8e2023-01-17 10:10:29 +0000182
183 if (status) {
Julian Hallf31da8e2023-01-17 10:10:29 +0000184 EMSG("Failed to init volume factory: %d", status);
185 return false;
186 }
187
188 status = fwu_configure(device_uuids, num_storage_devices);
189
190 if (status) {
Julian Hallf31da8e2023-01-17 10:10:29 +0000191 EMSG("Failed to setup FWU configuration: %d", status);
192 return false;
193 }
194
195 return true;
196}
197
198const struct metadata_serializer *select_metadata_serializer(unsigned int version)
199{
200 if (version == 1)
201 return metadata_serializer_v1();
202
203 if (version == 2)
204 return metadata_serializer_v2();
205
206 return NULL;
207}