aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Lombard <clombard@linux.ibm.com>2023-08-29 11:23:57 +0200
committerReza Arbab <arbab@linux.ibm.com>2023-09-12 14:22:11 -0500
commitf8608b8fe8847e89068875112b214197cfc2cb52 (patch)
tree07f948f72fad21cb7c54414321545a7ffa4cc449
parent3172f55e6961bbd3bc3dbfb045fb8cac4fc34f3c (diff)
downloadskiboot-f8608b8fe8847e89068875112b214197cfc2cb52.zip
skiboot-f8608b8fe8847e89068875112b214197cfc2cb52.tar.gz
skiboot-f8608b8fe8847e89068875112b214197cfc2cb52.tar.bz2
core/pldm: Decode the PlatformEventMessage request
PLDM Event Messages are sent as PLDM request messages to the Event Receiver using the PlatformEventMessage command. 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-platform-requests.c5
-rw-r--r--core/pldm/pldm-responder.c118
-rw-r--r--core/pldm/pldm.h1
3 files changed, 123 insertions, 1 deletions
diff --git a/core/pldm/pldm-platform-requests.c b/core/pldm/pldm-platform-requests.c
index c506bd4..568ed23 100644
--- a/core/pldm/pldm-platform-requests.c
+++ b/core/pldm/pldm-platform-requests.c
@@ -436,6 +436,11 @@ static int pldm_platform_load_pdrs(void)
return encode_and_queue_get_pdr_req(pdrs);
}
+int pldm_platform_reload_pdrs(void)
+{
+ return pldm_platform_load_pdrs();
+}
+
static int pdrs_init(void)
{
int rc;
diff --git a/core/pldm/pldm-responder.c b/core/pldm/pldm-responder.c
index 656c38c..19164a6 100644
--- a/core/pldm/pldm-responder.c
+++ b/core/pldm/pldm-responder.c
@@ -10,6 +10,7 @@
#include <string.h>
#include <debug_descriptor.h>
#include <libpldm/platform.h>
+#include <libpldm/platform_oem_ibm.h>
#include <libpldm/utils.h>
#include "pldm.h"
@@ -418,7 +419,9 @@ static int base_get_version_handler(const struct pldm_rx_data *rx)
}
free(tx);
- return OPAL_SUCCESS;
+
+ /* BMC has certainly rebooted, so reload the PDRs */
+ return pldm_platform_reload_pdrs();
}
static struct pldm_cmd pldm_base_get_version = {
@@ -510,6 +513,118 @@ static struct pldm_cmd pldm_platform_set_event_receiver = {
.handler = platform_set_event_receiver_handler,
};
+/*
+ * PlatformEventMessage (0x10)
+ * PLDM Event Messages are sent as PLDM request messages to the Event
+ * Receiver using the PlatformEventMessage command.
+ */
+static int platform_event_message(const struct pldm_rx_data *rx)
+{
+ size_t data_size = PLDM_MSG_SIZE(struct pldm_platform_event_message_resp);
+ struct pldm_bios_attribute_update_event_req *request;
+ uint8_t format_version, tid, event_class;
+ uint8_t *bios_attribute_handles;
+ uint8_t cc = PLDM_SUCCESS;
+ size_t event_data_offset;
+ struct pldm_tx_data *tx;
+ int rc, i;
+
+ /* decode PlatformEventMessage request data */
+ rc = decode_platform_event_message_req(
+ rx->msg,
+ sizeof(struct pldm_platform_event_message_req),
+ &format_version,
+ &tid,
+ &event_class,
+ &event_data_offset);
+ if (rc) {
+ prlog(PR_ERR, "Failed to decode PlatformEventMessage request, rc = %d\n", rc);
+ cc_resp(rx, rx->hdrinf.pldm_type,
+ rx->hdrinf.command, PLDM_ERROR);
+ return OPAL_INTERNAL_ERROR;
+ }
+
+ prlog(PR_DEBUG, "%s - format_version: %d, "
+ "tid: %d "
+ "event_class: %d "
+ "event_data: 0x%lx\n",
+ __func__,
+ format_version, tid,
+ event_class, event_data_offset);
+
+ /* we don't support any other event than the PDR Repo Changed event */
+ if ((event_class != PLDM_PDR_REPOSITORY_CHG_EVENT) &&
+ (event_class != PLDM_EVENT_TYPE_OEM_EVENT_BIOS_ATTRIBUTE_UPDATE)) {
+ prlog(PR_ERR, "%s - Invalid event class %d in platform event handler\n",
+ __func__, event_class);
+ cc = PLDM_ERROR;
+ }
+
+ /* Encode the platform event request */
+ tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
+ if (!tx)
+ return OPAL_NO_MEM;
+ tx->data_size = data_size;
+ tx->tag_owner = true;
+ tx->msg_tag = rx->msg_tag;
+
+ rc = encode_platform_event_message_resp(
+ rx->hdrinf.instance,
+ cc,
+ PLDM_EVENT_NO_LOGGING,
+ (struct pldm_msg *)tx->data);
+ if (rc != PLDM_SUCCESS) {
+ prlog(PR_ERR, "Encode PlatformEventMessage Error, rc: %d\n", rc);
+ cc_resp(rx, rx->hdrinf.pldm_type,
+ rx->hdrinf.command, PLDM_ERROR);
+ free(tx);
+ return OPAL_PARAMETER;
+ }
+
+ /* send PLDM message over MCTP */
+ rc = pldm_mctp_message_tx(tx);
+ if (rc) {
+ prlog(PR_ERR, "Failed to send PlatformEventMessage response, rc = %d\n", rc);
+ free(tx);
+ return OPAL_HARDWARE;
+ }
+
+ /* invoke the appropriate callback handler */
+ if (event_class == PLDM_PDR_REPOSITORY_CHG_EVENT) {
+ free(tx);
+ return pldm_platform_reload_pdrs();
+ }
+
+ /* When the attribute value changes for any BIOS attribute, then
+ * PlatformEventMessage command with OEM event type
+ * PLDM_EVENT_TYPE_OEM_EVENT_BIOS_ATTRIBUTE_UPDATE is send to
+ * host with the list of BIOS attribute handles.
+ */
+ if (event_class == PLDM_EVENT_TYPE_OEM_EVENT_BIOS_ATTRIBUTE_UPDATE) {
+ request = (struct pldm_bios_attribute_update_event_req *)rx->msg->payload;
+ bios_attribute_handles = (uint8_t *)request->bios_attribute_handles;
+
+ prlog(PR_DEBUG, "%s - OEM_EVENT_BIOS_ATTRIBUTE_UPDATE, handles: %d\n",
+ __func__, request->num_handles);
+
+ /* list of BIOS attribute handles */
+ for (i = 0; i < request->num_handles; i++) {
+ prlog(PR_DEBUG, "%s - OEM_EVENT_BIOS_ATTRIBUTE_UPDATE: handle(%d): %d\n",
+ __func__, i, *bios_attribute_handles);
+ bios_attribute_handles += sizeof(uint16_t);
+ }
+ }
+
+ free(tx);
+ return OPAL_SUCCESS;
+}
+
+static struct pldm_cmd pldm_platform_event_message = {
+ .name = "PLDM_PLATFORM_EVENT_MESSAGE",
+ .pldm_cmd_id = PLDM_PLATFORM_EVENT_MESSAGE,
+ .handler = platform_event_message,
+};
+
int pldm_responder_handle_request(struct pldm_rx_data *rx)
{
const struct pldm_type *type;
@@ -553,6 +668,7 @@ int pldm_responder_init(void)
/* Register platform commands we'll respond to - DSP0248 */
add_type(&pldm_platform_type);
add_cmd(&pldm_platform_type, &pldm_platform_set_event_receiver);
+ add_cmd(&pldm_platform_type, &pldm_platform_event_message);
return OPAL_SUCCESS;
}
diff --git a/core/pldm/pldm.h b/core/pldm/pldm.h
index b0c7560..f4e1617 100644
--- a/core/pldm/pldm.h
+++ b/core/pldm/pldm.h
@@ -74,6 +74,7 @@ int pldm_bios_init(void);
uint8_t pldm_base_get_bmc_tid(void);
int pldm_base_get_tid_req(void);
+int pldm_platform_reload_pdrs(void);
int pldm_platform_init(void);
void pldm_platform_exit(void);