|
12 | 12 | #include <suit_platform_internal.h> |
13 | 13 | #include <suit_plat_digest_cache.h> |
14 | 14 | #include <suit_plat_memptr_size_update.h> |
| 15 | +#include <suit_memory_layout.h> |
15 | 16 |
|
16 | 17 | #if CONFIG_SUIT_IPUC |
17 | 18 | #include <suit_plat_ipuc.h> |
| 19 | +#include <suit_flash_sink.h> |
18 | 20 | #endif /* CONFIG_SUIT_IPUC */ |
19 | 21 |
|
20 | 22 | #ifdef CONFIG_SUIT_STREAM |
@@ -140,6 +142,7 @@ int suit_plat_copy(suit_component_t dst_handle, suit_component_t src_handle, |
140 | 142 | { |
141 | 143 | #ifdef CONFIG_SUIT_STREAM |
142 | 144 | struct stream_sink dst_sink; |
| 145 | + uint32_t soc_spec_number = 0; |
143 | 146 | #ifdef CONFIG_SUIT_STREAM_SOURCE_MEMPTR |
144 | 147 | const uint8_t *payload_ptr; |
145 | 148 | size_t payload_size; |
@@ -167,6 +170,29 @@ int suit_plat_copy(suit_component_t dst_handle, suit_component_t src_handle, |
167 | 170 | return SUIT_ERR_UNSUPPORTED_COMPONENT_ID; |
168 | 171 | } |
169 | 172 |
|
| 173 | + if (dst_component_type == SUIT_COMPONENT_TYPE_SOC_SPEC) { |
| 174 | + struct zcbor_string *component_id = NULL; |
| 175 | + |
| 176 | + ret = suit_plat_component_id_get(dst_handle, &component_id); |
| 177 | + if (ret != SUIT_SUCCESS) { |
| 178 | + LOG_ERR("suit_plat_component_id_get failed - error %i", ret); |
| 179 | + return ret; |
| 180 | + } |
| 181 | + |
| 182 | + plat_ret = suit_plat_decode_component_number(component_id, &soc_spec_number); |
| 183 | + if (plat_ret != SUIT_PLAT_SUCCESS) { |
| 184 | + LOG_ERR("suit_plat_decode_component_number failed - error %i", plat_ret); |
| 185 | + ret = suit_plat_err_to_processor_err_convert(plat_ret); |
| 186 | + return ret; |
| 187 | + } |
| 188 | + |
| 189 | + if (soc_spec_number != SUIT_SECDOM_COMPONENT_NUMBER_SDFW && |
| 190 | + soc_spec_number != SUIT_SECDOM_COMPONENT_NUMBER_SDFW_RECOVERY) { |
| 191 | + LOG_ERR("Unsupported destination component type"); |
| 192 | + return SUIT_ERR_UNSUPPORTED_COMPONENT_ID; |
| 193 | + } |
| 194 | + } |
| 195 | + |
170 | 196 | /* Get source component type based on component handle*/ |
171 | 197 | ret = suit_plat_component_type_get(src_handle, &src_component_type); |
172 | 198 | if (ret != SUIT_SUCCESS) { |
@@ -250,6 +276,92 @@ int suit_plat_copy(suit_component_t dst_handle, suit_component_t src_handle, |
250 | 276 | } |
251 | 277 | } |
252 | 278 |
|
| 279 | + if (ret == SUIT_SUCCESS && dst_component_type == SUIT_COMPONENT_TYPE_SOC_SPEC && |
| 280 | + (soc_spec_number == SUIT_SECDOM_COMPONENT_NUMBER_SDFW || |
| 281 | + soc_spec_number == SUIT_SECDOM_COMPONENT_NUMBER_SDFW_RECOVERY)) { |
| 282 | + uintptr_t sdfw_update_area_addr = 0; |
| 283 | + size_t sdfw_update_area_size = 0; |
| 284 | + |
| 285 | + suit_memory_sdfw_update_area_info_get(&sdfw_update_area_addr, |
| 286 | + &sdfw_update_area_size); |
| 287 | + |
| 288 | + if (sdfw_update_area_size > 0) { |
| 289 | + /* SoC enforces constrains on update candidate location |
| 290 | + */ |
| 291 | + if ((uintptr_t)payload_ptr < sdfw_update_area_addr || |
| 292 | + (uintptr_t)payload_ptr + payload_size > |
| 293 | + sdfw_update_area_addr + sdfw_update_area_size) { |
| 294 | + |
| 295 | + LOG_WRN("SDFW or SDFW_RECOVERY update - candidate mirror required " |
| 296 | + "(%d bytes)", |
| 297 | + payload_size); |
| 298 | +#ifdef CONFIG_SUIT_IPUC |
| 299 | + struct stream_sink mirror_sink; |
| 300 | + intptr_t mirror_addr = |
| 301 | + suit_plat_ipuc_sdfw_mirror_addr(payload_size); |
| 302 | + |
| 303 | + if (mirror_addr == 0) { |
| 304 | + LOG_ERR("SDFW or SDFW_RECOVERY update - candidate mirror " |
| 305 | + "not found"); |
| 306 | + ret = suit_plat_err_to_processor_err_convert( |
| 307 | + SUIT_PLAT_ERR_NOMEM); |
| 308 | + } |
| 309 | + |
| 310 | + if (ret == SUIT_SUCCESS) { |
| 311 | + plat_ret = suit_flash_sink_get( |
| 312 | + &mirror_sink, (uint8_t *)mirror_addr, payload_size); |
| 313 | + if (plat_ret != SUIT_PLAT_SUCCESS) { |
| 314 | + LOG_ERR("Could not acquire SDFW or SDFW_RECOVERY " |
| 315 | + "mirror sink: %d", |
| 316 | + plat_ret); |
| 317 | + ret = suit_plat_err_to_processor_err_convert( |
| 318 | + plat_ret); |
| 319 | + } |
| 320 | + } |
| 321 | + |
| 322 | + if (ret == SUIT_SUCCESS && mirror_sink.erase != NULL) { |
| 323 | + plat_ret = mirror_sink.erase(mirror_sink.ctx); |
| 324 | + if (plat_ret != SUIT_PLAT_SUCCESS) { |
| 325 | + LOG_ERR("SDFW or SDFW_RECOVERY mirror sink erase " |
| 326 | + "failed: %d", |
| 327 | + plat_ret); |
| 328 | + } |
| 329 | + } |
| 330 | + |
| 331 | + if (ret == SUIT_SUCCESS) { |
| 332 | + LOG_INF("Streaming to SDFW or SDFW_RECOVERY mirror sink, " |
| 333 | + "%d bytes", |
| 334 | + payload_size); |
| 335 | + plat_ret = suit_generic_address_streamer_stream( |
| 336 | + payload_ptr, payload_size, &mirror_sink); |
| 337 | + |
| 338 | + if (mirror_sink.flush != NULL) { |
| 339 | + mirror_sink.flush(mirror_sink.ctx); |
| 340 | + } |
| 341 | + |
| 342 | + if (mirror_sink.release != NULL) { |
| 343 | + mirror_sink.release(mirror_sink.ctx); |
| 344 | + } |
| 345 | + |
| 346 | + if (plat_ret != SUIT_PLAT_SUCCESS) { |
| 347 | + LOG_ERR("Streaming to SDFW or SDFW_RECOVERY mirror " |
| 348 | + "sink failed: %d", |
| 349 | + plat_ret); |
| 350 | + ret = suit_plat_err_to_processor_err_convert( |
| 351 | + plat_ret); |
| 352 | + } |
| 353 | + } |
| 354 | + |
| 355 | + if (ret == SUIT_SUCCESS) { |
| 356 | + payload_ptr = (uint8_t *)mirror_addr; |
| 357 | + } |
| 358 | +#else |
| 359 | + ret = suit_plat_err_to_processor_err_convert(SUIT_PLAT_ERR_NOMEM); |
| 360 | +#endif |
| 361 | + } |
| 362 | + } |
| 363 | + } |
| 364 | + |
253 | 365 | if (ret == SUIT_SUCCESS) { |
254 | 366 | ret = suit_generic_address_streamer_stream(payload_ptr, payload_size, &dst_sink); |
255 | 367 | if (ret != SUIT_PLAT_SUCCESS) { |
|
0 commit comments