blob: ffc997a44a1cf5be475aa5dc5de090e804683121 [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
2 * Copyright (c) 2018, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
8#include <assert.h>
9#include <debug.h>
Antonio Nino Diaz09a00ef2019-01-11 13:12:58 +000010#include <drivers/io/io_driver.h>
11#include <drivers/io/io_fip.h>
12#include <drivers/io/io_memmap.h>
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020013#include <firmware_image_package.h>
14#include <image_loader.h>
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020015#include <io_storage.h>
16#include <platform.h>
17#include <platform_def.h>
18#include <string.h>
19#include <tftf_lib.h>
20
21unsigned long get_image_offset(unsigned int image_id)
22{
23 uintptr_t dev_handle;
24 uintptr_t image_handle;
25 uintptr_t image_spec;
26 unsigned long img_offset;
27 int io_result;
28 io_entity_t *entity;
29 fip_file_state_t *fp;
30
31 /* Obtain a reference to the image by querying the platform layer */
32 io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
33 if (io_result != IO_SUCCESS) {
34 WARN("Failed to obtain reference to image id=%u (%i)\n",
35 image_id, io_result);
36 return 0;
37 }
38
39 /* Attempt to access the image */
40 io_result = io_open(dev_handle, image_spec, &image_handle);
41 if (io_result != IO_SUCCESS) {
42 WARN("Failed to access image id=%u (%i)\n",
43 image_id, io_result);
44 return 0;
45 }
46
47 entity = (io_entity_t *)image_handle;
48
49 fp = (fip_file_state_t *)entity->info;
50 img_offset = PLAT_ARM_FWU_FIP_BASE + fp->entry.offset_address;
51
52 (void)io_close(image_handle);
53 (void)io_dev_close(dev_handle);
54
55 return img_offset;
56}
57
58
59unsigned long get_image_size(unsigned int image_id)
60{
61 uintptr_t dev_handle;
62 uintptr_t image_handle;
63 uintptr_t image_spec;
64 size_t image_size;
65 int io_result;
66
67 /* Obtain a reference to the image by querying the platform layer */
68 io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
69 if (io_result != IO_SUCCESS) {
70 WARN("Failed to obtain reference to image id=%u (%i)\n",
71 image_id, io_result);
72 return 0;
73 }
74
75 /* Attempt to access the image */
76 io_result = io_open(dev_handle, image_spec, &image_handle);
77 if (io_result != IO_SUCCESS) {
78 WARN("Failed to access image id=%u (%i)\n",
79 image_id, io_result);
80 return 0;
81 }
82
83 /* Find the size of the image */
84 io_result = io_size(image_handle, &image_size);
85 if ((io_result != IO_SUCCESS) || (image_size == 0)) {
86 WARN("Failed to determine the size of the image id=%u (%i)\n",
87 image_id, io_result);
88 }
89 io_result = io_close(image_handle);
90 io_result = io_dev_close(dev_handle);
91
92 return image_size;
93}
94
95
96int load_image(unsigned int image_id, uintptr_t image_base)
97{
98 uintptr_t dev_handle;
99 uintptr_t image_handle;
100 uintptr_t image_spec;
101 size_t image_size;
102 size_t bytes_read;
103 int io_result;
104
105 /* Obtain a reference to the image by querying the platform layer */
106 io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
107 if (io_result != IO_SUCCESS) {
108 WARN("Failed to obtain reference to image id=%u (%i)\n",
109 image_id, io_result);
110 return io_result;
111 }
112
113 /* Attempt to access the image */
114 io_result = io_open(dev_handle, image_spec, &image_handle);
115 if (io_result != IO_SUCCESS) {
116 WARN("Failed to access image id=%u (%i)\n",
117 image_id, io_result);
118 return io_result;
119 }
120
121 INFO("Loading image id=%u at address %p\n", image_id, (void *)image_base);
122
123 /* Find the size of the image */
124 io_result = io_size(image_handle, &image_size);
125 if ((io_result != IO_SUCCESS) || (image_size == 0)) {
126 WARN("Failed to determine the size of the image id=%u (%i)\n",
127 image_id, io_result);
128 goto exit;
129 }
130
131 /* Load the image now */
132 io_result = io_read(image_handle, image_base, image_size, &bytes_read);
133 if ((io_result != IO_SUCCESS) || (bytes_read < image_size)) {
134 WARN("Failed to load image id=%u (%i)\n", image_id, io_result);
135 goto exit;
136 }
137
138 /*
139 * File has been successfully loaded.
140 * Flush the image so that the next EL can see it.
141 */
142 flush_dcache_range(image_base, image_size);
143
144 INFO("Image id=%u loaded: %p - %p\n", image_id, (void *)image_base,
145 (void *)(image_base + image_size - 1));
146
147exit:
148 io_close(image_handle);
149 io_dev_close(dev_handle);
150 return io_result;
151}
152
153
154int load_partial_image(unsigned int image_id,
155 uintptr_t image_base,
156 size_t image_size,
157 unsigned int is_last_block)
158{
159 static uintptr_t dev_handle;
160 static uintptr_t image_handle;
161 uintptr_t image_spec;
162 size_t bytes_read;
163 int io_result;
164
165 if (!image_handle) {
166 /* Obtain a reference to the image by querying the platform layer */
167 io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
168 if (io_result != IO_SUCCESS) {
169 WARN("Failed to obtain reference to image id=%u (%i)\n",
170 image_id, io_result);
171 return io_result;
172 }
173
174 /* Attempt to access the image */
175 io_result = io_open(dev_handle, image_spec, &image_handle);
176 if (io_result != IO_SUCCESS) {
177 WARN("Failed to access image id=%u (%i)\n",
178 image_id, io_result);
179 return io_result;
180 }
181 }
182
183 INFO("Loading image id=%u at address %p\n", image_id, (void *)image_base);
184
185 io_result = io_read(image_handle, image_base, image_size, &bytes_read);
186 if ((io_result != IO_SUCCESS) || (bytes_read < image_size)) {
187 WARN("Failed to load image id=%u (%i)\n", image_id, io_result);
188 is_last_block = 0;
189 goto exit;
190 }
191
192 /*
193 * File has been successfully loaded.
194 * Flush the image so that the next EL can see it.
195 */
196 flush_dcache_range(image_base, image_size);
197
198 INFO("Image id=%u loaded: %p - %p\n", image_id, (void *)image_base,
199 (void *)(image_base + image_size - 1));
200
201exit:
202
203 if (is_last_block == 0) {
204 io_close(image_handle);
205 io_dev_close(dev_handle);
206 image_handle = 0;
207 }
208 return io_result;
209}
210