in common/util/util_spi.c [166:265]
uint8_t fw_update(uint32_t offset, uint16_t msg_len, uint8_t *msg_buf, bool update_en,
uint8_t spi_bus)
{
static bool is_init = 0;
static uint8_t *txbuf = NULL;
static uint32_t buf_offset = 0;
uint32_t ret = 0;
const struct device *flash_dev;
if (!is_init) {
if ((offset & 0x0000) != 0) {
return fwupdate_error_offset;
}
if (txbuf != NULL) {
free(txbuf);
txbuf = NULL;
}
txbuf = (uint8_t *)malloc(sector_sz_64k);
if (txbuf == NULL) { // Retry alloc
k_msleep(100);
txbuf = (uint8_t *)malloc(sector_sz_64k);
}
if (txbuf == NULL) {
printk("spi index%x update buffer alloc fail\n", spi_bus);
return fwupdate_out_of_heap;
}
is_init = 1;
buf_offset = 0;
k_msleep(10);
}
if ((buf_offset + msg_len) > sector_sz_64k) {
printk("spi bus%x recv data %d over sector size %d\n", spi_bus,
buf_offset + msg_len, sector_sz_64k);
free(txbuf);
txbuf = NULL;
k_msleep(10);
is_init = 0;
return fwupdate_over_length;
}
if ((offset % sector_sz_64k) != buf_offset) {
printk("spi bus%x recorded offset 0x%x but updating 0x%x\n", spi_bus, buf_offset,
offset % sector_sz_64k);
free(txbuf);
txbuf = NULL;
k_msleep(10);
is_init = 0;
return fwupdate_repeated_updated;
}
if (FW_UPDATE_DEBUG) {
printk("spi bus%x update offset %x %x, msg_len %d, update_en %d, msg_buf: %2x %2x %2x %2x\n",
spi_bus, offset, buf_offset, msg_len, update_en, msg_buf[0], msg_buf[1],
msg_buf[2], msg_buf[3]);
}
memcpy(&txbuf[buf_offset], msg_buf, msg_len);
buf_offset += msg_len;
if ((buf_offset == sector_sz_64k) ||
update_en) { // Update fmc while collect 64k bytes data or BMC signal last image package with target | 0x80
flash_dev = device_get_binding(flash_device[spi_bus]);
uint8_t sector = 16;
uint32_t txbuf_offset;
uint32_t update_offset;
for (int i = 0; i < sector; i++) {
txbuf_offset = sector_sz_4k * i;
update_offset = (offset / sector_sz_64k) * sector_sz_64k + txbuf_offset;
ret = do_update(flash_dev, update_offset, &txbuf[txbuf_offset],
sector_sz_4k);
if (ret) {
printk("SPI update fail status: %x\n", ret);
break;
}
}
if (!ret) {
printk("Update success\n");
}
free(txbuf);
txbuf = NULL;
k_msleep(10);
is_init = 0;
if (FW_UPDATE_DEBUG) {
printk("***update %x, offset %x, sector_sz_16k %x\n",
(offset / sector_sz_16k) * sector_sz_16k, offset, sector_sz_16k);
}
if (update_en && spi_bus == (devspi_fmc_cs0)) { // reboot bic itself after fw update
submit_bic_warm_reset();
}
return ret;
}
return fwupdate_success;
}