blob: f72dbb8807a36e79fc7eaf030690c5ff2a00706e [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 Chong539408d2018-01-03 01:53:08 +090025static const io_dev_connector_t *emmc_dev_con;
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020026static const io_dev_connector_t *fip_dev_con;
27
Victor Chong539408d2018-01-03 01:53:08 +090028static uintptr_t emmc_dev_handle;
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020029static uintptr_t fip_dev_handle;
30
Victor Chong539408d2018-01-03 01:53:08 +090031static int open_emmc(const uintptr_t spec);
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020032static int open_fip(const uintptr_t spec);
33
Victor Chong539408d2018-01-03 01:53:08 +090034static const io_block_spec_t emmc_fip_spec = {
35 .offset = FIP_BASE_EMMC,
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020036 .length = FIP_SIZE
37};
38
Victor Chong539408d2018-01-03 01:53:08 +090039static const io_block_dev_spec_t emmc_dev_spec = {
40 .buffer = {
41 .offset = POPLAR_EMMC_DATA_BASE,
42 .length = POPLAR_EMMC_DATA_SIZE,
43 },
44 .ops = {
45 .read = emmc_read_blocks,
46 .write = emmc_write_blocks,
47 },
48 .block_size = EMMC_BLOCK_SIZE,
49};
50
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020051static const io_uuid_spec_t bl2_uuid_spec = {
52 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
53};
54
55static const io_uuid_spec_t bl31_uuid_spec = {
56 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
57};
58
Victor Chong662556a2017-10-28 01:59:41 +090059static const io_uuid_spec_t bl32_uuid_spec = {
60 .uuid = UUID_SECURE_PAYLOAD_BL32,
61};
62
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020063static const io_uuid_spec_t bl33_uuid_spec = {
64 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
65};
66
67struct plat_io_policy {
68 uintptr_t *dev_handle;
69 uintptr_t image_spec;
70 int (*check)(const uintptr_t spec);
71};
72
73static const struct plat_io_policy policies[] = {
74 [FIP_IMAGE_ID] = {
Victor Chong539408d2018-01-03 01:53:08 +090075 &emmc_dev_handle,
76 (uintptr_t)&emmc_fip_spec,
77 open_emmc
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020078 },
79 [BL2_IMAGE_ID] = {
80 &fip_dev_handle,
81 (uintptr_t)&bl2_uuid_spec,
82 open_fip
83 },
84 [BL31_IMAGE_ID] = {
85 &fip_dev_handle,
86 (uintptr_t)&bl31_uuid_spec,
87 open_fip
88 },
Victor Chong662556a2017-10-28 01:59:41 +090089 [BL32_IMAGE_ID] = {
90 &fip_dev_handle,
91 (uintptr_t)&bl32_uuid_spec,
92 open_fip
93 },
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020094 [BL33_IMAGE_ID] = {
95 &fip_dev_handle,
96 (uintptr_t)&bl33_uuid_spec,
97 open_fip
98 },
99};
100
Victor Chong539408d2018-01-03 01:53:08 +0900101static int open_emmc(const uintptr_t spec)
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200102{
103 int result;
104 uintptr_t local_image_handle;
105
Victor Chong539408d2018-01-03 01:53:08 +0900106 result = io_dev_init(emmc_dev_handle, (uintptr_t)NULL);
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200107 if (result == 0) {
Victor Chong539408d2018-01-03 01:53:08 +0900108 result = io_open(emmc_dev_handle, spec, &local_image_handle);
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200109 if (result == 0) {
Victor Chong539408d2018-01-03 01:53:08 +0900110 INFO("Using eMMC\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200111 io_close(local_image_handle);
Victor Chong539408d2018-01-03 01:53:08 +0900112 } else {
113 ERROR("error opening emmc\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200114 }
Victor Chong539408d2018-01-03 01:53:08 +0900115 } else {
116 ERROR("error initializing emmc\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200117 }
Victor Chong539408d2018-01-03 01:53:08 +0900118
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200119 return result;
120}
121
122static int open_fip(const uintptr_t spec)
123{
124 uintptr_t local_image_handle;
125 int result;
126
127 result = io_dev_init(fip_dev_handle, (uintptr_t) FIP_IMAGE_ID);
128 if (result == 0) {
129 result = io_open(fip_dev_handle, spec, &local_image_handle);
130 if (result == 0) {
Victor Chong539408d2018-01-03 01:53:08 +0900131 INFO("Using FIP\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200132 io_close(local_image_handle);
133 } else {
Victor Chong539408d2018-01-03 01:53:08 +0900134 ERROR("error opening fip\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200135 }
136 } else {
Victor Chong539408d2018-01-03 01:53:08 +0900137 ERROR("error initializing fip\n");
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200138 }
139
140 return result;
141}
142
143int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
144 uintptr_t *image_spec)
145{
146 const struct plat_io_policy *policy;
147 int result;
148
149 assert(image_id < ARRAY_SIZE(policies));
150
151 policy = &policies[image_id];
152 result = policy->check(policy->image_spec);
153 assert(result == 0);
154
155 *image_spec = policy->image_spec;
156 *dev_handle = *(policy->dev_handle);
157
158 return result;
159}
160
161void plat_io_setup(void)
162{
163 int result;
164
Victor Chong539408d2018-01-03 01:53:08 +0900165 result = register_io_dev_block(&emmc_dev_con);
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200166 assert(result == 0);
167
168 result = register_io_dev_fip(&fip_dev_con);
169 assert(result == 0);
170
Victor Chong539408d2018-01-03 01:53:08 +0900171 result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200172 &fip_dev_handle);
173 assert(result == 0);
174
Victor Chong539408d2018-01-03 01:53:08 +0900175 result = io_dev_open(emmc_dev_con, (uintptr_t)&emmc_dev_spec,
176 &emmc_dev_handle);
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200177 assert(result == 0);
178
179 (void) result;
180}