blob: a5a62907c0f5009712fd0a5ecd03277cfe5fe329 [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
Julian Hall56387ba2022-11-18 11:47:44 +00007#include "installer_index.h"
8
Gyorgy Szing3c446242023-03-31 01:53:15 +02009#include <assert.h>
10#include <stdint.h>
11#include <string.h>
12
13#include "installer.h"
14#include "trace.h"
15
Julian Hall56387ba2022-11-18 11:47:44 +000016#ifndef INSTALLER_INDEX_LIMIT
Gyorgy Szing3c446242023-03-31 01:53:15 +020017#define INSTALLER_INDEX_LIMIT (8)
Julian Hall56387ba2022-11-18 11:47:44 +000018#endif
19
20#ifndef INSTALLER_INDEX_LOCATION_ID_LIMIT
Gyorgy Szing3c446242023-03-31 01:53:15 +020021#define INSTALLER_INDEX_LOCATION_ID_LIMIT (8)
Julian Hall56387ba2022-11-18 11:47:44 +000022#endif
23
24/**
25 * Singleton index of installers to use for different classes of image.
26 */
27static struct {
Julian Hall56387ba2022-11-18 11:47:44 +000028 /* An index for registered installers to handle update installation
29 * for the platform. The set of registered installers will have been
30 * selected for compatibility with the class of update image handled
31 * by the installer.
32 */
33 size_t num_registered;
34 struct installer *installers[INSTALLER_INDEX_LIMIT];
35
36 /* Each installer is associated with a location via the assigned
37 * location_id. This is used as a logical identifier for the part
38 * of the device firmware that the installer handles. Multiple
39 * installers may be associated with the same location.
40 */
41 size_t num_location_ids;
42 uint32_t location_ids[INSTALLER_INDEX_LOCATION_ID_LIMIT];
43
44} installer_index;
45
46static void add_location_id(uint32_t location_id)
47{
48 /* Check if location_id already added. Because 1..* installers
49 * may be associated with the same location_id, we can ignore
50 * location_ids that have already been added.
51 */
52 for (size_t i = 0; i < installer_index.num_location_ids; i++) {
Julian Hall56387ba2022-11-18 11:47:44 +000053 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) {
Julian Hall56387ba2022-11-18 11:47:44 +000059 installer_index.location_ids[installer_index.num_location_ids] = location_id;
60 ++installer_index.num_location_ids;
61 } else {
62 EMSG("Too many FWU locations");
63 }
64}
65
66void installer_index_init(void)
67{
68 installer_index_clear();
69}
70
71void installer_index_clear(void)
72{
73 memset(&installer_index, 0, sizeof(installer_index));
74}
75
Gyorgy Szing3c446242023-03-31 01:53:15 +020076void installer_index_register(struct installer *installer)
Julian Hall56387ba2022-11-18 11:47:44 +000077{
78 assert(installer);
79
80 if (installer_index.num_registered < INSTALLER_INDEX_LIMIT) {
Julian Hall56387ba2022-11-18 11:47:44 +000081 installer_index.installers[installer_index.num_registered] = installer;
82 ++installer_index.num_registered;
83
Julian Hall56387ba2022-11-18 11:47:44 +000084 add_location_id(installer->location_id);
85 } else {
86 EMSG("FWU configuration exceeds installer limit");
87 }
88}
89
Gyorgy Szing3c446242023-03-31 01:53:15 +020090struct installer *installer_index_find(enum install_type install_type, uint32_t location_id)
Julian Hall56387ba2022-11-18 11:47:44 +000091{
92 struct installer *result = NULL;
93
94 for (size_t i = 0; i < installer_index.num_registered; i++) {
Julian Hall56387ba2022-11-18 11:47:44 +000095 struct installer *installer = installer_index.installers[i];
96
97 if ((installer->install_type == install_type) &&
Gyorgy Szing3c446242023-03-31 01:53:15 +020098 (installer->location_id == location_id)) {
Julian Hall56387ba2022-11-18 11:47:44 +000099 result = installer;
100 break;
101 }
102 }
103
104 return result;
105}
106
Gyorgy Szing3c446242023-03-31 01:53:15 +0200107struct installer *installer_index_find_by_location_uuid(const struct uuid_octets *location_uuid)
Julian Hall56387ba2022-11-18 11:47:44 +0000108{
109 struct installer *result = NULL;
110
111 for (size_t i = 0; i < installer_index.num_registered; i++) {
Julian Hall56387ba2022-11-18 11:47:44 +0000112 struct installer *installer = installer_index.installers[i];
113
Gyorgy Szing3c446242023-03-31 01:53:15 +0200114 if (uuid_is_equal(location_uuid->octets, installer->location_uuid.octets)) {
Julian Hall56387ba2022-11-18 11:47:44 +0000115 result = installer;
116 break;
117 }
118 }
119
120 return result;
121}
122
Gyorgy Szing3c446242023-03-31 01:53:15 +0200123struct installer *installer_index_get(unsigned int index)
Julian Hall56387ba2022-11-18 11:47:44 +0000124{
125 struct installer *result = NULL;
126
127 if (index < installer_index.num_registered)
128 result = installer_index.installers[index];
129
130 return result;
131}
132
133const uint32_t *installer_index_get_location_ids(size_t *num_ids)
134{
135 *num_ids = installer_index.num_location_ids;
136 return installer_index.location_ids;
137}