aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Lombard <clombard@linux.ibm.com>2023-08-29 11:23:33 +0200
committerReza Arbab <arbab@linux.ibm.com>2023-09-12 14:22:11 -0500
commit86c3ac6109790d2f1f723c75e09b11c3c7fd19e0 (patch)
tree4cecb15511b69f29d2fcda654907d8fc5d72b508
parent672312fe381d3dc3d854bc64c4e953afc37f800a (diff)
downloadskiboot-86c3ac6109790d2f1f723c75e09b11c3c7fd19e0.zip
skiboot-86c3ac6109790d2f1f723c75e09b11c3c7fd19e0.tar.gz
skiboot-86c3ac6109790d2f1f723c75e09b11c3c7fd19e0.tar.bz2
core/pldm: PLDM for FRU data Specification
Specification, defines a FRU data format that provides platform asset information including part number, serial number and manufacturer. Use the GetFruRecordByOptionReq command to get specific FRU (Field Replaceable Unit) record according the Record Set Identifier, the Record Type and the field Type. Reviewed-by: Abhishek Singh Tomar <abhishek@linux.ibm.com> Signed-off-by: Christophe Lombard <clombard@linux.ibm.com> Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
-rw-r--r--core/pldm/Makefile.inc2
-rw-r--r--core/pldm/pldm-fru-requests.c147
-rw-r--r--core/pldm/pldm-mctp.c4
-rw-r--r--core/pldm/pldm.h2
4 files changed, 153 insertions, 2 deletions
diff --git a/core/pldm/Makefile.inc b/core/pldm/Makefile.inc
index e4135ac..0b54b7e 100644
--- a/core/pldm/Makefile.inc
+++ b/core/pldm/Makefile.inc
@@ -9,7 +9,7 @@ CPPFLAGS += -I$(SRC)/pldm/include/libpldm/oem/ibm/
PLDM_OBJS = pldm-mctp.o pldm-responder.o pldm-requester.o
PLDM_OBJS += pldm-base-requests.o pldm-platform-requests.o
-PLDM_OBJS += pldm-bios-requests.o
+PLDM_OBJS += pldm-bios-requests.o pldm-fru-requests.o
PLDM = $(PLDM_DIR)/built-in.a
$(PLDM): $(PLDM_OBJS:%=$(PLDM_DIR)/%)
diff --git a/core/pldm/pldm-fru-requests.c b/core/pldm/pldm-fru-requests.c
new file mode 100644
index 0000000..ae1d9fa
--- /dev/null
+++ b/core/pldm/pldm-fru-requests.c
@@ -0,0 +1,147 @@
+// 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 <libpldm/fru.h>
+#include "pldm.h"
+
+static void *fru_record_table;
+static size_t fru_record_length;
+
+static bool fru_ready;
+
+static void fru_init_complete(bool success)
+{
+ /* Read not successful, error out and free the buffer */
+ if (!success) {
+ fru_ready = false;
+
+ if (fru_record_table != NULL) {
+ free(fru_record_table);
+ fru_record_length = 0;
+ }
+ return;
+ }
+
+ /* Mark ready */
+ fru_ready = true;
+}
+
+static int get_fru_record_table_req(void **record_table_data,
+ size_t *record_table_length)
+{
+ size_t data_size = PLDM_MSG_SIZE(struct pldm_get_fru_record_table_req);
+ uint8_t transfer_flag, completion_code;
+ size_t response_len, payload_len;
+ struct pldm_tx_data *tx = NULL;
+ uint32_t next_transfer_handle;
+ uint8_t *table_data;
+ size_t table_length;
+ void *response_msg;
+ int rc = OPAL_SUCCESS;
+
+ struct pldm_get_fru_record_table_req fru_record_table_req = {
+ .data_transfer_handle = 0, /* (0 if operation op is FIRSTPART) */
+ .transfer_operation_flag = PLDM_GET_FIRSTPART,
+ };
+ payload_len = sizeof(struct pldm_get_fru_record_table_req);
+
+ /* Encode the file table request */
+ tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
+ if (!tx)
+ return OPAL_NO_MEM;
+ tx->data_size = data_size;
+
+ rc = encode_get_fru_record_table_req(
+ DEFAULT_INSTANCE_ID,
+ fru_record_table_req.data_transfer_handle,
+ fru_record_table_req.transfer_operation_flag,
+ (struct pldm_msg *)tx->data,
+ payload_len);
+ if (rc != PLDM_SUCCESS) {
+ prlog(PR_ERR, "Encode GetFruRecordTableReq Error, rc: %d\n", rc);
+ free(tx);
+ return OPAL_PARAMETER;
+ }
+
+ /* Send and get the response message bytes */
+ rc = pldm_requester_queue_and_wait(tx, &response_msg, &response_len);
+ if (rc) {
+ prlog(PR_ERR, "Communication Error, req: GetFruRecordTableReq, rc: %d\n", rc);
+ free(tx);
+ return rc;
+ }
+
+ /* Decode the message */
+ payload_len = response_len - sizeof(struct pldm_msg_hdr);
+ table_data = zalloc(payload_len);
+ if (!table_data) {
+ free(tx);
+ return OPAL_NO_MEM;
+ }
+
+ rc = decode_get_fru_record_table_resp(
+ response_msg,
+ payload_len,
+ &completion_code,
+ &next_transfer_handle,
+ &transfer_flag,
+ table_data,
+ &table_length);
+ if (rc != PLDM_SUCCESS || completion_code != PLDM_SUCCESS) {
+ prlog(PR_ERR, "Decode GetFruRecordTableReq Error, rc: %d, cc: %d\n",
+ rc, completion_code);
+ rc = OPAL_PARAMETER;
+ goto out;
+ }
+
+ /* we do not support multipart transfer */
+ if ((next_transfer_handle != PLDM_GET_NEXTPART) ||
+ (transfer_flag != PLDM_START_AND_END)) {
+ prlog(PR_ERR, "Transfert GetFruRecordTableReq not complete, "
+ "transfer_hndl: %d, transfer_flag: %d\n",
+ next_transfer_handle,
+ transfer_flag);
+ rc = OPAL_PARAMETER;
+ goto out;
+ }
+
+ *record_table_length = table_length;
+ *record_table_data = zalloc(table_length);
+ if (!record_table_data)
+ rc = OPAL_NO_MEM;
+ else
+ memcpy(*record_table_data, table_data, table_length);
+
+out:
+ free(tx);
+ free(table_data);
+ free(response_msg);
+ return rc;
+}
+
+int pldm_fru_init(void)
+{
+ int rc;
+
+ /* get fru record table */
+ rc = get_fru_record_table_req(&fru_record_table,
+ &fru_record_length);
+ if (rc)
+ goto err;
+
+ fru_init_complete(true);
+ prlog(PR_DEBUG, "%s - done\n", __func__);
+
+ return OPAL_SUCCESS;
+
+err:
+ fru_init_complete(false);
+ return rc;
+}
diff --git a/core/pldm/pldm-mctp.c b/core/pldm/pldm-mctp.c
index 6003b66..b31587f 100644
--- a/core/pldm/pldm-mctp.c
+++ b/core/pldm/pldm-mctp.c
@@ -74,7 +74,7 @@ out:
int pldm_mctp_init(void)
{
- int nbr_elt = 6, rc = OPAL_SUCCESS;
+ int nbr_elt = 7, rc = OPAL_SUCCESS;
int (*pldm_config[])(void) = {
ast_mctp_init, /* MCTP Binding */
@@ -83,6 +83,7 @@ int pldm_mctp_init(void)
pldm_base_get_tid_req, /* Get BMC tid */
pldm_platform_init, /* Get PDRs data */
pldm_bios_init, /* Get Bios data */
+ pldm_fru_init, /* Get Fru data */
};
const char *pldm_config_error[] = {
@@ -92,6 +93,7 @@ int pldm_mctp_init(void)
"Failed to retrieve BMC Tid",
"Failed to retrieve Data Records",
"Failed to retrieve Bios data",
+ "Failed to retrieve Fru data",
};
prlog(PR_NOTICE, "%s - Getting PLDM data\n", __func__);
diff --git a/core/pldm/pldm.h b/core/pldm/pldm.h
index 0601349..dbc19ab 100644
--- a/core/pldm/pldm.h
+++ b/core/pldm/pldm.h
@@ -52,6 +52,8 @@ int pldm_responder_handle_request(struct pldm_rx_data *rx);
int pldm_responder_init(void);
/* Requester support */
+int pldm_fru_init(void);
+
int pldm_bios_find_lid_by_attr_name(const char *name, char **lid);
int pldm_bios_get_lids_id(char **lid_ids_string);
int pldm_bios_init(void);