Message ID | 20220913102724.65563-10-clombard@linux.vnet.ibm.com |
---|---|
State | Superseded |
Headers | show |
Series | Complete PLDM responder and enable PLDM support | expand |
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@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@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/skiboot
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; }
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@linux.vnet.ibm.com> --- core/pldm/pldm-responder.c | 127 +++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+)