blob: 2d3d7980c82df83445421939dc95cf3b9e47d74a [file] [log] [blame]
Hadi Asyrafi616da772019-06-27 11:34:03 +08001/*
2 * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
Jit Loon Lim86f6fb32023-05-17 12:26:11 +08003 * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
Hadi Asyrafi616da772019-06-27 11:34:03 +08004 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#include <arch_helpers.h>
9#include <assert.h>
10#include <common/debug.h>
11#include <common/tbbr/tbbr_img_def.h>
Jit Loon Limb24dddf2023-05-17 12:26:11 +080012#include <drivers/cadence/cdns_nand.h>
13#include <drivers/cadence/cdns_sdmmc.h>
Hadi Asyrafi616da772019-06-27 11:34:03 +080014#include <drivers/io/io_block.h>
15#include <drivers/io/io_driver.h>
16#include <drivers/io/io_fip.h>
17#include <drivers/io/io_memmap.h>
Jit Loon Limb24dddf2023-05-17 12:26:11 +080018#include <drivers/io/io_mtd.h>
Hadi Asyrafi616da772019-06-27 11:34:03 +080019#include <drivers/io/io_storage.h>
20#include <drivers/mmc.h>
21#include <drivers/partition/partition.h>
22#include <lib/mmio.h>
23#include <tools_share/firmware_image_package.h>
24
Jit Loon Lima7f54942023-05-17 12:26:11 +080025#include "drivers/sdmmc/sdmmc.h"
Hadi Asyrafif0fa8072019-10-23 17:02:55 +080026#include "socfpga_private.h"
Hadi Asyrafi616da772019-06-27 11:34:03 +080027
Jit Loon Limb24dddf2023-05-17 12:26:11 +080028
Hadi Asyrafi616da772019-06-27 11:34:03 +080029#define PLAT_FIP_BASE (0)
30#define PLAT_FIP_MAX_SIZE (0x1000000)
31#define PLAT_MMC_DATA_BASE (0xffe3c000)
32#define PLAT_MMC_DATA_SIZE (0x2000)
33#define PLAT_QSPI_DATA_BASE (0x3C00000)
34#define PLAT_QSPI_DATA_SIZE (0x1000000)
Jit Loon Limb24dddf2023-05-17 12:26:11 +080035#define PLAT_NAND_DATA_BASE (0x0200000)
36#define PLAT_NAND_DATA_SIZE (0x1000000)
Hadi Asyrafi616da772019-06-27 11:34:03 +080037
38static const io_dev_connector_t *fip_dev_con;
39static const io_dev_connector_t *boot_dev_con;
40
Jit Loon Limb24dddf2023-05-17 12:26:11 +080041static io_mtd_dev_spec_t nand_dev_spec;
42
Hadi Asyrafi616da772019-06-27 11:34:03 +080043static uintptr_t fip_dev_handle;
44static uintptr_t boot_dev_handle;
45
46static const io_uuid_spec_t bl2_uuid_spec = {
47 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
48};
49
50static const io_uuid_spec_t bl31_uuid_spec = {
51 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
52};
53
54static const io_uuid_spec_t bl33_uuid_spec = {
55 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
56};
57
Jit Loon Limc5a3e3a2023-10-16 00:19:34 +080058# if ARM_LINUX_KERNEL_AS_BL33 != 0
59static const io_uuid_spec_t nt_fw_config_uuid_spec = {
60 .uuid = UUID_NT_FW_CONFIG,
61};
62# endif
63
Hadi Asyrafi616da772019-06-27 11:34:03 +080064uintptr_t a2_lba_offset;
65const char a2[] = {0xa2, 0x0};
66
67static const io_block_spec_t gpt_block_spec = {
68 .offset = 0,
69 .length = MMC_BLOCK_SIZE
70};
71
72static int check_fip(const uintptr_t spec);
73static int check_dev(const uintptr_t spec);
74
75static io_block_dev_spec_t boot_dev_spec;
76static int (*register_io_dev)(const io_dev_connector_t **);
77
78static io_block_spec_t fip_spec = {
79 .offset = PLAT_FIP_BASE,
80 .length = PLAT_FIP_MAX_SIZE,
81};
82
83struct plat_io_policy {
84 uintptr_t *dev_handle;
85 uintptr_t image_spec;
86 int (*check)(const uintptr_t spec);
87};
88
89static const struct plat_io_policy policies[] = {
90 [FIP_IMAGE_ID] = {
91 &boot_dev_handle,
92 (uintptr_t)&fip_spec,
93 check_dev
94 },
95 [BL2_IMAGE_ID] = {
96 &fip_dev_handle,
97 (uintptr_t)&bl2_uuid_spec,
98 check_fip
99 },
100 [BL31_IMAGE_ID] = {
101 &fip_dev_handle,
102 (uintptr_t)&bl31_uuid_spec,
103 check_fip
104 },
105 [BL33_IMAGE_ID] = {
106 &fip_dev_handle,
107 (uintptr_t) &bl33_uuid_spec,
108 check_fip
109 },
Jit Loon Limc5a3e3a2023-10-16 00:19:34 +0800110# if ARM_LINUX_KERNEL_AS_BL33 != 0
111 [NT_FW_CONFIG_ID] = {
112 &fip_dev_handle,
113 (uintptr_t)&nt_fw_config_uuid_spec,
114 check_fip
115 },
116# endif
Hadi Asyrafi616da772019-06-27 11:34:03 +0800117 [GPT_IMAGE_ID] = {
118 &boot_dev_handle,
119 (uintptr_t) &gpt_block_spec,
120 check_dev
121 },
122};
123
124static int check_dev(const uintptr_t spec)
125{
126 int result;
127 uintptr_t local_handle;
128
129 result = io_dev_init(boot_dev_handle, (uintptr_t)NULL);
130 if (result == 0) {
131 result = io_open(boot_dev_handle, spec, &local_handle);
132 if (result == 0)
133 io_close(local_handle);
134 }
135 return result;
136}
137
138static int check_fip(const uintptr_t spec)
139{
140 int result;
141 uintptr_t local_image_handle;
142
143 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
144 if (result == 0) {
145 result = io_open(fip_dev_handle, spec, &local_image_handle);
146 if (result == 0)
147 io_close(local_image_handle);
148 }
149 return result;
150}
151
152void socfpga_io_setup(int boot_source)
153{
154 int result;
155
156 switch (boot_source) {
157 case BOOT_SOURCE_SDMMC:
158 register_io_dev = &register_io_dev_block;
159 boot_dev_spec.buffer.offset = PLAT_MMC_DATA_BASE;
Jit Loon Limb24dddf2023-05-17 12:26:11 +0800160 boot_dev_spec.buffer.length = SOCFPGA_MMC_BLOCK_SIZE;
Jit Loon Lima7f54942023-05-17 12:26:11 +0800161 boot_dev_spec.ops.read = SDMMC_READ_BLOCKS;
162 boot_dev_spec.ops.write = SDMMC_WRITE_BLOCKS;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800163 boot_dev_spec.block_size = MMC_BLOCK_SIZE;
164 break;
165
166 case BOOT_SOURCE_QSPI:
167 register_io_dev = &register_io_dev_memmap;
Jit Loon Limb24dddf2023-05-17 12:26:11 +0800168 fip_spec.offset = PLAT_QSPI_DATA_BASE;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800169 break;
170
Jit Loon Limb24dddf2023-05-17 12:26:11 +0800171#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
172 case BOOT_SOURCE_NAND:
173 register_io_dev = &register_io_dev_mtd;
174 nand_dev_spec.ops.init = cdns_nand_init_mtd;
175 nand_dev_spec.ops.read = cdns_nand_read;
176 nand_dev_spec.ops.write = NULL;
177 fip_spec.offset = PLAT_NAND_DATA_BASE;
178 break;
179#endif
180
Hadi Asyrafi616da772019-06-27 11:34:03 +0800181 default:
182 ERROR("Unsupported boot source\n");
183 panic();
184 break;
185 }
186
187 result = (*register_io_dev)(&boot_dev_con);
188 assert(result == 0);
189
190 result = register_io_dev_fip(&fip_dev_con);
191 assert(result == 0);
192
Jit Loon Limb24dddf2023-05-17 12:26:11 +0800193 if (boot_source == BOOT_SOURCE_NAND) {
194 result = io_dev_open(boot_dev_con, (uintptr_t)&nand_dev_spec,
195 &boot_dev_handle);
196 } else {
197 result = io_dev_open(boot_dev_con, (uintptr_t)&boot_dev_spec,
198 &boot_dev_handle);
199 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800200 assert(result == 0);
201
202 result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);
203 assert(result == 0);
204
205 if (boot_source == BOOT_SOURCE_SDMMC) {
206 partition_init(GPT_IMAGE_ID);
207 fip_spec.offset = get_partition_entry(a2)->start;
208 }
209
210 (void)result;
211}
212
213int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
214 uintptr_t *image_spec)
215{
216 int result;
217 const struct plat_io_policy *policy;
218
219 assert(image_id < ARRAY_SIZE(policies));
220
221 policy = &policies[image_id];
222 result = policy->check(policy->image_spec);
223 assert(result == 0);
224
225 *image_spec = policy->image_spec;
226 *dev_handle = *(policy->dev_handle);
227
228 return result;
229}