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