@@ -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)
new file mode 100644
@@ -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)/%)
new file mode 100644
@@ -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();
+}
new file mode 100644
@@ -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__ */
@@ -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);
+ }
}
/*
new file mode 100644
@@ -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__ */