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