blob: fc3c4a4f648978ad033f3a5f84fc8b98d0839828 [file] [log] [blame]
Pankaj Guptaba97e052020-12-09 14:02:40 +05301/*
2 * Copyright 2018-2020 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <assert.h>
9#include <string.h>
10
11#include <io_block.h>
12#include <io_driver.h>
13#include <io_fip.h>
14#include <io_memmap.h>
15#include <io_storage.h>
16#include <lib/utils.h>
17#include <tools_share/firmware_image_package.h>
18#include "ddr_io_storage.h"
19#include "plat_common.h"
20#include "platform_def.h"
21
22
23/* TBD - Move these defined to the platform_def.h file.
24 * Keeping them for reference here
25 */
26extern uintptr_t backend_dev_handle;
27
28static uint32_t ddr_fip;
29
30static uintptr_t ddr_fip_dev_handle;
31
32static io_block_spec_t ddr_fip_block_spec = {
33 .offset = PLAT_DDR_FIP_OFFSET,
34 .length = PLAT_DDR_FIP_MAX_SIZE
35};
36
37static const io_uuid_spec_t ddr_imem_udimm_1d_uuid_spec = {
38 .uuid = UUID_DDR_IMEM_UDIMM_1D,
39};
40
41static const io_uuid_spec_t ddr_imem_udimm_2d_uuid_spec = {
42 .uuid = UUID_DDR_IMEM_UDIMM_2D,
43};
44
45static const io_uuid_spec_t ddr_dmem_udimm_1d_uuid_spec = {
46 .uuid = UUID_DDR_DMEM_UDIMM_1D,
47};
48
49static const io_uuid_spec_t ddr_dmem_udimm_2d_uuid_spec = {
50 .uuid = UUID_DDR_DMEM_UDIMM_2D,
51};
52
53static const io_uuid_spec_t ddr_imem_rdimm_1d_uuid_spec = {
54 .uuid = UUID_DDR_IMEM_RDIMM_1D,
55};
56
57static const io_uuid_spec_t ddr_imem_rdimm_2d_uuid_spec = {
58 .uuid = UUID_DDR_IMEM_RDIMM_2D,
59};
60
61static const io_uuid_spec_t ddr_dmem_rdimm_1d_uuid_spec = {
62 .uuid = UUID_DDR_DMEM_RDIMM_1D,
63};
64
65static const io_uuid_spec_t ddr_dmem_rdimm_2d_uuid_spec = {
66 .uuid = UUID_DDR_DMEM_RDIMM_2D,
67};
68
69#if TRUSTED_BOARD_BOOT
70static const io_uuid_spec_t ddr_fw_key_cert_uuid_spec = {
71 .uuid = UUID_DDR_FW_KEY_CERT,
72};
73static const io_uuid_spec_t ddr_udimm_fw_cert_uuid_spec = {
74 .uuid = UUID_DDR_UDIMM_FW_CONTENT_CERT,
75};
76static const io_uuid_spec_t ddr_rdimm_fw_cert_uuid_spec = {
77 .uuid = UUID_DDR_RDIMM_FW_CONTENT_CERT,
78};
79#endif
80
81static int open_ddr_fip(const uintptr_t spec);
82
83struct plat_io_policy {
84 uintptr_t *dev_handle;
85 uintptr_t image_spec;
86 int (*check)(const uintptr_t spec);
87};
88
89/* By default, ARM platforms load images from the FIP */
90static const struct plat_io_policy ddr_policies[] = {
91 [DDR_FIP_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
92 &backend_dev_handle,
93 (uintptr_t)&ddr_fip_block_spec,
94 NULL
95 },
96 [DDR_IMEM_UDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
97 &ddr_fip_dev_handle,
98 (uintptr_t)&ddr_imem_udimm_1d_uuid_spec,
99 open_ddr_fip
100 },
101 [DDR_IMEM_UDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
102 &ddr_fip_dev_handle,
103 (uintptr_t)&ddr_imem_udimm_2d_uuid_spec,
104 open_ddr_fip
105 },
106 [DDR_DMEM_UDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
107 &ddr_fip_dev_handle,
108 (uintptr_t)&ddr_dmem_udimm_1d_uuid_spec,
109 open_ddr_fip
110 },
111 [DDR_DMEM_UDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
112 &ddr_fip_dev_handle,
113 (uintptr_t)&ddr_dmem_udimm_2d_uuid_spec,
114 open_ddr_fip
115 },
116 [DDR_IMEM_RDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
117 &ddr_fip_dev_handle,
118 (uintptr_t)&ddr_imem_rdimm_1d_uuid_spec,
119 open_ddr_fip
120 },
121 [DDR_IMEM_RDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
122 &ddr_fip_dev_handle,
123 (uintptr_t)&ddr_imem_rdimm_2d_uuid_spec,
124 open_ddr_fip
125 },
126 [DDR_DMEM_RDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
127 &ddr_fip_dev_handle,
128 (uintptr_t)&ddr_dmem_rdimm_1d_uuid_spec,
129 open_ddr_fip
130 },
131 [DDR_DMEM_RDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
132 &ddr_fip_dev_handle,
133 (uintptr_t)&ddr_dmem_rdimm_2d_uuid_spec,
134 open_ddr_fip
135 },
136#if TRUSTED_BOARD_BOOT
137 [DDR_FW_KEY_CERT_ID - DDR_FIP_IMAGE_ID] = {
138 &ddr_fip_dev_handle,
139 (uintptr_t)&ddr_fw_key_cert_uuid_spec,
140 open_ddr_fip
141 },
142 [DDR_UDIMM_FW_CONTENT_CERT_ID - DDR_FIP_IMAGE_ID] = {
143 &ddr_fip_dev_handle,
144 (uintptr_t)&ddr_udimm_fw_cert_uuid_spec,
145 open_ddr_fip
146 },
147 [DDR_RDIMM_FW_CONTENT_CERT_ID - DDR_FIP_IMAGE_ID] = {
148 &ddr_fip_dev_handle,
149 (uintptr_t)&ddr_rdimm_fw_cert_uuid_spec,
150 open_ddr_fip
151 },
152#endif
153};
154
155static int open_ddr_fip(const uintptr_t spec)
156{
157 int result;
158 uintptr_t local_image_handle;
159
160 /* See if a Firmware Image Package is available */
161 result = io_dev_init(ddr_fip_dev_handle, (uintptr_t)DDR_FIP_IMAGE_ID);
162 if (result == 0) {
163 result = io_open(ddr_fip_dev_handle, spec, &local_image_handle);
164 if (result == 0) {
165 VERBOSE("Using FIP\n");
166 io_close(local_image_handle);
167 }
168 }
169 return result;
170}
171
172/* The image can be one of the DDR PHY images, which can be sleected via DDR
173 * policies
174 */
175int plat_get_ddr_fip_image_source(unsigned int image_id, uintptr_t *dev_handle,
176 uintptr_t *image_spec,
177 int (*check)(const uintptr_t spec))
178{
179 int result = -1;
180 const struct plat_io_policy *policy;
181
182 if (image_id >= (DDR_FIP_IMAGE_ID + ARRAY_SIZE(ddr_policies))) {
183 return result;
184 }
185
186 policy = &ddr_policies[image_id - DDR_FIP_IMAGE_ID];
187 if (image_id == DDR_FIP_IMAGE_ID) {
188 result = check(policy->image_spec);
189 } else {
190 result = policy->check(policy->image_spec);
191 }
192 if (result == 0) {
193 *image_spec = policy->image_spec;
194 *dev_handle = *(policy->dev_handle);
195 }
196 return result;
197}
198
199int ddr_fip_setup(const io_dev_connector_t *fip_dev_con, unsigned int boot_dev)
200{
201 int io_result;
202 size_t ddr_fip_offset = PLAT_DDR_FIP_OFFSET;
203
204 /* Open connections to ddr fip and cache the handles */
205 io_result = io_dev_open(fip_dev_con, (uintptr_t)&ddr_fip,
206 &ddr_fip_dev_handle);
207 assert(io_result == 0);
208
209 switch (boot_dev) {
210#if QSPI_BOOT
211 case BOOT_DEVICE_QSPI:
212 ddr_fip_offset += NXP_QSPI_FLASH_ADDR;
213 break;
214#endif
215#if NOR_BOOT
216 case BOOT_DEVICE_IFC_NOR:
217 ddr_fip_offset += NXP_NOR_FLASH_ADDR;
218 break;
219#endif
220#if FLEXSPI_NOR_BOOT
221 case BOOT_DEVICE_FLEXSPI_NOR:
222 ddr_fip_offset += NXP_FLEXSPI_FLASH_ADDR;
223 break;
224#endif
225 default:
226 break;
227 }
228
229 ddr_fip_block_spec.offset = ddr_fip_offset;
230
231 return io_result;
232}