blob: 5fe4dbdfd32bb0e86d2663ab8cc5bbe3e83d0f3c [file] [log] [blame]
Ang, Chee Hongdcc3bb62018-12-19 18:35:14 -08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2018 Intel Corporation <www.intel.com>
4 */
5
Ang, Chee Hongdcc3bb62018-12-19 18:35:14 -08006#include <altera.h>
Simon Glass0f2af882020-05-10 11:40:05 -06007#include <log.h>
Tom Rinidec7ea02024-05-20 13:35:03 -06008#include <time.h>
Chee Hong Ang4e87fcd2020-08-07 11:50:04 +08009#include <watchdog.h>
Ang, Chee Hongdcc3bb62018-12-19 18:35:14 -080010#include <asm/arch/mailbox_s10.h>
Chee Hong Angec4c6792020-12-24 18:21:07 +080011#include <asm/arch/smc_api.h>
Simon Glassdbd79542020-05-10 11:40:11 -060012#include <linux/delay.h>
Tom Rinidec7ea02024-05-20 13:35:03 -060013#include <linux/errno.h>
Chee Hong Angec4c6792020-12-24 18:21:07 +080014#include <linux/intel-smc.h>
Tom Rinidec7ea02024-05-20 13:35:03 -060015#include <linux/string.h>
Ang, Chee Hongdcc3bb62018-12-19 18:35:14 -080016
17#define RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS 60000
18#define RECONFIG_STATUS_INTERVAL_DELAY_US 1000000
19
Simon Glass7ec24132024-09-29 19:49:48 -060020#if !defined(CONFIG_XPL_BUILD) && defined(CONFIG_SPL_ATF)
Chee Hong Angec4c6792020-12-24 18:21:07 +080021
22#define BITSTREAM_CHUNK_SIZE 0xFFFF0
23#define RECONFIG_STATUS_POLL_RETRY_MAX 100
24
Boon Khai Ng483a1bb2025-01-17 14:33:31 +080025static const struct mbox_cfgstat_major_err {
26 int err_no;
27 const char *error_name;
28} mbox_cfgstat_major_err[] = {
29 {MBOX_CFGSTATE_MAJOR_ERR_WRONG_BL31_VER,
30 "Please check ATF BL31 version, require v2.11 above to print more error status."},
31 {MBOX_CFGSTATE_MAJOR_ERR_STATE_CONFIG,
32 "Mailbox in configuration state."},
33 {MBOX_CFGSTATE_MAJOR_ERR_BITSTREAM_ERR,
34 "Bitstream Invalid."},
35 {MBOX_CFGSTATE_MAJOR_ERR_EXT_HW_ACCESS_FAIL,
36 "External HW access failure."},
37 {MBOX_CFGSTATE_MAJOR_ERR_BITSTREAM_CORRUPTION,
38 "Bitstream valid but corrupted. Bitstream corruption error when reading the bitstream from the source."
39 },
40 {MBOX_CFGSTATE_MAJOR_ERR_INTERNAL_ERR,
41 "Bitstream element not understood. Internal error."},
42 {MBOX_CFGSTATE_MAJOR_ERR_DEVICE_ERR,
43 "Unable to communicate on internal configuration network. Device operation error."},
44 {MBOX_CFGSTATE_MAJOR_ERR_HPS_WDT,
45 "HPS Watchdog Timer. HPS watchdog timeout failure."},
46 {MBOX_CFGSTATE_MAJOR_ERR_INTERNAL_UNKNOWN_ERR,
47 "Other unknown error occurred"},
48 {MBOX_CFGSTATE_MAJOR_ERR_SYSTEM_INIT_ERR,
49 "Error before main CMF start. System initialization failure."},
50 {MBOX_CFGSTATE_MAJOR_ERR_DECRYPTION_ERR,
51 "Decryption Error."},
52 {MBOX_CFGSTATE_MAJOR_ERR_VERIFY_IMAGE_ERR,
53 "Verify image error."},
54 {MBOX_CFGSTATE_MAJOR_ERR_UNK,
55 "Unknown error number at major field!"}
56};
57
58#define MBOX_CFGSTAT_MAJOR_ERR_MAX ARRAY_SIZE(mbox_cfgstat_major_err)
59
60static const struct mbox_cfgstat_minor_err {
61 int err_no;
62 const char *error_name;
63} mbox_cfgstat_minor_err[] = {
64 {MBOX_CFGSTATE_MINOR_ERR_BASIC_ERR,
65 "Catchall Error."},
66 {MBOX_CFGSTATE_MINOR_ERR_CNT_RESP_ERR,
67 "Detected an error during configuration. Detected an error during configuration."
68 },
69 {MBOX_CFGSTATE_MINOR_ERR_QSPI_DEV_ERR,
70 "QSPI Device related error. Detected QSPI device related error during configuration."
71 },
72 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_INV,
73 "Bitstream section main descriptor invalid. Detected an error during configuration due to a corrupted bitstream."
74 },
75 {MBOX_CFGSTATE_MINOR_ERR_BS_INCOMPATIBLE,
76 "Bistream not compatible with device. Detected an error during configuration due to incompatible bitstream with the device."
77 },
78 {MBOX_CFGSTATE_MINOR_ERR_BS_INV_SHA,
79 "Bitstream invalid SHA setting. Detected an error during configuration due to a corrupted bitstream."
80 },
81 {MBOX_CFGSTATE_MINOR_ERR_ROUTE_FAIL,
82 "Bitstream processing route failed. Detected an error during configuration due to a corrupted bitstream."
83 },
84 {MBOX_CFGSTATE_MINOR_ERR_GO_BIT_ALREADY_SET,
85 "Failed DMA during bitstream processing. Detected an error during configuration due to a corrupted bitstream."
86 },
87 {MBOX_CFGSTATE_MINOR_ERR_CPU_BLK_FAIL,
88 "Failed DMA during bitstream processing. Detected an error during configuration."
89 },
90 {MBOX_CFGSTATE_MINOR_ERR_ACT_SKIP_FAIL,
91 "Skip action failed. Detected an error during configuration."},
92 {MBOX_CFGSTATE_MINOR_ERR_ACT_MCAST_FAIL,
93 "Multicast Action Failed. Detected an error during configuration."},
94 {MBOX_CFGSTATE_MINOR_ERR_ACT_IND_SZ_FAIL,
95 "Index Size Action Failed. Detected an error during configuration."},
96 {MBOX_CFGSTATE_MINOR_ERR_ACT_IF_FAIL,
97 "If Action Failed. Detected an error during configuration."},
98 {MBOX_CFGSTATE_MINOR_ERR_ACT_PIN_FAIL,
99 "Pin Action Failed. Detected an error during configuration."},
100 {MBOX_CFGSTATE_MINOR_ERR_ACT_FUSEFLTR_FAIL,
101 "Fuse Filter Action Failed. Detected an error during configuration."},
102 {MBOX_CFGSTATE_MINOR_ERR_ACT_GENERIC_FAIL,
103 "Other Action Failed. Detected an error during configuration."},
104 {MBOX_CFGSTATE_MINOR_ERR_DATA_STARVE_ERR,
105 "Datapath starved. Detected an error during configuration."},
106 {MBOX_CFGSTATE_MINOR_ERR_CNT_RAM_INIT_FAIL,
107 "CNT/SSM RAM Initialization Failed. Detected an error during configuration."},
108 {MBOX_CFGSTATE_MINOR_ERR_ACT_SETUP_S4,
109 "S4 Setup Failed. Detected an error during configuration."},
110 {MBOX_CFGSTATE_MINOR_ERR_WIPE_DATA_STARVE,
111 "Datapath starved during wipe. Detected an error during configuration."},
112 {MBOX_CFGSTATE_MINOR_ERR_FUSE_RD_FAIL,
113 "eFUSE Read Failure. Detected an error during configuration."},
114 {MBOX_CFGSTATE_MINOR_ERR_AUTH_FAIL,
115 "Authentication Failure. Detected a bitstream authentication error during configuration."
116 },
117 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_SHA_FAIL,
118 "Bitstream Section Main Descriptor Hash Check Failed. Detected an error during configuration due to a corrupted bitstream."
119 },
120 {MBOX_CFGSTATE_MINOR_ERR_SKIP_DATA_RAM_FAIL,
121 "Skip Action Failed. Detected an error during configuration."},
122 {MBOX_CFGSTATE_MINOR_ERR_ACT_FIXED_FAIL,
123 "Fixed Action Failed. Detected an error during configuration."},
124 {MBOX_CFGSTATE_MINOR_ERR_ACT_MCAST_FLTR_FAIL,
125 "Multicast Filter Action Failed. Detected an error during configuration."},
126 {MBOX_CFGSTATE_MINOR_ERR_ACT_SECTOR_FAIL,
127 "Sector Group Action Failed. Detected an error during configuration."},
128 {MBOX_CFGSTATE_MINOR_ERR_ACT_HASH_FAIL,
129 "Hash Action Failed. Detected an error during configuration."},
130 {MBOX_CFGSTATE_MINOR_ERR_ACT_DECOMP_SETUP_FAIL,
131 "Decompression Setup Action Failed. Detected an error during configuration."},
132 {MBOX_CFGSTATE_MINOR_ERR_INTERNAL_OS_ERR,
133 "RTOS Error. Detected an error during configuration."},
134 {MBOX_CFGSTATE_MINOR_ERR_WIPE_FAIL,
135 "Wipe Bitstream Failed. Detected an error during configuration."},
136 {MBOX_CFGSTATE_MINOR_ERR_CNOC_ERR,
137 "Internal Configuration Network Failure. Detected an error during configuration."
138 },
139 {MBOX_CFGSTATE_MINOR_ERR_PMF_RESUME_FAIL,
140 "Power Management Firmware Failed Resume. Detected an error during configuration."
141 },
142 {MBOX_CFGSTATE_MINOR_ERR_PMF_RUN_FAIL,
143 "Power Management Firmware Failed Run. Detected an error during configuration."},
144 {MBOX_CFGSTATE_MINOR_ERR_PMF_PAUSE_FAIL,
145 "Power Management Firmware Failed Pause. Detected an error during configuration."
146 },
147 {MBOX_CFGSTATE_MINOR_ERR_RET_INT_ASSERT_FAIL,
148 "Internal Configuration Network Return Interrupt Failure. Detected an error during configuration."
149 },
150 {MBOX_CFGSTATE_MINOR_ERR_STATE_MACHINE_ERR,
151 "Configuration State Machine Error. Detected an error during configuration."},
152 {MBOX_CFGSTATE_MINOR_ERR_CMF_TRANSITION_FAIL,
153 "Error during CMF load/reload. Detected a firmware transition error during configuration."
154 },
155 {MBOX_CFGSTATE_MINOR_ERR_SHA_SETUP_FAIL,
156 "Error setting up SHA engine. Detected an error during configuration."},
157 {MBOX_CFGSTATE_MINOR_ERR_WR_DMA_TIMEOUT,
158 "Write DMA timed out. Detected an error during configuration."},
159 {MBOX_CFGSTATE_MINOR_ERR_MEM_ALLOC_FAIL,
160 "Out of Memory. Detected an error during configuration."},
161 {MBOX_CFGSTATE_MINOR_ERR_SYNC_RD_FAIL,
162 "Sync Block Read Fail. Detected an error during configuration."},
163 {MBOX_CFGSTATE_MINOR_ERR_CHK_CFG_REQ_FAIL,
164 "Configuration Status Check Failed. Detected an error during configuration."},
165 {MBOX_CFGSTATE_MINOR_ERR_HPS_CFG_REQ_FAIL,
166 "HPS Configuration Request Failed. Detected an error during configuration."},
167 {MBOX_CFGSTATE_MINOR_ERR_CFG_HANDLE_ERR,
168 "Driver Handle Error. Detected an error during configuration."},
169 {MBOX_CFGSTATE_MINOR_ERR_INV_ACTION_ITEM,
170 "Bistream contains invalid action. Detected an error during configuration."},
171 {MBOX_CFGSTATE_MINOR_ERR_SKIP_DATA_PREBUF_ERR,
172 "Prebuffer Error during Skip Action. Detected an error during configuration."},
173 {MBOX_CFGSTATE_MINOR_ERR_MBOX_TIMEOUT,
174 "Mailbox Processing Timeout. Detected an error during configuration."},
175 {MBOX_CFGSTATE_MINOR_ERR_AVST_FIFO_OVERFLOW_ERR,
176 "AVST FIFO Overflow. Detected an error during configuration."},
177 {MBOX_CFGSTATE_MINOR_ERR_RD_DMA_TIMEOUT,
178 "Read DMA timed out. Detected an error during configuration."},
179 {MBOX_CFGSTATE_MINOR_ERR_PMF_INIT_ERR,
180 "Power Management Firmware Initialization Error. Detected a PMBUS error during configuration."
181 },
182 {MBOX_CFGSTATE_MINOR_ERR_PMF_SHUTDOWN_ERR,
183 "Power Management Firmware Shutdown Error. Detected a PMBUS error during configuration."
184 },
185 {MBOX_CFGSTATE_MINOR_ERR_BITSTREAM_INTERRUPTED,
186 "Bitstream processing was interrupted by another event. Detected an error during configuration."
187 },
188 {MBOX_CFGSTATE_MINOR_ERR_FPGA_MBOX_WIPE_TIMEOUT,
189 "Mailbox Wipe Timeout. Detected an error during configuration."},
190 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_TYPE_INV,
191 "Bitstream Section Main Descriptor Type is Invalid. Detected an error during configuration due to a corrupted bitstream."
192 },
193 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_VERSION_INV,
194 "Bitstream Section Main Descriptor Version is Invalid. Detected an error during configuration due to a corrupted bitstream."
195 },
196 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_DEVICE_TYPE_INV,
197 "Bitstream Section Main Descriptor Device is Invalid. Detected an error during configuration due to a corrupted bitstream."
198 },
199 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_DESIGN_HASH_ERR,
200 "Bitstream Section Main Descriptor Hash Mismatch. Detected an error during configuration due to a corrupted bitstream."
201 },
202 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_EXT_REF_CLK_ERR,
203 "Bitstream Section Main Descriptor External Clock Setting Invalid. Detected an error during configuration due to a corrupted bitstream."
204 },
205 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_PWR_TBL_INV,
206 "Bitstream Section Main Descriptor Power Table is invalid. Detected an error during configuration due to a corrupted bitstream."
207 },
208 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_PIN_TBL_OFST_ERR,
209 "Bitstream Section Main Descriptor Offset to Pin Table is Invalid. Detected an error during configuration due to a corrupted bitstream."
210 },
211 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_PIN_TBL_INV,
212 "Bitstream Section Main Descriptor Pin Table is Invalid. Detected an error during configuration due to a corrupted bitstream."
213 },
214 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_NO_PIN_TBL,
215 "Bitstream Section Main Descriptor missing pin table. Detected an error during configuration due to a corrupted bitstream."
216 },
217 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_CFG_CLK_PLL_FAILED,
218 "Bitstream Section Main Descriptor PLL setting failure. Detected an error during configuration due to a corrupted bitstream."
219 },
220 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_AS_CLK_FAILED,
221 "Bitstream Section Main Descriptor QSPI Clock Setting Failure. Detected an error during configuration due to a corrupted bitstream."
222 },
223 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_POF_ID_FAILED,
224 "Bitstream Section Main Descriptor POF ID not valid. Detected an incompatible PR bitstream during configuration."
225 },
226 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_PW_TBL_OFST_ERR,
227 "code not used."},
228 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_PP_TBL_OFST_ERR,
229 "code not used."},
230 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_PP_TBL_INV,
231 "code not used."},
232 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_SP_TBL_OFST_ERR,
233 "code not used."},
234 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_SP_TBL_INV,
235 "code not used."},
236 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_SU_TBL_OFST_ERR,
237 "code not used."},
238 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_SU_TBL_INV,
239 "code not used."},
240 {MBOX_CFGSTATE_MINOR_ERR_MBOX_TASK_CRYPTO_SRC_CLR_ERR,
241 "Mailbox Source Failed to Clear. Detected an error during configuration."},
242 {MBOX_CFGSTATE_MINOR_ERR_MBOX_TASK_EVENT_GROUP_POST_ERR,
243 "Mailbox Event Post Error. Detected an error during configuration."},
244 {MBOX_CFGSTATE_MINOR_ERR_TRNG_TEST_FAIL,
245 "True Random Number Generator Failed Test. Detected an error during configuration."
246 },
247 {MBOX_CFGSTATE_MINOR_ERR_MBOX_TASK_ANTI_DOS_TMR_INIT_ERR,
248 "Mailbox Anti-DOS Timer failed initialization. Detected an error during configuration."
249 },
250 {MBOX_CFGSTATE_MINOR_ERR_OS_STK_CHK_ERR,
251 "RTOS Stack Check Error. Detected an error during configuration."},
252 {MBOX_CFGSTATE_MINOR_ERR_MBOX_TASK_INIT,
253 "Mailbox Task failed to initialize. Detected an error during configuration."},
254 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_COMPAT_ID_MATCH_ERR,
255 "Bitstream Section Main Descriptor Compatibility ID mismatch. Detected a bitstream error during configuration."
256 },
257 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_COMPAT_ID_INV,
258 "Bitstream Section Main Descriptor Compatibility ID not Valid. Detected an error during configuration due to a corrupted bitstream."
259 },
260 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_AES_ECRYPT_CHK_FAIL,
261 "Bitstream Section Main Descriptor AES Test Failed. Detected an error during configuration due to a corrupted bitstream."
262 },
263 {MBOX_CFGSTATE_MINOR_ERR_ACT_KEY_FAIL,
264 "Key Action Failure. Detected a bitstream decryption error during configuration due to a corrupted bitstream."
265 },
266 {MBOX_CFGSTATE_MINOR_ERR_ACT_KEY_CHALLENGE_FAIL,
267 "Key Challenge Failure. Detected a bitstream decryption error during configuration."
268 },
269 {MBOX_CFGSTATE_MINOR_ERR_MBOX_TASK_MSGQ_DEQUEUE_FAIL,
270 "Mailbox Task Queue failed to dequeue. Detected an error during configuration."},
271 {MBOX_CFGSTATE_MINOR_ERR_SECT_COMPAT_CHK_ERR,
272 "Bitstream Section Compatibility Check Error. Detected an error during configuration due to a corrupted bitstream."
273 },
274 {MBOX_CFGSTATE_MINOR_ERR_SECT_COMPAT_UPDATE_ERR,
275 "Bitstream Section Compatibility Update Error. Detected an error during configuration due to a corrupted bitstream."
276 },
277 {MBOX_CFGSTATE_MINOR_ERR_SECT_SEC_CHK_FAILED,
278 "Bitstream Section Security Check Failed. Detected an error during configuration due to a corrupted bitstream."
279 },
280 {MBOX_CFGSTATE_MINOR_ERR_CNT_RAM_ECC_ERR_UNRECOVERABLE,
281 "Unrecoverable Error in CNT/SSM RAM. Detected an error during configuration."},
282 {MBOX_CFGSTATE_MINOR_ERR_MBOX_REFORMAT_INPUT_ERR,
283 "Mailbox Input Processing Error. Detected an error during configuration."},
284 {MBOX_CFGSTATE_MINOR_ERR_MBOX_REFORMAT_OUTPUT_ERR,
285 "Mailbox Output Processing Error. Detected an error during configuration."},
286 {MBOX_CFGSTATE_MINOR_ERR_MBOX_WLBL_ERR,
287 "(Provision only) Provision CMF's allowed mailbox cmd group is invalid. Detected an error during configuration."
288 },
289 {MBOX_CFGSTATE_MINOR_ERR_MBOX_HOOK_CB_ERR,
290 "Mailbox Callback Error. Detected an error during configuration."},
291 {MBOX_CFGSTATE_MINOR_ERR_CMF_RLD_DECOMP_LOAD_ERR,
292 "CMF Reload failed to load Decompression Code. Detected an error during configuration."
293 },
294 {MBOX_CFGSTATE_MINOR_ERR_CMF_RLD_DECOMP_RUN_ERR,
295 "CMF Reload failed to run Decompression Code. Detected an error during configuration."
296 },
297 {MBOX_CFGSTATE_MINOR_ERR_CNT_PERIPH_ECC_ERR_UNRECOVERABLE,
298 "Unrecoverable Error in CNT/SSM Peripheral. Detected an error during configuration."
299 },
300 {MBOX_CFGSTATE_MINOR_ERR_MAIN_SECT_ADDR_ERR,
301 "(Provision only) invalid Flash image CMF header's main section address. Detected an error during configuration."
302 },
303 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_SCRAMBLE_RATIO_CHK_FAIL,
304 "Bitstream Section Main Descriptor Invalid Scrambler Ratio. Detected an error during configuration due to a corrupted bitstream."
305 },
306 {MBOX_CFGSTATE_MINOR_ERR_TAMPER_EVENT_TRIGGERED,
307 "Tamper Detected. Detected an error during configuration."},
308 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_ANTI_TAMPER_TBL_INV,
309 "Bitstream Section Main Descriptor Anti Tamper Table Invalid. Detected an error during configuration due to a corrupted bitstream."
310 },
311 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_EXT_CLCK_MODE_DISALLOWED,
312 "External Clock info presented, but external clock not allowed on device. Detected an error during configuration due to a corrupted bitstream."
313 },
314 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_SEC_OPTIONS_INIT_FAIL,
315 "Bitstream Section Main Descriptor Security Option Initialization Failed. Detected an error during configuration due to a corrupted bitstream."
316 },
317 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_EN_USR_CAN_FUSE_INV,
318 "User cancellation fuse table initialization failed. Detected an error during configuration."
319 },
320 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_AS_DEVICE_NO_SGX_ERR,
321 "Not yet turned on for Rearch code. Detected an incompatible bitstream during configuration. You cannot use the bitstream from an advanced security-enabled devices on a non-advanced security-enabled device."
322 },
323 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_POF_ID_LIMIT_EXCEED_ERR,
324 "Not yet turned on for Rearch code. Detected an invalid bitstream during configuration."
325 },
326 {MBOX_CFGSTATE_MINOR_ERR_PROVISION_CMF_INV_STATE,
327 "(Provision only) Internal state machine wrong state. Detected an error during configuration."
328 },
329 {MBOX_CFGSTATE_MINOR_ERR_PROVISION_CMF_FATAL_ERR,
330 "(Provision only) Fatal error detected with Provision CMF. Detected an error during configuration."
331 },
332 {MBOX_CFGSTATE_MINOR_ERR_PROVISION_CMF_SM_EXIT_FAIL,
333 "(Provision only) State machine's state function exit error. Detected an error during configuration."
334 },
335 {MBOX_CFGSTATE_MINOR_ERR_PROVISION_CMF_SM_ENTRY_FAIL,
336 "(Provision only) State machine's state function entry error. Detected an error during configuration."
337 },
338 {MBOX_CFGSTATE_MINOR_ERR_ACTION_DATA_UNSUPPORTED_CTX,
339 "Not yet turned on for Rearch code. Detected an error during configuration."},
340 {MBOX_CFGSTATE_MINOR_ERR_CMF_EXCEPTION,
341 "Processor Exception. Detected an error during configuration."},
342 {MBOX_CFGSTATE_MINOR_ERR_ECC_INIT_FAIL,
343 "SDM Peripheral ECC Initialization Failure. Detected an error during configuration."
344 },
345 {MBOX_CFGSTATE_MINOR_ERR_DEFAULT_UNREGISTERED_ISR,
346 "Unregistered Interrupt Occurred. Detected an error during configuration."},
347 {MBOX_CFGSTATE_MINOR_ERR_GENERAL_TIMEOUT,
348 "Execution Timeout. Detected an error during configuration."},
349 {MBOX_CFGSTATE_MINOR_ERR_ACT_OPERATION_CLK_FAIL,
350 "Clock Operation Action Failed. Detected an error during configuration."},
351 {MBOX_CFGSTATE_MINOR_ERR_ACT_VERIFY_HASH_FAIL,
352 "Verify Hash Action Failed. Detected an error during configuration."},
353 {MBOX_CFGSTATE_MINOR_ERR_CFG_STATE_UPDATE_ERR,
354 "Error updating configuration state. Detected an error during configuration."},
355 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_READ_DDR_HASH_FAIL,
356 "Error while reading HPS DDR hash from main descriptor."},
357 {MBOX_CFGSTATE_MINOR_ERR_CVP_FLOW_ERR,
358 "Error during CvP Phase 2 data flow handling or handshake."},
359 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_KEYED_HASH_ERR,
360 "Encountered keyed hash error while processing a main descriptor."},
361 {MBOX_CFGSTATE_MINOR_ERR_CMF_DESC_BAD_JTAG_ID,
362 "New CMF Descriptor JTAG ID mismatch with original configured CMF JTAG ID."
363 },
364 {MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_PMF_NOT_SUPPORTED,
365 "The IO Descriptor contains a power table but the current CMF does not support PMF. Bitstream incompatile with Firmware."
366 },
367 {
368 MBOX_CFGSTATE_MINOR_ERR_MAIN_DESC_ANTI_TAMPER_NOT_SUPPORTED,
369 "The IO Descriptor contains anti-tamper setting but the current CMF does not support anti-tamper. Bitstream incompatile with Firmware."
370 },
371 {MBOX_CFGSTATE_MINOR_ERR_ACT_RECOVERY_FAIL,
372 "Recovery Action Failed. Detected an error during configuration."},
373 {MBOX_CFGSTATE_MINOR_ERR_COLD_RESET_CMF_CORRUPTED,
374 "Error when process CMF section after cold reset. Detected CMF section error or incompatible upon cold reset using JTAG or AVST."
375 },
376 {MBOX_CFGSTATE_MINOR_ERR_COLD_RESET_IO_HPS_CORRUPTED,
377 "Error when process IO/HPIO/HPS section after cold reset and hps wipe. Detected an error when try to bring up HPS again after cold reset."
378 },
379 {MBOX_CFGSTATE_MINOR_ERR_COLD_RESET_FPGA_CORRUPTED,
380 "Error when process FPGA section header after cold reset. Detected an error in FPGA after successfully bring up HPS."
381 },
382 {MBOX_CFGSTATE_MINOR_ERR_CRC_CHK_FAIL,
383 " CRC32 Check Fail. Detected an error during configuration."},
384 {MBOX_CFGSTATE_MINOR_ERR_COMPAT_TBL_SFIXED_VALUE_INV,
385 "Error when process compatibility table in main section header. SFixed offset value in compatibility table is not valid."
386 },
387 {
388 MBOX_CFGSTATE_MINOR_ERR_FEATURE_EN_FUSE_NOT_BLOWN,
389 "Error bitstream contains feature(s) that are only allowed when a feature fuse is blown on the device, and the device did not have the feature fuse blown. Bitstream requires feature enable fuse to be blown."
390 },
391 {MBOX_CFGSTATE_MINOR_ERR_UIB_REFCLK_MISSING,
392 "UIB REFCLK missing. Device requires refclk to proceed configuration."},
393 {MBOX_CFGSTATE_MINOR_ERR_UIB_REFCLK_TIMEOUT,
394 "UIB REFCLK timeout. Device requires refclk to proceed configuration."},
395 {MBOX_CFGSTATE_MINOR_ERR_UIB_REFCLK_TIMEOUT_MISSING,
396 "UIB REFCLK missing and timeout. Device requires refclk to proceed configuration."
397 },
398 {MBOX_CFGSTATE_MINOR_ERR_TRAMP_SYNC_BLCK_ERR,
399 "Sync block before SSBL processing failure. Detected a firmware error during reconfiguration."
400 },
401 {MBOX_CFGSTATE_MINOR_ERR_TRAMP_SSBL_SHA_ERR,
402 "SSBL sha mismatch with bitstream. Detected a bitstream error during reconfiguration."
403 },
404 {MBOX_CFGSTATE_MINOR_ERR_TRAMP_BLCK0_SHA_MISMATCH_ERR,
405 "Block0 Sha mismatch when trampoline reloads. Detected a bitstream error during reconfiguration."
406 },
407 {MBOX_CFGSTATE_MINOR_ERR_TRAMP_BLCK0_AUTH_ERR,
408 "Trampoline authentication failure. Detected a bitstream error during reconfiguration."
409 },
410 {MBOX_CFGSTATE_MINOR_ERR_TRAMP_TRAMP_LOAD_ERR,
411 "Trampoline Load compressed tramp failure. Detected a bitstream error during reconfiguration."
412 },
413 {MBOX_CFGSTATE_MINOR_ERR_TRAMP_CMF_SIZE_ERR,
414 "Trampoline failed to retrieve SSBL or TSBL load information. Detected a bitstream error during reconfiguration."
415 },
416 {MBOX_CFGSTATE_MINOR_ERR_TRAMP_TRANSITION_ERR,
417 "Trampoline failed to find a bootable DCMF. Detected an error during application images transition."
418 },
419 {MBOX_CFGSTATE_MINOR_ERR_TRAMP_SYNC_ERR,
420 "Only used by RMA and ENG loader on legacy code. Detected an error during configuration."
421 },
422 {MBOX_CFGSTATE_MINOR_ERR_TRAMP_LOAD_CERT_ERR,
423 "Main CMF failed to authenticate a certificate bitstream. Detected a bitstream authentication error during reconfiguration."
424 },
425 {MBOX_CFGSTATE_MINOR_ERR_TRAMP_LOAD_NOT_ALLOWED_ERR,
426 "Only used by Provision CMF, failure to initialize HW drivers. Detected an error during reconfiguration."
427 },
428 {MBOX_CFGSTATE_MINOR_ERR_TRAMP_FUSE_ERR,
429 "Only used by RMA and Eng loader on Legacy code. Detected an error during configuration."
430 },
431 {MBOX_CFGSTATE_MINOR_ERR_TRAMP_INPUT_BUFFER_ERR,
432 "Provision CMF only, Trampoline inbuf HW access error. Detected a hardware error during reconfiguration."
433 },
434 {MBOX_CFGSTATE_MINOR_ERR_TRAMP_CMF_TYPE_ERR,
435 "Trampoline/DCMF loading another CMF andfound CMF type mismatched with current one. Detected a bitstream error during reconfiguration."
436 },
437 {MBOX_CFGSTATE_MINOR_ERR_TRAMP_QSPI_INDR_READ_START_ERR,
438 "Trampoline QSPI indirect read start error. Detected an error when accessing the QSPI flash."
439 },
440 {MBOX_CFGSTATE_MINOR_ERR_PMF_I2C_COMM_ERR,
441 "Generic I2C error, ie Bad Address."},
442 {MBOX_CFGSTATE_MINOR_ERR_PMF_TARGET_VOLTAGE_ERR,
443 "Failed to reach Target Voltage. Voltage Regulator unable to achieve the requested voltage."
444 },
445 {MBOX_CFGSTATE_MINOR_ERR_PMF_HANDSHAKE_ERR,
446 "Slave Mode ALERT/VOUT_COMMAND handshake did not happen."},
447 {MBOX_CFGSTATE_MINOR_ERR_PMF_ITD_OUT_OF_RANGE_ERR,
448 "Fuse values calculated voltage greater that cutoff max. ITD fuse is out of range."
449 },
450 {MBOX_CFGSTATE_MINOR_ERR_PMF_PWR_TABLE_ERR,
451 "Error while reading or processing the Power Table. Internal Error while reading or decoding the Bitstream's Power Table."
452 },
453 {MBOX_CFGSTATE_MINOR_ERR_PMF_EFUSE_DECODE_ERR,
454 "Error while reading or decoding the efuse values. Internal Error while reading or decoding the efuse values."
455 },
456 {MBOX_CFGSTATE_MINOR_ERR_PMF_VCCL_PWRGOOD_ERR,
457 "Failed to verify the vccl power is good. Failed to validate the vccl power is valid on the board."
458 },
459 {MBOX_CFGSTATE_MINOR_ERR_PMF_CLR_FAULTS_ERR,
460 "Error while sending CLEAR_FAULTS command. Error while sending CLEAR_FAULTS command,"
461 },
462 {MBOX_CFGSTATE_MINOR_ERR_PMF_VOUT_MODE_ERR,
463 "Error while sending VOUT_MODE command. Error while sending VOUT_MODE command,"},
464 {MBOX_CFGSTATE_MINOR_ERR_PMF_PAGE_COMMAND_ERR,
465 "Error while sending PAGE_COMMAND command. Error while sending PAGE_COMMAND command,"
466 },
467 {MBOX_CFGSTATE_MINOR_ERR_PMF_VOUT_COMMAND_ERR,
468 "Error while sending VOUT_COMMAND command. Error while sending VOUT_COMMAND command,"
469 },
470 {MBOX_CFGSTATE_MINOR_ERR_PMF_READ_VOUT_ERR,
471 "Error while sending READ_VOUT command. Error while sending READ_VOUT command,"},
472 {MBOX_CFGSTATE_MINOR_ERR_PMF_LTM4677_DEFAULT_ADC_CTRL_ERR,
473 "Error while sending the vendor specific LTM4677 MFR_ADC_CTRL command. Error while sending the vendor specific LTM4677 MFR_ADC_CTRL command,"
474 },
475 {MBOX_CFGSTATE_MINOR_ERR_PMF_FIRST_I2C_CMD_FAILED_ERR,
476 "First I2C messaged failed, ie Bad Address. The first I2C command has failed, no response from Voltage Regulator."
477 },
478 {MBOX_CFGSTATE_MINOR_ERR_RSU_CMF_AUTH_ERR,
479 "Failed to authenticate CMF section. Detected a firmware authentication error during configuration."
480 },
481 {MBOX_CFGSTATE_MINOR_ERR_RSU_USER_AUTH_ERR,
482 "Failed to authenticate USER section. Detected a bitstream authentication error during configuration."
483 },
484 {MBOX_CFGSTATE_MINOR_ERR_RSU_CMF_DESC_SHA_MISMATCH,
485 "Block0 SHA mismatch when DCMF loads an APP image. Detected an error when loading the application image from flash."
486 },
487 {MBOX_CFGSTATE_MINOR_ERR_RSU_POINTERS_NOT_FOUND_ERR,
488 "RSU CPB table parsing failed. Detected an error when parsing the RSU CPB block."
489 },
490 {MBOX_CFGSTATE_MINOR_ERR_RSU_QSPI_FREQ_CHANGE,
491 "QSPI reference clock freq update failed. Detected an error during configuration."
492 },
493 {MBOX_CFGSTATE_MINOR_ERR_RSU_FACTORY_IMG_FAILED,
494 "RSU factory image failed to boot. Detected an error when loading the factory image. Check the factory image validity. If corrupted, regenerate and reprogram again the factory image in the flash. When authentication enabled,"
495 },
496 {MBOX_CFGSTATE_MINOR_ERR_RSU_CMF_TYPE_ERR,
497 "APP image CMF type mismatched with DCMF. Detected an error when loading the application image."
498 },
499 {
500 MBOX_CFGSTATE_MINOR_ERR_RSU_UCMF_SIG_DESC_ERR,
501 "UCMF reports failure in parsing of an signature block, can be from new DCMF, new DCIO or new Factory. Detected an error during factory image update in flash."
502 },
503 {MBOX_CFGSTATE_MINOR_ERR_RSU_UCMF_INTERNAL_AUTH_ERR,
504 "UCMF reports authentication failure of new DCMF, new DCIO or new Factory. Detected an error during DCMF update in flash."
505 },
506 {MBOX_CFGSTATE_MINOR_ERR_RSU_UCMF_COPY_FAILED,
507 "UCMF reports QSPI flash write failure while upgrading DCMF, DCIO or Factory. Detected an error during DCMF update in flash."
508 },
509 {MBOX_CFGSTATE_MINOR_ERR_RSU_UCMF_ERASE_FAILED,
510 "UCMF reports QSPI flash erase failure while upgrading DCMF, DCIO or Factory. Detected an error during DCMF update in flash."
511 },
512 {MBOX_CFGSTATE_MINOR_ERR_RSU_RM_UCMF_FROM_CPB_FAILED,
513 "UCMF reports failure to remove UCMF address from RSU CPB table. Detected an error during RSU CPB table update in flash."
514 },
515 {MBOX_CFGSTATE_MINOR_ERR_RSU_UCMF_COMBINED_APP_AUTH_ERR,
516 "UCMF reports authentication failure of new combined app image. Detected an error during combined app image update in flash."
517 },
518 {MBOX_CFGSTATE_MINOR_ERR_RSU_UCMF_FLASH_ACCESS_ERR,
519 "UCMF failed to upgrade for more than max retry times. Detected an error during DCMF update in flash."
520 },
521 {MBOX_CFGSTATE_MINOR_ERR_RSU_DCMF_DCIO_CORRUPTED,
522 "DCMF reports failure when parse dcio section, causing force factory boot. Detected an error when parsing dcio section."
523 },
524 {MBOX_CFGSTATE_MINOR_ERR_RSU_DCMF_CPB0_CORRUPTED,
525 "DCMF reports failure when parse cpb0 and thus cpb1 is used. Detected an error in RSU CPB0 table."
526 },
527 {MBOX_CFGSTATE_MINOR_ERR_RSU_DCMF_CPB1_CORRUPTED,
528 "DCMF reports failure when parse both cpb0 and cpb1, causing force factory boot. Detected an error in both RSU CPB0 and CPB1 table."
529 },
530 {MBOX_CFGSTATE_MINOR_ERR_RSU_PROVISION_COMPLETE,
531 "Non-JTAG Provisioning Successful. Non-Jtag Provisioning was Successful DCMF will load next highest priority application image."
532 },
533 {MBOX_CFGSTATE_MINOR_ERR_RSU_PROVISION_ERR,
534 "Non-JTAG Provisioning Failed. An error occurred while provisioning the device."},
535 {MBOX_CFGSTATE_MINOR_ERR_SYSINIT_EFUSE_INIT_FAIL,
536 "Efuse cache generation failure. Detected an error during configuration."},
537 {MBOX_CFGSTATE_MINOR_ERR_SYSINIT_SEC_PROT_ERR,
538 "Security lock and disable driver failure. Detected an error during configuration."
539 },
540 {MBOX_CFGSTATE_MINOR_ERR_SYSINIT_EFUSE_LCK_ERR,
541 "efuse lock operation failure."},
542 {MBOX_CFGSTATE_MINOR_ERR_SYSINIT_SEC_BBRAM_CLEAN_ERR,
543 "BBRAM clean up failure."},
544 {MBOX_CFGSTATE_MINOR_ERR_SYSINIT_ENG_LOAD_DIMK_ERR,
545 "DIMK failed to derive device identity."},
546 {MBOX_CFGSTATE_MINOR_ERR_SYSINIT_SEC_UKV_CLEAN_ERR,
547 "Key Vault clean up failure."},
548 {MBOX_CFGSTATE_MINOR_ERR_SYSINIT_EFUSE_ZERO_ERR,
549 "No security efuse allowed."},
550 {MBOX_CFGSTATE_MINOR_ERR_SYSINIT_ENG_LOAD_ERR,
551 "efuse policy check failed."},
552 {MBOX_CFGSTATE_MINOR_ERR_SYSINIT_PERST_INIT_FAIL,
553 "Peristent data initialization failure. Detected an error during configuration."
554 },
555 {MBOX_CFGSTATE_MINOR_ERR_SYSINIT_DIMK_INIT_FAIL,
556 "DIMK Initialization failure. Detected an error during configuration."},
557 {MBOX_CFGSTATE_MINOR_ERR_SYSINIT_PERST_SECONDARY_INIT_FAIL,
558 "Handoff data include CMF main and signature blocks validation failure. Detected an error during configuration."
559 },
560 {MBOX_CFGSTATE_MINOR_ERR_SYSINIT_BR_INFO_INIT_FAIL,
561 "CMF Bootrom header validation failure."},
562 {MBOX_CFGSTATE_MINOR_ERR_SYSINIT_CMF_DESC_FAIL,
563 "CMF Descriptor failure."},
564 {MBOX_CFGSTATE_MINOR_ERR_SYSINIT_DRNG_INIT_FAIL,
565 "DRNG Initialization failed."},
566 {MBOX_CFGSTATE_MINOR_ERR_UNK,
567 "Unknown error number at minor field!"}
568};
569
570#define MBOX_CFGSTAT_MINOR_ERR_MAX ARRAY_SIZE(mbox_cfgstat_minor_err)
571
572struct mbox_err_msg {
573 const char *major_err_str;
574 const char *minor_err_str;
575};
576
577static void mbox_cfgstat_to_str(int err, struct mbox_err_msg *err_msg)
578{
579 int i;
580 u32 major_err;
581 u32 minor_err;
582
583 major_err = FIELD_GET(MBOX_CFG_STATUS_MAJOR_ERR_MSK, err);
584
585 minor_err = FIELD_GET(MBOX_CFG_STATUS_MINOR_ERR_MSK, err);
586
587 if (!err_msg) {
588 printf("Invalid argument\n");
589 return;
590 }
591
592 err_msg->major_err_str = "";
593 err_msg->minor_err_str = "";
594
595 /*
596 * In the case of getting error number 0, meaning the
597 * ATF BL31 is not supporting the feature yet thus,
598 * the SMC call will return 0 at the second argument
599 * return the message to indicate that current BL31
600 * is not yet supporting feature and need to check
601 * the BL31 version.
602 */
603 if (err == 0) {
604 err_msg->major_err_str = mbox_cfgstat_major_err[err].error_name;
605 return;
606 }
607
608 /* Initialize the major error string with unknown error */
609 err_msg->major_err_str = mbox_cfgstat_major_err[0].error_name;
610
611 for (i = 0; i < MBOX_CFGSTAT_MAJOR_ERR_MAX - 1; i++) {
612 if (mbox_cfgstat_major_err[i].err_no == major_err) {
613 err_msg->major_err_str = mbox_cfgstat_major_err[i].error_name;
614 break;
615 }
616 }
617
618 /* Return configuration state if device still under config state */
619 if (major_err == MBOX_CFGSTATE_MAJOR_ERR_STATE_CONFIG)
620 return;
621
622 /* Initialize the minor error string with unknown error */
623 err_msg->minor_err_str = mbox_cfgstat_minor_err[0].error_name;
624
625 for (i = 0; i < MBOX_CFGSTAT_MINOR_ERR_MAX - 1; i++) {
626 if (mbox_cfgstat_minor_err[i].err_no == minor_err) {
627 err_msg->minor_err_str = mbox_cfgstat_minor_err[i].error_name;
628 break;
629 }
630 }
631}
632
Chee Hong Angec4c6792020-12-24 18:21:07 +0800633/*
634 * Polling the FPGA configuration status.
635 * Return 0 for success, non-zero for error.
636 */
Boon Khai Ng483a1bb2025-01-17 14:33:31 +0800637static int reconfig_status_polling_resp(uint32_t *error_status)
Chee Hong Angec4c6792020-12-24 18:21:07 +0800638{
639 int ret;
Boon Khai Ng483a1bb2025-01-17 14:33:31 +0800640 u64 res_buf[3];
Chee Hong Angec4c6792020-12-24 18:21:07 +0800641 unsigned long start = get_timer(0);
642
643 while (1) {
644 ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_ISDONE, NULL, 0,
Boon Khai Ng483a1bb2025-01-17 14:33:31 +0800645 res_buf, ARRAY_SIZE(res_buf));
646
647 if (error_status)
648 *error_status = (uint32_t)res_buf[0];
Chee Hong Angec4c6792020-12-24 18:21:07 +0800649
650 if (!ret)
651 return 0; /* configuration success */
652
653 if (ret != INTEL_SIP_SMC_STATUS_BUSY)
654 return ret;
655
656 if (get_timer(start) > RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS)
657 return -ETIMEDOUT; /* time out */
658
659 puts(".");
660 udelay(RECONFIG_STATUS_INTERVAL_DELAY_US);
Stefan Roese80877fa2022-09-02 14:10:46 +0200661 schedule();
Chee Hong Angec4c6792020-12-24 18:21:07 +0800662 }
663
664 return -ETIMEDOUT;
665}
666
667static int send_bitstream(const void *rbf_data, size_t rbf_size)
668{
669 int i;
670 u64 res_buf[3];
671 u64 args[2];
672 u32 xfer_count = 0;
673 int ret, wr_ret = 0, retry = 0;
674 size_t buf_size = (rbf_size > BITSTREAM_CHUNK_SIZE) ?
675 BITSTREAM_CHUNK_SIZE : rbf_size;
676
677 while (rbf_size || xfer_count) {
678 if (!wr_ret && rbf_size) {
679 args[0] = (u64)rbf_data;
680 args[1] = buf_size;
681 wr_ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_WRITE,
682 args, 2, NULL, 0);
683
684 debug("wr_ret = %d, rbf_data = %p, buf_size = %08lx\n",
685 wr_ret, rbf_data, buf_size);
686
687 if (wr_ret)
688 continue;
689
690 rbf_size -= buf_size;
691 rbf_data += buf_size;
692
693 if (buf_size >= rbf_size)
694 buf_size = rbf_size;
695
696 xfer_count++;
697 puts(".");
698 } else {
699 ret = invoke_smc(
700 INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE,
701 NULL, 0, res_buf, ARRAY_SIZE(res_buf));
702 if (!ret) {
703 for (i = 0; i < ARRAY_SIZE(res_buf); i++) {
704 if (!res_buf[i])
705 break;
706 xfer_count--;
707 wr_ret = 0;
708 retry = 0;
709 }
710 } else if (ret !=
711 INTEL_SIP_SMC_STATUS_BUSY)
712 return ret;
713 else if (!xfer_count)
714 return INTEL_SIP_SMC_STATUS_ERROR;
715
716 if (++retry >= RECONFIG_STATUS_POLL_RETRY_MAX)
717 return -ETIMEDOUT;
718
719 udelay(20000);
720 }
Stefan Roese80877fa2022-09-02 14:10:46 +0200721 schedule();
Chee Hong Angec4c6792020-12-24 18:21:07 +0800722 }
723
724 return 0;
725}
726
727/*
728 * This is the interface used by FPGA driver.
729 * Return 0 for success, non-zero for error.
730 */
731int intel_sdm_mb_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
732{
733 int ret;
734 u64 arg = 1;
Boon Khai Ng483a1bb2025-01-17 14:33:31 +0800735 u32 err_status = 0;
736 u64 res_buf[3];
737 struct mbox_err_msg err_msg;
Chee Hong Angec4c6792020-12-24 18:21:07 +0800738
739 debug("Invoking FPGA_CONFIG_START...\n");
740
741 ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_START, &arg, 1, NULL, 0);
742
743 if (ret) {
Boon Khai Ng483a1bb2025-01-17 14:33:31 +0800744 puts("U-Boot SMC: Failure in RECONFIG mailbox command!\n");
Chee Hong Angec4c6792020-12-24 18:21:07 +0800745 return ret;
746 }
747
748 ret = send_bitstream(rbf_data, rbf_size);
749 if (ret) {
Boon Khai Ng483a1bb2025-01-17 14:33:31 +0800750 puts("\nU-Boot SMC: Error sending bitstream!\n");
751 ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_ISDONE, NULL, 0,
752 res_buf, ARRAY_SIZE(res_buf));
753
754 err_status = res_buf[0];
755 mbox_cfgstat_to_str(err_status, &err_msg);
756 printf("SDM: Config status: (0x%x)\nSDM Err: %s\n%s\n", err_status,
757 err_msg.major_err_str, err_msg.minor_err_str);
758
Chee Hong Angec4c6792020-12-24 18:21:07 +0800759 return ret;
760 }
761
762 /* Make sure we don't send MBOX_RECONFIG_STATUS too fast */
763 udelay(RECONFIG_STATUS_INTERVAL_DELAY_US);
764
Boon Khai Ng483a1bb2025-01-17 14:33:31 +0800765 debug("U-Boot SMC: Polling with MBOX_RECONFIG_STATUS...\n");
766 ret = reconfig_status_polling_resp(&err_status);
Chee Hong Angec4c6792020-12-24 18:21:07 +0800767 if (ret) {
Boon Khai Ng483a1bb2025-01-17 14:33:31 +0800768 printf("\nU-Boot SMC: FPGA reconfiguration failed!\n");
769 mbox_cfgstat_to_str(err_status, &err_msg);
770 printf("SDM: Config status: (0x%x)\nSDM Err:%s\n%s\n", err_status,
771 err_msg.major_err_str, err_msg.minor_err_str);
772
Chee Hong Angec4c6792020-12-24 18:21:07 +0800773 return ret;
774 }
775
776 puts("FPGA reconfiguration OK!\n");
777
778 return ret;
779}
780
781#else
782
Ang, Chee Hongdcc3bb62018-12-19 18:35:14 -0800783static const struct mbox_cfgstat_state {
784 int err_no;
785 const char *error_name;
786} mbox_cfgstat_state[] = {
787 {MBOX_CFGSTAT_STATE_IDLE, "FPGA in idle mode."},
788 {MBOX_CFGSTAT_STATE_CONFIG, "FPGA in config mode."},
789 {MBOX_CFGSTAT_STATE_FAILACK, "Acknowledgment failed!"},
790 {MBOX_CFGSTAT_STATE_ERROR_INVALID, "Invalid bitstream!"},
791 {MBOX_CFGSTAT_STATE_ERROR_CORRUPT, "Corrupted bitstream!"},
792 {MBOX_CFGSTAT_STATE_ERROR_AUTH, "Authentication failed!"},
793 {MBOX_CFGSTAT_STATE_ERROR_CORE_IO, "I/O error!"},
794 {MBOX_CFGSTAT_STATE_ERROR_HARDWARE, "Hardware error!"},
795 {MBOX_CFGSTAT_STATE_ERROR_FAKE, "Fake error!"},
796 {MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO, "Error in boot info!"},
797 {MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR, "Error in QSPI!"},
798 {MBOX_RESP_ERROR, "Mailbox general error!"},
799 {-ETIMEDOUT, "I/O timeout error"},
800 {-1, "Unknown error!"}
801};
802
803#define MBOX_CFGSTAT_MAX ARRAY_SIZE(mbox_cfgstat_state)
804
805static const char *mbox_cfgstat_to_str(int err)
806{
807 int i;
808
809 for (i = 0; i < MBOX_CFGSTAT_MAX - 1; i++) {
810 if (mbox_cfgstat_state[i].err_no == err)
811 return mbox_cfgstat_state[i].error_name;
812 }
813
814 return mbox_cfgstat_state[MBOX_CFGSTAT_MAX - 1].error_name;
815}
816
817/*
818 * Add the ongoing transaction's command ID into pending list and return
819 * the command ID for next transfer.
820 */
821static u8 add_transfer(u32 *xfer_pending_list, size_t list_size, u8 id)
822{
823 int i;
824
825 for (i = 0; i < list_size; i++) {
826 if (xfer_pending_list[i])
827 continue;
828 xfer_pending_list[i] = id;
829 debug("ID(%d) added to transaction pending list\n", id);
830 /*
831 * Increment command ID for next transaction.
832 * Valid command ID (4 bits) is from 1 to 15.
833 */
834 id = (id % 15) + 1;
835 break;
836 }
837
838 return id;
839}
840
841/*
842 * Check whether response ID match the command ID in the transfer
843 * pending list. If a match is found in the transfer pending list,
844 * it clears the transfer pending list and return the matched
845 * command ID.
846 */
847static int get_and_clr_transfer(u32 *xfer_pending_list, size_t list_size,
848 u8 id)
849{
850 int i;
851
852 for (i = 0; i < list_size; i++) {
853 if (id != xfer_pending_list[i])
854 continue;
855 xfer_pending_list[i] = 0;
856 return id;
857 }
858
859 return 0;
860}
861
862/*
863 * Polling the FPGA configuration status.
864 * Return 0 for success, non-zero for error.
865 */
866static int reconfig_status_polling_resp(void)
867{
868 int ret;
869 unsigned long start = get_timer(0);
870
871 while (1) {
872 ret = mbox_get_fpga_config_status(MBOX_RECONFIG_STATUS);
873 if (!ret)
874 return 0; /* configuration success */
875
876 if (ret != MBOX_CFGSTAT_STATE_CONFIG)
877 return ret;
878
879 if (get_timer(start) > RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS)
880 break; /* time out */
881
882 puts(".");
883 udelay(RECONFIG_STATUS_INTERVAL_DELAY_US);
Stefan Roese80877fa2022-09-02 14:10:46 +0200884 schedule();
Ang, Chee Hongdcc3bb62018-12-19 18:35:14 -0800885 }
886
887 return -ETIMEDOUT;
888}
889
890static u32 get_resp_hdr(u32 *r_index, u32 *w_index, u32 *resp_count,
891 u32 *resp_buf, u32 buf_size, u32 client_id)
892{
893 u32 buf[MBOX_RESP_BUFFER_SIZE];
894 u32 mbox_hdr;
895 u32 resp_len;
896 u32 hdr_len;
897 u32 i;
898
899 if (*resp_count < buf_size) {
900 u32 rcv_len_max = buf_size - *resp_count;
901
902 if (rcv_len_max > MBOX_RESP_BUFFER_SIZE)
903 rcv_len_max = MBOX_RESP_BUFFER_SIZE;
904 resp_len = mbox_rcv_resp(buf, rcv_len_max);
905
906 for (i = 0; i < resp_len; i++) {
907 resp_buf[(*w_index)++] = buf[i];
908 *w_index %= buf_size;
909 (*resp_count)++;
910 }
911 }
912
913 /* No response in buffer */
914 if (*resp_count == 0)
915 return 0;
916
917 mbox_hdr = resp_buf[*r_index];
918
919 hdr_len = MBOX_RESP_LEN_GET(mbox_hdr);
920
921 /* Insufficient header length to return a mailbox header */
922 if ((*resp_count - 1) < hdr_len)
923 return 0;
924
925 *r_index += (hdr_len + 1);
926 *r_index %= buf_size;
927 *resp_count -= (hdr_len + 1);
928
929 /* Make sure response belongs to us */
930 if (MBOX_RESP_CLIENT_GET(mbox_hdr) != client_id)
931 return 0;
932
933 return mbox_hdr;
934}
935
936/* Send bit stream data to SDM via RECONFIG_DATA mailbox command */
937static int send_reconfig_data(const void *rbf_data, size_t rbf_size,
938 u32 xfer_max, u32 buf_size_max)
939{
940 u32 response_buffer[MBOX_RESP_BUFFER_SIZE];
941 u32 xfer_pending[MBOX_RESP_BUFFER_SIZE];
942 u32 resp_rindex = 0;
943 u32 resp_windex = 0;
944 u32 resp_count = 0;
945 u32 xfer_count = 0;
Ang, Chee Hongc4192f72019-02-17 20:07:50 -0800946 int resp_err = 0;
Ang, Chee Hongdcc3bb62018-12-19 18:35:14 -0800947 u8 cmd_id = 1;
948 u32 args[3];
949 int ret;
950
951 debug("SDM xfer_max = %d\n", xfer_max);
952 debug("SDM buf_size_max = %x\n\n", buf_size_max);
953
954 memset(xfer_pending, 0, sizeof(xfer_pending));
955
956 while (rbf_size || xfer_count) {
957 if (!resp_err && rbf_size && xfer_count < xfer_max) {
958 args[0] = MBOX_ARG_DESC_COUNT(1);
959 args[1] = (u64)rbf_data;
960 if (rbf_size >= buf_size_max) {
961 args[2] = buf_size_max;
962 rbf_size -= buf_size_max;
963 rbf_data += buf_size_max;
964 } else {
965 args[2] = (u64)rbf_size;
966 rbf_size = 0;
967 }
968
Ang, Chee Hongc4192f72019-02-17 20:07:50 -0800969 resp_err = mbox_send_cmd_only(cmd_id, MBOX_RECONFIG_DATA,
Ang, Chee Hongdcc3bb62018-12-19 18:35:14 -0800970 MBOX_CMD_INDIRECT, 3, args);
Ang, Chee Hongc4192f72019-02-17 20:07:50 -0800971 if (!resp_err) {
Ang, Chee Hongdcc3bb62018-12-19 18:35:14 -0800972 xfer_count++;
973 cmd_id = add_transfer(xfer_pending,
974 MBOX_RESP_BUFFER_SIZE,
975 cmd_id);
976 }
977 puts(".");
978 } else {
979 u32 resp_hdr = get_resp_hdr(&resp_rindex, &resp_windex,
980 &resp_count,
981 response_buffer,
982 MBOX_RESP_BUFFER_SIZE,
983 MBOX_CLIENT_ID_UBOOT);
984
985 /*
986 * If no valid response header found or
987 * non-zero length from RECONFIG_DATA
988 */
989 if (!resp_hdr || MBOX_RESP_LEN_GET(resp_hdr))
990 continue;
991
992 /* Check for response's status */
993 if (!resp_err) {
Ang, Chee Hongc4192f72019-02-17 20:07:50 -0800994 resp_err = MBOX_RESP_ERR_GET(resp_hdr);
995 debug("Response error code: %08x\n", resp_err);
Ang, Chee Hongdcc3bb62018-12-19 18:35:14 -0800996 }
997
998 ret = get_and_clr_transfer(xfer_pending,
999 MBOX_RESP_BUFFER_SIZE,
1000 MBOX_RESP_ID_GET(resp_hdr));
1001 if (ret) {
1002 /* Claim and reuse the ID */
1003 cmd_id = (u8)ret;
1004 xfer_count--;
1005 }
1006
1007 if (resp_err && !xfer_count)
Ang, Chee Hongc4192f72019-02-17 20:07:50 -08001008 return resp_err;
Ang, Chee Hongdcc3bb62018-12-19 18:35:14 -08001009 }
Stefan Roese80877fa2022-09-02 14:10:46 +02001010 schedule();
Ang, Chee Hongdcc3bb62018-12-19 18:35:14 -08001011 }
1012
1013 return 0;
1014}
1015
1016/*
1017 * This is the interface used by FPGA driver.
1018 * Return 0 for success, non-zero for error.
1019 */
Chee Hong Ang14192452020-08-07 11:50:03 +08001020int intel_sdm_mb_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
Ang, Chee Hongdcc3bb62018-12-19 18:35:14 -08001021{
1022 int ret;
1023 u32 resp_len = 2;
1024 u32 resp_buf[2];
1025
1026 debug("Sending MBOX_RECONFIG...\n");
1027 ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_RECONFIG, MBOX_CMD_DIRECT, 0,
1028 NULL, 0, &resp_len, resp_buf);
1029 if (ret) {
1030 puts("Failure in RECONFIG mailbox command!\n");
1031 return ret;
1032 }
1033
1034 ret = send_reconfig_data(rbf_data, rbf_size, resp_buf[0], resp_buf[1]);
1035 if (ret) {
1036 printf("RECONFIG_DATA error: %08x, %s\n", ret,
1037 mbox_cfgstat_to_str(ret));
1038 return ret;
1039 }
1040
1041 /* Make sure we don't send MBOX_RECONFIG_STATUS too fast */
1042 udelay(RECONFIG_STATUS_INTERVAL_DELAY_US);
1043
1044 debug("Polling with MBOX_RECONFIG_STATUS...\n");
1045 ret = reconfig_status_polling_resp();
1046 if (ret) {
1047 printf("RECONFIG_STATUS Error: %08x, %s\n", ret,
1048 mbox_cfgstat_to_str(ret));
1049 return ret;
1050 }
1051
1052 puts("FPGA reconfiguration OK!\n");
1053
1054 return ret;
1055}
Chee Hong Angec4c6792020-12-24 18:21:07 +08001056#endif