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