blob: 468e229264a39fd133dd571a8ed117c5b61ce0b3 [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>
Victor Chong539408d2018-01-03 01:53:08 +090010#include <emmc.h>
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020011#include <firmware_image_package.h>
12#include <io_block.h>
13#include <io_driver.h>
14#include <io_fip.h>
15#include <io_memmap.h>
16#include <io_storage.h>
17#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 = {
41 .read = emmc_read_blocks,
42 .write = emmc_write_blocks,
43 },
44 .block_size = EMMC_BLOCK_SIZE,
45};
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
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020073static const io_uuid_spec_t bl33_uuid_spec = {
74 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
75};
76
77struct plat_io_policy {
78 uintptr_t *dev_handle;
79 uintptr_t image_spec;
80 int (*check)(const uintptr_t spec);
81};
82
83static const struct plat_io_policy policies[] = {
Victor Chongf0c7c612018-01-16 00:29:47 +090084#if !POPLAR_RECOVERY
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020085 [FIP_IMAGE_ID] = {
Victor Chong539408d2018-01-03 01:53:08 +090086 &emmc_dev_handle,
87 (uintptr_t)&emmc_fip_spec,
88 open_emmc
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020089 },
Victor Chongf0c7c612018-01-16 00:29:47 +090090#else
91 [FIP_IMAGE_ID] = {
92 &mmap_dev_handle,
93 (uintptr_t)&loader_fip_spec,
94 open_mmap
95 },
96#endif
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020097 [BL2_IMAGE_ID] = {
98 &fip_dev_handle,
99 (uintptr_t)&bl2_uuid_spec,
100 open_fip
101 },
102 [BL31_IMAGE_ID] = {
103 &fip_dev_handle,
104 (uintptr_t)&bl31_uuid_spec,
105 open_fip
106 },
Victor Chong662556a2017-10-28 01:59:41 +0900107 [BL32_IMAGE_ID] = {
108 &fip_dev_handle,
109 (uintptr_t)&bl32_uuid_spec,
110 open_fip
111 },
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200112 [BL33_IMAGE_ID] = {
113 &fip_dev_handle,
114 (uintptr_t)&bl33_uuid_spec,
115 open_fip
116 },
117};
118
Victor Chongf0c7c612018-01-16 00:29:47 +0900119#if !POPLAR_RECOVERY
Victor Chong539408d2018-01-03 01:53:08 +0900120static int open_emmc(const uintptr_t spec)
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200121{
122 int result;
123 uintptr_t local_image_handle;
124
Victor Chong539408d2018-01-03 01:53:08 +0900125 result = io_dev_init(emmc_dev_handle, (uintptr_t)NULL);
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200126 if (result == 0) {
Victor Chong539408d2018-01-03 01:53:08 +0900127 result = io_open(emmc_dev_handle, spec, &local_image_handle);
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200128 if (result == 0) {
Victor Chong539408d2018-01-03 01:53:08 +0900129 INFO("Using eMMC\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200130 io_close(local_image_handle);
Victor Chong539408d2018-01-03 01:53:08 +0900131 } else {
132 ERROR("error opening emmc\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200133 }
Victor Chong539408d2018-01-03 01:53:08 +0900134 } else {
135 ERROR("error initializing emmc\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200136 }
Victor Chong539408d2018-01-03 01:53:08 +0900137
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200138 return result;
139}
Victor Chongf0c7c612018-01-16 00:29:47 +0900140#else
141static int open_mmap(const uintptr_t spec)
142{
143 int result;
144 uintptr_t local_image_handle;
145
146 result = io_dev_init(mmap_dev_handle, (uintptr_t)NULL);
147 if (result == 0) {
148 result = io_open(mmap_dev_handle, spec, &local_image_handle);
149 if (result == 0) {
150 INFO("Using mmap\n");
151 io_close(local_image_handle);
152 } else {
153 ERROR("error opening mmap\n");
154 }
155 } else {
156 ERROR("error initializing mmap\n");
157 }
158
159 return result;
160}
161#endif
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200162
163static int open_fip(const uintptr_t spec)
164{
165 uintptr_t local_image_handle;
166 int result;
167
168 result = io_dev_init(fip_dev_handle, (uintptr_t) FIP_IMAGE_ID);
169 if (result == 0) {
170 result = io_open(fip_dev_handle, spec, &local_image_handle);
171 if (result == 0) {
Victor Chong539408d2018-01-03 01:53:08 +0900172 INFO("Using FIP\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200173 io_close(local_image_handle);
174 } else {
Victor Chong539408d2018-01-03 01:53:08 +0900175 ERROR("error opening fip\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200176 }
177 } else {
Victor Chong539408d2018-01-03 01:53:08 +0900178 ERROR("error initializing fip\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200179 }
180
181 return result;
182}
183
184int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
185 uintptr_t *image_spec)
186{
187 const struct plat_io_policy *policy;
188 int result;
189
190 assert(image_id < ARRAY_SIZE(policies));
191
192 policy = &policies[image_id];
193 result = policy->check(policy->image_spec);
194 assert(result == 0);
195
196 *image_spec = policy->image_spec;
197 *dev_handle = *(policy->dev_handle);
198
199 return result;
200}
201
202void plat_io_setup(void)
203{
204 int result;
205
Victor Chongf0c7c612018-01-16 00:29:47 +0900206#if !POPLAR_RECOVERY
Victor Chong539408d2018-01-03 01:53:08 +0900207 result = register_io_dev_block(&emmc_dev_con);
Victor Chongf0c7c612018-01-16 00:29:47 +0900208#else
209 result = register_io_dev_memmap(&mmap_dev_con);
210#endif
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200211 assert(result == 0);
212
213 result = register_io_dev_fip(&fip_dev_con);
214 assert(result == 0);
215
Victor Chongf0c7c612018-01-16 00:29:47 +0900216#if !POPLAR_RECOVERY
Victor Chong539408d2018-01-03 01:53:08 +0900217 result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200218 &fip_dev_handle);
Victor Chongf0c7c612018-01-16 00:29:47 +0900219#else
220 result = io_dev_open(fip_dev_con, (uintptr_t)&loader_fip_spec,
221 &fip_dev_handle);
222#endif
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200223 assert(result == 0);
224
Victor Chongf0c7c612018-01-16 00:29:47 +0900225#if !POPLAR_RECOVERY
Victor Chong539408d2018-01-03 01:53:08 +0900226 result = io_dev_open(emmc_dev_con, (uintptr_t)&emmc_dev_spec,
227 &emmc_dev_handle);
Victor Chongf0c7c612018-01-16 00:29:47 +0900228#else
229 result = io_dev_open(mmap_dev_con, (uintptr_t)NULL, &mmap_dev_handle);
230#endif
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200231 assert(result == 0);
232
233 (void) result;
234}