[Skiboot] [PATCH V3 09/15] core/pldm: Decode the GetPDR request
Abhishek SIngh Tomar
abhishek at linux.ibm.com
Mon Oct 3 16:16:52 AEDT 2022
On Tue, Sep 13, 2022 at 12:27:18PM +0200, Christophe Lombard wrote:
> The GetPDR command is used to retrieve individual PDRs from a PDR
> repository. The record is identified by the PDR recordHandle value
> that is passed in the request.
>
> Signed-off-by: Christophe Lombard <clombard at linux.vnet.ibm.com>
Reviewed-by: Abhishek Singh Tomar
> ---
> core/pldm/pldm-responder.c | 127 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 127 insertions(+)
>
> diff --git a/core/pldm/pldm-responder.c b/core/pldm/pldm-responder.c
> index bbfd167d..8fbd57c3 100644
> --- a/core/pldm/pldm-responder.c
> +++ b/core/pldm/pldm-responder.c
> @@ -788,6 +788,132 @@ static struct pldm_cmd pldm_platform_set_state_effecter_states = {
> .handler = platform_set_state_effecter_states_handler,
> };
>
> +struct get_pdr_req {
> + uint32_t record_handle;
> + uint32_t data_transfer_handle;
> + uint8_t transfer_op_flag;
> + uint16_t request_count;
> + uint16_t record_change_number;
> +};
> +
> +/*
> + * GetPDR (0x51)
> + * The GetPDR command is used to retrieve individual PDRs from a PDR
> + * Repository. The record is identified by the PDR recordHandle value
> + * that is passed in the request.
> + */
> +static int platform_get_pdr_handle(const struct pldm_rx_data *req)
> +{
> + size_t payload_len, response_length;
> + uint32_t next_record_handle;
> + struct get_pdr_req pdr_req;
> + uint8_t *pdr_data = NULL;
> + uint32_t pdr_data_size = 0;
> + char *response_msg;
> + int rc;
> +
> + payload_len = req->msg_len - sizeof(struct pldm_msg_hdr);
> + rc = decode_get_pdr_req(req->msg,
> + payload_len,
> + &pdr_req.record_handle,
> + &pdr_req.data_transfer_handle,
> + &pdr_req.transfer_op_flag,
> + &pdr_req.request_count,
> + &pdr_req.record_change_number);
> + if (rc) {
> + prlog(PR_ERR, "Failed to decode GetPDR request, rc = %d\n", rc);
> + cc_resp(req, req->hdrinf.pldm_type,
> + req->hdrinf.command, PLDM_ERROR);
> + return OPAL_INTERNAL_ERROR;
> + }
> +
> + if (pdr_req.data_transfer_handle != 0) {
> + /* We don't support multipart transfers */
> + prlog(PR_ERR, "Got invalid data transfer handle 0x%x in GetPDR request\n",
> + pdr_req.data_transfer_handle);
> + cc_resp(req, req->hdrinf.pldm_type,
> + req->hdrinf.command,
> + PLDM_PLATFORM_INVALID_DATA_TRANSFER_HANDLE);
> + return OPAL_PARAMETER;
> + }
> +
> + if (pdr_req.transfer_op_flag != PLDM_GET_FIRSTPART) {
> + prlog(PR_ERR, "Got invalid transfer op flag 0x%x in GetPDR request\n",
> + pdr_req.transfer_op_flag);
> + cc_resp(req, req->hdrinf.pldm_type,
> + req->hdrinf.command,
> + PLDM_PLATFORM_INVALID_TRANSFER_OPERATION_FLAG);
> + return OPAL_PARAMETER;
> + }
> +
> + if (pdr_req.record_change_number != 0) {
> + prlog(PR_ERR, "Got invalid record change number 0x%x in GetPDR request\n",
> + pdr_req.record_change_number);
> + cc_resp(req, req->hdrinf.pldm_type,
> + req->hdrinf.command,
> + PLDM_PLATFORM_INVALID_RECORD_CHANGE_NUMBER);
> + return OPAL_PARAMETER;
> + }
> +
> + /* find PDR record by record handle */
> + prlog(PR_INFO, "BMC requesting PDR handle %d\n", pdr_req.record_handle);
> +
> + rc = pldm_platform_pdr_find_record(pdr_req.record_handle,
> + &pdr_data,
> + &pdr_data_size,
> + &next_record_handle);
> + if (rc) {
> + prlog(PR_ERR, "Got invalid record handle 0x%x in GetPDR request\n",
> + pdr_req.record_handle);
> + cc_resp(req, req->hdrinf.pldm_type,
> + req->hdrinf.command,
> + PLDM_PLATFORM_INVALID_RECORD_HANDLE);
> + return OPAL_PARAMETER;
> + }
> +
> + response_length = sizeof(struct pldm_msg_hdr) +
> + sizeof(struct pldm_get_pdr_resp) +
> + pdr_data_size;
> + response_msg = zalloc(response_length);
> + memset(response_msg, 0, response_length);
> +
> + /* create a PLDM response message for GetPDR */
> + rc = encode_get_pdr_resp(req->hdrinf.instance,
> + PLDM_SUCCESS,
> + next_record_handle,
> + 0, /* No remaining data */
> + PLDM_START_AND_END,
> + pdr_data_size,
> + pdr_data,
> + 0, /* CRC not used for START_AND_END */
> + (struct pldm_msg *)response_msg);
> + if (rc != PLDM_SUCCESS) {
> + prlog(PR_ERR, "Encode GetPDR Error, rc: %d\n", rc);
> + cc_resp(req, req->hdrinf.pldm_type,
> + req->hdrinf.command, PLDM_ERROR);
> + free(response_msg);
> + return OPAL_PARAMETER;
> + }
> +
> + /* send PLDM message over MCTP */
> + rc = pldm_mctp_message_tx(req->source_eid, response_msg, response_length - 1);
> + if (rc) {
> + prlog(PR_ERR, "Failed to send GetPDR response, rc = %d\n", rc);
> + free(response_msg);
> + return OPAL_HARDWARE;
> + }
> +
> + free(response_msg);
> +
> + return OPAL_SUCCESS;
> +}
> +
> +static struct pldm_cmd pldm_platform_get_pdr = {
> + .name = "PLDM_GET_PDR",
> + .pldm_cmd_id = PLDM_GET_PDR,
> + .handler = platform_get_pdr_handle,
> +};
> +
> int pldm_responder_handle_request(struct pldm_rx_data *rx)
> {
> const struct pldm_type *type;
> @@ -834,6 +960,7 @@ int pldm_responder_init(void)
> add_cmd(&pldm_platform_type, &pldm_platform_event_message);
> add_cmd(&pldm_platform_type, &pldm_platform_get_state_sensor_readings);
> add_cmd(&pldm_platform_type, &pldm_platform_set_state_effecter_states);
> + add_cmd(&pldm_platform_type, &pldm_platform_get_pdr);
>
> return OPAL_SUCCESS;
> }
> --
> 2.37.3
>
> _______________________________________________
> Skiboot mailing list
> Skiboot at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/skiboot
More information about the Skiboot
mailing list