1 /*
2  * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "metadata_reader.h"
8 
9 #include "media/volume/index/volume_index.h"
10 #include "media/volume/volume.h"
11 #include "service/fwu/fw_store/banked/volume_id.h"
12 
13 extern "C" {
14 #include "trace.h"
15 }
16 
metadata_reader()17 metadata_reader::metadata_reader()
18 	: registered_readers()
19 {
20 }
21 
~metadata_reader()22 metadata_reader::~metadata_reader()
23 {
24 }
25 
instance()26 metadata_reader *metadata_reader::instance()
27 {
28 	static metadata_reader the_instance;
29 	return &the_instance;
30 }
31 
register_reader(metadata_version_specific_reader * reader)32 void metadata_reader::register_reader(metadata_version_specific_reader *reader)
33 {
34 	registered_readers.push_back(reader);
35 }
36 
get_boot_info(unsigned int & active_index,unsigned int & metadata_version) const37 int metadata_reader::get_boot_info(unsigned int &active_index, unsigned int &metadata_version) const
38 {
39 	struct volume *volume;
40 
41 	int status = volume_index_find(BANKED_VOLUME_ID_PRIMARY_METADATA, &volume);
42 
43 	if (status) {
44 		IMSG("Failed to find metadata volume");
45 		return status;
46 	}
47 
48 	status = volume_open(volume);
49 
50 	if (!status) {
51 		/* Assume whatever metadata version is in-use, it will fit in the buffer */
52 		size_t len_read = 0;
53 		uint8_t buf[1000];
54 
55 		status = volume_read(volume, (uintptr_t)buf, sizeof(buf), &len_read);
56 
57 		if (!status) {
58 			bool is_handled = false;
59 
60 			for (unsigned int i = 0; i < registered_readers.size(); i++) {
61 				metadata_version_specific_reader *reader = registered_readers[i];
62 
63 				if (reader->is_supported(buf, len_read)) {
64 					reader->get_version(buf, len_read, metadata_version);
65 					reader->get_active_index(buf, len_read, active_index);
66 
67 					is_handled = true;
68 					break;
69 				}
70 			}
71 
72 			if (!is_handled) {
73 				/* This is normal on first-boot */
74 				status = -1;
75 			}
76 
77 		} else
78 			IMSG("Failed to read metadata volume");
79 
80 		volume_close(volume);
81 
82 	} else
83 		IMSG("Failed to open metadata volume");
84 
85 	return status;
86 }
87