aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Lombard <clombard@linux.ibm.com>2023-08-29 11:23:56 +0200
committerReza Arbab <arbab@linux.ibm.com>2023-09-12 14:22:11 -0500
commit3172f55e6961bbd3bc3dbfb045fb8cac4fc34f3c (patch)
tree9666196194d55ee5ff5662aaf4ccb5079ea7c590
parent7691c4ae8592800f2cd5b0d12d5d3461ce0b4940 (diff)
downloadskiboot-3172f55e6961bbd3bc3dbfb045fb8cac4fc34f3c.zip
skiboot-3172f55e6961bbd3bc3dbfb045fb8cac4fc34f3c.tar.gz
skiboot-3172f55e6961bbd3bc3dbfb045fb8cac4fc34f3c.tar.bz2
core/pldm: Decode the SetEventReceiver request
The SetEventReceiver command is used to set the address of the Event Receiver into a terminus that generates event messages. It is also used to globally enable or disable whether event messages are generated from the terminus. For the time being, only the following global event message is supported: PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE. The Event Receiver acknowledges receiving the PLDM Event Message in the response to this command. Signed-off-by: Christophe Lombard <clombard@linux.ibm.com> Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
-rw-r--r--core/pldm/pldm-responder.c89
-rw-r--r--core/pldm/pldm.h3
2 files changed, 92 insertions, 0 deletions
diff --git a/core/pldm/pldm-responder.c b/core/pldm/pldm-responder.c
index a233ea3..656c38c 100644
--- a/core/pldm/pldm-responder.c
+++ b/core/pldm/pldm-responder.c
@@ -8,6 +8,8 @@
#include <opal.h>
#include <stdio.h>
#include <string.h>
+#include <debug_descriptor.h>
+#include <libpldm/platform.h>
#include <libpldm/utils.h>
#include "pldm.h"
@@ -425,6 +427,89 @@ static struct pldm_cmd pldm_base_get_version = {
.handler = base_get_version_handler,
};
+/*
+ * PLDM Platform commands support
+ */
+static struct pldm_type pldm_platform_type = {
+ .name = "platform",
+ .pldm_type_id = PLDM_PLATFORM,
+};
+
+#define MIN_WATCHDOG_TIMEOUT_SEC 15
+
+/*
+ * SetEventReceiver (0x04)
+ * The SetEventReceiver command is used to set the address of the Event
+ * Receiver into a terminus that generates event messages. It is also
+ * used to globally enable or disable whether event messages are
+ * generated from the terminus.
+ */
+static int platform_set_event_receiver_handler(const struct pldm_rx_data *rx)
+{
+ uint8_t event_message_global_enable, transport_protocol_type;
+ uint8_t event_receiver_address_info, cc = PLDM_SUCCESS;
+ uint16_t heartbeat_timer;
+ int rc = OPAL_SUCCESS;
+
+ /* decode SetEventReceiver request data */
+ rc = decode_set_event_receiver_req(
+ rx->msg,
+ PLDM_SET_EVENT_RECEIVER_REQ_BYTES,
+ &event_message_global_enable,
+ &transport_protocol_type,
+ &event_receiver_address_info,
+ &heartbeat_timer);
+ if (rc) {
+ prlog(PR_ERR, "Failed to decode SetEventReceiver request, rc = %d\n", rc);
+ cc_resp(rx, rx->hdrinf.pldm_type,
+ rx->hdrinf.command, PLDM_ERROR);
+ return OPAL_INTERNAL_ERROR;
+ }
+
+ /* invoke the appropriate callback handler */
+ prlog(PR_DEBUG, "%s - event_message_global_enable: %d, "
+ "transport_protocol_type: %d "
+ "event_receiver_address_info: %d "
+ "heartbeat_timer: %d\n",
+ __func__,
+ event_message_global_enable,
+ transport_protocol_type,
+ event_receiver_address_info,
+ heartbeat_timer);
+
+ if (event_message_global_enable !=
+ PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
+
+ prlog(PR_ERR, "%s - invalid value for message global enable received: %d\n",
+ __func__, event_message_global_enable);
+ cc = PLDM_PLATFORM_ENABLE_METHOD_NOT_SUPPORTED;
+ }
+
+ if (heartbeat_timer < MIN_WATCHDOG_TIMEOUT_SEC) {
+ prlog(PR_ERR, "%s - BMC requested watchdog timeout that's too small: %d\n",
+ __func__, heartbeat_timer);
+ cc = PLDM_PLATFORM_HEARTBEAT_FREQUENCY_TOO_HIGH;
+ } else {
+ /* set the internal watchdog period to what BMC indicated */
+ watchdog_period_sec = heartbeat_timer;
+ }
+
+ /* send the response to BMC */
+ cc_resp(rx, PLDM_PLATFORM, PLDM_SET_EVENT_RECEIVER, cc);
+
+ /* no error happened above, so arm the watchdog and set the default timeout */
+ if (cc == PLDM_SUCCESS)
+ watchdog_armed = true;
+
+ return rc;
+}
+
+static struct pldm_cmd pldm_platform_set_event_receiver = {
+ .name = "PLDM_SET_EVENT_RECEIVER",
+ .pldm_cmd_id = PLDM_SET_EVENT_RECEIVER,
+ .handler = platform_set_event_receiver_handler,
+};
+
int pldm_responder_handle_request(struct pldm_rx_data *rx)
{
const struct pldm_type *type;
@@ -465,5 +550,9 @@ int pldm_responder_init(void)
add_cmd(&pldm_base_type, &pldm_base_get_commands);
add_cmd(&pldm_base_type, &pldm_base_get_version);
+ /* Register platform commands we'll respond to - DSP0248 */
+ add_type(&pldm_platform_type);
+ add_cmd(&pldm_platform_type, &pldm_platform_set_event_receiver);
+
return OPAL_SUCCESS;
}
diff --git a/core/pldm/pldm.h b/core/pldm/pldm.h
index 3127ee5..b0c7560 100644
--- a/core/pldm/pldm.h
+++ b/core/pldm/pldm.h
@@ -15,6 +15,9 @@
/* For all of the encode functions just pass in a default ID (0x00) */
#define DEFAULT_INSTANCE_ID 0
+extern bool watchdog_armed;
+extern int watchdog_period_sec;
+
struct pldm_tx_data {
/* Contains an message header and payload of an MCTP packet.
* Size of data[]