blob: bf7cbe8fa566cbbd01348a02f3a6a58cb927a098 [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
Gyorgy Szing3c446242023-03-31 01:53:15 +02008#include "config/loader/sp/sp_config_loader.h"
9#include "config/ramstore/config_ramstore.h"
10#include "media/volume/factory/volume_factory.h"
11#include "protocols/rpc/common/packed-c/status.h"
12#include "rpc/ffarpc/endpoint/ffarpc_call_ep.h"
13#include "service/discovery/provider/discovery_provider.h"
14#include "service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.h"
15#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
43void __noreturn sp_main(struct ffa_init_info *init_info)
44{
45 struct ffa_call_ep ffarpc_call_ep = { 0 };
46 struct fwu_provider service_provider = { 0 };
47 struct rpc_interface *service_iface = NULL;
48 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;
54
55 /* Boot phase */
56 if (!sp_init(&own_id)) {
57 EMSG("Failed to init SP");
58 goto fatal_error;
59 }
60
61 config_ramstore_init();
62
63 if (!sp_config_load(init_info)) {
64 EMSG("Failed to load SP config");
65 goto fatal_error;
66 }
67
68 /* Configuration - discovers required volumes and installers */
69 if (!configure_for_platform()) {
70 EMSG("Failed to configure for platform");
71 goto fatal_error;
72 }
73
74 /* Select FWU metadata serializer for compatibility with bootloader */
75 const struct metadata_serializer *serializer =
76 select_metadata_serializer(HARD_CODED_METADATA_VER);
77
78 if (!serializer) {
79 EMSG("Unsupported FWU metadata version");
80 goto fatal_error;
81 }
82
83 /* Initialise fw store */
84 if (banked_fw_store_init(&fw_store, serializer)) {
85 EMSG("Failed to init fw store");
86 goto fatal_error;
87 }
88
Gyorgy Szing3c446242023-03-31 01:53:15 +020089 if (update_agent_init(&update_agent, HARD_CODED_BOOT_INDEX, direct_fw_inspector_inspect,
90 &fw_store)) {
Julian Hallf31da8e2023-01-17 10:10:29 +000091 EMSG("Failed to init update agent");
92 goto fatal_error;
93 }
94
95 /* Initialise the FWU service provider */
Gyorgy Szing3c446242023-03-31 01:53:15 +020096 service_iface = fwu_provider_init(&service_provider, &update_agent);
Julian Hallf31da8e2023-01-17 10:10:29 +000097
98 if (!service_iface) {
99 EMSG("Failed to init service provider");
100 goto fatal_error;
101 }
102
Gyorgy Szing3c446242023-03-31 01:53:15 +0200103 fwu_provider_register_serializer(&service_provider, TS_RPC_ENCODING_PACKED_C,
104 packedc_fwu_provider_serializer_instance());
Julian Hallf31da8e2023-01-17 10:10:29 +0000105
Gyorgy Szing3c446242023-03-31 01:53:15 +0200106 discovery_provider_register_serializer(&service_provider.discovery_provider,
107 TS_RPC_ENCODING_PACKED_C,
108 packedc_discovery_provider_serializer_instance());
Julian Hallf31da8e2023-01-17 10:10:29 +0000109
110 /* Associate service interface with FFA call endpoint */
111 ffa_call_ep_init(&ffarpc_call_ep, service_iface, own_id);
112
113 /* End of boot phase */
114 result = sp_msg_wait(&req_msg);
115 if (result != SP_RESULT_OK) {
116 EMSG("Failed to send message wait %d", result);
117 goto fatal_error;
118 }
119
120 while (1) {
121 ffa_call_ep_receive(&ffarpc_call_ep, &req_msg, &resp_msg);
122
123 result = sp_msg_send_direct_resp(&resp_msg, &req_msg);
124 if (result != SP_RESULT_OK) {
125 EMSG("Failed to send direct response %d", result);
126 result = sp_msg_wait(&req_msg);
127 if (result != SP_RESULT_OK) {
128 EMSG("Failed to send message wait %d", result);
129 goto fatal_error;
130 }
131 }
132 }
133
134fatal_error:
135 /* SP is not viable */
136 EMSG("FWU SP error");
Gyorgy Szing3c446242023-03-31 01:53:15 +0200137 while (1) {
138 }
Julian Hallf31da8e2023-01-17 10:10:29 +0000139}
140
141void sp_interrupt_handler(uint32_t interrupt_id)
142{
143 (void)interrupt_id;
144}
145
146static bool sp_init(uint16_t *own_id)
147{
Julian Hallf31da8e2023-01-17 10:10:29 +0000148 static uint8_t tx_buffer[4096] __aligned(4096);
149 static uint8_t rx_buffer[4096] __aligned(4096);
150
Gyorgy Szing3c446242023-03-31 01:53:15 +0200151 sp_result sp_res = sp_rxtx_buffer_map(tx_buffer, rx_buffer, sizeof(rx_buffer));
Julian Hallf31da8e2023-01-17 10:10:29 +0000152 if (sp_res != SP_RESULT_OK) {
153 EMSG("Failed to map RXTX buffers: %d", sp_res);
154 return false;
155 }
156
157 sp_res = sp_discovery_own_id_get(own_id);
158 if (sp_res != SP_RESULT_OK) {
159 EMSG("Failed to query own ID: %d", sp_res);
160 return false;
161 }
162
163 return true;
164}
165
166static bool configure_for_platform(void)
167{
168 struct uuid_octets device_uuids[FWU_SP_MAX_STORAGE_DEVICES];
169 size_t num_storage_devices = 0;
170
Gyorgy Szing3c446242023-03-31 01:53:15 +0200171 int status =
172 volume_factory_init(device_uuids, FWU_SP_MAX_STORAGE_DEVICES, &num_storage_devices);
Julian Hallf31da8e2023-01-17 10:10:29 +0000173
174 if (status) {
Julian Hallf31da8e2023-01-17 10:10:29 +0000175 EMSG("Failed to init volume factory: %d", status);
176 return false;
177 }
178
179 status = fwu_configure(device_uuids, num_storage_devices);
180
181 if (status) {
Julian Hallf31da8e2023-01-17 10:10:29 +0000182 EMSG("Failed to setup FWU configuration: %d", status);
183 return false;
184 }
185
186 return true;
187}
188
189const struct metadata_serializer *select_metadata_serializer(unsigned int version)
190{
191 if (version == 1)
192 return metadata_serializer_v1();
193
194 if (version == 2)
195 return metadata_serializer_v2();
196
197 return NULL;
198}