diff options
-rw-r--r-- | core/Makefile.inc | 6 | ||||
-rw-r--r-- | core/pldm/Makefile.inc | 13 | ||||
-rw-r--r-- | core/pldm/pldm-mctp.c | 91 | ||||
-rw-r--r-- | core/pldm/pldm.h | 44 | ||||
-rw-r--r-- | hw/ast-bmc/ast-mctp.c | 18 | ||||
-rw-r--r-- | include/pldm.h | 24 |
6 files changed, 195 insertions, 1 deletions
diff --git a/core/Makefile.inc b/core/Makefile.inc index f80019b..263a0e5 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 0000000..ae45bb8 --- /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 0000000..fb67584 --- /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 0000000..bd32cf8 --- /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 c2efb7b..00f66ab 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 0000000..617287f --- /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__ */ |