1 /*
2 * Copyright (c) 2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <string.h>
11 #include "volume_index.h"
12
13 #ifndef VOLUME_INDEX_MAX_ENTRIES
14 #define VOLUME_INDEX_MAX_ENTRIES (8)
15 #endif
16
17 /**
18 * Singleton index of volume IDs to IO devices.
19 */
20 static struct {
21
22 size_t size;
23 struct {
24 unsigned int volume_id;
25 struct volume *volume;
26 } entries[VOLUME_INDEX_MAX_ENTRIES];
27
28 } volume_index;
29
30 /**
31 * @brief Gets a device for volume IO operations
32 *
33 * @param[in] volume_id Identifies the image
34 * @param[out] dev_handle Handle for IO operations
35 * @param[out] io_spec Opaque configuration data
36 *
37 * This function realizes the interface expected by tf-a components to
38 * provide a concrete IO device for the specified volume ID. When used in
39 * TS deployments, the set of IO devices required for a deployment
40 * are registered during service configuration.
41 */
plat_get_image_source(unsigned int volume_id,uintptr_t * dev_handle,uintptr_t * io_spec)42 int plat_get_image_source(
43 unsigned int volume_id,
44 uintptr_t *dev_handle,
45 uintptr_t *io_spec)
46 {
47 struct volume *volume = NULL;
48 int result = volume_index_find(volume_id, &volume);
49
50 if (result == 0) {
51
52 if (volume) {
53
54 *dev_handle = volume->dev_handle;
55 *io_spec = volume->io_spec;
56 } else
57 result = -1;
58 }
59
60 return result;
61 }
62
volume_index_init(void)63 void volume_index_init(void)
64 {
65 volume_index_clear();
66 }
67
volume_index_clear(void)68 void volume_index_clear(void)
69 {
70 memset(&volume_index, 0, sizeof(volume_index));
71 }
72
volume_index_add(unsigned int volume_id,struct volume * volume)73 int volume_index_add(
74 unsigned int volume_id,
75 struct volume *volume)
76 {
77 int result = -1;
78
79 if (volume_index.size < VOLUME_INDEX_MAX_ENTRIES) {
80 size_t i = volume_index.size;
81
82 ++volume_index.size;
83 volume_index.entries[i].volume_id = volume_id;
84 volume_index.entries[i].volume = volume;
85
86 result = 0;
87 }
88
89 return result;
90 }
91
volume_index_find(unsigned int volume_id,struct volume ** volume)92 int volume_index_find(
93 unsigned int volume_id,
94 struct volume **volume)
95 {
96 int result = -1;
97
98 for (size_t i = 0; i < volume_index.size; i++) {
99
100 if (volume_index.entries[i].volume_id == volume_id) {
101
102 *volume = volume_index.entries[i].volume;
103 result = 0;
104 break;
105 }
106 }
107
108 return result;
109 }
110
volume_index_get(unsigned int index)111 struct volume *volume_index_get(unsigned int index)
112 {
113 struct volume *volume = NULL;
114
115 if (index < volume_index.size)
116 volume = volume_index.entries[index].volume;
117
118 return volume;
119 }
120