xref: /rk3399_ARM-atf/plat/marvell/armada/common/marvell_io_storage.c (revision e555787b66dfa2a1e3b9145a5c55763850ae66dc)
1 /*
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 <string.h>
10 
11 #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 
21 /* IO devices */
22 static const io_dev_connector_t *fip_dev_con;
23 static uintptr_t fip_dev_handle;
24 static const io_dev_connector_t *memmap_dev_con;
25 static uintptr_t memmap_dev_handle;
26 
27 static const io_block_spec_t fip_block_spec = {
28 	.offset = PLAT_MARVELL_FIP_BASE,
29 	.length = PLAT_MARVELL_FIP_MAX_SIZE
30 };
31 
32 static const io_uuid_spec_t bl2_uuid_spec = {
33 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
34 };
35 
36 static const io_uuid_spec_t scp_bl2_uuid_spec = {
37 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
38 };
39 
40 static const io_uuid_spec_t bl31_uuid_spec = {
41 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
42 };
43 static const io_uuid_spec_t bl32_uuid_spec = {
44 	.uuid = UUID_SECURE_PAYLOAD_BL32,
45 };
46 static const io_uuid_spec_t bl33_uuid_spec = {
47 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
48 };
49 
50 static int open_fip(const uintptr_t spec);
51 static int open_memmap(const uintptr_t spec);
52 
53 struct 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 */
60 static 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 
99 static 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 
117 static 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 
134 void 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 
157 void plat_marvell_io_setup(void)
158 {
159 	marvell_io_setup();
160 }
161 
162 int 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  */
175 int 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  */
201 int 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 }
209