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