Message ID | 20220913102705.65506-4-clombard@linux.vnet.ibm.com |
---|---|
State | Superseded |
Headers | show |
Series | Implement MCTP and PLDM features | expand |
On Tue, Sep 13, 2022 at 12:26:47PM +0200, Christophe Lombard wrote: > 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). > > Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> Reviewed-by: Abhishek Singh Tomar <abhishek@linux.ibm.com> > --- > core/Makefile.inc | 6 ++- > core/pldm/Makefile.inc | 13 +++++ > core/pldm/pldm-mctp.c | 118 +++++++++++++++++++++++++++++++++++++++++ > core/pldm/pldm.h | 33 ++++++++++++ > include/pldm.h | 18 +++++++ > 5 files changed, 187 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 --git a/core/Makefile.inc b/core/Makefile.inc > index f80019b6..263a0e50 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 00000000..c878ef1f > --- /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/libpldm/ > +CPPFLAGS += -I$(SRC)/pldm/ibm/libpldm/ > + > +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 00000000..832b767a > --- /dev/null > +++ b/core/pldm/pldm-mctp.c > @@ -0,0 +1,118 @@ > +// 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 <ast.h> > +#include "pldm.h" > + > +/* > + * Print content of PLDM message in hex mode. > + * 15 bytes per line. > + * Ex: pldm_mctp_message_tx: 000: 08 01 00 00 02 00 01 > + */ > +void printbuf(const char *name, const char *msg, int len) > +{ > + int i, j; > + char linebuf[128]; > + > + linebuf[0] = 0; > + > + for (i = 0; i < len; i += j) { > + linebuf[0] = 0; > + for (j = 0; i + j < len && j < 15; j++) { > + char s[5]; > + > + snprintf(s, 5, "%02x ", msg[i + j]); > + strcat(linebuf, s); > + } > + prlog(PR_TRACE, "%s: %03x: %s\n", name, i, linebuf); > + } > +} > + > +/* > + * Send PLDM message over MCTP > + */ > +int pldm_mctp_message_tx(uint8_t dest_id, uint8_t *buf, int len) > +{ > + uint8_t *msg; > + int rc; > + > + /* Message TYPE: PLDM = 0x01 (000_0001b) - DSP0240 */ > + msg = zalloc(len + 1); > + msg[0] = 0x01; > + memcpy(&msg[1], buf, len); > + > + rc = ast_mctp_message_tx(dest_id, msg, len + 1); > + free(msg); > + > + return rc; > +} > + > +/* > + * Handle messages received from MCTP > + */ > +static int handle_message_rx(uint8_t eid, const uint8_t *buf, int len) > +{ > + struct pldm_rx_data rx; > + > + if (len < sizeof(rx.msg->hdr)) { > + prlog(PR_ERR, "%s: packet is smaller than pldm header\n", __func__); > + return OPAL_EMPTY; > + } > + > + memset(&rx, 0, sizeof(rx)); > + rx.msg = (struct pldm_msg *) buf; > + rx.source_eid = eid; > + rx.msg_len = len; > + > + if (unpack_pldm_header(&rx.msg->hdr, &rx.hdrinf)) { > + prlog(PR_ERR, "%s: unable to decode header\n", __func__); > + return OPAL_EMPTY; > + } > + > + return OPAL_UNSUPPORTED; > +} > + > +/* > + * MCTP message rx callback > + */ > +static void message_rx(uint8_t eid, bool tag_owner __unused, > + uint8_t msg_tag __unused, void *data __unused, > + void *vmsg, size_t len) > +{ > + uint8_t *msg = vmsg; > + > + prlog(PR_TRACE, "message received: msg: %p, len %zd (eid: %d)\n", > + msg, len, eid); > + > + /* pldm message type */ > + if ((msg[0] & 0x7f) != 0x01) { > + prlog(PR_ERR, "%s - not a pldm message type\n", __func__); > + return; > + } > + > + handle_message_rx(eid, &msg[1], len - 1); > +} > + > +int pldm_mctp_init(uint8_t mode) > +{ > + int rc; > + > + /* MCTP Binding */ > + rc = ast_mctp_init(mode, message_rx); > + if (rc) > + prlog(PR_ERR, "Failed to bind MCTP\n"); > + > + 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 00000000..a006d1f4 > --- /dev/null > +++ b/core/pldm/pldm.h > @@ -0,0 +1,33 @@ > +/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later > + * Copyright 2022 IBM Corp. > + */ > + > +#ifndef __COREPLDM_H__ > +#define __COREPLDM_H__ > + > +#include <pldm/libpldm/base.h> > +#include <pldm.h> > + > +/* Common support */ > + > +void printbuf(const char *name, const char *msg, int len); > + > +/* > + * EID is the MCTP endpoint ID, which aids in routing MCTP packets. > + * For the EIDs: the valid range is 8-254. > + * We are saying that BMC is EID 8 and Skiboot is HOST_EID 9 > + */ > +#define BMC_EID 8 > +#define HOST_EID 9 > + > +struct pldm_rx_data { > + struct pldm_header_info hdrinf; /* parsed message header */ > + > + struct pldm_msg *msg; > + int msg_len; > + int source_eid; > +}; > + > +int pldm_mctp_message_tx(uint8_t dest_id, uint8_t *buf, int len); > + > +#endif /* __COREPLDM_H__ */ > diff --git a/include/pldm.h b/include/pldm.h > new file mode 100644 > index 00000000..3aae560c > --- /dev/null > +++ b/include/pldm.h > @@ -0,0 +1,18 @@ > +/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later > + * Copyright 2022 IBM Corp. > + */ > + > +#ifndef __PLDM_H__ > +#define __PLDM_H__ > + > +/** > + * PLDM over MCTP initialization > + */ > +int pldm_mctp_init(uint8_t mode); > + > +/** > + * PLDM over MCTP stop > + */ > +void pldm_mctp_exit(void); > + > +#endif /* __PLDM_H__ */ > -- > 2.37.3 > > _______________________________________________ > Skiboot mailing list > Skiboot@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/skiboot
On 13/09/2022 12:26, Christophe Lombard wrote: > 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). > > Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> > --- > core/Makefile.inc | 6 ++- > core/pldm/Makefile.inc | 13 +++++ > core/pldm/pldm-mctp.c | 118 +++++++++++++++++++++++++++++++++++++++++ > core/pldm/pldm.h | 33 ++++++++++++ > include/pldm.h | 18 +++++++ > 5 files changed, 187 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 --git a/core/Makefile.inc b/core/Makefile.inc > index f80019b6..263a0e50 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 00000000..c878ef1f > --- /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/libpldm/ > +CPPFLAGS += -I$(SRC)/pldm/ibm/libpldm/ > + > +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 00000000..832b767a > --- /dev/null > +++ b/core/pldm/pldm-mctp.c > @@ -0,0 +1,118 @@ > +// 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 <ast.h> > +#include "pldm.h" > + > +/* > + * Print content of PLDM message in hex mode. > + * 15 bytes per line. Should be 16 bytes per line. Looks like debug code. Either convert to static or use a less generic name. > + * Ex: pldm_mctp_message_tx: 000: 08 01 00 00 02 00 01 > + */ > +void printbuf(const char *name, const char *msg, int len) > +{ > + int i, j; > + char linebuf[128]; > + > + linebuf[0] = 0; That line is useless (already in the for loop) > + > + for (i = 0; i < len; i += j) { > + linebuf[0] = 0; > + for (j = 0; i + j < len && j < 15; j++) { > + char s[5]; > + > + snprintf(s, 5, "%02x ", msg[i + j]); > + strcat(linebuf, s); > + } > + prlog(PR_TRACE, "%s: %03x: %s\n", name, i, linebuf); > + } > +} > + > +/* > + * Send PLDM message over MCTP > + */ > +int pldm_mctp_message_tx(uint8_t dest_id, uint8_t *buf, int len) > +{ > + uint8_t *msg; > + int rc; > + > + /* Message TYPE: PLDM = 0x01 (000_0001b) - DSP0240 */ > + msg = zalloc(len + 1); As discussed, we should look to always have the caller allocate the extra byte, so that we don't have to re-allocate and copy on each message. Fred > + msg[0] = 0x01; > + memcpy(&msg[1], buf, len); > + > + rc = ast_mctp_message_tx(dest_id, msg, len + 1); > + free(msg); > + > + return rc; > +} > + > +/* > + * Handle messages received from MCTP > + */ > +static int handle_message_rx(uint8_t eid, const uint8_t *buf, int len) > +{ > + struct pldm_rx_data rx; > + > + if (len < sizeof(rx.msg->hdr)) { > + prlog(PR_ERR, "%s: packet is smaller than pldm header\n", __func__); > + return OPAL_EMPTY; > + } > + > + memset(&rx, 0, sizeof(rx)); > + rx.msg = (struct pldm_msg *) buf; > + rx.source_eid = eid; > + rx.msg_len = len; > + > + if (unpack_pldm_header(&rx.msg->hdr, &rx.hdrinf)) { > + prlog(PR_ERR, "%s: unable to decode header\n", __func__); > + return OPAL_EMPTY; > + } > + > + return OPAL_UNSUPPORTED; > +} > + > +/* > + * MCTP message rx callback > + */ > +static void message_rx(uint8_t eid, bool tag_owner __unused, > + uint8_t msg_tag __unused, void *data __unused, > + void *vmsg, size_t len) > +{ > + uint8_t *msg = vmsg; > + > + prlog(PR_TRACE, "message received: msg: %p, len %zd (eid: %d)\n", > + msg, len, eid); > + > + /* pldm message type */ > + if ((msg[0] & 0x7f) != 0x01) { > + prlog(PR_ERR, "%s - not a pldm message type\n", __func__); > + return; > + } > + > + handle_message_rx(eid, &msg[1], len - 1); > +} > + > +int pldm_mctp_init(uint8_t mode) > +{ > + int rc; > + > + /* MCTP Binding */ > + rc = ast_mctp_init(mode, message_rx); > + if (rc) > + prlog(PR_ERR, "Failed to bind MCTP\n"); > + > + 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 00000000..a006d1f4 > --- /dev/null > +++ b/core/pldm/pldm.h > @@ -0,0 +1,33 @@ > +/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later > + * Copyright 2022 IBM Corp. > + */ > + > +#ifndef __COREPLDM_H__ > +#define __COREPLDM_H__ > + > +#include <pldm/libpldm/base.h> > +#include <pldm.h> > + > +/* Common support */ > + > +void printbuf(const char *name, const char *msg, int len); > + > +/* > + * EID is the MCTP endpoint ID, which aids in routing MCTP packets. > + * For the EIDs: the valid range is 8-254. > + * We are saying that BMC is EID 8 and Skiboot is HOST_EID 9 > + */ > +#define BMC_EID 8 > +#define HOST_EID 9 > + > +struct pldm_rx_data { > + struct pldm_header_info hdrinf; /* parsed message header */ > + > + struct pldm_msg *msg; > + int msg_len; > + int source_eid; > +}; > + > +int pldm_mctp_message_tx(uint8_t dest_id, uint8_t *buf, int len); > + > +#endif /* __COREPLDM_H__ */ > diff --git a/include/pldm.h b/include/pldm.h > new file mode 100644 > index 00000000..3aae560c > --- /dev/null > +++ b/include/pldm.h > @@ -0,0 +1,18 @@ > +/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later > + * Copyright 2022 IBM Corp. > + */ > + > +#ifndef __PLDM_H__ > +#define __PLDM_H__ > + > +/** > + * PLDM over MCTP initialization > + */ > +int pldm_mctp_init(uint8_t mode); > + > +/** > + * PLDM over MCTP stop > + */ > +void pldm_mctp_exit(void); > + > +#endif /* __PLDM_H__ */
Le 12/04/2023 à 16:36, Frederic Barrat a écrit : > > > On 13/09/2022 12:26, Christophe Lombard wrote: >> 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). >> >> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> >> --- >> core/Makefile.inc | 6 ++- >> core/pldm/Makefile.inc | 13 +++++ >> core/pldm/pldm-mctp.c | 118 +++++++++++++++++++++++++++++++++++++++++ >> core/pldm/pldm.h | 33 ++++++++++++ >> include/pldm.h | 18 +++++++ >> 5 files changed, 187 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 --git a/core/Makefile.inc b/core/Makefile.inc >> index f80019b6..263a0e50 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 00000000..c878ef1f >> --- /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/libpldm/ >> +CPPFLAGS += -I$(SRC)/pldm/ibm/libpldm/ >> + >> +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 00000000..832b767a >> --- /dev/null >> +++ b/core/pldm/pldm-mctp.c >> @@ -0,0 +1,118 @@ >> +// 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 <ast.h> >> +#include "pldm.h" >> + >> +/* >> + * Print content of PLDM message in hex mode. >> + * 15 bytes per line. > > > Should be 16 bytes per line. > Looks like debug code. Either convert to static or use a less generic > name. > > Correct. printbuf is only used for debug. We can remove it to avoid confusion. >> + * Ex: pldm_mctp_message_tx: 000: 08 01 00 00 02 00 01 >> + */ >> +void printbuf(const char *name, const char *msg, int len) > +{ >> + int i, j; >> + char linebuf[128]; >> + >> + linebuf[0] = 0; > > > That line is useless (already in the for loop) > > >> + >> + for (i = 0; i < len; i += j) { >> + linebuf[0] = 0; >> + for (j = 0; i + j < len && j < 15; j++) { >> + char s[5]; >> + >> + snprintf(s, 5, "%02x ", msg[i + j]); >> + strcat(linebuf, s); >> + } >> + prlog(PR_TRACE, "%s: %03x: %s\n", name, i, linebuf); >> + } >> +} >> + >> +/* >> + * Send PLDM message over MCTP >> + */ >> +int pldm_mctp_message_tx(uint8_t dest_id, uint8_t *buf, int len) >> +{ >> + uint8_t *msg; >> + int rc; >> + >> + /* Message TYPE: PLDM = 0x01 (000_0001b) - DSP0240 */ >> + msg = zalloc(len + 1); > > > As discussed, we should look to always have the caller allocate the > extra byte, so that we don't have to re-allocate and copy on each > message. > > Fred > > yep. We could provide a common function which allocates the request msg, including the pldm msg type byte, for the caller. >> + msg[0] = 0x01; >> + memcpy(&msg[1], buf, len); >> + >> + rc = ast_mctp_message_tx(dest_id, msg, len + 1); >> + free(msg); >> + >> + return rc; >> +} >> + >> +/* >> + * Handle messages received from MCTP >> + */ >> +static int handle_message_rx(uint8_t eid, const uint8_t *buf, int len) >> +{ >> + struct pldm_rx_data rx; >> + >> + if (len < sizeof(rx.msg->hdr)) { >> + prlog(PR_ERR, "%s: packet is smaller than pldm header\n", >> __func__); >> + return OPAL_EMPTY; >> + } >> + >> + memset(&rx, 0, sizeof(rx)); >> + rx.msg = (struct pldm_msg *) buf; >> + rx.source_eid = eid; >> + rx.msg_len = len; >> + >> + if (unpack_pldm_header(&rx.msg->hdr, &rx.hdrinf)) { >> + prlog(PR_ERR, "%s: unable to decode header\n", __func__); >> + return OPAL_EMPTY; >> + } >> + >> + return OPAL_UNSUPPORTED; >> +} >> + >> +/* >> + * MCTP message rx callback >> + */ >> +static void message_rx(uint8_t eid, bool tag_owner __unused, >> + uint8_t msg_tag __unused, void *data __unused, >> + void *vmsg, size_t len) >> +{ >> + uint8_t *msg = vmsg; >> + >> + prlog(PR_TRACE, "message received: msg: %p, len %zd (eid: %d)\n", >> + msg, len, eid); >> + >> + /* pldm message type */ >> + if ((msg[0] & 0x7f) != 0x01) { >> + prlog(PR_ERR, "%s - not a pldm message type\n", __func__); >> + return; >> + } >> + >> + handle_message_rx(eid, &msg[1], len - 1); >> +} >> + >> +int pldm_mctp_init(uint8_t mode) >> +{ >> + int rc; >> + >> + /* MCTP Binding */ >> + rc = ast_mctp_init(mode, message_rx); >> + if (rc) >> + prlog(PR_ERR, "Failed to bind MCTP\n"); >> + >> + 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 00000000..a006d1f4 >> --- /dev/null >> +++ b/core/pldm/pldm.h >> @@ -0,0 +1,33 @@ >> +/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later >> + * Copyright 2022 IBM Corp. >> + */ >> + >> +#ifndef __COREPLDM_H__ >> +#define __COREPLDM_H__ >> + >> +#include <pldm/libpldm/base.h> >> +#include <pldm.h> >> + >> +/* Common support */ >> + >> +void printbuf(const char *name, const char *msg, int len); >> + >> +/* >> + * EID is the MCTP endpoint ID, which aids in routing MCTP packets. >> + * For the EIDs: the valid range is 8-254. >> + * We are saying that BMC is EID 8 and Skiboot is HOST_EID 9 >> + */ >> +#define BMC_EID 8 >> +#define HOST_EID 9 >> + >> +struct pldm_rx_data { >> + struct pldm_header_info hdrinf; /* parsed message header */ >> + >> + struct pldm_msg *msg; >> + int msg_len; >> + int source_eid; >> +}; >> + >> +int pldm_mctp_message_tx(uint8_t dest_id, uint8_t *buf, int len); >> + >> +#endif /* __COREPLDM_H__ */ >> diff --git a/include/pldm.h b/include/pldm.h >> new file mode 100644 >> index 00000000..3aae560c >> --- /dev/null >> +++ b/include/pldm.h >> @@ -0,0 +1,18 @@ >> +/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later >> + * Copyright 2022 IBM Corp. >> + */ >> + >> +#ifndef __PLDM_H__ >> +#define __PLDM_H__ >> + >> +/** >> + * PLDM over MCTP initialization >> + */ >> +int pldm_mctp_init(uint8_t mode); >> + >> +/** >> + * PLDM over MCTP stop >> + */ >> +void pldm_mctp_exit(void); >> + >> +#endif /* __PLDM_H__ */
diff --git a/core/Makefile.inc b/core/Makefile.inc index f80019b6..263a0e50 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 00000000..c878ef1f --- /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/libpldm/ +CPPFLAGS += -I$(SRC)/pldm/ibm/libpldm/ + +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 00000000..832b767a --- /dev/null +++ b/core/pldm/pldm-mctp.c @@ -0,0 +1,118 @@ +// 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 <ast.h> +#include "pldm.h" + +/* + * Print content of PLDM message in hex mode. + * 15 bytes per line. + * Ex: pldm_mctp_message_tx: 000: 08 01 00 00 02 00 01 + */ +void printbuf(const char *name, const char *msg, int len) +{ + int i, j; + char linebuf[128]; + + linebuf[0] = 0; + + for (i = 0; i < len; i += j) { + linebuf[0] = 0; + for (j = 0; i + j < len && j < 15; j++) { + char s[5]; + + snprintf(s, 5, "%02x ", msg[i + j]); + strcat(linebuf, s); + } + prlog(PR_TRACE, "%s: %03x: %s\n", name, i, linebuf); + } +} + +/* + * Send PLDM message over MCTP + */ +int pldm_mctp_message_tx(uint8_t dest_id, uint8_t *buf, int len) +{ + uint8_t *msg; + int rc; + + /* Message TYPE: PLDM = 0x01 (000_0001b) - DSP0240 */ + msg = zalloc(len + 1); + msg[0] = 0x01; + memcpy(&msg[1], buf, len); + + rc = ast_mctp_message_tx(dest_id, msg, len + 1); + free(msg); + + return rc; +} + +/* + * Handle messages received from MCTP + */ +static int handle_message_rx(uint8_t eid, const uint8_t *buf, int len) +{ + struct pldm_rx_data rx; + + if (len < sizeof(rx.msg->hdr)) { + prlog(PR_ERR, "%s: packet is smaller than pldm header\n", __func__); + return OPAL_EMPTY; + } + + memset(&rx, 0, sizeof(rx)); + rx.msg = (struct pldm_msg *) buf; + rx.source_eid = eid; + rx.msg_len = len; + + if (unpack_pldm_header(&rx.msg->hdr, &rx.hdrinf)) { + prlog(PR_ERR, "%s: unable to decode header\n", __func__); + return OPAL_EMPTY; + } + + return OPAL_UNSUPPORTED; +} + +/* + * MCTP message rx callback + */ +static void message_rx(uint8_t eid, bool tag_owner __unused, + uint8_t msg_tag __unused, void *data __unused, + void *vmsg, size_t len) +{ + uint8_t *msg = vmsg; + + prlog(PR_TRACE, "message received: msg: %p, len %zd (eid: %d)\n", + msg, len, eid); + + /* pldm message type */ + if ((msg[0] & 0x7f) != 0x01) { + prlog(PR_ERR, "%s - not a pldm message type\n", __func__); + return; + } + + handle_message_rx(eid, &msg[1], len - 1); +} + +int pldm_mctp_init(uint8_t mode) +{ + int rc; + + /* MCTP Binding */ + rc = ast_mctp_init(mode, message_rx); + if (rc) + prlog(PR_ERR, "Failed to bind MCTP\n"); + + 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 00000000..a006d1f4 --- /dev/null +++ b/core/pldm/pldm.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + * Copyright 2022 IBM Corp. + */ + +#ifndef __COREPLDM_H__ +#define __COREPLDM_H__ + +#include <pldm/libpldm/base.h> +#include <pldm.h> + +/* Common support */ + +void printbuf(const char *name, const char *msg, int len); + +/* + * EID is the MCTP endpoint ID, which aids in routing MCTP packets. + * For the EIDs: the valid range is 8-254. + * We are saying that BMC is EID 8 and Skiboot is HOST_EID 9 + */ +#define BMC_EID 8 +#define HOST_EID 9 + +struct pldm_rx_data { + struct pldm_header_info hdrinf; /* parsed message header */ + + struct pldm_msg *msg; + int msg_len; + int source_eid; +}; + +int pldm_mctp_message_tx(uint8_t dest_id, uint8_t *buf, int len); + +#endif /* __COREPLDM_H__ */ diff --git a/include/pldm.h b/include/pldm.h new file mode 100644 index 00000000..3aae560c --- /dev/null +++ b/include/pldm.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + * Copyright 2022 IBM Corp. + */ + +#ifndef __PLDM_H__ +#define __PLDM_H__ + +/** + * PLDM over MCTP initialization + */ +int pldm_mctp_init(uint8_t mode); + +/** + * PLDM over MCTP stop + */ +void pldm_mctp_exit(void); + +#endif /* __PLDM_H__ */
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). Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> --- core/Makefile.inc | 6 ++- core/pldm/Makefile.inc | 13 +++++ core/pldm/pldm-mctp.c | 118 +++++++++++++++++++++++++++++++++++++++++ core/pldm/pldm.h | 33 ++++++++++++ include/pldm.h | 18 +++++++ 5 files changed, 187 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