blob: 925274ce4e4aa2c0f19c6461ab3bcf518c8a469e [file] [log] [blame]
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +02001/*
2 * Copyright (c) 2017, ARM Limited and Contributors. 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>
10#include <firmware_image_package.h>
11#include <io_block.h>
12#include <io_driver.h>
13#include <io_fip.h>
14#include <io_memmap.h>
15#include <io_storage.h>
Haojian Zhuang3eff4092018-08-04 18:07:26 +080016#include <mmc.h>
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020017#include <mmio.h>
18#include <partition/partition.h>
19#include <semihosting.h>
20#include <string.h>
21#include <tbbr_img_def.h>
22#include <utils.h>
23#include "platform_def.h"
24
Victor Chongf0c7c612018-01-16 00:29:47 +090025#if !POPLAR_RECOVERY
Victor Chong539408d2018-01-03 01:53:08 +090026static const io_dev_connector_t *emmc_dev_con;
Victor Chong539408d2018-01-03 01:53:08 +090027static uintptr_t emmc_dev_handle;
Victor Chong539408d2018-01-03 01:53:08 +090028static int open_emmc(const uintptr_t spec);
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020029
Victor Chong539408d2018-01-03 01:53:08 +090030static const io_block_spec_t emmc_fip_spec = {
31 .offset = FIP_BASE_EMMC,
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020032 .length = FIP_SIZE
33};
34
Victor Chong539408d2018-01-03 01:53:08 +090035static const io_block_dev_spec_t emmc_dev_spec = {
36 .buffer = {
37 .offset = POPLAR_EMMC_DATA_BASE,
38 .length = POPLAR_EMMC_DATA_SIZE,
39 },
40 .ops = {
Haojian Zhuang3eff4092018-08-04 18:07:26 +080041 .read = mmc_read_blocks,
42 .write = mmc_write_blocks,
Victor Chong539408d2018-01-03 01:53:08 +090043 },
Haojian Zhuang3eff4092018-08-04 18:07:26 +080044 .block_size = MMC_BLOCK_SIZE,
Victor Chong539408d2018-01-03 01:53:08 +090045};
Victor Chongf0c7c612018-01-16 00:29:47 +090046#else
47static const io_dev_connector_t *mmap_dev_con;
48static uintptr_t mmap_dev_handle;
49static int open_mmap(const uintptr_t spec);
50
51static const io_block_spec_t loader_fip_spec = {
52 .offset = FIP_BASE,
53 .length = FIP_SIZE
54};
55#endif
56
57static const io_dev_connector_t *fip_dev_con;
58static uintptr_t fip_dev_handle;
59static int open_fip(const uintptr_t spec);
Victor Chong539408d2018-01-03 01:53:08 +090060
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020061static const io_uuid_spec_t bl2_uuid_spec = {
62 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
63};
64
65static const io_uuid_spec_t bl31_uuid_spec = {
66 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
67};
68
Victor Chong662556a2017-10-28 01:59:41 +090069static const io_uuid_spec_t bl32_uuid_spec = {
70 .uuid = UUID_SECURE_PAYLOAD_BL32,
71};
72
Victor Chongaa033472018-02-01 00:35:39 +090073static const io_uuid_spec_t bl32_extra1_uuid_spec = {
74 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
75};
76
77static const io_uuid_spec_t bl32_extra2_uuid_spec = {
78 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
79};
80
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020081static const io_uuid_spec_t bl33_uuid_spec = {
82 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
83};
84
85struct plat_io_policy {
86 uintptr_t *dev_handle;
87 uintptr_t image_spec;
88 int (*check)(const uintptr_t spec);
89};
90
91static const struct plat_io_policy policies[] = {
Victor Chongf0c7c612018-01-16 00:29:47 +090092#if !POPLAR_RECOVERY
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020093 [FIP_IMAGE_ID] = {
Victor Chong539408d2018-01-03 01:53:08 +090094 &emmc_dev_handle,
95 (uintptr_t)&emmc_fip_spec,
96 open_emmc
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020097 },
Victor Chongf0c7c612018-01-16 00:29:47 +090098#else
99 [FIP_IMAGE_ID] = {
100 &mmap_dev_handle,
101 (uintptr_t)&loader_fip_spec,
102 open_mmap
103 },
104#endif
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200105 [BL2_IMAGE_ID] = {
106 &fip_dev_handle,
107 (uintptr_t)&bl2_uuid_spec,
108 open_fip
109 },
110 [BL31_IMAGE_ID] = {
111 &fip_dev_handle,
112 (uintptr_t)&bl31_uuid_spec,
113 open_fip
114 },
Victor Chong662556a2017-10-28 01:59:41 +0900115 [BL32_IMAGE_ID] = {
116 &fip_dev_handle,
117 (uintptr_t)&bl32_uuid_spec,
118 open_fip
119 },
Victor Chongaa033472018-02-01 00:35:39 +0900120 [BL32_EXTRA1_IMAGE_ID] = {
121 &fip_dev_handle,
122 (uintptr_t)&bl32_extra1_uuid_spec,
123 open_fip
124 },
125 [BL32_EXTRA2_IMAGE_ID] = {
126 &fip_dev_handle,
127 (uintptr_t)&bl32_extra2_uuid_spec,
128 open_fip
129 },
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200130 [BL33_IMAGE_ID] = {
131 &fip_dev_handle,
132 (uintptr_t)&bl33_uuid_spec,
133 open_fip
134 },
135};
136
Victor Chongf0c7c612018-01-16 00:29:47 +0900137#if !POPLAR_RECOVERY
Victor Chong539408d2018-01-03 01:53:08 +0900138static int open_emmc(const uintptr_t spec)
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200139{
140 int result;
141 uintptr_t local_image_handle;
142
Victor Chong539408d2018-01-03 01:53:08 +0900143 result = io_dev_init(emmc_dev_handle, (uintptr_t)NULL);
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200144 if (result == 0) {
Victor Chong539408d2018-01-03 01:53:08 +0900145 result = io_open(emmc_dev_handle, spec, &local_image_handle);
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200146 if (result == 0) {
Victor Chong539408d2018-01-03 01:53:08 +0900147 INFO("Using eMMC\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200148 io_close(local_image_handle);
Victor Chong539408d2018-01-03 01:53:08 +0900149 } else {
150 ERROR("error opening emmc\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200151 }
Victor Chong539408d2018-01-03 01:53:08 +0900152 } else {
153 ERROR("error initializing emmc\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200154 }
Victor Chong539408d2018-01-03 01:53:08 +0900155
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200156 return result;
157}
Victor Chongf0c7c612018-01-16 00:29:47 +0900158#else
159static int open_mmap(const uintptr_t spec)
160{
161 int result;
162 uintptr_t local_image_handle;
163
164 result = io_dev_init(mmap_dev_handle, (uintptr_t)NULL);
165 if (result == 0) {
166 result = io_open(mmap_dev_handle, spec, &local_image_handle);
167 if (result == 0) {
168 INFO("Using mmap\n");
169 io_close(local_image_handle);
170 } else {
171 ERROR("error opening mmap\n");
172 }
173 } else {
174 ERROR("error initializing mmap\n");
175 }
176
177 return result;
178}
179#endif
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200180
181static int open_fip(const uintptr_t spec)
182{
183 uintptr_t local_image_handle;
184 int result;
185
186 result = io_dev_init(fip_dev_handle, (uintptr_t) FIP_IMAGE_ID);
187 if (result == 0) {
188 result = io_open(fip_dev_handle, spec, &local_image_handle);
189 if (result == 0) {
Victor Chong539408d2018-01-03 01:53:08 +0900190 INFO("Using FIP\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200191 io_close(local_image_handle);
192 } else {
Victor Chong539408d2018-01-03 01:53:08 +0900193 ERROR("error opening fip\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200194 }
195 } else {
Victor Chong539408d2018-01-03 01:53:08 +0900196 ERROR("error initializing fip\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200197 }
198
199 return result;
200}
201
202int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
203 uintptr_t *image_spec)
204{
205 const struct plat_io_policy *policy;
206 int result;
207
208 assert(image_id < ARRAY_SIZE(policies));
209
210 policy = &policies[image_id];
211 result = policy->check(policy->image_spec);
212 assert(result == 0);
213
214 *image_spec = policy->image_spec;
215 *dev_handle = *(policy->dev_handle);
216
217 return result;
218}
219
220void plat_io_setup(void)
221{
222 int result;
223
Victor Chongf0c7c612018-01-16 00:29:47 +0900224#if !POPLAR_RECOVERY
Victor Chong539408d2018-01-03 01:53:08 +0900225 result = register_io_dev_block(&emmc_dev_con);
Victor Chongf0c7c612018-01-16 00:29:47 +0900226#else
227 result = register_io_dev_memmap(&mmap_dev_con);
228#endif
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200229 assert(result == 0);
230
231 result = register_io_dev_fip(&fip_dev_con);
232 assert(result == 0);
233
Victor Chongf0c7c612018-01-16 00:29:47 +0900234#if !POPLAR_RECOVERY
Victor Chong539408d2018-01-03 01:53:08 +0900235 result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200236 &fip_dev_handle);
Victor Chongf0c7c612018-01-16 00:29:47 +0900237#else
238 result = io_dev_open(fip_dev_con, (uintptr_t)&loader_fip_spec,
239 &fip_dev_handle);
240#endif
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200241 assert(result == 0);
242
Victor Chongf0c7c612018-01-16 00:29:47 +0900243#if !POPLAR_RECOVERY
Victor Chong539408d2018-01-03 01:53:08 +0900244 result = io_dev_open(emmc_dev_con, (uintptr_t)&emmc_dev_spec,
245 &emmc_dev_handle);
Victor Chongf0c7c612018-01-16 00:29:47 +0900246#else
247 result = io_dev_open(mmap_dev_con, (uintptr_t)NULL, &mmap_dev_handle);
248#endif
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200249 assert(result == 0);
250
251 (void) result;
252}