in meta-facebook/yv35-bb/src/ipmi/plat_ipmi.c [635:707]
void pal_OEM_1S_FW_UPDATE(ipmi_msg *msg)
{
/*********************************
* buf 0: target, 0x80 indicate last byte
* buf 1~4: offset, 1 lsb
* buf 5~6: length, 5 lsb
* buf 7~N: data
***********************************/
if (msg->data_len < 8) {
msg->completion_code = CC_INVALID_LENGTH;
return;
}
uint8_t target = msg->data[0], status = 0;
uint32_t offset =
((msg->data[4] << 24) | (msg->data[3] << 16) | (msg->data[2] << 8) | msg->data[1]);
uint16_t length = ((msg->data[6] << 8) | msg->data[5]);
if ((length == 0) || (length != msg->data_len - 7)) {
msg->completion_code = CC_INVALID_LENGTH;
return;
}
if ((target == BIC_UPDATE) || (target == (BIC_UPDATE | UPDATE_EN))) {
if (offset > 0x50000) { // Expect BIC firmware size not bigger than 320k
msg->completion_code = CC_PARAM_OUT_OF_RANGE;
return;
}
status = fw_update(offset, length, &msg->data[7], (target & UPDATE_EN),
devspi_fmc_cs0);
} else if (target & CPLD_UPDATE) {
if (offset == 0) {
printf("[CPLD] CPLD update start\n");
}
status = cpld_altera_fw_update(offset, length, &msg->data[7]);
} else {
return msg->completion_code = CC_PARAM_OUT_OF_RANGE;
}
msg->data_len = 0;
switch (status) {
case fwupdate_success:
msg->completion_code = CC_SUCCESS;
break;
case fwupdate_out_of_heap:
msg->completion_code = CC_LENGTH_EXCEEDED;
break;
case fwupdate_over_length:
msg->completion_code = CC_OUT_OF_SPACE;
break;
case fwupdate_repeated_updated:
msg->completion_code = CC_INVALID_DATA_FIELD;
break;
case fwupdate_update_fail:
msg->completion_code = CC_TIMEOUT;
break;
case fwupdate_error_offset:
msg->completion_code = CC_PARAM_OUT_OF_RANGE;
break;
default:
msg->completion_code = CC_UNSPECIFIED_ERROR;
break;
}
if (status != fwupdate_success) {
printf("firmware (0x%02X) update failed cc: %x\n", target, msg->completion_code);
}
return;
}