File Index
Files and directories
Sign in
FILE

mpfs-auto-update.c

File preview with syntax highlighting.

linux-6.19.14/drivers/firmware/microchip/mpfs-auto-update.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Microchip Polarfire SoC "Auto Update" FPGA reprogramming.
  4 *
  5 * Documentation of this functionality is available in the "PolarFire® FPGA and
  6 * PolarFire SoC FPGA Programming" User Guide.
  7 *
  8 * Copyright (c) 2022-2023 Microchip Corporation. All rights reserved.
  9 *
 10 * Author: Conor Dooley <conor.dooley@microchip.com>
 11 */
 12#include <linux/cleanup.h>
 13#include <linux/debugfs.h>
 14#include <linux/firmware.h>
 15#include <linux/math.h>
 16#include <linux/module.h>
 17#include <linux/mtd/mtd.h>
 18#include <linux/platform_device.h>
 19#include <linux/sizes.h>
 20
 21#include <soc/microchip/mpfs.h>
 22
 23#define AUTO_UPDATE_DEFAULT_MBOX_OFFSET		0u
 24#define AUTO_UPDATE_DEFAULT_RESP_OFFSET		0u
 25
 26#define AUTO_UPDATE_FEATURE_CMD_OPCODE		0x05u
 27#define AUTO_UPDATE_FEATURE_CMD_DATA_SIZE	0u
 28#define AUTO_UPDATE_FEATURE_RESP_SIZE		33u
 29#define AUTO_UPDATE_FEATURE_CMD_DATA		NULL
 30#define AUTO_UPDATE_FEATURE_ENABLED		BIT(5)
 31
 32#define AUTO_UPDATE_AUTHENTICATE_CMD_OPCODE	0x22u
 33#define AUTO_UPDATE_AUTHENTICATE_CMD_DATA_SIZE	0u
 34#define AUTO_UPDATE_AUTHENTICATE_RESP_SIZE	1u
 35#define AUTO_UPDATE_AUTHENTICATE_CMD_DATA	NULL
 36
 37#define AUTO_UPDATE_PROGRAM_CMD_OPCODE		0x46u
 38#define AUTO_UPDATE_PROGRAM_CMD_DATA_SIZE	0u
 39#define AUTO_UPDATE_PROGRAM_RESP_SIZE		1u
 40#define AUTO_UPDATE_PROGRAM_CMD_DATA		NULL
 41
 42/*
 43 * SPI Flash layout example:
 44 * |------------------------------| 0x0000000
 45 * | 1 KiB                        |
 46 * | SPI "directories"            |
 47 * |------------------------------| 0x0000400
 48 * | 1 MiB                        |
 49 * | Reserved area                |
 50 * | Used for bitstream info      |
 51 * |------------------------------| 0x0100400
 52 * | 20 MiB                       |
 53 * | Golden Image                 |
 54 * |------------------------------| 0x1500400
 55 * | 20 MiB                       |
 56 * | Auto Upgrade Image           |
 57 * |------------------------------| 0x2900400
 58 * | 20 MiB                       |
 59 * | Reserved for multi-image IAP |
 60 * | Unused for Auto Upgrade      |
 61 * |------------------------------| 0x3D00400
 62 * | ? B                          |
 63 * | Unused                       |
 64 * |------------------------------| 0x?
 65 */
 66#define AUTO_UPDATE_DIRECTORY_BASE	0u
 67#define AUTO_UPDATE_DIRECTORY_WIDTH	4u
 68#define AUTO_UPDATE_GOLDEN_INDEX	0u
 69#define AUTO_UPDATE_UPGRADE_INDEX	1u
 70#define AUTO_UPDATE_BLANK_INDEX		2u
 71#define AUTO_UPDATE_GOLDEN_DIRECTORY	(AUTO_UPDATE_DIRECTORY_WIDTH * AUTO_UPDATE_GOLDEN_INDEX)
 72#define AUTO_UPDATE_UPGRADE_DIRECTORY	(AUTO_UPDATE_DIRECTORY_WIDTH * AUTO_UPDATE_UPGRADE_INDEX)
 73#define AUTO_UPDATE_BLANK_DIRECTORY	(AUTO_UPDATE_DIRECTORY_WIDTH * AUTO_UPDATE_BLANK_INDEX)
 74#define AUTO_UPDATE_DIRECTORY_SIZE	SZ_1K
 75#define AUTO_UPDATE_INFO_BASE		AUTO_UPDATE_DIRECTORY_SIZE
 76#define AUTO_UPDATE_INFO_SIZE		SZ_1M
 77#define AUTO_UPDATE_BITSTREAM_BASE	(AUTO_UPDATE_DIRECTORY_SIZE + AUTO_UPDATE_INFO_SIZE)
 78
 79struct mpfs_auto_update_priv {
 80	struct mpfs_sys_controller *sys_controller;
 81	struct device *dev;
 82	struct mtd_info *flash;
 83	struct fw_upload *fw_uploader;
 84	size_t size_per_bitstream;
 85	bool cancel_request;
 86};
 87
 88static bool mpfs_auto_update_is_bitstream_info(const u8 *data, u32 size)
 89{
 90	if (size < 4)
 91		return false;
 92
 93	if (data[0] == 0x4d && data[1] == 0x43 && data[2] == 0x48 && data[3] == 0x50)
 94		return true;
 95
 96	return false;
 97}
 98
 99static enum fw_upload_err mpfs_auto_update_prepare(struct fw_upload *fw_uploader, const u8 *data,
100						   u32 size)
101{
102	struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;
103	size_t erase_size = AUTO_UPDATE_DIRECTORY_SIZE;
104
105	/*
106	 * Verifying the Golden Image is idealistic. It will be evaluated
107	 * against the currently programmed image and thus may fail - due to
108	 * either rollback protection (if its an older version than that in use)
109	 * or if the version is the same as that of the in-use image.
110	 * Extracting the information as to why a failure occurred is not
111	 * currently possible due to limitations of the system controller
112	 * driver. If those are fixed, verification of the Golden Image should
113	 * be added here.
114	 */
115
116	erase_size = round_up(erase_size, (u64)priv->flash->erasesize);
117
118	/*
119	 * We need to calculate if we have enough space in the flash for the
120	 * new image.
121	 * First, chop off the first 1 KiB as it's reserved for the directory.
122	 * The 1 MiB reserved for design info needs to be ignored also.
123	 * All that remains is carved into 3 & rounded down to the erasesize.
124	 * If this is smaller than the image size, we abort.
125	 * There's also no need to consume more than 20 MiB per image.
126	 */
127	priv->size_per_bitstream = priv->flash->size - SZ_1K - SZ_1M;
128	priv->size_per_bitstream = round_down(priv->size_per_bitstream / 3, erase_size);
129	if (priv->size_per_bitstream > 20 * SZ_1M)
130		priv->size_per_bitstream = 20 * SZ_1M;
131
132	if (priv->size_per_bitstream < size) {
133		dev_err(priv->dev,
134			"flash device has insufficient capacity to store this bitstream\n");
135		return FW_UPLOAD_ERR_INVALID_SIZE;
136	}
137
138	priv->cancel_request = false;
139
140	return FW_UPLOAD_ERR_NONE;
141}
142
143static void mpfs_auto_update_cancel(struct fw_upload *fw_uploader)
144{
145	struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;
146
147	priv->cancel_request = true;
148}
149
150static enum fw_upload_err mpfs_auto_update_poll_complete(struct fw_upload *fw_uploader)
151{
152	return FW_UPLOAD_ERR_NONE;
153}
154
155static int mpfs_auto_update_verify_image(struct fw_upload *fw_uploader)
156{
157	struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;
158	u32 *response_msg __free(kfree) =
159		kzalloc(AUTO_UPDATE_FEATURE_RESP_SIZE * sizeof(*response_msg), GFP_KERNEL);
160	struct mpfs_mss_response *response __free(kfree) =
161		kzalloc(sizeof(struct mpfs_mss_response), GFP_KERNEL);
162	struct mpfs_mss_msg *message __free(kfree) =
163		kzalloc(sizeof(struct mpfs_mss_msg), GFP_KERNEL);
164	int ret;
165
166	if (!response_msg || !response || !message)
167		return -ENOMEM;
168
169	/*
170	 * The system controller can verify that an image in the flash is valid.
171	 * Rather than duplicate the check in this driver, call the relevant
172	 * service from the system controller instead.
173	 * This service has no command data and no response data. It overloads
174	 * mbox_offset with the image index in the flash's SPI directory where
175	 * the bitstream is located.
176	 */
177	response->resp_msg = response_msg;
178	response->resp_size = AUTO_UPDATE_AUTHENTICATE_RESP_SIZE;
179	message->cmd_opcode = AUTO_UPDATE_AUTHENTICATE_CMD_OPCODE;
180	message->cmd_data_size = AUTO_UPDATE_AUTHENTICATE_CMD_DATA_SIZE;
181	message->response = response;
182	message->cmd_data = AUTO_UPDATE_AUTHENTICATE_CMD_DATA;
183	message->mbox_offset = AUTO_UPDATE_UPGRADE_INDEX;
184	message->resp_offset = AUTO_UPDATE_DEFAULT_RESP_OFFSET;
185
186	dev_info(priv->dev, "Running verification of Upgrade Image\n");
187	ret = mpfs_blocking_transaction(priv->sys_controller, message);
188	if (ret | response->resp_status) {
189		dev_warn(priv->dev, "Verification of Upgrade Image failed!\n");
190		return ret ? ret : -EBADMSG;
191	}
192
193	dev_info(priv->dev, "Verification of Upgrade Image passed!\n");
194
195	return 0;
196}
197
198static int mpfs_auto_update_set_image_address(struct mpfs_auto_update_priv *priv,
199					      u32 image_address, loff_t directory_address)
200{
201	struct erase_info erase;
202	size_t erase_size = round_up(AUTO_UPDATE_DIRECTORY_SIZE, (u64)priv->flash->erasesize);
203	size_t bytes_written = 0, bytes_read = 0;
204	char *buffer __free(kfree) = kzalloc(erase_size, GFP_KERNEL);
205	int ret;
206
207	if (!buffer)
208		return -ENOMEM;
209
210	erase.addr = AUTO_UPDATE_DIRECTORY_BASE;
211	erase.len = erase_size;
212
213	/*
214	 * We need to write the "SPI DIRECTORY" to the first 1 KiB, telling
215	 * the system controller where to find the actual bitstream. Since
216	 * this is spi-nor, we have to read the first eraseblock, erase that
217	 * portion of the flash, modify the data and then write it back.
218	 * There's no need to do this though if things are already the way they
219	 * should be, so check and save the write in that case.
220	 */
221	ret = mtd_read(priv->flash, AUTO_UPDATE_DIRECTORY_BASE, erase_size, &bytes_read,
222		       (u_char *)buffer);
223	if (ret)
224		return ret;
225
226	if (bytes_read != erase_size)
227		return -EIO;
228
229	if ((*(u32 *)(buffer + AUTO_UPDATE_UPGRADE_DIRECTORY) == image_address) &&
230	    !(*(u32 *)(buffer + AUTO_UPDATE_BLANK_DIRECTORY)))
231		return 0;
232
233	ret = mtd_erase(priv->flash, &erase);
234	if (ret)
235		return ret;
236
237	/*
238	 * Populate the image address and then zero out the next directory so
239	 * that the system controller doesn't complain if in "Single Image"
240	 * mode.
241	 */
242	memcpy(buffer + AUTO_UPDATE_UPGRADE_DIRECTORY, &image_address,
243	       AUTO_UPDATE_DIRECTORY_WIDTH);
244	memset(buffer + AUTO_UPDATE_BLANK_DIRECTORY, 0x0, AUTO_UPDATE_DIRECTORY_WIDTH);
245
246	dev_info(priv->dev, "Writing the image address (0x%x) to the flash directory (0x%llx)\n",
247		 image_address, directory_address);
248
249	ret = mtd_write(priv->flash, 0x0, erase_size, &bytes_written, (u_char *)buffer);
250	if (ret)
251		return ret;
252
253	if (bytes_written != erase_size)
254		return -EIO;
255
256	return 0;
257}
258
259static int mpfs_auto_update_write_bitstream(struct fw_upload *fw_uploader, const u8 *data,
260					    u32 offset, u32 size, u32 *written)
261{
262	struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;
263	struct erase_info erase;
264	loff_t directory_address = AUTO_UPDATE_UPGRADE_DIRECTORY;
265	size_t erase_size = AUTO_UPDATE_DIRECTORY_SIZE;
266	size_t bytes_written = 0;
267	bool is_info = mpfs_auto_update_is_bitstream_info(data, size);
268	u32 image_address;
269	int ret;
270
271	erase_size = round_up(erase_size, (u64)priv->flash->erasesize);
272
273	if (is_info)
274		image_address = AUTO_UPDATE_INFO_BASE;
275	else
276		image_address = AUTO_UPDATE_BITSTREAM_BASE +
277				AUTO_UPDATE_UPGRADE_INDEX * priv->size_per_bitstream;
278
279	/*
280	 * For bitstream info, the descriptor is written to a fixed offset,
281	 * so there is no need to set the image address.
282	 */
283	if (!is_info) {
284		ret = mpfs_auto_update_set_image_address(priv, image_address, directory_address);
285		if (ret) {
286			dev_err(priv->dev, "failed to set image address in the SPI directory: %d\n", ret);
287			return ret;
288		}
289	} else {
290		if (size > AUTO_UPDATE_INFO_SIZE) {
291			dev_err(priv->dev, "bitstream info exceeds permitted size\n");
292			return -ENOSPC;
293		}
294	}
295
296	/*
297	 * Now the .spi image itself can be written to the flash. Preservation
298	 * of contents here is not important here, unlike the spi "directory"
299	 * which must be RMWed.
300	 */
301	erase.len = round_up(size, (size_t)priv->flash->erasesize);
302	erase.addr = image_address;
303
304	dev_info(priv->dev, "Erasing the flash at address (0x%x)\n", image_address);
305	ret = mtd_erase(priv->flash, &erase);
306	if (ret)
307		return ret;
308
309	/*
310	 * No parsing etc of the bitstream is required. The system controller
311	 * will do all of that itself - including verifying that the bitstream
312	 * is valid.
313	 */
314	dev_info(priv->dev, "Writing the image to the flash at address (0x%x)\n", image_address);
315	ret = mtd_write(priv->flash, (loff_t)image_address, size, &bytes_written, data);
316	if (ret)
317		return ret;
318
319	if (bytes_written != size)
320		return -EIO;
321
322	*written = bytes_written;
323	dev_info(priv->dev, "Wrote 0x%zx bytes to the flash\n", bytes_written);
324
325	return 0;
326}
327
328static enum fw_upload_err mpfs_auto_update_write(struct fw_upload *fw_uploader, const u8 *data,
329						 u32 offset, u32 size, u32 *written)
330{
331	struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;
332	int ret;
333
334	ret = mpfs_auto_update_write_bitstream(fw_uploader, data, offset, size, written);
335	if (ret)
336		return FW_UPLOAD_ERR_RW_ERROR;
337
338	if (priv->cancel_request)
339		return FW_UPLOAD_ERR_CANCELED;
340
341	if (mpfs_auto_update_is_bitstream_info(data, size))
342		return FW_UPLOAD_ERR_NONE;
343
344	ret = mpfs_auto_update_verify_image(fw_uploader);
345	if (ret)
346		return FW_UPLOAD_ERR_FW_INVALID;
347
348	return FW_UPLOAD_ERR_NONE;
349}
350
351static const struct fw_upload_ops mpfs_auto_update_ops = {
352	.prepare = mpfs_auto_update_prepare,
353	.write = mpfs_auto_update_write,
354	.poll_complete = mpfs_auto_update_poll_complete,
355	.cancel = mpfs_auto_update_cancel,
356};
357
358static int mpfs_auto_update_available(struct mpfs_auto_update_priv *priv)
359{
360	u32 *response_msg __free(kfree) =
361		kzalloc(AUTO_UPDATE_FEATURE_RESP_SIZE * sizeof(*response_msg), GFP_KERNEL);
362	struct mpfs_mss_response *response __free(kfree) =
363		kzalloc(sizeof(struct mpfs_mss_response), GFP_KERNEL);
364	struct mpfs_mss_msg *message __free(kfree) =
365		kzalloc(sizeof(struct mpfs_mss_msg), GFP_KERNEL);
366	int ret;
367
368	if (!response_msg || !response || !message)
369		return -ENOMEM;
370
371	/*
372	 * To verify that Auto Update is possible, the "Query Security Service
373	 * Request" is performed.
374	 * This service has no command data & does not overload mbox_offset.
375	 */
376	response->resp_msg = response_msg;
377	response->resp_size = AUTO_UPDATE_FEATURE_RESP_SIZE;
378	message->cmd_opcode = AUTO_UPDATE_FEATURE_CMD_OPCODE;
379	message->cmd_data_size = AUTO_UPDATE_FEATURE_CMD_DATA_SIZE;
380	message->response = response;
381	message->cmd_data = AUTO_UPDATE_FEATURE_CMD_DATA;
382	message->mbox_offset = AUTO_UPDATE_DEFAULT_MBOX_OFFSET;
383	message->resp_offset = AUTO_UPDATE_DEFAULT_RESP_OFFSET;
384
385	ret = mpfs_blocking_transaction(priv->sys_controller, message);
386	if (ret)
387		return ret;
388
389	/*
390	 * Currently, the system controller's firmware does not generate any
391	 * interrupts for failed services, so mpfs_blocking_transaction() should
392	 * time out & therefore return an error.
393	 * Hitting this check is highly unlikely at present, but if the system
394	 * controller's behaviour changes so that it does generate interrupts
395	 * for failed services, it will be required.
396	 */
397	if (response->resp_status)
398		return -EIO;
399
400	/*
401	 * Bit 5 of byte 1 is "UL_IAP" & if it is set, Auto Update is
402	 * not possible.
403	 */
404	if ((((u8 *)response_msg)[1] & AUTO_UPDATE_FEATURE_ENABLED))
405		return -EPERM;
406
407	return 0;
408}
409
410static int mpfs_auto_update_probe(struct platform_device *pdev)
411{
412	struct device *dev = &pdev->dev;
413	struct mpfs_auto_update_priv *priv;
414	struct fw_upload *fw_uploader;
415	int ret;
416
417	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
418	if (!priv)
419		return -ENOMEM;
420
421	priv->sys_controller = mpfs_sys_controller_get(dev);
422	if (IS_ERR(priv->sys_controller))
423		return dev_err_probe(dev, PTR_ERR(priv->sys_controller),
424				     "Could not register as a sub device of the system controller\n");
425
426	priv->flash = mpfs_sys_controller_get_flash(priv->sys_controller);
427	if (IS_ERR_OR_NULL(priv->flash)) {
428		dev_dbg(dev, "No flash connected to the system controller, auto-update not supported\n");
429		return -ENODEV;
430	}
431
432	priv->dev = dev;
433	platform_set_drvdata(pdev, priv);
434
435	ret = mpfs_auto_update_available(priv);
436	if (ret)
437		return dev_err_probe(dev, ret,
438				     "The current bitstream does not support auto-update\n");
439
440	fw_uploader = firmware_upload_register(THIS_MODULE, dev, "mpfs-auto-update",
441					       &mpfs_auto_update_ops, priv);
442	if (IS_ERR(fw_uploader))
443		return dev_err_probe(dev, PTR_ERR(fw_uploader),
444				     "Failed to register the bitstream uploader\n");
445
446	priv->fw_uploader = fw_uploader;
447
448	return 0;
449}
450
451static void mpfs_auto_update_remove(struct platform_device *pdev)
452{
453	struct mpfs_auto_update_priv *priv = platform_get_drvdata(pdev);
454
455	firmware_upload_unregister(priv->fw_uploader);
456}
457
458static struct platform_driver mpfs_auto_update_driver = {
459	.driver = {
460		.name = "mpfs-auto-update",
461	},
462	.probe = mpfs_auto_update_probe,
463	.remove = mpfs_auto_update_remove,
464};
465module_platform_driver(mpfs_auto_update_driver);
466
467MODULE_LICENSE("GPL");
468MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
469MODULE_DESCRIPTION("PolarFire SoC Auto Update FPGA reprogramming");
~/ Read-only file preview.