blob: b2b24eff10798f983f739a22993359aef3685143 [file] [log] [blame]
Julian Hall56387ba2022-11-18 11:47:44 +00001/*
2 * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <string.h>
9#include <stdint.h>
10#include <trace.h>
11#include "installer.h"
12#include "installer_index.h"
13
14#ifndef INSTALLER_INDEX_LIMIT
15#define INSTALLER_INDEX_LIMIT (8)
16#endif
17
18#ifndef INSTALLER_INDEX_LOCATION_ID_LIMIT
19#define INSTALLER_INDEX_LOCATION_ID_LIMIT (8)
20#endif
21
22/**
23 * Singleton index of installers to use for different classes of image.
24 */
25static struct {
26
27 /* An index for registered installers to handle update installation
28 * for the platform. The set of registered installers will have been
29 * selected for compatibility with the class of update image handled
30 * by the installer.
31 */
32 size_t num_registered;
33 struct installer *installers[INSTALLER_INDEX_LIMIT];
34
35 /* Each installer is associated with a location via the assigned
36 * location_id. This is used as a logical identifier for the part
37 * of the device firmware that the installer handles. Multiple
38 * installers may be associated with the same location.
39 */
40 size_t num_location_ids;
41 uint32_t location_ids[INSTALLER_INDEX_LOCATION_ID_LIMIT];
42
43} installer_index;
44
45static void add_location_id(uint32_t location_id)
46{
47 /* Check if location_id already added. Because 1..* installers
48 * may be associated with the same location_id, we can ignore
49 * location_ids that have already been added.
50 */
51 for (size_t i = 0; i < installer_index.num_location_ids; i++) {
52
53 if (location_id == installer_index.location_ids[i])
54 return;
55 }
56
57 /* It's a new location_id so add it */
58 if (installer_index.num_location_ids < INSTALLER_INDEX_LOCATION_ID_LIMIT) {
59
60 installer_index.location_ids[installer_index.num_location_ids] = location_id;
61 ++installer_index.num_location_ids;
62 } else {
63 EMSG("Too many FWU locations");
64 }
65}
66
67void installer_index_init(void)
68{
69 installer_index_clear();
70}
71
72void installer_index_clear(void)
73{
74 memset(&installer_index, 0, sizeof(installer_index));
75}
76
77void installer_index_register(
78 struct installer *installer)
79{
80 assert(installer);
81
82 if (installer_index.num_registered < INSTALLER_INDEX_LIMIT) {
83
84 installer_index.installers[installer_index.num_registered] = installer;
85 ++installer_index.num_registered;
86
87
88 add_location_id(installer->location_id);
89 } else {
90 EMSG("FWU configuration exceeds installer limit");
91 }
92}
93
94struct installer *installer_index_find(
95 enum install_type install_type,
96 uint32_t location_id)
97{
98 struct installer *result = NULL;
99
100 for (size_t i = 0; i < installer_index.num_registered; i++) {
101
102 struct installer *installer = installer_index.installers[i];
103
104 if ((installer->install_type == install_type) &&
105 (installer->location_id == location_id)) {
106
107 result = installer;
108 break;
109 }
110 }
111
112 return result;
113}
114
115struct installer *installer_index_find_by_location_uuid(
116 const struct uuid_octets *location_uuid)
117{
118 struct installer *result = NULL;
119
120 for (size_t i = 0; i < installer_index.num_registered; i++) {
121
122 struct installer *installer = installer_index.installers[i];
123
124 if (uuid_is_equal(location_uuid->octets,
125 installer->location_uuid.octets)) {
126
127 result = installer;
128 break;
129 }
130 }
131
132 return result;
133}
134
135struct installer *installer_index_get(
136 unsigned int index)
137{
138 struct installer *result = NULL;
139
140 if (index < installer_index.num_registered)
141 result = installer_index.installers[index];
142
143 return result;
144}
145
146const uint32_t *installer_index_get_location_ids(size_t *num_ids)
147{
148 *num_ids = installer_index.num_location_ids;
149 return installer_index.location_ids;
150}