Path: blob/master/drivers/firmware/microchip/mpfs-auto-update.c
26444 views
// SPDX-License-Identifier: GPL-2.01/*2* Microchip Polarfire SoC "Auto Update" FPGA reprogramming.3*4* Documentation of this functionality is available in the "PolarFire® FPGA and5* PolarFire SoC FPGA Programming" User Guide.6*7* Copyright (c) 2022-2023 Microchip Corporation. All rights reserved.8*9* Author: Conor Dooley <[email protected]>10*/11#include <linux/cleanup.h>12#include <linux/debugfs.h>13#include <linux/firmware.h>14#include <linux/math.h>15#include <linux/module.h>16#include <linux/mtd/mtd.h>17#include <linux/platform_device.h>18#include <linux/sizes.h>1920#include <soc/microchip/mpfs.h>2122#define AUTO_UPDATE_DEFAULT_MBOX_OFFSET 0u23#define AUTO_UPDATE_DEFAULT_RESP_OFFSET 0u2425#define AUTO_UPDATE_FEATURE_CMD_OPCODE 0x05u26#define AUTO_UPDATE_FEATURE_CMD_DATA_SIZE 0u27#define AUTO_UPDATE_FEATURE_RESP_SIZE 33u28#define AUTO_UPDATE_FEATURE_CMD_DATA NULL29#define AUTO_UPDATE_FEATURE_ENABLED BIT(5)3031#define AUTO_UPDATE_AUTHENTICATE_CMD_OPCODE 0x22u32#define AUTO_UPDATE_AUTHENTICATE_CMD_DATA_SIZE 0u33#define AUTO_UPDATE_AUTHENTICATE_RESP_SIZE 1u34#define AUTO_UPDATE_AUTHENTICATE_CMD_DATA NULL3536#define AUTO_UPDATE_PROGRAM_CMD_OPCODE 0x46u37#define AUTO_UPDATE_PROGRAM_CMD_DATA_SIZE 0u38#define AUTO_UPDATE_PROGRAM_RESP_SIZE 1u39#define AUTO_UPDATE_PROGRAM_CMD_DATA NULL4041/*42* SPI Flash layout example:43* |------------------------------| 0x000000044* | 1 KiB |45* | SPI "directories" |46* |------------------------------| 0x000040047* | 1 MiB |48* | Reserved area |49* | Used for bitstream info |50* |------------------------------| 0x010040051* | 20 MiB |52* | Golden Image |53* |------------------------------| 0x150040054* | 20 MiB |55* | Auto Upgrade Image |56* |------------------------------| 0x290040057* | 20 MiB |58* | Reserved for multi-image IAP |59* | Unused for Auto Upgrade |60* |------------------------------| 0x3D0040061* | ? B |62* | Unused |63* |------------------------------| 0x?64*/65#define AUTO_UPDATE_DIRECTORY_BASE 0u66#define AUTO_UPDATE_DIRECTORY_WIDTH 4u67#define AUTO_UPDATE_GOLDEN_INDEX 0u68#define AUTO_UPDATE_UPGRADE_INDEX 1u69#define AUTO_UPDATE_BLANK_INDEX 2u70#define AUTO_UPDATE_GOLDEN_DIRECTORY (AUTO_UPDATE_DIRECTORY_WIDTH * AUTO_UPDATE_GOLDEN_INDEX)71#define AUTO_UPDATE_UPGRADE_DIRECTORY (AUTO_UPDATE_DIRECTORY_WIDTH * AUTO_UPDATE_UPGRADE_INDEX)72#define AUTO_UPDATE_BLANK_DIRECTORY (AUTO_UPDATE_DIRECTORY_WIDTH * AUTO_UPDATE_BLANK_INDEX)73#define AUTO_UPDATE_DIRECTORY_SIZE SZ_1K74#define AUTO_UPDATE_INFO_BASE AUTO_UPDATE_DIRECTORY_SIZE75#define AUTO_UPDATE_INFO_SIZE SZ_1M76#define AUTO_UPDATE_BITSTREAM_BASE (AUTO_UPDATE_DIRECTORY_SIZE + AUTO_UPDATE_INFO_SIZE)7778struct mpfs_auto_update_priv {79struct mpfs_sys_controller *sys_controller;80struct device *dev;81struct mtd_info *flash;82struct fw_upload *fw_uploader;83size_t size_per_bitstream;84bool cancel_request;85};8687static bool mpfs_auto_update_is_bitstream_info(const u8 *data, u32 size)88{89if (size < 4)90return false;9192if (data[0] == 0x4d && data[1] == 0x43 && data[2] == 0x48 && data[3] == 0x50)93return true;9495return false;96}9798static enum fw_upload_err mpfs_auto_update_prepare(struct fw_upload *fw_uploader, const u8 *data,99u32 size)100{101struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;102size_t erase_size = AUTO_UPDATE_DIRECTORY_SIZE;103104/*105* Verifying the Golden Image is idealistic. It will be evaluated106* against the currently programmed image and thus may fail - due to107* either rollback protection (if its an older version than that in use)108* or if the version is the same as that of the in-use image.109* Extracting the information as to why a failure occurred is not110* currently possible due to limitations of the system controller111* driver. If those are fixed, verification of the Golden Image should112* be added here.113*/114115priv->flash = mpfs_sys_controller_get_flash(priv->sys_controller);116if (!priv->flash)117return FW_UPLOAD_ERR_HW_ERROR;118119erase_size = round_up(erase_size, (u64)priv->flash->erasesize);120121/*122* We need to calculate if we have enough space in the flash for the123* new image.124* First, chop off the first 1 KiB as it's reserved for the directory.125* The 1 MiB reserved for design info needs to be ignored also.126* All that remains is carved into 3 & rounded down to the erasesize.127* If this is smaller than the image size, we abort.128* There's also no need to consume more than 20 MiB per image.129*/130priv->size_per_bitstream = priv->flash->size - SZ_1K - SZ_1M;131priv->size_per_bitstream = round_down(priv->size_per_bitstream / 3, erase_size);132if (priv->size_per_bitstream > 20 * SZ_1M)133priv->size_per_bitstream = 20 * SZ_1M;134135if (priv->size_per_bitstream < size) {136dev_err(priv->dev,137"flash device has insufficient capacity to store this bitstream\n");138return FW_UPLOAD_ERR_INVALID_SIZE;139}140141priv->cancel_request = false;142143return FW_UPLOAD_ERR_NONE;144}145146static void mpfs_auto_update_cancel(struct fw_upload *fw_uploader)147{148struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;149150priv->cancel_request = true;151}152153static enum fw_upload_err mpfs_auto_update_poll_complete(struct fw_upload *fw_uploader)154{155return FW_UPLOAD_ERR_NONE;156}157158static int mpfs_auto_update_verify_image(struct fw_upload *fw_uploader)159{160struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;161u32 *response_msg __free(kfree) =162kzalloc(AUTO_UPDATE_FEATURE_RESP_SIZE * sizeof(*response_msg), GFP_KERNEL);163struct mpfs_mss_response *response __free(kfree) =164kzalloc(sizeof(struct mpfs_mss_response), GFP_KERNEL);165struct mpfs_mss_msg *message __free(kfree) =166kzalloc(sizeof(struct mpfs_mss_msg), GFP_KERNEL);167int ret;168169if (!response_msg || !response || !message)170return -ENOMEM;171172/*173* The system controller can verify that an image in the flash is valid.174* Rather than duplicate the check in this driver, call the relevant175* service from the system controller instead.176* This service has no command data and no response data. It overloads177* mbox_offset with the image index in the flash's SPI directory where178* the bitstream is located.179*/180response->resp_msg = response_msg;181response->resp_size = AUTO_UPDATE_AUTHENTICATE_RESP_SIZE;182message->cmd_opcode = AUTO_UPDATE_AUTHENTICATE_CMD_OPCODE;183message->cmd_data_size = AUTO_UPDATE_AUTHENTICATE_CMD_DATA_SIZE;184message->response = response;185message->cmd_data = AUTO_UPDATE_AUTHENTICATE_CMD_DATA;186message->mbox_offset = AUTO_UPDATE_UPGRADE_INDEX;187message->resp_offset = AUTO_UPDATE_DEFAULT_RESP_OFFSET;188189dev_info(priv->dev, "Running verification of Upgrade Image\n");190ret = mpfs_blocking_transaction(priv->sys_controller, message);191if (ret | response->resp_status) {192dev_warn(priv->dev, "Verification of Upgrade Image failed!\n");193return ret ? ret : -EBADMSG;194}195196dev_info(priv->dev, "Verification of Upgrade Image passed!\n");197198return 0;199}200201static int mpfs_auto_update_set_image_address(struct mpfs_auto_update_priv *priv,202u32 image_address, loff_t directory_address)203{204struct erase_info erase;205size_t erase_size = round_up(AUTO_UPDATE_DIRECTORY_SIZE, (u64)priv->flash->erasesize);206size_t bytes_written = 0, bytes_read = 0;207char *buffer __free(kfree) = kzalloc(erase_size, GFP_KERNEL);208int ret;209210if (!buffer)211return -ENOMEM;212213erase.addr = AUTO_UPDATE_DIRECTORY_BASE;214erase.len = erase_size;215216/*217* We need to write the "SPI DIRECTORY" to the first 1 KiB, telling218* the system controller where to find the actual bitstream. Since219* this is spi-nor, we have to read the first eraseblock, erase that220* portion of the flash, modify the data and then write it back.221* There's no need to do this though if things are already the way they222* should be, so check and save the write in that case.223*/224ret = mtd_read(priv->flash, AUTO_UPDATE_DIRECTORY_BASE, erase_size, &bytes_read,225(u_char *)buffer);226if (ret)227return ret;228229if (bytes_read != erase_size)230return -EIO;231232if ((*(u32 *)(buffer + AUTO_UPDATE_UPGRADE_DIRECTORY) == image_address) &&233!(*(u32 *)(buffer + AUTO_UPDATE_BLANK_DIRECTORY)))234return 0;235236ret = mtd_erase(priv->flash, &erase);237if (ret)238return ret;239240/*241* Populate the image address and then zero out the next directory so242* that the system controller doesn't complain if in "Single Image"243* mode.244*/245memcpy(buffer + AUTO_UPDATE_UPGRADE_DIRECTORY, &image_address,246AUTO_UPDATE_DIRECTORY_WIDTH);247memset(buffer + AUTO_UPDATE_BLANK_DIRECTORY, 0x0, AUTO_UPDATE_DIRECTORY_WIDTH);248249dev_info(priv->dev, "Writing the image address (0x%x) to the flash directory (0x%llx)\n",250image_address, directory_address);251252ret = mtd_write(priv->flash, 0x0, erase_size, &bytes_written, (u_char *)buffer);253if (ret)254return ret;255256if (bytes_written != erase_size)257return -EIO;258259return 0;260}261262static int mpfs_auto_update_write_bitstream(struct fw_upload *fw_uploader, const u8 *data,263u32 offset, u32 size, u32 *written)264{265struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;266struct erase_info erase;267loff_t directory_address = AUTO_UPDATE_UPGRADE_DIRECTORY;268size_t erase_size = AUTO_UPDATE_DIRECTORY_SIZE;269size_t bytes_written = 0;270bool is_info = mpfs_auto_update_is_bitstream_info(data, size);271u32 image_address;272int ret;273274erase_size = round_up(erase_size, (u64)priv->flash->erasesize);275276if (is_info)277image_address = AUTO_UPDATE_INFO_BASE;278else279image_address = AUTO_UPDATE_BITSTREAM_BASE +280AUTO_UPDATE_UPGRADE_INDEX * priv->size_per_bitstream;281282/*283* For bitstream info, the descriptor is written to a fixed offset,284* so there is no need to set the image address.285*/286if (!is_info) {287ret = mpfs_auto_update_set_image_address(priv, image_address, directory_address);288if (ret) {289dev_err(priv->dev, "failed to set image address in the SPI directory: %d\n", ret);290return ret;291}292} else {293if (size > AUTO_UPDATE_INFO_SIZE) {294dev_err(priv->dev, "bitstream info exceeds permitted size\n");295return -ENOSPC;296}297}298299/*300* Now the .spi image itself can be written to the flash. Preservation301* of contents here is not important here, unlike the spi "directory"302* which must be RMWed.303*/304erase.len = round_up(size, (size_t)priv->flash->erasesize);305erase.addr = image_address;306307dev_info(priv->dev, "Erasing the flash at address (0x%x)\n", image_address);308ret = mtd_erase(priv->flash, &erase);309if (ret)310return ret;311312/*313* No parsing etc of the bitstream is required. The system controller314* will do all of that itself - including verifying that the bitstream315* is valid.316*/317dev_info(priv->dev, "Writing the image to the flash at address (0x%x)\n", image_address);318ret = mtd_write(priv->flash, (loff_t)image_address, size, &bytes_written, data);319if (ret)320return ret;321322if (bytes_written != size)323return -EIO;324325*written = bytes_written;326dev_info(priv->dev, "Wrote 0x%zx bytes to the flash\n", bytes_written);327328return 0;329}330331static enum fw_upload_err mpfs_auto_update_write(struct fw_upload *fw_uploader, const u8 *data,332u32 offset, u32 size, u32 *written)333{334struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;335int ret;336337ret = mpfs_auto_update_write_bitstream(fw_uploader, data, offset, size, written);338if (ret)339return FW_UPLOAD_ERR_RW_ERROR;340341if (priv->cancel_request)342return FW_UPLOAD_ERR_CANCELED;343344if (mpfs_auto_update_is_bitstream_info(data, size))345return FW_UPLOAD_ERR_NONE;346347ret = mpfs_auto_update_verify_image(fw_uploader);348if (ret)349return FW_UPLOAD_ERR_FW_INVALID;350351return FW_UPLOAD_ERR_NONE;352}353354static const struct fw_upload_ops mpfs_auto_update_ops = {355.prepare = mpfs_auto_update_prepare,356.write = mpfs_auto_update_write,357.poll_complete = mpfs_auto_update_poll_complete,358.cancel = mpfs_auto_update_cancel,359};360361static int mpfs_auto_update_available(struct mpfs_auto_update_priv *priv)362{363u32 *response_msg __free(kfree) =364kzalloc(AUTO_UPDATE_FEATURE_RESP_SIZE * sizeof(*response_msg), GFP_KERNEL);365struct mpfs_mss_response *response __free(kfree) =366kzalloc(sizeof(struct mpfs_mss_response), GFP_KERNEL);367struct mpfs_mss_msg *message __free(kfree) =368kzalloc(sizeof(struct mpfs_mss_msg), GFP_KERNEL);369int ret;370371if (!response_msg || !response || !message)372return -ENOMEM;373374/*375* To verify that Auto Update is possible, the "Query Security Service376* Request" is performed.377* This service has no command data & does not overload mbox_offset.378*/379response->resp_msg = response_msg;380response->resp_size = AUTO_UPDATE_FEATURE_RESP_SIZE;381message->cmd_opcode = AUTO_UPDATE_FEATURE_CMD_OPCODE;382message->cmd_data_size = AUTO_UPDATE_FEATURE_CMD_DATA_SIZE;383message->response = response;384message->cmd_data = AUTO_UPDATE_FEATURE_CMD_DATA;385message->mbox_offset = AUTO_UPDATE_DEFAULT_MBOX_OFFSET;386message->resp_offset = AUTO_UPDATE_DEFAULT_RESP_OFFSET;387388ret = mpfs_blocking_transaction(priv->sys_controller, message);389if (ret)390return ret;391392/*393* Currently, the system controller's firmware does not generate any394* interrupts for failed services, so mpfs_blocking_transaction() should395* time out & therefore return an error.396* Hitting this check is highly unlikely at present, but if the system397* controller's behaviour changes so that it does generate interrupts398* for failed services, it will be required.399*/400if (response->resp_status)401return -EIO;402403/*404* Bit 5 of byte 1 is "UL_IAP" & if it is set, Auto Update is405* not possible.406*/407if ((((u8 *)response_msg)[1] & AUTO_UPDATE_FEATURE_ENABLED))408return -EPERM;409410return 0;411}412413static int mpfs_auto_update_probe(struct platform_device *pdev)414{415struct device *dev = &pdev->dev;416struct mpfs_auto_update_priv *priv;417struct fw_upload *fw_uploader;418int ret;419420priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);421if (!priv)422return -ENOMEM;423424priv->sys_controller = mpfs_sys_controller_get(dev);425if (IS_ERR(priv->sys_controller))426return dev_err_probe(dev, PTR_ERR(priv->sys_controller),427"Could not register as a sub device of the system controller\n");428429priv->dev = dev;430platform_set_drvdata(pdev, priv);431432ret = mpfs_auto_update_available(priv);433if (ret)434return dev_err_probe(dev, ret,435"The current bitstream does not support auto-update\n");436437fw_uploader = firmware_upload_register(THIS_MODULE, dev, "mpfs-auto-update",438&mpfs_auto_update_ops, priv);439if (IS_ERR(fw_uploader))440return dev_err_probe(dev, PTR_ERR(fw_uploader),441"Failed to register the bitstream uploader\n");442443priv->fw_uploader = fw_uploader;444445return 0;446}447448static void mpfs_auto_update_remove(struct platform_device *pdev)449{450struct mpfs_auto_update_priv *priv = platform_get_drvdata(pdev);451452firmware_upload_unregister(priv->fw_uploader);453}454455static struct platform_driver mpfs_auto_update_driver = {456.driver = {457.name = "mpfs-auto-update",458},459.probe = mpfs_auto_update_probe,460.remove = mpfs_auto_update_remove,461};462module_platform_driver(mpfs_auto_update_driver);463464MODULE_LICENSE("GPL");465MODULE_AUTHOR("Conor Dooley <[email protected]>");466MODULE_DESCRIPTION("PolarFire SoC Auto Update FPGA reprogramming");467468469