blob: 2627ba4ef94a55728a90ac95b28e7d728d87414d [file] [log] [blame]
Konstantin Porotchkinf69ec582018-06-07 18:31:14 +03001/*
2 * Copyright (C) 2018 Marvell International Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 * https://spdx.org/licenses
6 */
7
8#include <assert.h>
Konstantin Porotchkinf69ec582018-06-07 18:31:14 +03009#include <string.h>
10
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000011#include <platform_def.h>
12
13#include <common/bl_common.h>
14#include <common/debug.h>
15#include <drivers/io/io_driver.h>
16#include <drivers/io/io_fip.h>
17#include <drivers/io/io_memmap.h>
18#include <drivers/io/io_storage.h>
19#include <tools_share/firmware_image_package.h>
20
Konstantin Porotchkinf69ec582018-06-07 18:31:14 +030021/* IO devices */
22static const io_dev_connector_t *fip_dev_con;
23static uintptr_t fip_dev_handle;
24static const io_dev_connector_t *memmap_dev_con;
25static uintptr_t memmap_dev_handle;
26
27static const io_block_spec_t fip_block_spec = {
28 .offset = PLAT_MARVELL_FIP_BASE,
29 .length = PLAT_MARVELL_FIP_MAX_SIZE
30};
31
32static const io_uuid_spec_t bl2_uuid_spec = {
33 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
34};
35
36static const io_uuid_spec_t scp_bl2_uuid_spec = {
37 .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
38};
39
40static const io_uuid_spec_t bl31_uuid_spec = {
41 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
42};
43static const io_uuid_spec_t bl32_uuid_spec = {
44 .uuid = UUID_SECURE_PAYLOAD_BL32,
45};
Marcin Wojtas35b75f02019-11-13 13:31:48 +010046
47static const io_uuid_spec_t bl32_extra1_uuid_spec = {
48 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
49};
50
51static const io_uuid_spec_t bl32_extra2_uuid_spec = {
52 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
53};
54
Konstantin Porotchkinf69ec582018-06-07 18:31:14 +030055static const io_uuid_spec_t bl33_uuid_spec = {
56 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
57};
58
59static int open_fip(const uintptr_t spec);
60static int open_memmap(const uintptr_t spec);
61
62struct plat_io_policy {
63 uintptr_t *dev_handle;
64 uintptr_t image_spec;
65 int (*check)(const uintptr_t spec);
66};
67
68/* By default, Marvell platforms load images from the FIP */
69static const struct plat_io_policy policies[] = {
70 [FIP_IMAGE_ID] = {
71 &memmap_dev_handle,
72 (uintptr_t)&fip_block_spec,
73 open_memmap
74 },
75 [BL2_IMAGE_ID] = {
76 &fip_dev_handle,
77 (uintptr_t)&bl2_uuid_spec,
78 open_fip
79 },
80 [SCP_BL2_IMAGE_ID] = {
81 &fip_dev_handle,
82 (uintptr_t)&scp_bl2_uuid_spec,
83 open_fip
84 },
85 [BL31_IMAGE_ID] = {
86 &fip_dev_handle,
87 (uintptr_t)&bl31_uuid_spec,
88 open_fip
89 },
90 [BL32_IMAGE_ID] = {
91 &fip_dev_handle,
92 (uintptr_t)&bl32_uuid_spec,
93 open_fip
94 },
Marcin Wojtas35b75f02019-11-13 13:31:48 +010095 [BL32_EXTRA1_IMAGE_ID] = {
96 &fip_dev_handle,
97 (uintptr_t)&bl32_extra1_uuid_spec,
98 open_fip
99 },
100 [BL32_EXTRA2_IMAGE_ID] = {
101 &fip_dev_handle,
102 (uintptr_t)&bl32_extra2_uuid_spec,
103 open_fip
104 },
Konstantin Porotchkinf69ec582018-06-07 18:31:14 +0300105 [BL33_IMAGE_ID] = {
106 &fip_dev_handle,
107 (uintptr_t)&bl33_uuid_spec,
108 open_fip
109 },
110};
111
112
113/* Weak definitions may be overridden in specific ARM standard platform */
114#pragma weak plat_marvell_io_setup
115#pragma weak plat_marvell_get_alt_image_source
116
117
118static int open_fip(const uintptr_t spec)
119{
120 int result;
121 uintptr_t local_image_handle;
122
123 /* See if a Firmware Image Package is available */
124 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
125 if (result == 0) {
126 result = io_open(fip_dev_handle, spec, &local_image_handle);
127 if (result == 0) {
128 VERBOSE("Using FIP\n");
129 io_close(local_image_handle);
130 }
131 }
132 return result;
133}
134
135
136static int open_memmap(const uintptr_t spec)
137{
138 int result;
139 uintptr_t local_image_handle;
140
141 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
142 if (result == 0) {
143 result = io_open(memmap_dev_handle, spec, &local_image_handle);
144 if (result == 0) {
145 VERBOSE("Using Memmap\n");
146 io_close(local_image_handle);
147 }
148 }
149 return result;
150}
151
152
153void marvell_io_setup(void)
154{
155 int io_result;
156
157 io_result = register_io_dev_fip(&fip_dev_con);
158 assert(io_result == 0);
159
160 io_result = register_io_dev_memmap(&memmap_dev_con);
161 assert(io_result == 0);
162
163 /* Open connections to devices and cache the handles */
164 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
165 &fip_dev_handle);
166 assert(io_result == 0);
167
168 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
169 &memmap_dev_handle);
170 assert(io_result == 0);
171
172 /* Ignore improbable errors in release builds */
173 (void)io_result;
174}
175
176void plat_marvell_io_setup(void)
177{
178 marvell_io_setup();
179}
180
181int plat_marvell_get_alt_image_source(
182 unsigned int image_id __attribute__((unused)),
183 uintptr_t *dev_handle __attribute__((unused)),
184 uintptr_t *image_spec __attribute__((unused)))
185{
186 /* By default do not try an alternative */
187 return -ENOENT;
188}
189
190/*
191 * Return an IO device handle and specification which can be used to access
192 * an image. Use this to enforce platform load policy
193 */
194int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
195 uintptr_t *image_spec)
196{
197 int result;
198 const struct plat_io_policy *policy;
199
200 assert(image_id < ARRAY_SIZE(policies));
201
202 policy = &policies[image_id];
203 result = policy->check(policy->image_spec);
204 if (result == 0) {
205 *image_spec = policy->image_spec;
206 *dev_handle = *(policy->dev_handle);
207 } else {
208 VERBOSE("Trying alternative IO\n");
209 result = plat_marvell_get_alt_image_source(image_id, dev_handle,
210 image_spec);
211 }
212
213 return result;
214}
215
216/*
217 * See if a Firmware Image Package is available,
218 * by checking if TOC is valid or not.
219 */
220int marvell_io_is_toc_valid(void)
221{
222 int result;
223
224 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
225
226 return result == 0;
227}