pldmtool: Add GetFirmwareParameters firmware update command
Tested:
pldmtool fw_update GetFwParams -m <eid>
{
"CapabilitiesDuringUpdate": {
"Component Update Failure Recovery Capability": "Device will revert to previous component image upon failure, timeout or cancellation of the transfer.",
"Component Update Failure Retry Capability": " Device can have component updated again without exiting update mode and restarting transfer via RequestUpdate command.",
"Firmware Device Partial Updates": "Firmware Device cannot accept a partial update and all components present on the FD shall be updated.",
"Firmware Device Host Functionality during Firmware Update": "Device will revert to previous component image upon failure, timeout or cancellation of the transfer",
"Firmware Device Update Mode Restrictions": "No host OS environment restriction for update mode"
},
"ComponentCount": 2,
"ActiveComponentImageSetVersionString": "XXXXXXXX",
"PendingComponentImageSetVersionString": "",
"ComponentParameterEntries": [
{
"ComponentClassification": "Firmware",
"ComponentIdentifier": 1,
"ComponentClassificationIndex": 0,
"ActiveComponentComparisonStamp": 0,
"ActiveComponentReleaseDate": "",
"PendingComponentComparisonStamp": 0,
"PendingComponentReleaseDate": "",
"ComponentActivationMethods": [
"System reboot"
],
"CapabilitiesDuringUpdate": {
"Firmware Device apply state functionality": " Firmware Device will execute an operation during the APPLY state which will include migrating the new component image to its final non-volatile storage destination."
},
"ActiveComponentVersionString": "XXXXXXXX",
"PendingComponentVersionString": ""
},
{
"ComponentClassification": "Firmware",
"ComponentIdentifier": 2,
"ComponentClassificationIndex": 0,
"ActiveComponentComparisonStamp": 0,
"ActiveComponentReleaseDate": "",
"PendingComponentComparisonStamp": 0,
"PendingComponentReleaseDate": "",
"ComponentActivationMethods": [
"System reboot"
],
"CapabilitiesDuringUpdate": {
"Firmware Device apply state functionality": " Firmware Device will execute an operation during the APPLY state which will include migrating the new component image to its final non-volatile storage destination."
},
"ActiveComponentVersionString": "XXXXXXXX",
"PendingComponentVersionString": ""
}
]
}
Signed-off-by: Tom Joseph <rushtotom@gmail.com>
Change-Id: I1370beca144853f3b638a7541a8589282ccf1273
diff --git a/pldmtool/pldm_fw_update_cmd.cpp b/pldmtool/pldm_fw_update_cmd.cpp
index 857c2e6..b48a7f6 100644
--- a/pldmtool/pldm_fw_update_cmd.cpp
+++ b/pldmtool/pldm_fw_update_cmd.cpp
@@ -126,6 +126,269 @@
}
};
+const std::map<uint16_t, std::string> componentClassification{
+ {PLDM_COMP_UNKNOWN, "Unknown"},
+ {PLDM_COMP_OTHER, "Other"},
+ {PLDM_COMP_DRIVER, "Driver"},
+ {PLDM_COMP_CONFIGURATION_SOFTWARE, "Configuration Software"},
+ {PLDM_COMP_APPLICATION_SOFTWARE, "Application Software"},
+ {PLDM_COMP_INSTRUMENTATION, "Instrumentation"},
+ {PLDM_COMP_FIRMWARE_OR_BIOS, "Firmware/BIOS"},
+ {PLDM_COMP_DIAGNOSTIC_SOFTWARE, "Diagnostic Software"},
+ {PLDM_COMP_OPERATING_SYSTEM, "Operating System"},
+ {PLDM_COMP_MIDDLEWARE, "Middleware"},
+ {PLDM_COMP_FIRMWARE, "Firmware"},
+ {PLDM_COMP_BIOS_OR_FCODE, "BIOS/FCode"},
+ {PLDM_COMP_SUPPORT_OR_SERVICEPACK, "Support/Service Pack"},
+ {PLDM_COMP_SOFTWARE_BUNDLE, "Software Bundle"},
+ {PLDM_COMP_DOWNSTREAM_DEVICE, "Downstream Device"}};
+
+class GetFwParams : public CommandInterface
+{
+ public:
+ ~GetFwParams() = default;
+ GetFwParams() = delete;
+ GetFwParams(const GetFwParams&) = delete;
+ GetFwParams(GetFwParams&&) = default;
+ GetFwParams& operator=(const GetFwParams&) = delete;
+ GetFwParams& operator=(GetFwParams&&) = default;
+
+ using CommandInterface::CommandInterface;
+
+ std::pair<int, std::vector<uint8_t>> createRequestMsg() override
+ {
+ std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
+ PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES);
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+ auto rc = encode_get_firmware_parameters_req(
+ instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, request);
+ return {rc, requestMsg};
+ }
+
+ void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
+ {
+ pldm_get_firmware_parameters_resp fwParams{};
+ variable_field activeCompImageSetVersion{};
+ variable_field pendingCompImageSetVersion{};
+ variable_field compParameterTable{};
+
+ auto rc = decode_get_firmware_parameters_resp(
+ responsePtr, payloadLength, &fwParams, &activeCompImageSetVersion,
+ &pendingCompImageSetVersion, &compParameterTable);
+ if (rc != PLDM_SUCCESS || fwParams.completion_code != PLDM_SUCCESS)
+ {
+ std::cerr << "Response Message Error: "
+ << "rc=" << rc << ",cc=" << (int)fwParams.completion_code
+ << "\n";
+ return;
+ }
+
+ ordered_json capabilitiesDuringUpdate;
+ if (fwParams.capabilities_during_update.bits.bit0)
+ {
+ capabilitiesDuringUpdate
+ ["Component Update Failure Recovery Capability"] =
+ "Device will not revert to previous component image upon failure, timeout or cancellation of the transfer.";
+ }
+ else
+ {
+ capabilitiesDuringUpdate
+ ["Component Update Failure Recovery Capability"] =
+ "Device will revert to previous component image upon failure, timeout or cancellation of the transfer.";
+ }
+
+ if (fwParams.capabilities_during_update.bits.bit1)
+ {
+ capabilitiesDuringUpdate["Component Update Failure Retry Capability"] =
+ "Device will not be able to update component again unless it exits update mode and the UA sends a new Request Update command.";
+ }
+ else
+ {
+ capabilitiesDuringUpdate["Component Update Failure Retry Capability"] =
+ " Device can have component updated again without exiting update mode and restarting transfer via RequestUpdate command.";
+ }
+
+ if (fwParams.capabilities_during_update.bits.bit2)
+ {
+ capabilitiesDuringUpdate["Firmware Device Partial Updates"] =
+ "Firmware Device can support a partial update, whereby a package which contains a component image set that is a subset of all components currently residing on the FD, can be transferred.";
+ }
+ else
+ {
+ capabilitiesDuringUpdate["Firmware Device Partial Updates"] =
+ "Firmware Device cannot accept a partial update and all components present on the FD shall be updated.";
+ }
+
+ if (fwParams.capabilities_during_update.bits.bit3)
+ {
+ capabilitiesDuringUpdate
+ ["Firmware Device Host Functionality during Firmware Update"] =
+ "Device will not revert to previous component image upon failure, timeout or cancellation of the transfer";
+ }
+ else
+ {
+ capabilitiesDuringUpdate
+ ["Firmware Device Host Functionality during Firmware Update"] =
+ "Device will revert to previous component image upon failure, timeout or cancellation of the transfer";
+ }
+
+ if (fwParams.capabilities_during_update.bits.bit4)
+ {
+ capabilitiesDuringUpdate["Firmware Device Update Mode Restrictions"] =
+ "Firmware device unable to enter update mode if host OS environment is active.";
+ }
+ else
+ {
+ capabilitiesDuringUpdate
+ ["Firmware Device Update Mode Restrictions"] =
+ "No host OS environment restriction for update mode";
+ }
+
+ ordered_json data;
+ data["CapabilitiesDuringUpdate"] = capabilitiesDuringUpdate;
+ data["ComponentCount"] = static_cast<uint16_t>(fwParams.comp_count);
+ data["ActiveComponentImageSetVersionString"] =
+ pldm::utils::toString(activeCompImageSetVersion);
+ data["PendingComponentImageSetVersionString"] =
+ pldm::utils::toString(pendingCompImageSetVersion);
+
+ auto compParamPtr = compParameterTable.ptr;
+ auto compParamTableLen = compParameterTable.length;
+ pldm_component_parameter_entry compEntry{};
+ variable_field activeCompVerStr{};
+ variable_field pendingCompVerStr{};
+ ordered_json compDataEntries;
+
+ while (fwParams.comp_count-- && (compParamTableLen > 0))
+ {
+ ordered_json compData;
+ auto rc = decode_get_firmware_parameters_resp_comp_entry(
+ compParamPtr, compParamTableLen, &compEntry, &activeCompVerStr,
+ &pendingCompVerStr);
+ if (rc)
+ {
+ std::cerr
+ << "Decoding component parameter table entry failed, RC="
+ << rc << "\n";
+ return;
+ }
+
+ if (componentClassification.contains(compEntry.comp_classification))
+ {
+ compData["ComponentClassification"] =
+ componentClassification.at(compEntry.comp_classification);
+ }
+ else
+ {
+ compData["ComponentClassification"] =
+ static_cast<uint16_t>(compEntry.comp_classification);
+ }
+ compData["ComponentIdentifier"] =
+ static_cast<uint16_t>(compEntry.comp_identifier);
+ compData["ComponentClassificationIndex"] =
+ static_cast<uint8_t>(compEntry.comp_classification_index);
+ compData["ActiveComponentComparisonStamp"] =
+ static_cast<uint32_t>(compEntry.active_comp_comparison_stamp);
+
+ // ActiveComponentReleaseData
+ std::array<uint8_t, 8> noReleaseData{0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
+ if (std::equal(noReleaseData.begin(), noReleaseData.end(),
+ compEntry.active_comp_release_date))
+ {
+ compData["ActiveComponentReleaseDate"] = "";
+ }
+ else
+ {
+ std::string activeComponentReleaseDate(
+ reinterpret_cast<const char*>(
+ compEntry.active_comp_release_date),
+ sizeof(compEntry.active_comp_release_date));
+ compData["ActiveComponentReleaseDate"] =
+ activeComponentReleaseDate;
+ }
+
+ compData["PendingComponentComparisonStamp"] =
+ static_cast<uint32_t>(compEntry.pending_comp_comparison_stamp);
+
+ // PendingComponentReleaseData
+ if (std::equal(noReleaseData.begin(), noReleaseData.end(),
+ compEntry.pending_comp_release_date))
+ {
+ compData["PendingComponentReleaseDate"] = "";
+ }
+ else
+ {
+ std::string pendingComponentReleaseDate(
+ reinterpret_cast<const char*>(
+ compEntry.pending_comp_release_date),
+ sizeof(compEntry.pending_comp_release_date));
+ compData["PendingComponentReleaseDate"] =
+ pendingComponentReleaseDate;
+ }
+
+ // ComponentActivationMethods
+ ordered_json componentActivationMethods;
+ if (compEntry.comp_activation_methods.bits.bit0)
+ {
+ componentActivationMethods.push_back("Automatic");
+ }
+ else if (compEntry.comp_activation_methods.bits.bit1)
+ {
+ componentActivationMethods.push_back("Self-Contained");
+ }
+ else if (compEntry.comp_activation_methods.bits.bit2)
+ {
+ componentActivationMethods.push_back("Medium-specific reset");
+ }
+ else if (compEntry.comp_activation_methods.bits.bit3)
+ {
+ componentActivationMethods.push_back("System reboot");
+ }
+ else if (compEntry.comp_activation_methods.bits.bit4)
+ {
+ componentActivationMethods.push_back("DC power cycel");
+ }
+ else if (compEntry.comp_activation_methods.bits.bit5)
+ {
+ componentActivationMethods.push_back("AC power cycle");
+ }
+ compData["ComponentActivationMethods"] = componentActivationMethods;
+
+ // CapabilitiesDuringUpdate
+ ordered_json compCapabilitiesDuringUpdate;
+ if (compEntry.capabilities_during_update.bits.bit0)
+ {
+ compCapabilitiesDuringUpdate
+ ["Firmware Device apply state functionality"] =
+ "Firmware Device performs an auto-apply during transfer phase and apply step will be completed immediately.";
+ }
+ else
+ {
+ compCapabilitiesDuringUpdate
+ ["Firmware Device apply state functionality"] =
+ " Firmware Device will execute an operation during the APPLY state which will include migrating the new component image to its final non-volatile storage destination.";
+ }
+ compData["CapabilitiesDuringUpdate"] = compCapabilitiesDuringUpdate;
+
+ compData["ActiveComponentVersionString"] =
+ pldm::utils::toString(activeCompVerStr);
+ compData["PendingComponentVersionString"] =
+ pldm::utils::toString(pendingCompVerStr);
+
+ compParamPtr += sizeof(pldm_component_parameter_entry) +
+ activeCompVerStr.length + pendingCompVerStr.length;
+ compParamTableLen -= sizeof(pldm_component_parameter_entry) +
+ activeCompVerStr.length +
+ pendingCompVerStr.length;
+ compDataEntries.push_back(compData);
+ }
+ data["ComponentParameterEntries"] = compDataEntries;
+
+ pldmtool::helper::DisplayInJson(data);
+ }
+};
+
void registerCommand(CLI::App& app)
{
auto fwUpdate =
@@ -135,6 +398,11 @@
auto getStatus = fwUpdate->add_subcommand("GetStatus", "Status of the FD");
commands.push_back(
std::make_unique<GetStatus>("fw_update", "GetStatus", getStatus));
+
+ auto getFwParams = fwUpdate->add_subcommand(
+ "GetFwParams", "To get the component details of the FD");
+ commands.push_back(
+ std::make_unique<GetFwParams>("fw_update", "GetFwParams", getFwParams));
}
} // namespace fw_update