blob: b9cace09063ca8886e1d497bf7a88f86226efb42 [file] [log] [blame]
Bryan O'Donoghue4df2f172018-05-24 13:00:57 +01001/*
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00006
Bryan O'Donoghue4df2f172018-05-24 13:00:57 +01007#include <assert.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00008
Bryan O'Donoghue4df2f172018-05-24 13:00:57 +01009#include <platform_def.h>
10
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000011#include <common/debug.h>
12#include <drivers/io/io_block.h>
13#include <drivers/io/io_driver.h>
14#include <drivers/io/io_fip.h>
15#include <drivers/io/io_memmap.h>
16#include <drivers/mmc.h>
17#include <tools_share/firmware_image_package.h>
18
Bryan O'Donoghue4df2f172018-05-24 13:00:57 +010019static const io_dev_connector_t *fip_dev_con;
20static uintptr_t fip_dev_handle;
21
22#ifndef WARP7_FIP_MMAP
23static const io_dev_connector_t *mmc_dev_con;
24static uintptr_t mmc_dev_handle;
25
26static const io_block_spec_t mmc_fip_spec = {
27 .offset = WARP7_FIP_MMC_BASE,
28 .length = WARP7_FIP_SIZE
29};
30
31static const io_block_dev_spec_t mmc_dev_spec = {
32 /* It's used as temp buffer in block driver. */
33 .buffer = {
34 .offset = WARP7_FIP_BASE,
35 /* do we need a new value? */
36 .length = WARP7_FIP_SIZE
37 },
38 .ops = {
39 .read = mmc_read_blocks,
40 .write = mmc_write_blocks,
41 },
42 .block_size = MMC_BLOCK_SIZE,
43};
44
45static int open_mmc(const uintptr_t spec);
46
47#else
48static const io_dev_connector_t *memmap_dev_con;
49static uintptr_t memmap_dev_handle;
50
51static const io_block_spec_t fip_block_spec = {
52 .offset = WARP7_FIP_BASE,
53 .length = WARP7_FIP_SIZE
54};
55static int open_memmap(const uintptr_t spec);
56#endif
57static int open_fip(const uintptr_t spec);
58
59static const io_uuid_spec_t bl32_uuid_spec = {
60 .uuid = UUID_SECURE_PAYLOAD_BL32,
61};
62
63static const io_uuid_spec_t hw_config_uuid_spec = {
64 .uuid = UUID_HW_CONFIG,
65};
66
67static const io_uuid_spec_t bl32_extra1_uuid_spec = {
68 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
69};
70
71static const io_uuid_spec_t bl32_extra2_uuid_spec = {
72 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
73};
74
75static const io_uuid_spec_t bl33_uuid_spec = {
76 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
77};
78
79/* TODO: this structure is replicated multiple times. rationalize it ! */
80struct plat_io_policy {
81 uintptr_t *dev_handle;
82 uintptr_t image_spec;
83 int (*check)(const uintptr_t spec);
84};
85
86static const struct plat_io_policy policies[] = {
87#ifndef WARP7_FIP_MMAP
88 [FIP_IMAGE_ID] = {
89 &mmc_dev_handle,
90 (uintptr_t)&mmc_fip_spec,
91 open_mmc
92 },
93#else
94 [FIP_IMAGE_ID] = {
95 &memmap_dev_handle,
96 (uintptr_t)&fip_block_spec,
97 open_memmap
98 },
99#endif
100 [BL32_IMAGE_ID] = {
101 &fip_dev_handle,
102 (uintptr_t)&bl32_uuid_spec,
103 open_fip
104 },
105 [BL32_EXTRA1_IMAGE_ID] = {
106 &fip_dev_handle,
107 (uintptr_t)&bl32_extra1_uuid_spec,
108 open_fip
109 },
110 [BL32_EXTRA2_IMAGE_ID] = {
111 &fip_dev_handle,
112 (uintptr_t)&bl32_extra2_uuid_spec,
113 open_fip
114 },
115 [HW_CONFIG_ID] = {
116 &fip_dev_handle,
117 (uintptr_t)&hw_config_uuid_spec,
118 open_fip
119 },
120 [BL33_IMAGE_ID] = {
121 &fip_dev_handle,
122 (uintptr_t)&bl33_uuid_spec,
123 open_fip
124 }
125};
126
127static int open_fip(const uintptr_t spec)
128{
129 int result;
130 uintptr_t local_image_handle;
131
132 /* See if a Firmware Image Package is available */
133 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
134 if (result == 0) {
135 result = io_open(fip_dev_handle, spec, &local_image_handle);
136 if (result == 0) {
137 VERBOSE("Using FIP\n");
138 io_close(local_image_handle);
139 }
140 }
141 return result;
142}
143
144#ifndef WARP7_FIP_MMAP
145static int open_mmc(const uintptr_t spec)
146{
147 int result;
148 uintptr_t local_handle;
149
150 result = io_dev_init(mmc_dev_handle, (uintptr_t)NULL);
151 if (result == 0) {
152 result = io_open(mmc_dev_handle, spec, &local_handle);
153 if (result == 0)
154 io_close(local_handle);
155 }
156 return result;
157}
158#else
159static int open_memmap(const uintptr_t spec)
160{
161 int result;
162 uintptr_t local_image_handle;
163
164 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
165 if (result == 0) {
166 result = io_open(memmap_dev_handle, spec, &local_image_handle);
167 if (result == 0) {
168 VERBOSE("Using Memmap\n");
169 io_close(local_image_handle);
170 }
171 }
172 return result;
173}
174#endif
175
176int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
177 uintptr_t *image_spec)
178{
179 int result;
180 const struct plat_io_policy *policy;
181
182 assert(image_id < ARRAY_SIZE(policies));
183
184 policy = &policies[image_id];
185 result = policy->check(policy->image_spec);
186 assert(result == 0);
187
188 *image_spec = policy->image_spec;
189 *dev_handle = *policy->dev_handle;
190
191 return result;
192}
193
194void plat_warp7_io_setup(void)
195{
196 int result __unused;
197
198#ifndef WARP7_FIP_MMAP
199 result = register_io_dev_block(&mmc_dev_con);
200 assert(result == 0);
201
202 result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_dev_spec,
203 &mmc_dev_handle);
204 assert(result == 0);
205
206#else
207 result = register_io_dev_memmap(&memmap_dev_con);
208 assert(result == 0);
209
210 result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
211 &memmap_dev_handle);
212 assert(result == 0);
213
214#endif
215 result = register_io_dev_fip(&fip_dev_con);
216 assert(result == 0);
217
218 result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
219 &fip_dev_handle);
220 assert(result == 0);
221}