Message ID | 20220304131154.58409-11-clombard@linux.vnet.ibm.com |
---|---|
State | Superseded |
Headers | show |
Series | Implement MCTP and PLDM features | expand |
hello Christophe Lombard In function get_pdr_req() CRC is not checked for data integrity. I recommend use of CRC for integrity check. Regards Abhishek Singh Tomar On Fri, Mar 04, 2022 at 02:11:43PM +0100, Christophe Lombard wrote: > This specification defines the functions and data structures used for > discovering, describing, initializing, and accessing sensors and effecters > within the management controllers and management devices of a platform > management subsystem using PLDM messaging. > > A PDR (Platform Descriptor Record) is a set of data that is used to > provide semantic information about sensors, effecters, monitored or > controller entities, and functions and services within a PLDM > implementation. > PDRs are mostly used to support PLDM monitoring and control and platform > events. > > The PDRs for a PLDM subsystem are collected into a single, central PDR > Repository. A central repository provides a single place from which PDR > information can be retrieved. > > 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. > > The patch dump all the PDRs within a PDR Repository. > > Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> > --- > core/pldm/Makefile.inc | 3 + > core/pldm/pldm-common.c | 9 ++ > core/pldm/pldm-platform-requests.c | 232 +++++++++++++++++++++++++++++ > core/pldm/pldm.h | 7 + > 4 files changed, 251 insertions(+) > create mode 100644 core/pldm/pldm-platform-requests.c > > diff --git a/core/pldm/Makefile.inc b/core/pldm/Makefile.inc > index c431288f..72f71cba 100644 > --- a/core/pldm/Makefile.inc > +++ b/core/pldm/Makefile.inc > @@ -7,7 +7,10 @@ SUBDIRS += $(PLDM_DIR) > CPPFLAGS += -I$(SRC)/pldm/libpldm/ > CPPFLAGS += -I$(SRC)/pldm/ibm/libpldm/ > > +CFLAGS_$(PLDM_DIR)/pldm-platform-requests.o = -Wno-strict-prototypes > + > PLDM_OBJS = pldm-common.o pldm-responder.o pldm-requester.o > +PLDM_OBJS += pldm-platform-requests.o > > PLDM = $(PLDM_DIR)/built-in.a > $(PLDM): $(PLDM_OBJS:%=$(PLDM_DIR)/%) > diff --git a/core/pldm/pldm-common.c b/core/pldm/pldm-common.c > index 15ee2af9..ea6cb2c3 100644 > --- a/core/pldm/pldm-common.c > +++ b/core/pldm/pldm-common.c > @@ -112,6 +112,8 @@ int pldm_mctp_init(void) > { > int rc; > > + prlog(PR_NOTICE, "%s - Getting PLDM data\n", __func__); > + > /* MCTP Binding */ > rc = ast_mctp_init(pldm_rx_message); > if (rc) > @@ -119,7 +121,14 @@ int pldm_mctp_init(void) > > /* Register mandatory commands we'll respond to */ > rc = pldm_mctp_responder_init(); > + if (rc) > + goto out; > + > + /* Get PDRs data */ > + rc = pldm_platform_init(); > > out: > + prlog(PR_NOTICE, "%s - done (rc: %d)\n", __func__, rc); > + > return rc; > } > diff --git a/core/pldm/pldm-platform-requests.c b/core/pldm/pldm-platform-requests.c > new file mode 100644 > index 00000000..b416cc76 > --- /dev/null > +++ b/core/pldm/pldm-platform-requests.c > @@ -0,0 +1,232 @@ > +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later > +// Copyright 2022 IBM Corp. > + > +#define pr_fmt(fmt) "PLDM: " fmt > + > +#include <cpu.h> > +#include <opal.h> > +#include <stdio.h> > +#include <string.h> > +#include <inttypes.h> > +#include <pldm/libpldm/entity.h> > +#include <pldm/libpldm/state_set.h> > +#include <pldm/libpldm/platform.h> > +#include "pldm.h" > + > +#define NO_MORE_PDR_HANDLES 0 > + > +static pldm_pdr *repo; > +static bool pdr_ready; > + > +static void pdr_init_complete(bool success) > +{ > + /* Read not successful, error out and free the buffer */ > + if (!success) { > + pdr_ready = false; > + > + pldm_pdr_destroy(repo); > + return; > + } > + > + /* Mark ready */ > + pdr_ready = true; > +} > + > +struct get_pdr_response { > + uint8_t completion_code; > + uint32_t next_record_hndl; > + uint32_t next_data_transfer_hndl; > + uint8_t transfer_flag; > + uint16_t resp_cnt; > + uint8_t *record_data; > + size_t record_data_length; > + uint8_t transfer_crc; > +}; > + > +/* > + * Send/receive a PLDM GetPDR stateEffecter request message > + * Get platform descriptor records. > + * > + * pldmtool platform GetPDR -t stateEffecter > + * ... > + * { > + * "nextRecordHandle": 138, > + * "responseCount": 30, > + * "recordHandle": 137, > + * "PDRHeaderVersion": 1, > + * "PDRType": "State Effecter PDR", > + * "recordChangeNumber": 0, > + * "dataLength": 20, > + * "PLDMTerminusHandle": 1, > + * "effecterID": 43, > + * "entityType": "[Physical] System chassis (main enclosure)", > + * ... > + * "Off-Soft Graceful(9)" > + * } > + * ... > + */ > +static int get_pdr_req(uint32_t record_hndl, uint32_t *next_record_hndl, > + void **pdr_data, uint16_t *pdr_length) > +{ > + char request_msg[PKT_SIZE(struct pldm_get_pdr_req)]; > + size_t response_len, payload_len; > + void *response_msg; > + int rc, i; > + > + struct pldm_get_pdr_req pdr_req = { > + .record_handle = record_hndl, /* record change number (0 for first request) */ > + .data_transfer_handle = 0, /* (0 if transfer op is FIRSTPART) */ > + .transfer_op_flag = PLDM_GET_FIRSTPART, /* transfer op flag */ > + .request_count = SHRT_MAX, /* Don't limit the size of the PDR */ > + .record_change_number = 0 /* record change number (0 for first request) */ > + }; > + > + struct get_pdr_response response; > + > + prlog(PR_DEBUG, "%s - record_hndl: %d\n", __func__, record_hndl); > + > + /* Encode the get_PDR request */ > + rc = encode_get_pdr_req(DEFAULT_INSTANCE_ID, > + pdr_req.record_handle, > + pdr_req.data_transfer_handle, > + pdr_req.transfer_op_flag, > + pdr_req.request_count, > + pdr_req.record_change_number, > + (struct pldm_msg *)request_msg, > + PLDM_GET_PDR_REQ_BYTES); > + if (rc != PLDM_SUCCESS) { > + prlog(PR_ERR, "Encode GetPDRReq Error (rc: %d)\n", rc); > + return OPAL_PARAMETER; > + } > + > + /* Send and get the response message bytes */ > + rc = pldm_do_request(BMC_EID, request_msg, sizeof(request_msg), > + &response_msg, &response_len); > + if (rc) { > + prlog(PR_ERR, "PLDM: Communication Error (req: GetPDRReq, rc: %d)\n", rc); > + return OPAL_PARAMETER; > + } > + > + /* Decode the message twice; the first time, the payload buffer > + * will be null so that the decoder will simply tell us how big > + * the buffer should be. Then we create a suitable payload > + * buffer and call the decoder again, this time with the real > + * buffer so that it can fill it with data from the message. > + */ > + payload_len = response_len - sizeof(struct pldm_msg_hdr); > + response.record_data_length = 0; > + response.record_data = NULL; > + > + for (i = 0; i < 2; i++) { > + rc = decode_get_pdr_resp( > + response_msg, payload_len, > + &response.completion_code, > + &response.next_record_hndl, > + &response.next_data_transfer_hndl, > + &response.transfer_flag, > + &response.resp_cnt, > + response.record_data, > + response.record_data_length, > + &response.transfer_crc); > + > + if (rc != PLDM_SUCCESS || response.completion_code != PLDM_SUCCESS) { > + /* Message decoding failed */ > + prlog(PR_ERR, "Decode GetPDRResp Error (rc: %d, cc: %d)\n", > + rc, response.completion_code); > + return OPAL_PARAMETER; > + } > + > + if (response.record_data == NULL) { > + response.record_data_length = response.resp_cnt; > + response.record_data = malloc(response.resp_cnt); > + } > + } > + > + /* we do not support multipart transfer */ > + if (response.transfer_flag != PLDM_START_AND_END) > + prlog(PR_ERR, "Transfert GetPDRResp not complete, transfer_flag: %d\n", > + response.transfer_flag); > + > + prlog(PR_DEBUG, "%s - record_hndl: %d, next_record_hndl: %d, resp_cnt: %d\n", > + __func__, pdr_req.record_handle, > + response.next_record_hndl, > + response.resp_cnt); > + > + *next_record_hndl = response.next_record_hndl; > + *pdr_length = response.resp_cnt; > + *pdr_data = malloc(response.resp_cnt); > + memcpy(*pdr_data, response.record_data, response.resp_cnt); > + > + free(response.record_data); > + free(response_msg); > + > + return OPAL_SUCCESS; > +} > + > +/* > + * Collect all PDrs into a PDR Repository. > + */ > +static int get_all_pdrs(pldm_pdr *repo) > +{ > + uint32_t record_hndl = 0; /* first pdr handle */ > + uint32_t next_record_hdl; > + void *pdr_data = NULL; > + uint16_t pdr_length; > + int rc = OPAL_SUCCESS; > + > + do { > + /* send/receive a PLDM GetPDR request message */ > + rc = get_pdr_req(record_hndl, &next_record_hdl, > + &pdr_data, &pdr_length); > + if (rc) > + goto err; > + > + /* Add a PDR record to a PDR repository */ > + pldm_pdr_add(repo, > + pdr_data, > + pdr_length, > + record_hndl, > + false); > + > + if (pdr_data) { > + free(pdr_data); > + pdr_data = NULL; > + } > + > + record_hndl = next_record_hdl; > + > + } while (next_record_hdl != NO_MORE_PDR_HANDLES); > + > +err: > + if (pdr_data) > + free(pdr_data); > + > + return rc; > +} > + > +int pldm_platform_init(void) > +{ > + int rc; > + > + /* make a new PDR repository */ > + repo = pldm_pdr_init(); > + > + /* retrieve all PDRs */ > + rc = get_all_pdrs(repo); > + if (rc) { > + pdr_init_complete(false); > + prlog(PR_ERR, "%s - done, rc: %d\n", __func__, rc); > + return rc; > + } > + > + pdr_init_complete(true); > + prlog(PR_DEBUG, "%s - done\n", __func__); > + > + return OPAL_SUCCESS; > +} > + > +void pldm_platform_exit(void) > +{ > + if (pdr_ready) > + pldm_pdr_destroy(repo); > +} > diff --git a/core/pldm/pldm.h b/core/pldm/pldm.h > index fd677742..3950b111 100644 > --- a/core/pldm/pldm.h > +++ b/core/pldm/pldm.h > @@ -6,6 +6,7 @@ > #define __COREPLDM_H__ > > #include <pldm/libpldm/base.h> > +#include <pldm/libpldm/utils.h> > #include <pldm.h> > > /* Common support */ > @@ -21,6 +22,9 @@ void printbuf(const char *name, const char *msg, int len); > > #define PKT_SIZE(x) (sizeof(struct pldm_msg_hdr) + sizeof(x)) > > +/* For all of the encode functions just pass in a default ID (0x00) */ > +#define DEFAULT_INSTANCE_ID 0 > + > struct pldm_rx_data { > struct pldm_header_info hdrinf; /* parsed message header */ > > @@ -47,6 +51,9 @@ int pldm_rx_handle_request(struct pldm_rx_data *rx); > int pldm_mctp_responder_init(void); > > /* Requester support */ > +void pldm_platform_exit(void); > +int pldm_platform_init(void); > + > int pldm_do_request(uint8_t dest_eid, > void *request_msg, size_t request_len, > void **response_msg, size_t *response_len); > -- > 2.35.1 > > _______________________________________________ > Skiboot mailing list > Skiboot@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/skiboot
Le 16/03/2022 à 10:18, Abhishek SIngh Tomar a écrit : > hello Christophe Lombard > > In function get_pdr_req() CRC is not checked for data integrity. > I recommend use of CRC for integrity check. CRC is not used for START_AND_END. The value is always equal to 0. > > Regards > Abhishek Singh Tomar > > On Fri, Mar 04, 2022 at 02:11:43PM +0100, Christophe Lombard wrote: >> This specification defines the functions and data structures used for >> discovering, describing, initializing, and accessing sensors and effecters >> within the management controllers and management devices of a platform >> management subsystem using PLDM messaging. >> >> A PDR (Platform Descriptor Record) is a set of data that is used to >> provide semantic information about sensors, effecters, monitored or >> controller entities, and functions and services within a PLDM >> implementation. >> PDRs are mostly used to support PLDM monitoring and control and platform >> events. >> >> The PDRs for a PLDM subsystem are collected into a single, central PDR >> Repository. A central repository provides a single place from which PDR >> information can be retrieved. >> >> 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. >> >> The patch dump all the PDRs within a PDR Repository. >> >> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> >> --- >> core/pldm/Makefile.inc | 3 + >> core/pldm/pldm-common.c | 9 ++ >> core/pldm/pldm-platform-requests.c | 232 +++++++++++++++++++++++++++++ >> core/pldm/pldm.h | 7 + >> 4 files changed, 251 insertions(+) >> create mode 100644 core/pldm/pldm-platform-requests.c >> >> diff --git a/core/pldm/Makefile.inc b/core/pldm/Makefile.inc >> index c431288f..72f71cba 100644 >> --- a/core/pldm/Makefile.inc >> +++ b/core/pldm/Makefile.inc >> @@ -7,7 +7,10 @@ SUBDIRS += $(PLDM_DIR) >> CPPFLAGS += -I$(SRC)/pldm/libpldm/ >> CPPFLAGS += -I$(SRC)/pldm/ibm/libpldm/ >> >> +CFLAGS_$(PLDM_DIR)/pldm-platform-requests.o = -Wno-strict-prototypes >> + >> PLDM_OBJS = pldm-common.o pldm-responder.o pldm-requester.o >> +PLDM_OBJS += pldm-platform-requests.o >> >> PLDM = $(PLDM_DIR)/built-in.a >> $(PLDM): $(PLDM_OBJS:%=$(PLDM_DIR)/%) >> diff --git a/core/pldm/pldm-common.c b/core/pldm/pldm-common.c >> index 15ee2af9..ea6cb2c3 100644 >> --- a/core/pldm/pldm-common.c >> +++ b/core/pldm/pldm-common.c >> @@ -112,6 +112,8 @@ int pldm_mctp_init(void) >> { >> int rc; >> >> + prlog(PR_NOTICE, "%s - Getting PLDM data\n", __func__); >> + >> /* MCTP Binding */ >> rc = ast_mctp_init(pldm_rx_message); >> if (rc) >> @@ -119,7 +121,14 @@ int pldm_mctp_init(void) >> >> /* Register mandatory commands we'll respond to */ >> rc = pldm_mctp_responder_init(); >> + if (rc) >> + goto out; >> + >> + /* Get PDRs data */ >> + rc = pldm_platform_init(); >> >> out: >> + prlog(PR_NOTICE, "%s - done (rc: %d)\n", __func__, rc); >> + >> return rc; >> } >> diff --git a/core/pldm/pldm-platform-requests.c b/core/pldm/pldm-platform-requests.c >> new file mode 100644 >> index 00000000..b416cc76 >> --- /dev/null >> +++ b/core/pldm/pldm-platform-requests.c >> @@ -0,0 +1,232 @@ >> +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later >> +// Copyright 2022 IBM Corp. >> + >> +#define pr_fmt(fmt) "PLDM: " fmt >> + >> +#include <cpu.h> >> +#include <opal.h> >> +#include <stdio.h> >> +#include <string.h> >> +#include <inttypes.h> >> +#include <pldm/libpldm/entity.h> >> +#include <pldm/libpldm/state_set.h> >> +#include <pldm/libpldm/platform.h> >> +#include "pldm.h" >> + >> +#define NO_MORE_PDR_HANDLES 0 >> + >> +static pldm_pdr *repo; >> +static bool pdr_ready; >> + >> +static void pdr_init_complete(bool success) >> +{ >> + /* Read not successful, error out and free the buffer */ >> + if (!success) { >> + pdr_ready = false; >> + >> + pldm_pdr_destroy(repo); >> + return; >> + } >> + >> + /* Mark ready */ >> + pdr_ready = true; >> +} >> + >> +struct get_pdr_response { >> + uint8_t completion_code; >> + uint32_t next_record_hndl; >> + uint32_t next_data_transfer_hndl; >> + uint8_t transfer_flag; >> + uint16_t resp_cnt; >> + uint8_t *record_data; >> + size_t record_data_length; >> + uint8_t transfer_crc; >> +}; >> + >> +/* >> + * Send/receive a PLDM GetPDR stateEffecter request message >> + * Get platform descriptor records. >> + * >> + * pldmtool platform GetPDR -t stateEffecter >> + * ... >> + * { >> + * "nextRecordHandle": 138, >> + * "responseCount": 30, >> + * "recordHandle": 137, >> + * "PDRHeaderVersion": 1, >> + * "PDRType": "State Effecter PDR", >> + * "recordChangeNumber": 0, >> + * "dataLength": 20, >> + * "PLDMTerminusHandle": 1, >> + * "effecterID": 43, >> + * "entityType": "[Physical] System chassis (main enclosure)", >> + * ... >> + * "Off-Soft Graceful(9)" >> + * } >> + * ... >> + */ >> +static int get_pdr_req(uint32_t record_hndl, uint32_t *next_record_hndl, >> + void **pdr_data, uint16_t *pdr_length) >> +{ >> + char request_msg[PKT_SIZE(struct pldm_get_pdr_req)]; >> + size_t response_len, payload_len; >> + void *response_msg; >> + int rc, i; >> + >> + struct pldm_get_pdr_req pdr_req = { >> + .record_handle = record_hndl, /* record change number (0 for first request) */ >> + .data_transfer_handle = 0, /* (0 if transfer op is FIRSTPART) */ >> + .transfer_op_flag = PLDM_GET_FIRSTPART, /* transfer op flag */ >> + .request_count = SHRT_MAX, /* Don't limit the size of the PDR */ >> + .record_change_number = 0 /* record change number (0 for first request) */ >> + }; >> + >> + struct get_pdr_response response; >> + >> + prlog(PR_DEBUG, "%s - record_hndl: %d\n", __func__, record_hndl); >> + >> + /* Encode the get_PDR request */ >> + rc = encode_get_pdr_req(DEFAULT_INSTANCE_ID, >> + pdr_req.record_handle, >> + pdr_req.data_transfer_handle, >> + pdr_req.transfer_op_flag, >> + pdr_req.request_count, >> + pdr_req.record_change_number, >> + (struct pldm_msg *)request_msg, >> + PLDM_GET_PDR_REQ_BYTES); >> + if (rc != PLDM_SUCCESS) { >> + prlog(PR_ERR, "Encode GetPDRReq Error (rc: %d)\n", rc); >> + return OPAL_PARAMETER; >> + } >> + >> + /* Send and get the response message bytes */ >> + rc = pldm_do_request(BMC_EID, request_msg, sizeof(request_msg), >> + &response_msg, &response_len); >> + if (rc) { >> + prlog(PR_ERR, "PLDM: Communication Error (req: GetPDRReq, rc: %d)\n", rc); >> + return OPAL_PARAMETER; >> + } >> + >> + /* Decode the message twice; the first time, the payload buffer >> + * will be null so that the decoder will simply tell us how big >> + * the buffer should be. Then we create a suitable payload >> + * buffer and call the decoder again, this time with the real >> + * buffer so that it can fill it with data from the message. >> + */ >> + payload_len = response_len - sizeof(struct pldm_msg_hdr); >> + response.record_data_length = 0; >> + response.record_data = NULL; >> + >> + for (i = 0; i < 2; i++) { >> + rc = decode_get_pdr_resp( >> + response_msg, payload_len, >> + &response.completion_code, >> + &response.next_record_hndl, >> + &response.next_data_transfer_hndl, >> + &response.transfer_flag, >> + &response.resp_cnt, >> + response.record_data, >> + response.record_data_length, >> + &response.transfer_crc); >> + >> + if (rc != PLDM_SUCCESS || response.completion_code != PLDM_SUCCESS) { >> + /* Message decoding failed */ >> + prlog(PR_ERR, "Decode GetPDRResp Error (rc: %d, cc: %d)\n", >> + rc, response.completion_code); >> + return OPAL_PARAMETER; >> + } >> + >> + if (response.record_data == NULL) { >> + response.record_data_length = response.resp_cnt; >> + response.record_data = malloc(response.resp_cnt); >> + } >> + } >> + >> + /* we do not support multipart transfer */ >> + if (response.transfer_flag != PLDM_START_AND_END) >> + prlog(PR_ERR, "Transfert GetPDRResp not complete, transfer_flag: %d\n", >> + response.transfer_flag); >> + >> + prlog(PR_DEBUG, "%s - record_hndl: %d, next_record_hndl: %d, resp_cnt: %d\n", >> + __func__, pdr_req.record_handle, >> + response.next_record_hndl, >> + response.resp_cnt); >> + >> + *next_record_hndl = response.next_record_hndl; >> + *pdr_length = response.resp_cnt; >> + *pdr_data = malloc(response.resp_cnt); >> + memcpy(*pdr_data, response.record_data, response.resp_cnt); >> + >> + free(response.record_data); >> + free(response_msg); >> + >> + return OPAL_SUCCESS; >> +} >> + >> +/* >> + * Collect all PDrs into a PDR Repository. >> + */ >> +static int get_all_pdrs(pldm_pdr *repo) >> +{ >> + uint32_t record_hndl = 0; /* first pdr handle */ >> + uint32_t next_record_hdl; >> + void *pdr_data = NULL; >> + uint16_t pdr_length; >> + int rc = OPAL_SUCCESS; >> + >> + do { >> + /* send/receive a PLDM GetPDR request message */ >> + rc = get_pdr_req(record_hndl, &next_record_hdl, >> + &pdr_data, &pdr_length); >> + if (rc) >> + goto err; >> + >> + /* Add a PDR record to a PDR repository */ >> + pldm_pdr_add(repo, >> + pdr_data, >> + pdr_length, >> + record_hndl, >> + false); >> + >> + if (pdr_data) { >> + free(pdr_data); >> + pdr_data = NULL; >> + } >> + >> + record_hndl = next_record_hdl; >> + >> + } while (next_record_hdl != NO_MORE_PDR_HANDLES); >> + >> +err: >> + if (pdr_data) >> + free(pdr_data); >> + >> + return rc; >> +} >> + >> +int pldm_platform_init(void) >> +{ >> + int rc; >> + >> + /* make a new PDR repository */ >> + repo = pldm_pdr_init(); >> + >> + /* retrieve all PDRs */ >> + rc = get_all_pdrs(repo); >> + if (rc) { >> + pdr_init_complete(false); >> + prlog(PR_ERR, "%s - done, rc: %d\n", __func__, rc); >> + return rc; >> + } >> + >> + pdr_init_complete(true); >> + prlog(PR_DEBUG, "%s - done\n", __func__); >> + >> + return OPAL_SUCCESS; >> +} >> + >> +void pldm_platform_exit(void) >> +{ >> + if (pdr_ready) >> + pldm_pdr_destroy(repo); >> +} >> diff --git a/core/pldm/pldm.h b/core/pldm/pldm.h >> index fd677742..3950b111 100644 >> --- a/core/pldm/pldm.h >> +++ b/core/pldm/pldm.h >> @@ -6,6 +6,7 @@ >> #define __COREPLDM_H__ >> >> #include <pldm/libpldm/base.h> >> +#include <pldm/libpldm/utils.h> >> #include <pldm.h> >> >> /* Common support */ >> @@ -21,6 +22,9 @@ void printbuf(const char *name, const char *msg, int len); >> >> #define PKT_SIZE(x) (sizeof(struct pldm_msg_hdr) + sizeof(x)) >> >> +/* For all of the encode functions just pass in a default ID (0x00) */ >> +#define DEFAULT_INSTANCE_ID 0 >> + >> struct pldm_rx_data { >> struct pldm_header_info hdrinf; /* parsed message header */ >> >> @@ -47,6 +51,9 @@ int pldm_rx_handle_request(struct pldm_rx_data *rx); >> int pldm_mctp_responder_init(void); >> >> /* Requester support */ >> +void pldm_platform_exit(void); >> +int pldm_platform_init(void); >> + >> int pldm_do_request(uint8_t dest_eid, >> void *request_msg, size_t request_len, >> void **response_msg, size_t *response_len); >> -- >> 2.35.1 >> >> _______________________________________________ >> Skiboot mailing list >> Skiboot@lists.ozlabs.org >> https://lists.ozlabs.org/listinfo/skiboot
Le 17/03/2022 à 16:39, Christophe Lombard a écrit : > > Le 16/03/2022 à 10:18, Abhishek SIngh Tomar a écrit : >> hello Christophe Lombard >> >> In function get_pdr_req() CRC is not checked for data integrity. >> I recommend use of CRC for integrity check. > > CRC is not used for START_AND_END. The value is always equal to 0. > I will put a comment. Thanks. >> >> Regards >> Abhishek Singh Tomar >> >> On Fri, Mar 04, 2022 at 02:11:43PM +0100, Christophe Lombard wrote: >>> This specification defines the functions and data structures used for >>> discovering, describing, initializing, and accessing sensors and >>> effecters >>> within the management controllers and management devices of a platform >>> management subsystem using PLDM messaging. >>> >>> A PDR (Platform Descriptor Record) is a set of data that is used to >>> provide semantic information about sensors, effecters, monitored or >>> controller entities, and functions and services within a PLDM >>> implementation. >>> PDRs are mostly used to support PLDM monitoring and control and >>> platform >>> events. >>> >>> The PDRs for a PLDM subsystem are collected into a single, central PDR >>> Repository. A central repository provides a single place from which PDR >>> information can be retrieved. >>> >>> 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. >>> >>> The patch dump all the PDRs within a PDR Repository. >>> >>> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> >>> --- >>> core/pldm/Makefile.inc | 3 + >>> core/pldm/pldm-common.c | 9 ++ >>> core/pldm/pldm-platform-requests.c | 232 >>> +++++++++++++++++++++++++++++ >>> core/pldm/pldm.h | 7 + >>> 4 files changed, 251 insertions(+) >>> create mode 100644 core/pldm/pldm-platform-requests.c >>> >>> diff --git a/core/pldm/Makefile.inc b/core/pldm/Makefile.inc >>> index c431288f..72f71cba 100644 >>> --- a/core/pldm/Makefile.inc >>> +++ b/core/pldm/Makefile.inc >>> @@ -7,7 +7,10 @@ SUBDIRS += $(PLDM_DIR) >>> CPPFLAGS += -I$(SRC)/pldm/libpldm/ >>> CPPFLAGS += -I$(SRC)/pldm/ibm/libpldm/ >>> +CFLAGS_$(PLDM_DIR)/pldm-platform-requests.o = -Wno-strict-prototypes >>> + >>> PLDM_OBJS = pldm-common.o pldm-responder.o pldm-requester.o >>> +PLDM_OBJS += pldm-platform-requests.o >>> PLDM = $(PLDM_DIR)/built-in.a >>> $(PLDM): $(PLDM_OBJS:%=$(PLDM_DIR)/%) >>> diff --git a/core/pldm/pldm-common.c b/core/pldm/pldm-common.c >>> index 15ee2af9..ea6cb2c3 100644 >>> --- a/core/pldm/pldm-common.c >>> +++ b/core/pldm/pldm-common.c >>> @@ -112,6 +112,8 @@ int pldm_mctp_init(void) >>> { >>> int rc; >>> + prlog(PR_NOTICE, "%s - Getting PLDM data\n", __func__); >>> + >>> /* MCTP Binding */ >>> rc = ast_mctp_init(pldm_rx_message); >>> if (rc) >>> @@ -119,7 +121,14 @@ int pldm_mctp_init(void) >>> /* Register mandatory commands we'll respond to */ >>> rc = pldm_mctp_responder_init(); >>> + if (rc) >>> + goto out; >>> + >>> + /* Get PDRs data */ >>> + rc = pldm_platform_init(); >>> out: >>> + prlog(PR_NOTICE, "%s - done (rc: %d)\n", __func__, rc); >>> + >>> return rc; >>> } >>> diff --git a/core/pldm/pldm-platform-requests.c >>> b/core/pldm/pldm-platform-requests.c >>> new file mode 100644 >>> index 00000000..b416cc76 >>> --- /dev/null >>> +++ b/core/pldm/pldm-platform-requests.c >>> @@ -0,0 +1,232 @@ >>> +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later >>> +// Copyright 2022 IBM Corp. >>> + >>> +#define pr_fmt(fmt) "PLDM: " fmt >>> + >>> +#include <cpu.h> >>> +#include <opal.h> >>> +#include <stdio.h> >>> +#include <string.h> >>> +#include <inttypes.h> >>> +#include <pldm/libpldm/entity.h> >>> +#include <pldm/libpldm/state_set.h> >>> +#include <pldm/libpldm/platform.h> >>> +#include "pldm.h" >>> + >>> +#define NO_MORE_PDR_HANDLES 0 >>> + >>> +static pldm_pdr *repo; >>> +static bool pdr_ready; >>> + >>> +static void pdr_init_complete(bool success) >>> +{ >>> + /* Read not successful, error out and free the buffer */ >>> + if (!success) { >>> + pdr_ready = false; >>> + >>> + pldm_pdr_destroy(repo); >>> + return; >>> + } >>> + >>> + /* Mark ready */ >>> + pdr_ready = true; >>> +} >>> + >>> +struct get_pdr_response { >>> + uint8_t completion_code; >>> + uint32_t next_record_hndl; >>> + uint32_t next_data_transfer_hndl; >>> + uint8_t transfer_flag; >>> + uint16_t resp_cnt; >>> + uint8_t *record_data; >>> + size_t record_data_length; >>> + uint8_t transfer_crc; >>> +}; >>> + >>> +/* >>> + * Send/receive a PLDM GetPDR stateEffecter request message >>> + * Get platform descriptor records. >>> + * >>> + * pldmtool platform GetPDR -t stateEffecter >>> + * ... >>> + * { >>> + * "nextRecordHandle": 138, >>> + * "responseCount": 30, >>> + * "recordHandle": 137, >>> + * "PDRHeaderVersion": 1, >>> + * "PDRType": "State Effecter PDR", >>> + * "recordChangeNumber": 0, >>> + * "dataLength": 20, >>> + * "PLDMTerminusHandle": 1, >>> + * "effecterID": 43, >>> + * "entityType": "[Physical] System chassis (main enclosure)", >>> + * ... >>> + * "Off-Soft Graceful(9)" >>> + * } >>> + * ... >>> + */ >>> +static int get_pdr_req(uint32_t record_hndl, uint32_t >>> *next_record_hndl, >>> + void **pdr_data, uint16_t *pdr_length) >>> +{ >>> + char request_msg[PKT_SIZE(struct pldm_get_pdr_req)]; >>> + size_t response_len, payload_len; >>> + void *response_msg; >>> + int rc, i; >>> + >>> + struct pldm_get_pdr_req pdr_req = { >>> + .record_handle = record_hndl, /* record change number (0 >>> for first request) */ >>> + .data_transfer_handle = 0, /* (0 if transfer op is >>> FIRSTPART) */ >>> + .transfer_op_flag = PLDM_GET_FIRSTPART, /* transfer op flag */ >>> + .request_count = SHRT_MAX, /* Don't limit the size of the >>> PDR */ >>> + .record_change_number = 0 /* record change number (0 for >>> first request) */ >>> + }; >>> + >>> + struct get_pdr_response response; >>> + >>> + prlog(PR_DEBUG, "%s - record_hndl: %d\n", __func__, record_hndl); >>> + >>> + /* Encode the get_PDR request */ >>> + rc = encode_get_pdr_req(DEFAULT_INSTANCE_ID, >>> + pdr_req.record_handle, >>> + pdr_req.data_transfer_handle, >>> + pdr_req.transfer_op_flag, >>> + pdr_req.request_count, >>> + pdr_req.record_change_number, >>> + (struct pldm_msg *)request_msg, >>> + PLDM_GET_PDR_REQ_BYTES); >>> + if (rc != PLDM_SUCCESS) { >>> + prlog(PR_ERR, "Encode GetPDRReq Error (rc: %d)\n", rc); >>> + return OPAL_PARAMETER; >>> + } >>> + >>> + /* Send and get the response message bytes */ >>> + rc = pldm_do_request(BMC_EID, request_msg, sizeof(request_msg), >>> + &response_msg, &response_len); >>> + if (rc) { >>> + prlog(PR_ERR, "PLDM: Communication Error (req: GetPDRReq, >>> rc: %d)\n", rc); >>> + return OPAL_PARAMETER; >>> + } >>> + >>> + /* Decode the message twice; the first time, the payload buffer >>> + * will be null so that the decoder will simply tell us how big >>> + * the buffer should be. Then we create a suitable payload >>> + * buffer and call the decoder again, this time with the real >>> + * buffer so that it can fill it with data from the message. >>> + */ >>> + payload_len = response_len - sizeof(struct pldm_msg_hdr); >>> + response.record_data_length = 0; >>> + response.record_data = NULL; >>> + >>> + for (i = 0; i < 2; i++) { >>> + rc = decode_get_pdr_resp( >>> + response_msg, payload_len, >>> + &response.completion_code, >>> + &response.next_record_hndl, >>> + &response.next_data_transfer_hndl, >>> + &response.transfer_flag, >>> + &response.resp_cnt, >>> + response.record_data, >>> + response.record_data_length, >>> + &response.transfer_crc); >>> + >>> + if (rc != PLDM_SUCCESS || response.completion_code != >>> PLDM_SUCCESS) { >>> + /* Message decoding failed */ >>> + prlog(PR_ERR, "Decode GetPDRResp Error (rc: %d, cc: >>> %d)\n", >>> + rc, response.completion_code); >>> + return OPAL_PARAMETER; >>> + } >>> + >>> + if (response.record_data == NULL) { >>> + response.record_data_length = response.resp_cnt; >>> + response.record_data = malloc(response.resp_cnt); >>> + } >>> + } >>> + >>> + /* we do not support multipart transfer */ >>> + if (response.transfer_flag != PLDM_START_AND_END) >>> + prlog(PR_ERR, "Transfert GetPDRResp not complete, >>> transfer_flag: %d\n", >>> + response.transfer_flag); >>> + >>> + prlog(PR_DEBUG, "%s - record_hndl: %d, next_record_hndl: %d, >>> resp_cnt: %d\n", >>> + __func__, pdr_req.record_handle, >>> + response.next_record_hndl, >>> + response.resp_cnt); >>> + >>> + *next_record_hndl = response.next_record_hndl; >>> + *pdr_length = response.resp_cnt; >>> + *pdr_data = malloc(response.resp_cnt); >>> + memcpy(*pdr_data, response.record_data, response.resp_cnt); >>> + >>> + free(response.record_data); >>> + free(response_msg); >>> + >>> + return OPAL_SUCCESS; >>> +} >>> + >>> +/* >>> + * Collect all PDrs into a PDR Repository. >>> + */ >>> +static int get_all_pdrs(pldm_pdr *repo) >>> +{ >>> + uint32_t record_hndl = 0; /* first pdr handle */ >>> + uint32_t next_record_hdl; >>> + void *pdr_data = NULL; >>> + uint16_t pdr_length; >>> + int rc = OPAL_SUCCESS; >>> + >>> + do { >>> + /* send/receive a PLDM GetPDR request message */ >>> + rc = get_pdr_req(record_hndl, &next_record_hdl, >>> + &pdr_data, &pdr_length); >>> + if (rc) >>> + goto err; >>> + >>> + /* Add a PDR record to a PDR repository */ >>> + pldm_pdr_add(repo, >>> + pdr_data, >>> + pdr_length, >>> + record_hndl, >>> + false); >>> + >>> + if (pdr_data) { >>> + free(pdr_data); >>> + pdr_data = NULL; >>> + } >>> + >>> + record_hndl = next_record_hdl; >>> + >>> + } while (next_record_hdl != NO_MORE_PDR_HANDLES); >>> + >>> +err: >>> + if (pdr_data) >>> + free(pdr_data); >>> + >>> + return rc; >>> +} >>> + >>> +int pldm_platform_init(void) >>> +{ >>> + int rc; >>> + >>> + /* make a new PDR repository */ >>> + repo = pldm_pdr_init(); >>> + >>> + /* retrieve all PDRs */ >>> + rc = get_all_pdrs(repo); >>> + if (rc) { >>> + pdr_init_complete(false); >>> + prlog(PR_ERR, "%s - done, rc: %d\n", __func__, rc); >>> + return rc; >>> + } >>> + >>> + pdr_init_complete(true); >>> + prlog(PR_DEBUG, "%s - done\n", __func__); >>> + >>> + return OPAL_SUCCESS; >>> +} >>> + >>> +void pldm_platform_exit(void) >>> +{ >>> + if (pdr_ready) >>> + pldm_pdr_destroy(repo); >>> +} >>> diff --git a/core/pldm/pldm.h b/core/pldm/pldm.h >>> index fd677742..3950b111 100644 >>> --- a/core/pldm/pldm.h >>> +++ b/core/pldm/pldm.h >>> @@ -6,6 +6,7 @@ >>> #define __COREPLDM_H__ >>> #include <pldm/libpldm/base.h> >>> +#include <pldm/libpldm/utils.h> >>> #include <pldm.h> >>> /* Common support */ >>> @@ -21,6 +22,9 @@ void printbuf(const char *name, const char *msg, >>> int len); >>> #define PKT_SIZE(x) (sizeof(struct pldm_msg_hdr) + sizeof(x)) >>> +/* For all of the encode functions just pass in a default ID >>> (0x00) */ >>> +#define DEFAULT_INSTANCE_ID 0 >>> + >>> struct pldm_rx_data { >>> struct pldm_header_info hdrinf; /* parsed message header */ >>> @@ -47,6 +51,9 @@ int pldm_rx_handle_request(struct pldm_rx_data >>> *rx); >>> int pldm_mctp_responder_init(void); >>> /* Requester support */ >>> +void pldm_platform_exit(void); >>> +int pldm_platform_init(void); >>> + >>> int pldm_do_request(uint8_t dest_eid, >>> void *request_msg, size_t request_len, >>> void **response_msg, size_t *response_len); >>> -- >>> 2.35.1 >>> >>> _______________________________________________ >>> Skiboot mailing list >>> Skiboot@lists.ozlabs.org >>> https://lists.ozlabs.org/listinfo/skiboot > > _______________________________________________ > Skiboot mailing list > Skiboot@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/skiboot
diff --git a/core/pldm/Makefile.inc b/core/pldm/Makefile.inc index c431288f..72f71cba 100644 --- a/core/pldm/Makefile.inc +++ b/core/pldm/Makefile.inc @@ -7,7 +7,10 @@ SUBDIRS += $(PLDM_DIR) CPPFLAGS += -I$(SRC)/pldm/libpldm/ CPPFLAGS += -I$(SRC)/pldm/ibm/libpldm/ +CFLAGS_$(PLDM_DIR)/pldm-platform-requests.o = -Wno-strict-prototypes + PLDM_OBJS = pldm-common.o pldm-responder.o pldm-requester.o +PLDM_OBJS += pldm-platform-requests.o PLDM = $(PLDM_DIR)/built-in.a $(PLDM): $(PLDM_OBJS:%=$(PLDM_DIR)/%) diff --git a/core/pldm/pldm-common.c b/core/pldm/pldm-common.c index 15ee2af9..ea6cb2c3 100644 --- a/core/pldm/pldm-common.c +++ b/core/pldm/pldm-common.c @@ -112,6 +112,8 @@ int pldm_mctp_init(void) { int rc; + prlog(PR_NOTICE, "%s - Getting PLDM data\n", __func__); + /* MCTP Binding */ rc = ast_mctp_init(pldm_rx_message); if (rc) @@ -119,7 +121,14 @@ int pldm_mctp_init(void) /* Register mandatory commands we'll respond to */ rc = pldm_mctp_responder_init(); + if (rc) + goto out; + + /* Get PDRs data */ + rc = pldm_platform_init(); out: + prlog(PR_NOTICE, "%s - done (rc: %d)\n", __func__, rc); + return rc; } diff --git a/core/pldm/pldm-platform-requests.c b/core/pldm/pldm-platform-requests.c new file mode 100644 index 00000000..b416cc76 --- /dev/null +++ b/core/pldm/pldm-platform-requests.c @@ -0,0 +1,232 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +// Copyright 2022 IBM Corp. + +#define pr_fmt(fmt) "PLDM: " fmt + +#include <cpu.h> +#include <opal.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include <pldm/libpldm/entity.h> +#include <pldm/libpldm/state_set.h> +#include <pldm/libpldm/platform.h> +#include "pldm.h" + +#define NO_MORE_PDR_HANDLES 0 + +static pldm_pdr *repo; +static bool pdr_ready; + +static void pdr_init_complete(bool success) +{ + /* Read not successful, error out and free the buffer */ + if (!success) { + pdr_ready = false; + + pldm_pdr_destroy(repo); + return; + } + + /* Mark ready */ + pdr_ready = true; +} + +struct get_pdr_response { + uint8_t completion_code; + uint32_t next_record_hndl; + uint32_t next_data_transfer_hndl; + uint8_t transfer_flag; + uint16_t resp_cnt; + uint8_t *record_data; + size_t record_data_length; + uint8_t transfer_crc; +}; + +/* + * Send/receive a PLDM GetPDR stateEffecter request message + * Get platform descriptor records. + * + * pldmtool platform GetPDR -t stateEffecter + * ... + * { + * "nextRecordHandle": 138, + * "responseCount": 30, + * "recordHandle": 137, + * "PDRHeaderVersion": 1, + * "PDRType": "State Effecter PDR", + * "recordChangeNumber": 0, + * "dataLength": 20, + * "PLDMTerminusHandle": 1, + * "effecterID": 43, + * "entityType": "[Physical] System chassis (main enclosure)", + * ... + * "Off-Soft Graceful(9)" + * } + * ... + */ +static int get_pdr_req(uint32_t record_hndl, uint32_t *next_record_hndl, + void **pdr_data, uint16_t *pdr_length) +{ + char request_msg[PKT_SIZE(struct pldm_get_pdr_req)]; + size_t response_len, payload_len; + void *response_msg; + int rc, i; + + struct pldm_get_pdr_req pdr_req = { + .record_handle = record_hndl, /* record change number (0 for first request) */ + .data_transfer_handle = 0, /* (0 if transfer op is FIRSTPART) */ + .transfer_op_flag = PLDM_GET_FIRSTPART, /* transfer op flag */ + .request_count = SHRT_MAX, /* Don't limit the size of the PDR */ + .record_change_number = 0 /* record change number (0 for first request) */ + }; + + struct get_pdr_response response; + + prlog(PR_DEBUG, "%s - record_hndl: %d\n", __func__, record_hndl); + + /* Encode the get_PDR request */ + rc = encode_get_pdr_req(DEFAULT_INSTANCE_ID, + pdr_req.record_handle, + pdr_req.data_transfer_handle, + pdr_req.transfer_op_flag, + pdr_req.request_count, + pdr_req.record_change_number, + (struct pldm_msg *)request_msg, + PLDM_GET_PDR_REQ_BYTES); + if (rc != PLDM_SUCCESS) { + prlog(PR_ERR, "Encode GetPDRReq Error (rc: %d)\n", rc); + return OPAL_PARAMETER; + } + + /* Send and get the response message bytes */ + rc = pldm_do_request(BMC_EID, request_msg, sizeof(request_msg), + &response_msg, &response_len); + if (rc) { + prlog(PR_ERR, "PLDM: Communication Error (req: GetPDRReq, rc: %d)\n", rc); + return OPAL_PARAMETER; + } + + /* Decode the message twice; the first time, the payload buffer + * will be null so that the decoder will simply tell us how big + * the buffer should be. Then we create a suitable payload + * buffer and call the decoder again, this time with the real + * buffer so that it can fill it with data from the message. + */ + payload_len = response_len - sizeof(struct pldm_msg_hdr); + response.record_data_length = 0; + response.record_data = NULL; + + for (i = 0; i < 2; i++) { + rc = decode_get_pdr_resp( + response_msg, payload_len, + &response.completion_code, + &response.next_record_hndl, + &response.next_data_transfer_hndl, + &response.transfer_flag, + &response.resp_cnt, + response.record_data, + response.record_data_length, + &response.transfer_crc); + + if (rc != PLDM_SUCCESS || response.completion_code != PLDM_SUCCESS) { + /* Message decoding failed */ + prlog(PR_ERR, "Decode GetPDRResp Error (rc: %d, cc: %d)\n", + rc, response.completion_code); + return OPAL_PARAMETER; + } + + if (response.record_data == NULL) { + response.record_data_length = response.resp_cnt; + response.record_data = malloc(response.resp_cnt); + } + } + + /* we do not support multipart transfer */ + if (response.transfer_flag != PLDM_START_AND_END) + prlog(PR_ERR, "Transfert GetPDRResp not complete, transfer_flag: %d\n", + response.transfer_flag); + + prlog(PR_DEBUG, "%s - record_hndl: %d, next_record_hndl: %d, resp_cnt: %d\n", + __func__, pdr_req.record_handle, + response.next_record_hndl, + response.resp_cnt); + + *next_record_hndl = response.next_record_hndl; + *pdr_length = response.resp_cnt; + *pdr_data = malloc(response.resp_cnt); + memcpy(*pdr_data, response.record_data, response.resp_cnt); + + free(response.record_data); + free(response_msg); + + return OPAL_SUCCESS; +} + +/* + * Collect all PDrs into a PDR Repository. + */ +static int get_all_pdrs(pldm_pdr *repo) +{ + uint32_t record_hndl = 0; /* first pdr handle */ + uint32_t next_record_hdl; + void *pdr_data = NULL; + uint16_t pdr_length; + int rc = OPAL_SUCCESS; + + do { + /* send/receive a PLDM GetPDR request message */ + rc = get_pdr_req(record_hndl, &next_record_hdl, + &pdr_data, &pdr_length); + if (rc) + goto err; + + /* Add a PDR record to a PDR repository */ + pldm_pdr_add(repo, + pdr_data, + pdr_length, + record_hndl, + false); + + if (pdr_data) { + free(pdr_data); + pdr_data = NULL; + } + + record_hndl = next_record_hdl; + + } while (next_record_hdl != NO_MORE_PDR_HANDLES); + +err: + if (pdr_data) + free(pdr_data); + + return rc; +} + +int pldm_platform_init(void) +{ + int rc; + + /* make a new PDR repository */ + repo = pldm_pdr_init(); + + /* retrieve all PDRs */ + rc = get_all_pdrs(repo); + if (rc) { + pdr_init_complete(false); + prlog(PR_ERR, "%s - done, rc: %d\n", __func__, rc); + return rc; + } + + pdr_init_complete(true); + prlog(PR_DEBUG, "%s - done\n", __func__); + + return OPAL_SUCCESS; +} + +void pldm_platform_exit(void) +{ + if (pdr_ready) + pldm_pdr_destroy(repo); +} diff --git a/core/pldm/pldm.h b/core/pldm/pldm.h index fd677742..3950b111 100644 --- a/core/pldm/pldm.h +++ b/core/pldm/pldm.h @@ -6,6 +6,7 @@ #define __COREPLDM_H__ #include <pldm/libpldm/base.h> +#include <pldm/libpldm/utils.h> #include <pldm.h> /* Common support */ @@ -21,6 +22,9 @@ void printbuf(const char *name, const char *msg, int len); #define PKT_SIZE(x) (sizeof(struct pldm_msg_hdr) + sizeof(x)) +/* For all of the encode functions just pass in a default ID (0x00) */ +#define DEFAULT_INSTANCE_ID 0 + struct pldm_rx_data { struct pldm_header_info hdrinf; /* parsed message header */ @@ -47,6 +51,9 @@ int pldm_rx_handle_request(struct pldm_rx_data *rx); int pldm_mctp_responder_init(void); /* Requester support */ +void pldm_platform_exit(void); +int pldm_platform_init(void); + int pldm_do_request(uint8_t dest_eid, void *request_msg, size_t request_len, void **response_msg, size_t *response_len);
This specification defines the functions and data structures used for discovering, describing, initializing, and accessing sensors and effecters within the management controllers and management devices of a platform management subsystem using PLDM messaging. A PDR (Platform Descriptor Record) is a set of data that is used to provide semantic information about sensors, effecters, monitored or controller entities, and functions and services within a PLDM implementation. PDRs are mostly used to support PLDM monitoring and control and platform events. The PDRs for a PLDM subsystem are collected into a single, central PDR Repository. A central repository provides a single place from which PDR information can be retrieved. 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. The patch dump all the PDRs within a PDR Repository. Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> --- core/pldm/Makefile.inc | 3 + core/pldm/pldm-common.c | 9 ++ core/pldm/pldm-platform-requests.c | 232 +++++++++++++++++++++++++++++ core/pldm/pldm.h | 7 + 4 files changed, 251 insertions(+) create mode 100644 core/pldm/pldm-platform-requests.c