1 /*
2 * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <stdint.h>
9 #include <string.h>
10 #include "fwu_agent.h"
11 #include "Driver_Flash.h"
12 #include "flash_layout.h"
13 #include "fip_parser/external/uuid.h"
14 #include "region_defs.h"
15 #include "uefi_capsule_parser.h"
16 #include "flash_common.h"
17 #include "platform_base_address.h"
18 #include "platform_description.h"
19 #include "tfm_plat_nv_counters.h"
20 #include "tfm_plat_defs.h"
21 #include "uefi_fmp.h"
22 #include "uart_stdout.h"
23 #include "soft_crc.h"
24 #if !BL1
25 #include "partition.h"
26 #include "platform.h"
27 #endif
28
29 /* Properties of image in a bank */
30 struct fwu_image_properties {
31
32 /* UUID of the image in this bank */
33 uuid_t img_uuid;
34
35 /* [0]: bit describing the image acceptance status –
36 * 1 means the image is accepted
37 * [31:1]: MBZ
38 */
39 uint32_t accepted;
40
41 /* NOTE: using the reserved field */
42 /* image version */
43 uint32_t version;
44
45 } __packed;
46
47 /* Image entry information */
48 struct fwu_image_entry {
49
50 /* UUID identifying the image type */
51 uuid_t img_type_uuid;
52
53 /* UUID of the storage volume where the image is located */
54 uuid_t location_uuid;
55
56 /* Properties of images with img_type_uuid in the different FW banks */
57 struct fwu_image_properties img_props[NR_OF_FW_BANKS];
58
59 } __packed;
60
61 struct fwu_metadata {
62
63 /* Metadata CRC value */
64 uint32_t crc_32;
65
66 /* Metadata version */
67 uint32_t version;
68
69 /* Bank index with which device boots */
70 uint32_t active_index;
71
72 /* Previous bank index with which device booted successfully */
73 uint32_t previous_active_index;
74
75 /* Image entry information */
76 struct fwu_image_entry img_entry[NR_OF_IMAGES_IN_FW_BANK];
77
78 } __packed;
79
80 /* This is Corstone1000 speific metadata for OTA.
81 * Private metadata is written at next sector following
82 * FWU METADATA location */
83 struct fwu_private_metadata {
84
85 /* boot_index: the bank from which system is booted from */
86 uint32_t boot_index;
87
88 /* counter: tracking number of boot attempted so far */
89 uint32_t boot_attempted;
90
91 /* staged nv_counter: temprary location before written to the otp */
92 uint32_t nv_counter[NR_OF_IMAGES_IN_FW_BANK];
93
94 /* FMP information */
95 uint32_t fmp_version;
96 uint32_t fmp_last_attempt_version;
97 uint32_t fmp_last_attempt_status;
98
99 } __packed;
100
101 #define MAX_BOOT_ATTEMPTS_PER_BANK 3
102
103 struct fwu_metadata _metadata;
104
105 int is_initialized = 0;
106
107 capsule_image_info_t capsule_info;
108
109 enum fwu_agent_state_t {
110 FWU_AGENT_STATE_UNKNOWN = -1,
111 FWU_AGENT_STATE_REGULAR = 0,
112 FWU_AGENT_STATE_TRIAL,
113 };
114
115 struct efi_guid full_capsule_image_guid = {
116 .time_low = 0x989f3a4e,
117 .time_mid = 0x46e0,
118 .time_hi_and_version = 0x4cd0,
119 .clock_seq_and_node = {0x98, 0x77, 0xa2, 0x5c, 0x70, 0xc0, 0x13, 0x29}
120 };
121
122
123 #define IMAGE_ACCEPTED (1)
124 #define IMAGE_NOT_ACCEPTED (0)
125 #define BANK_0 (0)
126 #define BANK_1 (1)
127 #define IMAGE_0 (0)
128 #define IMAGE_1 (1)
129 #define IMAGE_2 (2)
130 #define IMAGE_3 (3)
131 #define IMAGE_END (IMAGE_3)
132 #define IMAGE_ALL (IMAGE_END + 1)
133 #define IMAGE_NOT_RECOGNIZED (-1)
134 #define INVALID_VERSION (0xffffffff)
135
136
137 #ifndef FWU_METADATA_FLASH_DEV
138 #ifndef FLASH_DEV_NAME
139 #error "FWU_METADATA_FLASH_DEV or FLASH_DEV_NAME must be defined in flash_layout.h"
140 #else
141 #define FWU_METADATA_FLASH_DEV FLASH_DEV_NAME
142 #endif
143 #endif
144
145 /* Import the CMSIS flash device driver */
146 extern ARM_DRIVER_FLASH FWU_METADATA_FLASH_DEV;
147
148 #define HOST_ACK_TIMEOUT_SEC (6 * 60) /* ~seconds, not exact */
149
150 #if BL1
private_metadata_read(struct fwu_private_metadata * p_metadata)151 static enum fwu_agent_error_t private_metadata_read(
152 struct fwu_private_metadata* p_metadata)
153 {
154 int ret;
155
156 FWU_LOG_MSG("%s: enter\n\r", __func__);
157
158 if (!p_metadata) {
159 return FWU_AGENT_ERROR;
160 }
161
162 ret = FWU_METADATA_FLASH_DEV.ReadData(FWU_PRIVATE_METADATA_REPLICA_1_OFFSET, p_metadata,
163 sizeof(struct fwu_private_metadata));
164 if (ret < 0 || ret != sizeof(struct fwu_private_metadata)) {
165 return FWU_AGENT_ERROR;
166 }
167
168 FWU_LOG_MSG("%s: success: boot_index = %u\n\r", __func__,
169 p_metadata->boot_index);
170
171 return FWU_AGENT_SUCCESS;
172 }
173 #elif
private_metadata_read(struct fwu_private_metadata * p_metadata)174 static enum fwu_agent_error_t private_metadata_read(
175 struct fwu_private_metadata* p_metadata)
176 {
177 partition_entry_t *part;
178 uuid_t private_uuid = PRIVATE_METADATA_TYPE_UUID;
179 int ret;
180
181 FWU_LOG_MSG("%s: enter\n\r", __func__);
182
183 if (!p_metadata) {
184 return FWU_AGENT_ERROR;
185 }
186
187 part = get_partition_entry_by_type(&private_uuid);
188 if (!part) {
189 FWU_LOG_MSG("Private metadata partition not found\n\r");
190 return FWU_AGENT_ERROR;
191 }
192
193 ret = FWU_METADATA_FLASH_DEV.ReadData(part->start, p_metadata,
194 sizeof(struct fwu_private_metadata));
195 if (ret < 0 || ret != sizeof(struct fwu_private_metadata)) {
196 return FWU_AGENT_ERROR;
197 }
198
199 FWU_LOG_MSG("%s: success: boot_index = %u\n\r", __func__,
200 p_metadata->boot_index);
201
202 return FWU_AGENT_SUCCESS;
203 }
204 #endif
205
206 #if BL1
private_metadata_write(struct fwu_private_metadata * p_metadata)207 static enum fwu_agent_error_t private_metadata_write(
208 struct fwu_private_metadata* p_metadata)
209 {
210 int ret;
211
212 FWU_LOG_MSG("%s: enter: boot_index = %u\n\r", __func__,
213 p_metadata->boot_index);
214
215 if (!p_metadata) {
216 return FWU_AGENT_ERROR;
217 }
218
219 ret = FWU_METADATA_FLASH_DEV.EraseSector(FWU_PRIVATE_METADATA_REPLICA_1_OFFSET);
220 if (ret != ARM_DRIVER_OK) {
221 return FWU_AGENT_ERROR;
222 }
223
224 ret = FWU_METADATA_FLASH_DEV.ProgramData(FWU_PRIVATE_METADATA_REPLICA_1_OFFSET,
225 p_metadata, sizeof(struct fwu_private_metadata));
226 if (ret < 0 || ret != sizeof(struct fwu_private_metadata)) {
227 return FWU_AGENT_ERROR;
228 }
229
230 FWU_LOG_MSG("%s: success\n\r", __func__);
231 return FWU_AGENT_SUCCESS;
232 }
233 #elif
private_metadata_write(struct fwu_private_metadata * p_metadata)234 static enum fwu_agent_error_t private_metadata_write(
235 struct fwu_private_metadata* p_metadata)
236 {
237 uuid_t private_uuid = PRIVATE_METADATA_TYPE_UUID;
238 partition_entry_t *part;
239 int ret;
240
241 FWU_LOG_MSG("%s: enter: boot_index = %u\n\r", __func__,
242 p_metadata->boot_index);
243
244 if (!p_metadata) {
245 return FWU_AGENT_ERROR;
246 }
247
248 part = get_partition_entry_by_type(&private_uuid);
249 if (!part) {
250 FWU_LOG_MSG("Private metadata partition not found\n\r");
251 return FWU_AGENT_ERROR;
252 }
253
254 ret = FWU_METADATA_FLASH_DEV.EraseSector(part->start);
255 if (ret != ARM_DRIVER_OK) {
256 return FWU_AGENT_ERROR;
257 }
258
259 ret = FWU_METADATA_FLASH_DEV.ProgramData(part->start,
260 p_metadata, sizeof(struct fwu_private_metadata));
261 if (ret < 0 || ret != sizeof(struct fwu_private_metadata)) {
262 return FWU_AGENT_ERROR;
263 }
264
265 FWU_LOG_MSG("%s: success\n\r", __func__);
266 return FWU_AGENT_SUCCESS;
267 }
268 #endif
269
metadata_validate(struct fwu_metadata * p_metadata)270 static enum fwu_agent_error_t metadata_validate(struct fwu_metadata *p_metadata)
271 {
272 int ret;
273
274 FWU_LOG_MSG("%s: enter:\n\r", __func__);
275
276 if (!p_metadata) {
277 return FWU_AGENT_ERROR;
278 }
279
280 uint32_t calculated_crc32 = crc32((uint8_t *)&(p_metadata->version),
281 sizeof(struct fwu_metadata) - sizeof(uint32_t));
282
283 if (p_metadata->crc_32 != calculated_crc32) {
284 FWU_LOG_MSG("%s: failed: crc32 calculated: 0x%x, given: 0x%x\n\r", __func__,
285 calculated_crc32, p_metadata->crc_32);
286 return FWU_AGENT_ERROR;
287 }
288
289 FWU_LOG_MSG("%s: success\n\r", __func__);
290
291 return FWU_AGENT_SUCCESS;
292 }
293
294 #if BL1
metadata_read_without_validation(struct fwu_metadata * p_metadata)295 static enum fwu_agent_error_t metadata_read_without_validation(struct fwu_metadata *p_metadata)
296 {
297 int ret;
298
299 FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__,
300 FWU_METADATA_REPLICA_1_OFFSET, sizeof(struct fwu_metadata));
301
302 if (!p_metadata) {
303 return FWU_AGENT_ERROR;
304 }
305
306 ret = FWU_METADATA_FLASH_DEV.ReadData(FWU_METADATA_REPLICA_1_OFFSET,
307 p_metadata, sizeof(struct fwu_metadata));
308 if (ret < 0 || ret != sizeof(struct fwu_metadata)) {
309 return FWU_AGENT_ERROR;
310 }
311
312 FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__,
313 p_metadata->active_index, p_metadata->previous_active_index);
314
315 return FWU_AGENT_SUCCESS;
316 }
317 #elif
metadata_read_without_validation(struct fwu_metadata * p_metadata)318 static enum fwu_agent_error_t metadata_read_without_validation(struct fwu_metadata *p_metadata)
319 {
320 uuid_t metadata_uuid = FWU_METADATA_TYPE_UUID;
321 partition_entry_t *part;
322 int ret;
323
324 if (!p_metadata) {
325 return FWU_AGENT_ERROR;
326 }
327
328 part = get_partition_entry_by_type(&metadata_uuid);
329 if (!part) {
330 FWU_LOG_MSG("%s: FWU metadata partition not found\n\r", __func__);
331 return FWU_AGENT_ERROR;
332 }
333
334 FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__,
335 part->start, sizeof(struct fwu_metadata));
336
337
338 ret = FWU_METADATA_FLASH_DEV.ReadData(part->start,
339 p_metadata, sizeof(struct fwu_metadata));
340 if (ret < 0 || ret != sizeof(struct fwu_metadata)) {
341 return FWU_AGENT_ERROR;
342 }
343
344 FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__,
345 p_metadata->active_index, p_metadata->previous_active_index);
346
347 return FWU_AGENT_SUCCESS;
348 }
349 #endif
350
351 #if BL1
metadata_read(struct fwu_metadata * p_metadata)352 static enum fwu_agent_error_t metadata_read(struct fwu_metadata *p_metadata)
353 {
354 int ret;
355
356 FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__,
357 FWU_METADATA_REPLICA_1_OFFSET, sizeof(struct fwu_metadata));
358
359 if (!p_metadata) {
360 return FWU_AGENT_ERROR;
361 }
362
363 ret = FWU_METADATA_FLASH_DEV.ReadData(FWU_METADATA_REPLICA_1_OFFSET,
364 p_metadata, sizeof(struct fwu_metadata));
365 if (ret < 0 || ret != sizeof(struct fwu_metadata)) {
366 return FWU_AGENT_ERROR;
367 }
368
369 if (metadata_validate(p_metadata) != FWU_AGENT_SUCCESS) {
370 return FWU_AGENT_ERROR;
371 }
372
373 FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__,
374 p_metadata->active_index, p_metadata->previous_active_index);
375
376 return FWU_AGENT_SUCCESS;
377 }
378 #elif
metadata_read(struct fwu_metadata * p_metadata)379 static enum fwu_agent_error_t metadata_read(struct fwu_metadata *p_metadata)
380 {
381 uuid_t metadata_uuid = FWU_METADATA_TYPE_UUID;
382 partition_entry_t *part;
383 int ret;
384
385 if (!p_metadata) {
386 return FWU_AGENT_ERROR;
387 }
388
389 part = get_partition_entry_by_type(&metadata_uuid);
390 if (!part) {
391 FWU_LOG_MSG("%s: FWU metadata partition not found\n\r", __func__);
392 return FWU_AGENT_ERROR;
393 }
394
395 FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__,
396 part->start, sizeof(struct fwu_metadata));
397
398 ret = FWU_METADATA_FLASH_DEV.ReadData(part->start,
399 p_metadata, sizeof(struct fwu_metadata));
400 if (ret < 0 || ret != sizeof(struct fwu_metadata)) {
401 return FWU_AGENT_ERROR;
402 }
403
404 if (metadata_validate(p_metadata) != FWU_AGENT_SUCCESS) {
405 return FWU_AGENT_ERROR;
406 }
407
408 FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__,
409 p_metadata->active_index, p_metadata->previous_active_index);
410
411 return FWU_AGENT_SUCCESS;
412 }
413 #endif
414
415
416 #if BL1
metadata_write(struct fwu_metadata * p_metadata)417 static enum fwu_agent_error_t metadata_write(
418 struct fwu_metadata *p_metadata)
419 {
420 int ret;
421
422 FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__,
423 FWU_METADATA_REPLICA_1_OFFSET, sizeof(struct fwu_metadata));
424
425 if (!p_metadata) {
426 return FWU_AGENT_ERROR;
427 }
428
429 ret = FWU_METADATA_FLASH_DEV.EraseSector(FWU_METADATA_REPLICA_1_OFFSET);
430 if (ret != ARM_DRIVER_OK) {
431 return FWU_AGENT_ERROR;
432 }
433
434 ret = FWU_METADATA_FLASH_DEV.ProgramData(FWU_METADATA_REPLICA_1_OFFSET,
435 p_metadata, sizeof(struct fwu_metadata));
436 if (ret < 0 || ret != sizeof(struct fwu_metadata)) {
437 return FWU_AGENT_ERROR;
438 }
439
440 FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__,
441 FWU_METADATA_REPLICA_2_OFFSET, sizeof(struct fwu_metadata));
442
443 ret = FWU_METADATA_FLASH_DEV.EraseSector(FWU_METADATA_REPLICA_2_OFFSET);
444 if (ret != ARM_DRIVER_OK) {
445 return FWU_AGENT_ERROR;
446 }
447
448 ret = FWU_METADATA_FLASH_DEV.ProgramData(FWU_METADATA_REPLICA_2_OFFSET,
449 p_metadata, sizeof(struct fwu_metadata));
450 if (ret < 0 || ret != sizeof(struct fwu_metadata)) {
451 return FWU_AGENT_ERROR;
452 }
453
454 FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__,
455 FWU_METADATA_REPLICA_2_OFFSET, sizeof(struct fwu_metadata));
456
457 ret = FWU_METADATA_FLASH_DEV.EraseSector(FWU_METADATA_REPLICA_2_OFFSET);
458 if (ret != ARM_DRIVER_OK) {
459 return FWU_AGENT_ERROR;
460 }
461
462 ret = FWU_METADATA_FLASH_DEV.ProgramData(FWU_METADATA_REPLICA_2_OFFSET,
463 p_metadata, sizeof(struct fwu_metadata));
464 if (ret < 0 || ret != sizeof(struct fwu_metadata)) {
465 return FWU_AGENT_ERROR;
466 }
467
468 FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__,
469 p_metadata->active_index, p_metadata->previous_active_index);
470 return FWU_AGENT_SUCCESS;
471 }
472 #elif
metadata_write(struct fwu_metadata * p_metadata)473 static enum fwu_agent_error_t metadata_write(
474 struct fwu_metadata *p_metadata)
475 {
476 uuid_t metadata_uuid = FWU_METADATA_TYPE_UUID;
477 partition_entry_t *part;
478 int ret;
479
480 if (!p_metadata) {
481 return FWU_AGENT_ERROR;
482 }
483
484 part = get_partition_entry_by_type(&metadata_uuid);
485 if (!part) {
486 FWU_LOG_MSG("%s: FWU metadata partition not found\n\r", __func__);
487 return FWU_AGENT_ERROR;
488 }
489
490 FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__,
491 part->start, sizeof(struct fwu_metadata));
492
493 ret = FWU_METADATA_FLASH_DEV.EraseSector(part->start);
494 if (ret != ARM_DRIVER_OK) {
495 return FWU_AGENT_ERROR;
496 }
497
498 ret = FWU_METADATA_FLASH_DEV.ProgramData(part->start,
499 p_metadata, sizeof(struct fwu_metadata));
500 if (ret < 0 || ret != sizeof(struct fwu_metadata)) {
501 return FWU_AGENT_ERROR;
502 }
503
504 part = get_partition_replica_by_type(&metadata_uuid);
505 if (!part) {
506 FWU_LOG_MSG("%s: FWU metadata replica partition not found\n\r", __func__);
507 return FWU_AGENT_ERROR;
508 }
509
510 FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__,
511 part->start, sizeof(struct fwu_metadata));
512
513 ret = FWU_METADATA_FLASH_DEV.EraseSector(part->start);
514 if (ret != ARM_DRIVER_OK) {
515 return FWU_AGENT_ERROR;
516 }
517
518 ret = FWU_METADATA_FLASH_DEV.ProgramData(part->start,
519 p_metadata, sizeof(struct fwu_metadata));
520 if (ret < 0 || ret != sizeof(struct fwu_metadata)) {
521 return FWU_AGENT_ERROR;
522 }
523
524 FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__,
525 FWU_METADATA_REPLICA_2_OFFSET, sizeof(struct fwu_metadata));
526
527 ret = FWU_METADATA_FLASH_DEV.EraseSector(FWU_METADATA_REPLICA_2_OFFSET);
528 if (ret != ARM_DRIVER_OK) {
529 return FWU_AGENT_ERROR;
530 }
531
532 ret = FWU_METADATA_FLASH_DEV.ProgramData(FWU_METADATA_REPLICA_2_OFFSET,
533 p_metadata, sizeof(struct fwu_metadata));
534 if (ret < 0 || ret != sizeof(struct fwu_metadata)) {
535 return FWU_AGENT_ERROR;
536 }
537
538 FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__,
539 p_metadata->active_index, p_metadata->previous_active_index);
540 return FWU_AGENT_SUCCESS;
541 }
542 #endif
543
544
fwu_metadata_init(void)545 enum fwu_agent_error_t fwu_metadata_init(void)
546 {
547 enum fwu_agent_error_t ret;
548 ARM_FLASH_INFO* flash_info;
549
550
551 if (is_initialized) {
552 return FWU_AGENT_SUCCESS;
553 }
554
555 /* Code assumes everything fits into a sector */
556 if (sizeof(struct fwu_metadata) > FWU_METADATA_FLASH_SECTOR_SIZE) {
557 return FWU_AGENT_ERROR;
558 }
559
560 if (sizeof(struct fwu_private_metadata) > FWU_METADATA_FLASH_SECTOR_SIZE) {
561 return FWU_AGENT_ERROR;
562 }
563
564 ret = FWU_METADATA_FLASH_DEV.Initialize(NULL);
565 if (ret != ARM_DRIVER_OK) {
566 return FWU_AGENT_ERROR;
567 }
568
569 flash_info = FWU_METADATA_FLASH_DEV.GetInfo();
570 if (flash_info->program_unit != 1) {
571 FWU_METADATA_FLASH_DEV.Uninitialize();
572 return FWU_AGENT_ERROR;
573 }
574
575 is_initialized = 1;
576
577 return FWU_AGENT_SUCCESS;
578 }
579
fwu_metadata_provision(void)580 enum fwu_agent_error_t fwu_metadata_provision(void)
581 {
582 enum fwu_agent_error_t ret;
583 struct fwu_private_metadata priv_metadata;
584 uint32_t image_version = FWU_IMAGE_INITIAL_VERSION;
585
586 FWU_LOG_MSG("%s: enter\n\r", __func__);
587
588 #if !BL1
589 plat_io_storage_init();
590 partition_init(PLATFORM_GPT_IMAGE);
591 #endif
592
593 ret = fwu_metadata_init();
594 if (ret) {
595 return ret;
596 }
597
598 /*
599 * check by chance if the previous reboot
600 * had a firmware data?. If yes, then don't initialize
601 * metadata
602 */
603 metadata_read(&_metadata);
604 if(_metadata.active_index < 2 || _metadata.previous_active_index <2){
605 if(_metadata.active_index ^ _metadata.previous_active_index)
606 return FWU_AGENT_SUCCESS;
607 }
608 /* Provision FWU Agent Metadata */
609
610 memset(&_metadata, 0, sizeof(struct fwu_metadata));
611
612 _metadata.version = 1;
613 _metadata.active_index = BANK_0;
614 _metadata.previous_active_index = BANK_1;
615
616 /* bank 0 is the place where images are located at the
617 * start of device lifecycle */
618
619 for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
620
621 _metadata.img_entry[i].img_props[BANK_0].accepted = IMAGE_ACCEPTED;
622 _metadata.img_entry[i].img_props[BANK_0].version = image_version;
623
624 _metadata.img_entry[i].img_props[BANK_1].accepted = IMAGE_NOT_ACCEPTED;
625 _metadata.img_entry[i].img_props[BANK_1].version = INVALID_VERSION;
626 }
627
628 /* Calculate CRC32 for fwu metadata */
629 _metadata.crc_32 = crc32((uint8_t *)&_metadata.version,
630 sizeof(struct fwu_metadata) - sizeof(uint32_t));
631
632 ret = metadata_write(&_metadata);
633 if (ret) {
634 return ret;
635 }
636
637 memset(&_metadata, 0, sizeof(struct fwu_metadata));
638 ret = metadata_read(&_metadata);
639 if (ret) {
640 return ret;
641 }
642 FWU_LOG_MSG("%s: provisioned values: active = %u, previous = %d\n\r",
643 __func__, _metadata.active_index, _metadata.previous_active_index);
644
645
646 /* Provision Private metadata for update agent which is shared
647 beween BL1 and tf-m of secure enclave */
648
649 memset(&priv_metadata, 0, sizeof(struct fwu_private_metadata));
650
651 priv_metadata.boot_index = BANK_0;
652 priv_metadata.boot_attempted = 0;
653
654 priv_metadata.fmp_version = FWU_IMAGE_INITIAL_VERSION;
655 priv_metadata.fmp_last_attempt_version = FWU_IMAGE_INITIAL_VERSION;
656 priv_metadata.fmp_last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
657
658 ret = private_metadata_write(&priv_metadata);
659 if (ret) {
660 return ret;
661 }
662
663 memset(&priv_metadata, 0, sizeof(struct fwu_private_metadata));
664 ret = private_metadata_read(&priv_metadata);
665 if (ret) {
666 return ret;
667 }
668 FWU_LOG_MSG("%s: provisioned values: boot_index = %u\n\r", __func__,
669 priv_metadata.boot_index);
670
671 FWU_LOG_MSG("%s: FWU METADATA PROVISIONED.\n\r", __func__);
672 return FWU_AGENT_SUCCESS;
673 }
674
get_fwu_agent_state(struct fwu_metadata * metadata_ptr,struct fwu_private_metadata * priv_metadata_ptr)675 static enum fwu_agent_state_t get_fwu_agent_state(
676 struct fwu_metadata *metadata_ptr,
677 struct fwu_private_metadata *priv_metadata_ptr)
678 {
679 uint32_t boot_index;
680
681 FWU_LOG_MSG("%s: enter\n\r", __func__);
682
683 boot_index = priv_metadata_ptr->boot_index;
684
685 if (boot_index != metadata_ptr->active_index) {
686 return FWU_AGENT_STATE_TRIAL;
687 }
688
689 for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
690 if ((metadata_ptr->img_entry[i].img_props[boot_index].accepted)
691 == (IMAGE_NOT_ACCEPTED)) {
692 return FWU_AGENT_STATE_TRIAL;
693 }
694 }
695
696 FWU_LOG_MSG("%s: exit: FWU_AGENT_STATE_REGULAR\n\r", __func__);
697 return FWU_AGENT_STATE_REGULAR;
698 }
699
get_image_info_in_bank(struct efi_guid * guid,uint32_t * image_bank_offset)700 static int get_image_info_in_bank(struct efi_guid* guid, uint32_t* image_bank_offset)
701 {
702 if ((memcmp(guid, &full_capsule_image_guid, sizeof(struct efi_guid))) == 0) {
703 *image_bank_offset = 0;
704 return IMAGE_ALL;
705 }
706
707 return IMAGE_NOT_RECOGNIZED;
708 }
709
erase_bank(uint32_t bank_offset)710 static enum fwu_agent_error_t erase_bank(uint32_t bank_offset)
711 {
712 int ret;
713 uint32_t sectors;
714
715 FWU_LOG_MSG("%s: enter\n\r", __func__);
716
717 if ((bank_offset % FWU_METADATA_FLASH_SECTOR_SIZE) != 0) {
718 return FWU_AGENT_ERROR;
719 }
720
721 if ((BANK_PARTITION_SIZE % FWU_METADATA_FLASH_SECTOR_SIZE) != 0) {
722 return FWU_AGENT_ERROR;
723 }
724
725 sectors = BANK_PARTITION_SIZE / FWU_METADATA_FLASH_SECTOR_SIZE;
726
727 FWU_LOG_MSG("%s: erasing sectors = %u, from offset = %u\n\r", __func__,
728 sectors, bank_offset);
729
730 for (int i = 0; i < sectors; i++) {
731 ret = FWU_METADATA_FLASH_DEV.EraseSector(
732 bank_offset + (i * FWU_METADATA_FLASH_SECTOR_SIZE));
733 if (ret != ARM_DRIVER_OK) {
734 return FWU_AGENT_ERROR;
735 }
736 }
737
738 FWU_LOG_MSG("%s: exit\n\r", __func__);
739 return FWU_AGENT_SUCCESS;
740 }
741
742
flash_full_capsule(struct fwu_metadata * metadata,void * images,uint32_t size,uint32_t version)743 static enum fwu_agent_error_t flash_full_capsule(
744 struct fwu_metadata* metadata, void* images, uint32_t size,
745 uint32_t version)
746 {
747 int ret;
748 uint32_t active_index = metadata->active_index;
749 uint32_t bank_offset;
750 uint32_t previous_active_index;
751
752 FWU_LOG_MSG("%s: enter: image = 0x%p, size = %u, version = %u\n\r"
753 , __func__, images, size, version);
754
755 if (!metadata || !images) {
756 return FWU_AGENT_ERROR;
757 }
758
759 if (size > BANK_PARTITION_SIZE) {
760 FWU_LOG_MSG("ERROR: %s: size error\n\r",__func__);
761 return FWU_AGENT_ERROR;
762 }
763
764 if (version <=
765 (metadata->img_entry[IMAGE_0].img_props[active_index].version)) {
766 FWU_LOG_MSG("ERROR: %s: version error\n\r",__func__);
767 return FWU_AGENT_ERROR;
768 }
769
770 if (active_index == BANK_0) {
771 previous_active_index = BANK_1;
772 bank_offset = BANK_1_PARTITION_OFFSET;
773 } else if (active_index == BANK_1) {
774 previous_active_index = BANK_0;
775 bank_offset = BANK_0_PARTITION_OFFSET;
776 } else {
777 FWU_LOG_MSG("ERROR: %s: active_index %d\n\r",__func__,active_index);
778 return FWU_AGENT_ERROR;
779 }
780
781 if (erase_bank(bank_offset)) {
782 return FWU_AGENT_ERROR;
783 }
784
785 FWU_LOG_MSG("%s: writing capsule to the flash at offset = %u...\n\r",
786 __func__, bank_offset);
787 ret = FWU_METADATA_FLASH_DEV.ProgramData(bank_offset, images, size);
788 if (ret < 0 || ret != size) {
789 return FWU_AGENT_ERROR;
790 }
791 FWU_LOG_MSG("%s: images are written to bank offset = %u\n\r", __func__,
792 bank_offset);
793
794 /* Change system state to trial bank state */
795 for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
796 metadata->img_entry[i].img_props[previous_active_index].accepted =
797 IMAGE_NOT_ACCEPTED;
798 metadata->img_entry[i].img_props[previous_active_index].version = version;
799 }
800 metadata->active_index = previous_active_index;
801 metadata->previous_active_index = active_index;
802 metadata->crc_32 = crc32((uint8_t *)&metadata->version,
803 sizeof(struct fwu_metadata) - sizeof(uint32_t));
804
805 ret = metadata_write(metadata);
806 if (ret) {
807 return ret;
808 }
809
810 FWU_LOG_MSG("%s: exit\n\r", __func__);
811 return FWU_AGENT_SUCCESS;
812 }
813
corstone1000_fwu_flash_image(void)814 enum fwu_agent_error_t corstone1000_fwu_flash_image(void)
815 {
816 enum fwu_agent_error_t ret;
817 struct fwu_private_metadata priv_metadata;
818 enum fwu_agent_state_t current_state;
819 void *capsule_ptr = (char*)CORSTONE1000_HOST_DRAM_UEFI_CAPSULE;
820 int image_index;
821 uint32_t image_bank_offset;
822 uint32_t nr_images;
823
824 FWU_LOG_MSG("%s: enter\n\r", __func__);
825
826 if (!is_initialized) {
827 return FWU_AGENT_ERROR;
828 }
829
830 Select_Write_Mode_For_Shared_Flash();
831
832 if (metadata_read(&_metadata)) {
833 ret = FWU_AGENT_ERROR;
834 goto out;
835 }
836
837 if (private_metadata_read(&priv_metadata)) {
838 ret = FWU_AGENT_ERROR;
839 goto out;
840 }
841
842 /* Firmware update process can only start in regular state. */
843 current_state = get_fwu_agent_state(&_metadata, &priv_metadata);
844 if (current_state != FWU_AGENT_STATE_REGULAR) {
845 ret = FWU_AGENT_ERROR;
846 goto out;
847 }
848
849 memset(&capsule_info, 0, sizeof(capsule_image_info_t));
850 if (uefi_capsule_retrieve_images(capsule_ptr, &capsule_info)) {
851 ret = FWU_AGENT_ERROR;
852 goto out;
853 }
854 nr_images = capsule_info.nr_image;
855
856 for (int i = 0; i < nr_images; i++) {
857 image_index = get_image_info_in_bank(&capsule_info.guid[i],
858 &image_bank_offset);
859 switch(image_index) {
860 case IMAGE_ALL:
861
862 ret = flash_full_capsule(&_metadata, capsule_info.image[i],
863 capsule_info.size[i],
864 capsule_info.version[i]);
865
866 if (ret != FWU_AGENT_SUCCESS) {
867
868 priv_metadata.fmp_last_attempt_version = capsule_info.version[i];
869 priv_metadata.fmp_last_attempt_status = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
870
871 private_metadata_write(&priv_metadata);
872
873 fmp_set_image_info(&full_capsule_image_guid,
874 priv_metadata.fmp_version,
875 priv_metadata.fmp_last_attempt_version,
876 priv_metadata.fmp_last_attempt_status);
877 }
878
879
880 break;
881 default:
882 FWU_LOG_MSG("%s: sent image not recognized\n\r", __func__);
883 ret = FWU_AGENT_ERROR;
884 break;
885 }
886 }
887
888 out:
889 Select_XIP_Mode_For_Shared_Flash();
890
891 FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret);
892 return ret;
893 }
894
accept_full_capsule(struct fwu_metadata * metadata,struct fwu_private_metadata * priv_metadata)895 static enum fwu_agent_error_t accept_full_capsule(
896 struct fwu_metadata* metadata,
897 struct fwu_private_metadata* priv_metadata)
898 {
899 uint32_t active_index = metadata->active_index;
900 enum fwu_agent_error_t ret;
901
902 FWU_LOG_MSG("%s: enter\n\r", __func__);
903
904 for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
905 metadata->img_entry[i].img_props[active_index].accepted =
906 IMAGE_ACCEPTED;
907 }
908
909 priv_metadata->boot_attempted = 0;
910
911 ret = private_metadata_write(priv_metadata);
912 if (ret) {
913 return ret;
914 }
915 metadata->crc_32 = crc32((uint8_t *)&metadata->version,
916 sizeof(struct fwu_metadata) - sizeof(uint32_t));
917
918 ret = metadata_write(metadata);
919 if (ret) {
920 return ret;
921 }
922
923 FWU_LOG_MSG("%s: exit: fwu state is changed to regular\n\r", __func__);
924 return FWU_AGENT_SUCCESS;
925 }
926
fwu_accept_image(struct efi_guid * guid,struct fwu_metadata * metadata,struct fwu_private_metadata * priv_metadata)927 static enum fwu_agent_error_t fwu_accept_image(struct efi_guid* guid,
928 struct fwu_metadata *metadata,
929 struct fwu_private_metadata *priv_metadata)
930 {
931 enum fwu_agent_state_t current_state;
932 int image_index;
933 uint32_t image_bank_offset;
934 enum fwu_agent_error_t ret;
935
936 FWU_LOG_MSG("%s: enter\n\r", __func__);
937
938 /* it is expected to receive this call only when
939 in trial state */
940 current_state = get_fwu_agent_state(metadata, priv_metadata);
941 if (current_state != FWU_AGENT_STATE_TRIAL) {
942 return FWU_AGENT_ERROR;
943 }
944
945 /* booted from previous_active_bank, not expected
946 * to receive this call in this state, rather host should
947 * call corstone1000_fwu_select_previous */
948 if (metadata->active_index != priv_metadata->boot_index) {
949 return FWU_AGENT_ERROR;
950 }
951
952 image_index = get_image_info_in_bank(guid, &image_bank_offset);
953 switch(image_index) {
954 case IMAGE_ALL:
955 ret = accept_full_capsule(metadata, priv_metadata);
956 break;
957 default:
958 FWU_LOG_MSG("%s: sent image not recognized\n\r", __func__);
959 ret = FWU_AGENT_ERROR;
960 break;
961 }
962
963 FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret);
964 return ret;
965 }
966
fwu_select_previous(struct fwu_metadata * metadata,struct fwu_private_metadata * priv_metadata)967 static enum fwu_agent_error_t fwu_select_previous(
968 struct fwu_metadata *metadata,
969 struct fwu_private_metadata *priv_metadata)
970 {
971 enum fwu_agent_error_t ret;
972 enum fwu_agent_state_t current_state;
973 uint32_t index;
974
975 FWU_LOG_MSG("%s: enter\n\r", __func__);
976
977 /* it is expected to receive this call only when
978 in trial state */
979 current_state = get_fwu_agent_state(metadata, priv_metadata);
980 if (current_state != FWU_AGENT_STATE_TRIAL) {
981 return FWU_AGENT_ERROR;
982 }
983
984 /* not expected to receive this call in this state, system
985 * did not boot from previous active index */
986 if (metadata->previous_active_index != priv_metadata->boot_index) {
987 return FWU_AGENT_ERROR;
988 }
989
990 FWU_LOG_MSG("%s: trial state: active index = %u, previous active = %u\n\r",
991 __func__, metadata->active_index, metadata->previous_active_index);
992
993 index = metadata->previous_active_index;
994 for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
995 if (metadata->img_entry[i].img_props[index].accepted != IMAGE_ACCEPTED)
996 {
997 FWU_ASSERT(0);
998 }
999 }
1000
1001 index = metadata->active_index;
1002 metadata->active_index = metadata->previous_active_index;
1003 metadata->previous_active_index = index;
1004
1005 priv_metadata->boot_attempted = 0;
1006
1007 ret = private_metadata_write(priv_metadata);
1008 if (ret) {
1009 return ret;
1010 }
1011 metadata->crc_32 = crc32((uint8_t *)&metadata->version,
1012 sizeof(struct fwu_metadata) - sizeof(uint32_t));
1013
1014 ret = metadata_write(metadata);
1015 if (ret) {
1016 return ret;
1017 }
1018
1019 FWU_LOG_MSG("%s: in regular state by choosing previous active bank\n\r",
1020 __func__);
1021
1022 FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret);
1023 return ret;
1024
1025 }
1026
bl1_get_active_bl2_image(uint32_t * offset)1027 void bl1_get_active_bl2_image(uint32_t *offset)
1028 {
1029 struct fwu_private_metadata priv_metadata;
1030 enum fwu_agent_state_t current_state;
1031 uint32_t boot_attempted;
1032 uint32_t boot_index;
1033
1034 FWU_LOG_MSG("%s: enter\n\r", __func__);
1035
1036 if (fwu_metadata_init()) {
1037 FWU_ASSERT(0);
1038 }
1039
1040 if (private_metadata_read(&priv_metadata)) {
1041 FWU_ASSERT(0);
1042 }
1043
1044 if (metadata_read(&_metadata)) {
1045 FWU_ASSERT(0);
1046 }
1047
1048 current_state = get_fwu_agent_state(&_metadata, &priv_metadata);
1049
1050 if (current_state == FWU_AGENT_STATE_REGULAR) {
1051 boot_index = _metadata.active_index;
1052 FWU_ASSERT(boot_index == priv_metadata.boot_index);
1053 boot_attempted = 0;
1054 } else if (current_state == FWU_AGENT_STATE_TRIAL) {
1055 boot_attempted = (++priv_metadata.boot_attempted);
1056 FWU_LOG_MSG("%s: attempting boot number = %u\n\r",
1057 __func__, boot_attempted);
1058 if (boot_attempted <= MAX_BOOT_ATTEMPTS_PER_BANK) {
1059 boot_index = _metadata.active_index;
1060 FWU_LOG_MSG("%s: booting from trial bank: %u\n\r",
1061 __func__, boot_index);
1062 } else if (boot_attempted <= (2 * MAX_BOOT_ATTEMPTS_PER_BANK)) {
1063 boot_index = _metadata.previous_active_index;
1064 FWU_LOG_MSG("%s: gave up booting from trial bank\n\r", __func__);
1065 FWU_LOG_MSG("%s: booting from previous active bank: %u\n\r",
1066 __func__, boot_index);
1067 } else {
1068 FWU_LOG_MSG("%s: cannot boot system from any bank, halting...\n\r", __func__);
1069 FWU_ASSERT(0);
1070 }
1071 } else {
1072 FWU_ASSERT(0);
1073 }
1074
1075 priv_metadata.boot_index = boot_index;
1076 if (private_metadata_write(&priv_metadata) < 0) {
1077 FWU_ASSERT(0);
1078 }
1079
1080 if (boot_index == BANK_0) {
1081 *offset = SE_BL2_BANK_0_OFFSET;
1082 } else if (boot_index == BANK_1) {
1083 *offset = SE_BL2_BANK_1_OFFSET;
1084 } else {
1085 FWU_ASSERT(0);
1086 }
1087
1088 FWU_LOG_MSG("%s: exit: booting from bank = %u, offset = 0x%x\n\r", __func__,
1089 boot_index, *offset);
1090
1091 return;
1092 }
1093
bl2_get_boot_bank(void)1094 uint8_t bl2_get_boot_bank(void)
1095 {
1096 uint8_t boot_index;
1097 struct fwu_private_metadata priv_metadata;
1098 FWU_LOG_MSG("%s: enter", __func__);
1099 if (fwu_metadata_init()) {
1100 FWU_ASSERT(0);
1101 }
1102 if (private_metadata_read(&priv_metadata)) {
1103 FWU_ASSERT(0);
1104 }
1105 boot_index = priv_metadata.boot_index;
1106 FWU_LOG_MSG("%s: exit: booting from bank = %u", __func__, boot_index);
1107 return boot_index;
1108 }
1109
disable_host_ack_timer(void)1110 static void disable_host_ack_timer(void)
1111 {
1112 FWU_LOG_MSG("%s: timer to reset is disabled\n\r", __func__);
1113 SysTick->CTRL &= (~SysTick_CTRL_ENABLE_Msk);
1114 }
1115
update_nv_counters(struct fwu_private_metadata * priv_metadata)1116 static enum fwu_agent_error_t update_nv_counters(
1117 struct fwu_private_metadata* priv_metadata)
1118 {
1119 enum tfm_plat_err_t err;
1120 uint32_t security_cnt;
1121 enum tfm_nv_counter_t tfm_nv_counter_i;
1122
1123 FWU_LOG_MSG("%s: enter\n\r", __func__);
1124
1125 for (int i = 0; i <= FWU_MAX_NV_COUNTER_INDEX; i++) {
1126
1127 switch (i) {
1128 case FWU_BL2_NV_COUNTER:
1129 tfm_nv_counter_i = PLAT_NV_COUNTER_BL1_0;
1130 break;
1131 case FWU_TFM_NV_COUNTER:
1132 tfm_nv_counter_i = PLAT_NV_COUNTER_BL2_0;
1133 break;
1134 case FWU_TFA_NV_COUNTER:
1135 tfm_nv_counter_i = PLAT_NV_COUNTER_BL2_1;
1136 break;
1137 default:
1138 FWU_ASSERT(0);
1139 break;
1140 }
1141
1142 err = tfm_plat_read_nv_counter(tfm_nv_counter_i,
1143 sizeof(security_cnt), (uint8_t *)&security_cnt);
1144 if (err != TFM_PLAT_ERR_SUCCESS) {
1145 return FWU_AGENT_ERROR;
1146 }
1147
1148 if (priv_metadata->nv_counter[i] < security_cnt) {
1149 return FWU_AGENT_ERROR;
1150 } else if (priv_metadata->nv_counter[i] > security_cnt) {
1151 FWU_LOG_MSG("%s: updaing index = %u nv counter = %u->%u\n\r",
1152 __func__, i, security_cnt,
1153 priv_metadata->nv_counter[FWU_BL2_NV_COUNTER]);
1154 err = tfm_plat_set_nv_counter(tfm_nv_counter_i,
1155 priv_metadata->nv_counter[FWU_BL2_NV_COUNTER]);
1156 if (err != TFM_PLAT_ERR_SUCCESS) {
1157 return FWU_AGENT_ERROR;
1158 }
1159 }
1160
1161 }
1162
1163 FWU_LOG_MSG("%s: exit\n\r", __func__);
1164 return FWU_AGENT_SUCCESS;
1165 }
1166
corstone1000_fwu_host_ack(void)1167 enum fwu_agent_error_t corstone1000_fwu_host_ack(void)
1168 {
1169 enum fwu_agent_error_t ret;
1170 struct fwu_private_metadata priv_metadata;
1171 enum fwu_agent_state_t current_state;
1172
1173 FWU_LOG_MSG("%s: enter\n\r", __func__);
1174
1175 if (!is_initialized) {
1176 return FWU_AGENT_ERROR;
1177 }
1178
1179 Select_Write_Mode_For_Shared_Flash();
1180
1181 if (metadata_read(&_metadata)) {
1182 ret = FWU_AGENT_ERROR;
1183 goto out;
1184 }
1185
1186 if (private_metadata_read(&priv_metadata)) {
1187 ret = FWU_AGENT_ERROR;
1188 goto out;
1189 }
1190
1191 current_state = get_fwu_agent_state(&_metadata, &priv_metadata);
1192 if (current_state == FWU_AGENT_STATE_REGULAR) {
1193
1194 ret = FWU_AGENT_SUCCESS; /* nothing to be done */
1195
1196 fmp_set_image_info(&full_capsule_image_guid,
1197 priv_metadata.fmp_version,
1198 priv_metadata.fmp_last_attempt_version,
1199 priv_metadata.fmp_last_attempt_status);
1200
1201 goto out;
1202
1203 } else if (current_state != FWU_AGENT_STATE_TRIAL) {
1204 FWU_ASSERT(0);
1205 }
1206
1207 if (_metadata.active_index != priv_metadata.boot_index) {
1208
1209 /* firmware update failed, revert back to previous bank */
1210
1211 priv_metadata.fmp_last_attempt_version =
1212 _metadata.img_entry[IMAGE_0].img_props[_metadata.active_index].version;
1213
1214 priv_metadata.fmp_last_attempt_status = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
1215
1216 ret = fwu_select_previous(&_metadata, &priv_metadata);
1217
1218 } else {
1219
1220 /* firmware update successful */
1221
1222 priv_metadata.fmp_version =
1223 _metadata.img_entry[IMAGE_0].img_props[_metadata.active_index].version;
1224 priv_metadata.fmp_last_attempt_version =
1225 _metadata.img_entry[IMAGE_0].img_props[_metadata.active_index].version;
1226
1227 priv_metadata.fmp_last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
1228
1229 ret = fwu_accept_image(&full_capsule_image_guid, &_metadata,
1230 &priv_metadata);
1231 if (!ret) {
1232 ret = update_nv_counters(&priv_metadata);
1233 }
1234 }
1235
1236 if (ret == FWU_AGENT_SUCCESS) {
1237 disable_host_ack_timer();
1238 fmp_set_image_info(&full_capsule_image_guid,
1239 priv_metadata.fmp_version,
1240 priv_metadata.fmp_last_attempt_version,
1241 priv_metadata.fmp_last_attempt_status);
1242 }
1243
1244 out:
1245 Select_XIP_Mode_For_Shared_Flash();
1246
1247 FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret);
1248 return ret;
1249 }
1250
1251 static int systic_counter = 0;
1252
SysTick_Handler(void)1253 void SysTick_Handler(void)
1254 {
1255 systic_counter++;
1256 if (systic_counter % 10 == 0) {
1257 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
1258 stdio_output_string("*", 1);
1259 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
1260 }
1261 if (systic_counter == HOST_ACK_TIMEOUT_SEC) {
1262 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
1263 stdio_output_string("timer expired!\n\r",
1264 sizeof("timer expired!\n\r"));
1265 NVIC_SystemReset();
1266 }
1267 }
1268
1269 /* When in trial state, start the timer for host to respond.
1270 * Diable timer when host responds back either by calling
1271 * corstone1000_fwu_accept_image or corstone1000_fwu_select_previous.
1272 * Otherwise, resets the system.
1273 */
host_acknowledgement_timer_to_reset(void)1274 void host_acknowledgement_timer_to_reset(void)
1275 {
1276 struct fwu_private_metadata priv_metadata;
1277 enum fwu_agent_state_t current_state;
1278
1279 FWU_LOG_MSG("%s: enter\n\r", __func__);
1280
1281 Select_Write_Mode_For_Shared_Flash();
1282
1283 if (!is_initialized) {
1284 FWU_ASSERT(0);
1285 }
1286
1287 if (private_metadata_read(&priv_metadata)) {
1288 FWU_ASSERT(0);
1289 }
1290
1291 if (metadata_read(&_metadata)) {
1292 FWU_ASSERT(0);
1293 }
1294
1295 Select_XIP_Mode_For_Shared_Flash();
1296
1297 current_state = get_fwu_agent_state(&_metadata, &priv_metadata);
1298
1299 if (current_state == FWU_AGENT_STATE_TRIAL) {
1300 FWU_LOG_MSG("%s: in trial state, starting host ack timer\n\r",
1301 __func__);
1302 systic_counter = 0;
1303 if (SysTick_Config(SysTick_LOAD_RELOAD_Msk)) {
1304 FWU_LOG_MSG("%s: timer init failed\n\r", __func__);
1305 FWU_ASSERT(0);
1306 } else {
1307 FWU_LOG_MSG("%s: timer started: seconds to expire : %u\n\r",
1308 __func__, HOST_ACK_TIMEOUT_SEC);
1309 }
1310 }
1311
1312 FWU_LOG_MSG("%s: exit\n\r", __func__);
1313 return;
1314 }
1315
1316 /* stage nv counter into private metadata section of the flash.
1317 * staged nv counters are written to the otp when firmware update
1318 * is successful
1319 * the function assumes that the api is called in the boot loading
1320 * stage
1321 */
fwu_stage_nv_counter(enum fwu_nv_counter_index_t index,uint32_t img_security_cnt)1322 enum fwu_agent_error_t fwu_stage_nv_counter(enum fwu_nv_counter_index_t index,
1323 uint32_t img_security_cnt)
1324 {
1325 struct fwu_private_metadata priv_metadata;
1326
1327 FWU_LOG_MSG("%s: enter: index = %u, val = %u\n\r", __func__,
1328 index, img_security_cnt);
1329
1330 if (!is_initialized) {
1331 FWU_ASSERT(0);
1332 }
1333
1334 if (index > FWU_MAX_NV_COUNTER_INDEX) {
1335 return FWU_AGENT_ERROR;
1336 }
1337
1338 if (private_metadata_read(&priv_metadata)) {
1339 FWU_ASSERT(0);
1340 }
1341
1342 if (priv_metadata.nv_counter[index] != img_security_cnt) {
1343 priv_metadata.nv_counter[index] = img_security_cnt;
1344 if (private_metadata_write(&priv_metadata)) {
1345 FWU_ASSERT(0);
1346 }
1347 }
1348
1349 FWU_LOG_MSG("%s: exit\n\r", __func__);
1350 return FWU_AGENT_SUCCESS;
1351 }
1352