468 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Microchip Polarfire SoC "Auto Update" FPGA reprogramming.4 *5 * Documentation of this functionality is available in the "PolarFire® FPGA and6 * 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 0u24#define AUTO_UPDATE_DEFAULT_RESP_OFFSET 0u25 26#define AUTO_UPDATE_FEATURE_CMD_OPCODE 0x05u27#define AUTO_UPDATE_FEATURE_CMD_DATA_SIZE 0u28#define AUTO_UPDATE_FEATURE_RESP_SIZE 33u29#define AUTO_UPDATE_FEATURE_CMD_DATA NULL30#define AUTO_UPDATE_FEATURE_ENABLED BIT(5)31 32#define AUTO_UPDATE_AUTHENTICATE_CMD_OPCODE 0x22u33#define AUTO_UPDATE_AUTHENTICATE_CMD_DATA_SIZE 0u34#define AUTO_UPDATE_AUTHENTICATE_RESP_SIZE 1u35#define AUTO_UPDATE_AUTHENTICATE_CMD_DATA NULL36 37#define AUTO_UPDATE_PROGRAM_CMD_OPCODE 0x46u38#define AUTO_UPDATE_PROGRAM_CMD_DATA_SIZE 0u39#define AUTO_UPDATE_PROGRAM_RESP_SIZE 1u40#define AUTO_UPDATE_PROGRAM_CMD_DATA NULL41 42/*43 * SPI Flash layout example:44 * |------------------------------| 0x000000045 * | 1 KiB |46 * | SPI "directories" |47 * |------------------------------| 0x000040048 * | 1 MiB |49 * | Reserved area |50 * | Used for bitstream info |51 * |------------------------------| 0x010040052 * | 20 MiB |53 * | Golden Image |54 * |------------------------------| 0x150040055 * | 20 MiB |56 * | Auto Upgrade Image |57 * |------------------------------| 0x290040058 * | 20 MiB |59 * | Reserved for multi-image IAP |60 * | Unused for Auto Upgrade |61 * |------------------------------| 0x3D0040062 * | ? B |63 * | Unused |64 * |------------------------------| 0x?65 */66#define AUTO_UPDATE_DIRECTORY_BASE 0u67#define AUTO_UPDATE_DIRECTORY_WIDTH 4u68#define AUTO_UPDATE_GOLDEN_INDEX 0u69#define AUTO_UPDATE_UPGRADE_INDEX 1u70#define AUTO_UPDATE_BLANK_INDEX 2u71#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_1K75#define AUTO_UPDATE_INFO_BASE AUTO_UPDATE_DIRECTORY_SIZE76#define AUTO_UPDATE_INFO_SIZE SZ_1M77#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 evaluated107 * against the currently programmed image and thus may fail - due to108 * 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 not111 * currently possible due to limitations of the system controller112 * driver. If those are fixed, verification of the Golden Image should113 * be added here.114 */115 116 priv->flash = mpfs_sys_controller_get_flash(priv->sys_controller);117 if (!priv->flash)118 return FW_UPLOAD_ERR_HW_ERROR;119 120 erase_size = round_up(erase_size, (u64)priv->flash->erasesize);121 122 /*123 * We need to calculate if we have enough space in the flash for the124 * new image.125 * First, chop off the first 1 KiB as it's reserved for the directory.126 * The 1 MiB reserved for design info needs to be ignored also.127 * All that remains is carved into 3 & rounded down to the erasesize.128 * If this is smaller than the image size, we abort.129 * There's also no need to consume more than 20 MiB per image.130 */131 priv->size_per_bitstream = priv->flash->size - SZ_1K - SZ_1M;132 priv->size_per_bitstream = round_down(priv->size_per_bitstream / 3, erase_size);133 if (priv->size_per_bitstream > 20 * SZ_1M)134 priv->size_per_bitstream = 20 * SZ_1M;135 136 if (priv->size_per_bitstream < size) {137 dev_err(priv->dev,138 "flash device has insufficient capacity to store this bitstream\n");139 return FW_UPLOAD_ERR_INVALID_SIZE;140 }141 142 priv->cancel_request = false;143 144 return FW_UPLOAD_ERR_NONE;145}146 147static void mpfs_auto_update_cancel(struct fw_upload *fw_uploader)148{149 struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;150 151 priv->cancel_request = true;152}153 154static enum fw_upload_err mpfs_auto_update_poll_complete(struct fw_upload *fw_uploader)155{156 return FW_UPLOAD_ERR_NONE;157}158 159static int mpfs_auto_update_verify_image(struct fw_upload *fw_uploader)160{161 struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;162 u32 *response_msg __free(kfree) =163 kzalloc(AUTO_UPDATE_FEATURE_RESP_SIZE * sizeof(*response_msg), GFP_KERNEL);164 struct mpfs_mss_response *response __free(kfree) =165 kzalloc(sizeof(struct mpfs_mss_response), GFP_KERNEL);166 struct mpfs_mss_msg *message __free(kfree) =167 kzalloc(sizeof(struct mpfs_mss_msg), GFP_KERNEL);168 int ret;169 170 if (!response_msg || !response || !message)171 return -ENOMEM;172 173 /*174 * The system controller can verify that an image in the flash is valid.175 * Rather than duplicate the check in this driver, call the relevant176 * service from the system controller instead.177 * This service has no command data and no response data. It overloads178 * mbox_offset with the image index in the flash's SPI directory where179 * the bitstream is located.180 */181 response->resp_msg = response_msg;182 response->resp_size = AUTO_UPDATE_AUTHENTICATE_RESP_SIZE;183 message->cmd_opcode = AUTO_UPDATE_AUTHENTICATE_CMD_OPCODE;184 message->cmd_data_size = AUTO_UPDATE_AUTHENTICATE_CMD_DATA_SIZE;185 message->response = response;186 message->cmd_data = AUTO_UPDATE_AUTHENTICATE_CMD_DATA;187 message->mbox_offset = AUTO_UPDATE_UPGRADE_INDEX;188 message->resp_offset = AUTO_UPDATE_DEFAULT_RESP_OFFSET;189 190 dev_info(priv->dev, "Running verification of Upgrade Image\n");191 ret = mpfs_blocking_transaction(priv->sys_controller, message);192 if (ret | response->resp_status) {193 dev_warn(priv->dev, "Verification of Upgrade Image failed!\n");194 return ret ? ret : -EBADMSG;195 }196 197 dev_info(priv->dev, "Verification of Upgrade Image passed!\n");198 199 return 0;200}201 202static int mpfs_auto_update_set_image_address(struct mpfs_auto_update_priv *priv,203 u32 image_address, loff_t directory_address)204{205 struct erase_info erase;206 size_t erase_size = round_up(AUTO_UPDATE_DIRECTORY_SIZE, (u64)priv->flash->erasesize);207 size_t bytes_written = 0, bytes_read = 0;208 char *buffer __free(kfree) = kzalloc(erase_size, GFP_KERNEL);209 int ret;210 211 if (!buffer)212 return -ENOMEM;213 214 erase.addr = AUTO_UPDATE_DIRECTORY_BASE;215 erase.len = erase_size;216 217 /*218 * We need to write the "SPI DIRECTORY" to the first 1 KiB, telling219 * the system controller where to find the actual bitstream. Since220 * this is spi-nor, we have to read the first eraseblock, erase that221 * portion of the flash, modify the data and then write it back.222 * There's no need to do this though if things are already the way they223 * should be, so check and save the write in that case.224 */225 ret = mtd_read(priv->flash, AUTO_UPDATE_DIRECTORY_BASE, erase_size, &bytes_read,226 (u_char *)buffer);227 if (ret)228 return ret;229 230 if (bytes_read != erase_size)231 return -EIO;232 233 if ((*(u32 *)(buffer + AUTO_UPDATE_UPGRADE_DIRECTORY) == image_address) &&234 !(*(u32 *)(buffer + AUTO_UPDATE_BLANK_DIRECTORY)))235 return 0;236 237 ret = mtd_erase(priv->flash, &erase);238 if (ret)239 return ret;240 241 /*242 * Populate the image address and then zero out the next directory so243 * that the system controller doesn't complain if in "Single Image"244 * mode.245 */246 memcpy(buffer + AUTO_UPDATE_UPGRADE_DIRECTORY, &image_address,247 AUTO_UPDATE_DIRECTORY_WIDTH);248 memset(buffer + AUTO_UPDATE_BLANK_DIRECTORY, 0x0, AUTO_UPDATE_DIRECTORY_WIDTH);249 250 dev_info(priv->dev, "Writing the image address (0x%x) to the flash directory (0x%llx)\n",251 image_address, directory_address);252 253 ret = mtd_write(priv->flash, 0x0, erase_size, &bytes_written, (u_char *)buffer);254 if (ret)255 return ret;256 257 if (bytes_written != erase_size)258 return -EIO;259 260 return 0;261}262 263static int mpfs_auto_update_write_bitstream(struct fw_upload *fw_uploader, const u8 *data,264 u32 offset, u32 size, u32 *written)265{266 struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;267 struct erase_info erase;268 loff_t directory_address = AUTO_UPDATE_UPGRADE_DIRECTORY;269 size_t erase_size = AUTO_UPDATE_DIRECTORY_SIZE;270 size_t bytes_written = 0;271 bool is_info = mpfs_auto_update_is_bitstream_info(data, size);272 u32 image_address;273 int ret;274 275 erase_size = round_up(erase_size, (u64)priv->flash->erasesize);276 277 if (is_info)278 image_address = AUTO_UPDATE_INFO_BASE;279 else280 image_address = AUTO_UPDATE_BITSTREAM_BASE +281 AUTO_UPDATE_UPGRADE_INDEX * priv->size_per_bitstream;282 283 /*284 * For bitstream info, the descriptor is written to a fixed offset,285 * so there is no need to set the image address.286 */287 if (!is_info) {288 ret = mpfs_auto_update_set_image_address(priv, image_address, directory_address);289 if (ret) {290 dev_err(priv->dev, "failed to set image address in the SPI directory: %d\n", ret);291 return ret;292 }293 } else {294 if (size > AUTO_UPDATE_INFO_SIZE) {295 dev_err(priv->dev, "bitstream info exceeds permitted size\n");296 return -ENOSPC;297 }298 }299 300 /*301 * Now the .spi image itself can be written to the flash. Preservation302 * of contents here is not important here, unlike the spi "directory"303 * which must be RMWed.304 */305 erase.len = round_up(size, (size_t)priv->flash->erasesize);306 erase.addr = image_address;307 308 dev_info(priv->dev, "Erasing the flash at address (0x%x)\n", image_address);309 ret = mtd_erase(priv->flash, &erase);310 if (ret)311 return ret;312 313 /*314 * No parsing etc of the bitstream is required. The system controller315 * will do all of that itself - including verifying that the bitstream316 * is valid.317 */318 dev_info(priv->dev, "Writing the image to the flash at address (0x%x)\n", image_address);319 ret = mtd_write(priv->flash, (loff_t)image_address, size, &bytes_written, data);320 if (ret)321 return ret;322 323 if (bytes_written != size)324 return -EIO;325 326 *written = bytes_written;327 dev_info(priv->dev, "Wrote 0x%zx bytes to the flash\n", bytes_written);328 329 return 0;330}331 332static enum fw_upload_err mpfs_auto_update_write(struct fw_upload *fw_uploader, const u8 *data,333 u32 offset, u32 size, u32 *written)334{335 struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;336 int ret;337 338 ret = mpfs_auto_update_write_bitstream(fw_uploader, data, offset, size, written);339 if (ret)340 return FW_UPLOAD_ERR_RW_ERROR;341 342 if (priv->cancel_request)343 return FW_UPLOAD_ERR_CANCELED;344 345 if (mpfs_auto_update_is_bitstream_info(data, size))346 return FW_UPLOAD_ERR_NONE;347 348 ret = mpfs_auto_update_verify_image(fw_uploader);349 if (ret)350 return FW_UPLOAD_ERR_FW_INVALID;351 352 return FW_UPLOAD_ERR_NONE;353}354 355static const struct fw_upload_ops mpfs_auto_update_ops = {356 .prepare = mpfs_auto_update_prepare,357 .write = mpfs_auto_update_write,358 .poll_complete = mpfs_auto_update_poll_complete,359 .cancel = mpfs_auto_update_cancel,360};361 362static int mpfs_auto_update_available(struct mpfs_auto_update_priv *priv)363{364 u32 *response_msg __free(kfree) =365 kzalloc(AUTO_UPDATE_FEATURE_RESP_SIZE * sizeof(*response_msg), GFP_KERNEL);366 struct mpfs_mss_response *response __free(kfree) =367 kzalloc(sizeof(struct mpfs_mss_response), GFP_KERNEL);368 struct mpfs_mss_msg *message __free(kfree) =369 kzalloc(sizeof(struct mpfs_mss_msg), GFP_KERNEL);370 int ret;371 372 if (!response_msg || !response || !message)373 return -ENOMEM;374 375 /*376 * To verify that Auto Update is possible, the "Query Security Service377 * Request" is performed.378 * This service has no command data & does not overload mbox_offset.379 */380 response->resp_msg = response_msg;381 response->resp_size = AUTO_UPDATE_FEATURE_RESP_SIZE;382 message->cmd_opcode = AUTO_UPDATE_FEATURE_CMD_OPCODE;383 message->cmd_data_size = AUTO_UPDATE_FEATURE_CMD_DATA_SIZE;384 message->response = response;385 message->cmd_data = AUTO_UPDATE_FEATURE_CMD_DATA;386 message->mbox_offset = AUTO_UPDATE_DEFAULT_MBOX_OFFSET;387 message->resp_offset = AUTO_UPDATE_DEFAULT_RESP_OFFSET;388 389 ret = mpfs_blocking_transaction(priv->sys_controller, message);390 if (ret)391 return ret;392 393 /*394 * Currently, the system controller's firmware does not generate any395 * interrupts for failed services, so mpfs_blocking_transaction() should396 * time out & therefore return an error.397 * Hitting this check is highly unlikely at present, but if the system398 * controller's behaviour changes so that it does generate interrupts399 * for failed services, it will be required.400 */401 if (response->resp_status)402 return -EIO;403 404 /*405 * Bit 5 of byte 1 is "UL_Auto Update" & if it is set, Auto Update is406 * not possible.407 */408 if (response_msg[1] & AUTO_UPDATE_FEATURE_ENABLED)409 return -EPERM;410 411 return 0;412}413 414static int mpfs_auto_update_probe(struct platform_device *pdev)415{416 struct device *dev = &pdev->dev;417 struct mpfs_auto_update_priv *priv;418 struct fw_upload *fw_uploader;419 int ret;420 421 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);422 if (!priv)423 return -ENOMEM;424 425 priv->sys_controller = mpfs_sys_controller_get(dev);426 if (IS_ERR(priv->sys_controller))427 return dev_err_probe(dev, PTR_ERR(priv->sys_controller),428 "Could not register as a sub device of the system controller\n");429 430 priv->dev = dev;431 platform_set_drvdata(pdev, priv);432 433 ret = mpfs_auto_update_available(priv);434 if (ret)435 return dev_err_probe(dev, ret,436 "The current bitstream does not support auto-update\n");437 438 fw_uploader = firmware_upload_register(THIS_MODULE, dev, "mpfs-auto-update",439 &mpfs_auto_update_ops, priv);440 if (IS_ERR(fw_uploader))441 return dev_err_probe(dev, PTR_ERR(fw_uploader),442 "Failed to register the bitstream uploader\n");443 444 priv->fw_uploader = fw_uploader;445 446 return 0;447}448 449static void mpfs_auto_update_remove(struct platform_device *pdev)450{451 struct mpfs_auto_update_priv *priv = platform_get_drvdata(pdev);452 453 firmware_upload_unregister(priv->fw_uploader);454}455 456static struct platform_driver mpfs_auto_update_driver = {457 .driver = {458 .name = "mpfs-auto-update",459 },460 .probe = mpfs_auto_update_probe,461 .remove_new = mpfs_auto_update_remove,462};463module_platform_driver(mpfs_auto_update_driver);464 465MODULE_LICENSE("GPL");466MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");467MODULE_DESCRIPTION("PolarFire SoC Auto Update FPGA reprogramming");468