blob: 173afce1eb21bde8bc6d06440f52e00e324fbb63 [file] [log] [blame]
Julian Hall65bb4102023-01-19 12:09:02 +00001/*
2 * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Gyorgy Szing3c446242023-03-31 01:53:15 +02007#include "fwu_app.h"
8
Julian Hall65bb4102023-01-19 12:09:02 +00009#include <cassert>
10#include <cstddef>
11#include <cstring>
12#include <errno.h>
Gyorgy Szing3c446242023-03-31 01:53:15 +020013
14#include "media/volume/factory/volume_factory.h"
Julian Hall65bb4102023-01-19 12:09:02 +000015#include "metadata_reader.h"
Gyorgy Szing3c446242023-03-31 01:53:15 +020016#include "service/block_storage/factory/file/block_store_factory.h"
17#include "service/fwu/agent/update_agent.h"
18#include "service/fwu/config/fwu_configure.h"
19#include "service/fwu/fw_store/banked/bank_scheme.h"
20#include "service/fwu/fw_store/banked/banked_fw_store.h"
21#include "service/fwu/fw_store/banked/metadata_serializer/v1/metadata_serializer_v1.h"
22#include "service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.h"
23#include "service/fwu/inspector/direct/direct_fw_inspector.h"
24#include "service/fwu/installer/factory/installer_factory.h"
Julian Hall65bb4102023-01-19 12:09:02 +000025
26extern "C" {
Gyorgy Szing3c446242023-03-31 01:53:15 +020027#include "trace.h"
Julian Hall65bb4102023-01-19 12:09:02 +000028}
29
Gyorgy Szing3c446242023-03-31 01:53:15 +020030fwu_app::fwu_app()
31 : m_update_agent()
32 , m_fw_store()
Julian Hall65bb4102023-01-19 12:09:02 +000033{
34 memset(&m_update_agent, 0, sizeof(m_update_agent));
35 memset(&m_fw_store, 0, sizeof(m_fw_store));
36}
37
38fwu_app::~fwu_app()
39{
40 update_agent_deinit(&m_update_agent);
41 banked_fw_store_deinit(&m_fw_store);
42
43 fwu_deconfigure();
44 volume_factory_deinit();
45}
46
Gyorgy Szing3c446242023-03-31 01:53:15 +020047int fwu_app::configure(const char *disk_img_filename)
Julian Hall65bb4102023-01-19 12:09:02 +000048{
49 if (disk_img_filename)
50 file_block_store_factory_set_filename(disk_img_filename);
51
52 struct uuid_octets device_uuids[MAX_STORAGE_DEVICES];
53 size_t num_storage_devices = 0;
54
Gyorgy Szing3c446242023-03-31 01:53:15 +020055 int status = volume_factory_init(device_uuids, MAX_STORAGE_DEVICES, &num_storage_devices);
Julian Hall65bb4102023-01-19 12:09:02 +000056
57 if (status) {
Julian Hall65bb4102023-01-19 12:09:02 +000058 EMSG("Failed to init volume factory: %d", status);
59 return -EIO;
60 }
61
62 status = fwu_configure(device_uuids, num_storage_devices);
63
64 if (status) {
Julian Hall65bb4102023-01-19 12:09:02 +000065 EMSG("Failed to setup FWU configuration: %d", status);
66 return -EIO;
67 }
68
69 return 0;
70}
71
Gyorgy Szing3c446242023-03-31 01:53:15 +020072int fwu_app::get_boot_info(unsigned int &active_index, unsigned int &metadata_version)
Julian Hall65bb4102023-01-19 12:09:02 +000073{
74 return metadata_reader::instance()->get_boot_info(active_index, metadata_version);
75}
76
Gyorgy Szing3c446242023-03-31 01:53:15 +020077int fwu_app::init_update_agent(unsigned int boot_index, unsigned int metadata_version)
Julian Hall65bb4102023-01-19 12:09:02 +000078{
79 if (boot_index >= BANK_SCHEME_NUM_BANKS) {
Julian Hall65bb4102023-01-19 12:09:02 +000080 IMSG("Invalid boot index");
81 return -1;
82 }
83
Gyorgy Szing3c446242023-03-31 01:53:15 +020084 const struct metadata_serializer *serializer = select_metadata_serializer(metadata_version);
Julian Hall65bb4102023-01-19 12:09:02 +000085
86 if (!serializer) {
Julian Hall65bb4102023-01-19 12:09:02 +000087 IMSG("Unsupported FWU metadata version");
88 return -1;
89 }
90
91 /* Initialise update_agent */
92 int status = banked_fw_store_init(&m_fw_store, serializer);
93
94 if (status) {
Julian Hall65bb4102023-01-19 12:09:02 +000095 IMSG("fw store initialisation error %d", status);
96 return -1;
97 }
98
Gyorgy Szing3c446242023-03-31 01:53:15 +020099 status = update_agent_init(&m_update_agent, boot_index, direct_fw_inspector_inspect,
100 &m_fw_store);
Julian Hall65bb4102023-01-19 12:09:02 +0000101
102 if (status) {
Julian Hall65bb4102023-01-19 12:09:02 +0000103 IMSG("update agent initialisation error %d", status);
104 return -1;
105 }
106
107 /* Success */
108 return 0;
109}
110
Gyorgy Szing3c446242023-03-31 01:53:15 +0200111int fwu_app::update_image(const struct uuid_octets &img_type_uuid, const uint8_t *img_data,
112 size_t img_size)
Julian Hall65bb4102023-01-19 12:09:02 +0000113{
114 int status = update_agent_begin_staging(&m_update_agent);
115
116 if (status)
117 return status;
118
119 uint32_t stream_handle = 0;
120
Gyorgy Szing3c446242023-03-31 01:53:15 +0200121 status = update_agent_open(&m_update_agent, &img_type_uuid, &stream_handle);
Julian Hall65bb4102023-01-19 12:09:02 +0000122
123 if (!status) {
Gyorgy Szing3c446242023-03-31 01:53:15 +0200124 status = update_agent_write_stream(&m_update_agent, stream_handle, img_data,
125 img_size);
Julian Hall65bb4102023-01-19 12:09:02 +0000126
127 if (!status)
Gyorgy Szing3c446242023-03-31 01:53:15 +0200128 status = update_agent_commit(&m_update_agent, stream_handle, false);
Julian Hall65bb4102023-01-19 12:09:02 +0000129 }
130
131 if (!status)
132 status = update_agent_end_staging(&m_update_agent);
133 else
134 update_agent_cancel_staging(&m_update_agent);
135
136 return status;
137}
138
Gyorgy Szing3c446242023-03-31 01:53:15 +0200139int fwu_app::read_object(const struct uuid_octets &object_uuid, std::vector<uint8_t> &data)
Julian Hall65bb4102023-01-19 12:09:02 +0000140{
141 uint32_t stream_handle = 0;
142 int status = update_agent_open(&m_update_agent, &object_uuid, &stream_handle);
143
144 if (status)
145 return status;
146
147 /* Don't yet know how big the object will be so allocate some space to get
148 * started with the initial read.
149 */
150 size_t reported_total_len = 0;
151 size_t read_so_far = 0;
152 size_t vector_capacity = 512;
153
154 data.resize(vector_capacity);
155
156 do {
Julian Hall65bb4102023-01-19 12:09:02 +0000157 size_t data_len_read = 0;
158 size_t requested_read_len = vector_capacity - read_so_far;
159
Gyorgy Szing3c446242023-03-31 01:53:15 +0200160 status = update_agent_read_stream(&m_update_agent, stream_handle,
161 &data[read_so_far], requested_read_len,
162 &data_len_read, &reported_total_len);
Julian Hall65bb4102023-01-19 12:09:02 +0000163
164 read_so_far += data_len_read;
165 data.resize(read_so_far);
166
167 if (reported_total_len > vector_capacity) {
Julian Hall65bb4102023-01-19 12:09:02 +0000168 vector_capacity = reported_total_len;
169 data.resize(vector_capacity);
170 }
171
172 assert(read_so_far <= reported_total_len);
173
174 if (read_so_far == reported_total_len) {
Julian Hall65bb4102023-01-19 12:09:02 +0000175 /* Read all the data */
176 if (vector_capacity > reported_total_len)
177 data.resize(reported_total_len);
178
179 break;
180 }
181
182 } while (!status);
183
184 status = update_agent_commit(&m_update_agent, stream_handle, false);
185
186 return status;
187}
188
189struct update_agent *fwu_app::update_agent()
190{
191 return &m_update_agent;
192}
193
Gyorgy Szing3c446242023-03-31 01:53:15 +0200194const struct metadata_serializer *fwu_app::select_metadata_serializer(unsigned int version)
Julian Hall65bb4102023-01-19 12:09:02 +0000195{
196 if (version == 1)
197 return metadata_serializer_v1();
198
199 if (version == 2)
200 return metadata_serializer_v2();
201
202 return NULL;
203}