diff mbox series

[V10,03/21] core/pldm: PLDM over MCTP Binding

Message ID 20230829092338.75785-4-clombard@linux.ibm.com
State Accepted
Headers show
Series Implement MCTP and PLDM features | expand

Commit Message

Christophe Lombard Aug. 29, 2023, 9:23 a.m. UTC
Enable the mctp binding over LPC bus interface and new wrappers to send
and receive PLDM messages over the mctp library.

PLDM is supported as a message type over MCTP. PLDM over MCTP binding
defines the format of PLDM over MCTP messages.

An MCTP Endpoint is the terminus for MCTP communication. A physical device
that supports MCTP may provide one or more MCTP Endpoints. Endpoints are
addressed using a logical address called the Endpoint ID, or EID. EIDs in
MCTP are analogous to IP Addresses in Internet Protocol networking.

The BMC EID default is 8.

First byte of the PLDM over MCTP Message Fields identifies the MCTP
message as carrying a PLDM message:
Message Type (7 bits)  PLDM = 0x01 (000_0001b).

Reviewed-by: Abhishek Singh Tomar <abhishek@linux.ibm.com>
Signed-off-by: Christophe Lombard <clombard@linux.ibm.com>
---
 core/Makefile.inc      |  6 ++-
 core/pldm/Makefile.inc | 13 ++++++
 core/pldm/pldm-mctp.c  | 91 ++++++++++++++++++++++++++++++++++++++++++
 core/pldm/pldm.h       | 44 ++++++++++++++++++++
 hw/ast-bmc/ast-mctp.c  | 18 +++++++++
 include/pldm.h         | 24 +++++++++++
 6 files changed, 195 insertions(+), 1 deletion(-)
 create mode 100644 core/pldm/Makefile.inc
 create mode 100644 core/pldm/pldm-mctp.c
 create mode 100644 core/pldm/pldm.h
 create mode 100644 include/pldm.h
diff mbox series

Patch

diff --git a/core/Makefile.inc b/core/Makefile.inc
index f80019b6a..263a0e506 100644
--- a/core/Makefile.inc
+++ b/core/Makefile.inc
@@ -22,8 +22,12 @@  endif
 
 CORE=core/built-in.a
 
+ifeq ($(CONFIG_PLDM),1)
+include $(SRC)/core/pldm/Makefile.inc
+endif
+
 CFLAGS_SKIP_core/relocate.o = -pg -fstack-protector-all
 CFLAGS_SKIP_core/relocate.o += -fstack-protector -fstack-protector-strong
 CFLAGS_SKIP_core/relocate.o += -fprofile-arcs -ftest-coverage
 
-$(CORE): $(CORE_OBJS:%=core/%)
+$(CORE): $(CORE_OBJS:%=core/%) $(PLDM)
diff --git a/core/pldm/Makefile.inc b/core/pldm/Makefile.inc
new file mode 100644
index 000000000..ae45bb8ba
--- /dev/null
+++ b/core/pldm/Makefile.inc
@@ -0,0 +1,13 @@ 
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+# Copyright 2022 IBM Corp
+
+PLDM_DIR ?= core/pldm
+SUBDIRS += $(PLDM_DIR)
+
+CPPFLAGS += -I$(SRC)/pldm/include/
+CPPFLAGS += -I$(SRC)/pldm/include/libpldm/oem/ibm/
+
+PLDM_OBJS = pldm-mctp.o
+
+PLDM = $(PLDM_DIR)/built-in.a
+$(PLDM): $(PLDM_OBJS:%=$(PLDM_DIR)/%)
diff --git a/core/pldm/pldm-mctp.c b/core/pldm/pldm-mctp.c
new file mode 100644
index 000000000..fb675849d
--- /dev/null
+++ b/core/pldm/pldm-mctp.c
@@ -0,0 +1,91 @@ 
+// 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 "pldm.h"
+
+/*
+ * PLDM over MCTP (DSP0241)
+ *
+ * First byte of the MCTP message is the message Type = PLDM
+ *    PLDM = 0x01 (000_0001b)
+ *
+ * Next bytes of the MCTP message (MCTP message body) contain the
+ * PLDM message (The base PLDM message fields are defined in DSP0240)
+ */
+
+int pldm_mctp_message_tx(struct pldm_tx_data *tx)
+{
+	tx->mctp_msg_type = MCTP_MSG_TYPE_PLDM;
+
+	return ast_mctp_message_tx(tx->tag_owner, tx->msg_tag,
+				   &tx->mctp_msg_type,
+				   tx->data_size + sizeof(tx->mctp_msg_type));
+}
+
+int pldm_mctp_message_rx(uint8_t eid, bool tag_owner, uint8_t msg_tag,
+			 const uint8_t *buf, int len)
+{
+	struct pldm_rx_data *rx;
+	int rc = 0;
+
+	rx = zalloc(sizeof(struct pldm_rx_data));
+	if (!rx) {
+		prlog(PR_ERR, "failed to allocate rx message\n");
+		return OPAL_NO_MEM;
+	}
+
+	rx->msg = (struct pldm_msg *)buf;
+	rx->source_eid = eid;
+	rx->msg_len = len;
+	rx->tag_owner = tag_owner;
+	rx->msg_tag = msg_tag;
+
+	/* Additional header information */
+	if (unpack_pldm_header(&rx->msg->hdr, &rx->hdrinf)) {
+		prlog(PR_ERR, "%s: unable to decode header\n", __func__);
+		rc = OPAL_EMPTY;
+		goto out;
+	}
+
+out:
+	free(rx);
+	return rc;
+}
+
+int pldm_mctp_init(void)
+{
+	int nbr_elt = 1, rc = OPAL_SUCCESS;
+
+	int (*pldm_config[])(void) = {
+		ast_mctp_init,		/* MCTP Binding */
+	};
+
+	const char *pldm_config_error[] = {
+		"Failed to bind MCTP",
+	};
+
+	prlog(PR_NOTICE, "%s - Getting PLDM data\n", __func__);
+
+	for (int i = 0; i < nbr_elt; i++) {
+		rc = pldm_config[i]();
+		if (rc) {
+			prlog(PR_ERR, "%s\n", pldm_config_error[i]);
+			goto out;
+		}
+	}
+
+out:
+	prlog(PR_NOTICE, "%s - done, rc: %d\n", __func__, rc);
+	return rc;
+}
+
+void pldm_mctp_exit(void)
+{
+	ast_mctp_exit();
+}
diff --git a/core/pldm/pldm.h b/core/pldm/pldm.h
new file mode 100644
index 000000000..bd32cf853
--- /dev/null
+++ b/core/pldm/pldm.h
@@ -0,0 +1,44 @@ 
+/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ * Copyright 2022 IBM Corp.
+ */
+
+#ifndef __COREPLDM_H__
+#define __COREPLDM_H__
+
+#include <ast.h>
+#include <base.h>
+#include <pldm.h>
+
+struct pldm_tx_data {
+	/* Contains an message header and payload of an MCTP packet.
+	 * Size of data[]
+	 */
+	size_t data_size;
+
+	/* Holds data related to the routing of an MCTP packet */
+	bool tag_owner;
+	uint8_t msg_tag;
+
+	/* This byte is situated just before the message body */
+	uint8_t mctp_msg_type;
+
+	/* The message payload (e.g. PLDM message) */
+	uint8_t data[1];
+};
+
+struct pldm_rx_data {
+	struct pldm_header_info hdrinf; /* parsed message header */
+
+	struct pldm_msg *msg;
+	int msg_len;
+	int source_eid;
+	bool tag_owner;
+	uint8_t msg_tag;
+};
+
+int pldm_mctp_message_tx(struct pldm_tx_data *tx);
+
+int pldm_mctp_message_rx(uint8_t eid, bool tag_owner, uint8_t msg_tag,
+			 const uint8_t *buf, int len);
+
+#endif /* __COREPLDM_H__ */
diff --git a/hw/ast-bmc/ast-mctp.c b/hw/ast-bmc/ast-mctp.c
index c2efb7b27..00f66abec 100644
--- a/hw/ast-bmc/ast-mctp.c
+++ b/hw/ast-bmc/ast-mctp.c
@@ -12,6 +12,7 @@ 
 #include <device.h>
 #include <ast.h>
 #include <console.h>
+#include <pldm.h>
 #include <libmctp.h>
 #include <libmctp-cmds.h>
 #include <libmctp-log.h>
@@ -286,6 +287,23 @@  static void message_rx(uint8_t eid, bool tag_owner,
 	prlog(PR_TRACE, "message received: msg type: %x, len %zd"
 			" (eid: %d), rx tag %d owner %d\n",
 			 *msg, len, eid, tag_owner, msg_tag);
+
+	/* The first byte defines the type of MCTP packet payload
+	 * contained in the message data portion of the MCTP message.
+	 * (See DSP0236 for more details about MCTP packet fields).
+	 * For now we only support PLDM over MCTP.
+	 */
+	switch (*msg) {
+	case MCTP_MSG_TYPE_PLDM:
+		/* handle the PLDM message */
+		pldm_mctp_message_rx(eid, tag_owner, msg_tag,
+				     msg + sizeof(uint8_t),
+				     len - sizeof(uint8_t));
+		break;
+	default:
+		prlog(PR_ERR, "%s - not a pldm message type (type: %x)\n",
+			      __func__, *msg);
+	}
 }
 
 /*
diff --git a/include/pldm.h b/include/pldm.h
new file mode 100644
index 000000000..617287fe3
--- /dev/null
+++ b/include/pldm.h
@@ -0,0 +1,24 @@ 
+/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ * Copyright 2022 IBM Corp.
+ */
+
+#ifndef __PLDM_H__
+#define __PLDM_H__
+
+/**
+ * Handle PLDM messages received from MCTP
+ */
+int pldm_mctp_message_rx(uint8_t eid, bool tag_owner, uint8_t msg_tag,
+			 const uint8_t *buf, int len);
+
+/**
+ * PLDM over MCTP initialization
+ */
+int pldm_mctp_init(void);
+
+/**
+ * PLDM over MCTP stop
+ */
+void pldm_mctp_exit(void);
+
+#endif /* __PLDM_H__ */