wcxb: Update the firmware meta block during flash update.
The meta block contains specific version and checksum information and allows the test tools to validate the image in the flash. Signed-off-by: Shaun Ruffell <sruffell@digium.com>
This commit is contained in:
parent
eed2e4e00b
commit
69a716af1a
@ -761,6 +761,12 @@ int wcxb_start(struct wcxb *xb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wcxb_meta_block {
|
||||||
|
__le32 chksum;
|
||||||
|
__le32 version;
|
||||||
|
__le32 size;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
struct wcxb_firm_header {
|
struct wcxb_firm_header {
|
||||||
u8 header[6];
|
u8 header[6];
|
||||||
__le32 chksum;
|
__le32 chksum;
|
||||||
@ -786,32 +792,54 @@ static int wcxb_update_firmware(struct wcxb *xb, const struct firmware *fw,
|
|||||||
const char *filename)
|
const char *filename)
|
||||||
{
|
{
|
||||||
u32 tdm_control;
|
u32 tdm_control;
|
||||||
int offset = 0x200000;
|
static const int APPLICATION_ADDRESS = 0x200000;
|
||||||
const u8 *data, *end;
|
static const int META_BLOCK_OFFSET = 0x170000;
|
||||||
|
static const int ERASE_BLOCK_SIZE = 0x010000;
|
||||||
|
static const int END_OFFSET = APPLICATION_ADDRESS + META_BLOCK_OFFSET +
|
||||||
|
ERASE_BLOCK_SIZE;
|
||||||
struct wcxb_spi_master *flash_spi_master;
|
struct wcxb_spi_master *flash_spi_master;
|
||||||
struct wcxb_spi_device *flash_spi_device;
|
struct wcxb_spi_device *flash_spi_device;
|
||||||
|
struct wcxb_meta_block meta;
|
||||||
|
int offset;
|
||||||
|
struct wcxb_firm_header *head = (struct wcxb_firm_header *)(fw->data);
|
||||||
|
|
||||||
|
if (fw->size > (META_BLOCK_OFFSET + sizeof(*head))) {
|
||||||
|
dev_err(&xb->pdev->dev,
|
||||||
|
"Firmware is too large to fit in available space.\n");
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
meta.size = cpu_to_le32(fw->size);
|
||||||
|
meta.version = head->version;
|
||||||
|
meta.chksum = head->chksum;
|
||||||
|
|
||||||
flash_spi_master = wcxb_spi_master_create(&xb->pdev->dev,
|
flash_spi_master = wcxb_spi_master_create(&xb->pdev->dev,
|
||||||
xb->membase + FLASH_SPI_BASE,
|
xb->membase + FLASH_SPI_BASE,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
flash_spi_device = wcxb_spi_device_create(flash_spi_master, 0);
|
flash_spi_device = wcxb_spi_device_create(flash_spi_master, 0);
|
||||||
|
|
||||||
dev_info(&xb->pdev->dev,
|
dev_info(&xb->pdev->dev,
|
||||||
"Uploading %s. This can take up to 30 seconds.\n", filename);
|
"Uploading %s. This can take up to 30 seconds.\n", filename);
|
||||||
|
|
||||||
data = &fw->data[sizeof(struct wcxb_firm_header)];
|
|
||||||
end = &fw->data[fw->size];
|
|
||||||
|
|
||||||
while (data < end) {
|
/* First erase all the blocks in the application area. */
|
||||||
|
offset = APPLICATION_ADDRESS;
|
||||||
|
while (offset < END_OFFSET) {
|
||||||
wcxb_flash_sector_erase(flash_spi_device, offset);
|
wcxb_flash_sector_erase(flash_spi_device, offset);
|
||||||
data += 0x10000;
|
offset += ERASE_BLOCK_SIZE;
|
||||||
offset += 0x10000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data = &fw->data[sizeof(struct wcxb_firm_header)];
|
/* Then write the new firmware file. */
|
||||||
offset = 0x200000;
|
wcxb_flash_write(flash_spi_device, APPLICATION_ADDRESS,
|
||||||
|
&fw->data[sizeof(struct wcxb_firm_header)],
|
||||||
|
fw->size - sizeof(struct wcxb_firm_header));
|
||||||
|
|
||||||
wcxb_flash_write(flash_spi_device, offset, data, end-data);
|
/* Finally, update the meta block. */
|
||||||
|
wcxb_flash_write(flash_spi_device,
|
||||||
|
APPLICATION_ADDRESS + META_BLOCK_OFFSET,
|
||||||
|
&meta, sizeof(meta));
|
||||||
|
|
||||||
/* Reset fpga after loading firmware */
|
/* Reset fpga after loading firmware */
|
||||||
dev_info(&xb->pdev->dev, "Firmware load complete. Reseting device.\n");
|
dev_info(&xb->pdev->dev, "Firmware load complete. Reseting device.\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user