aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Lombard <clombard@linux.ibm.com>2023-08-29 11:23:59 +0200
committerReza Arbab <arbab@linux.ibm.com>2023-09-12 14:22:11 -0500
commitba5d1e1f89c2c0d36d077275a147d1c73b74a81b (patch)
treef4a5aad29942739af26570ab2de8802add878709
parent33351a0958af1a62427f2b2dc32cf862d65b1a2f (diff)
downloadskiboot-ba5d1e1f89c2c0d36d077275a147d1c73b74a81b.zip
skiboot-ba5d1e1f89c2c0d36d077275a147d1c73b74a81b.tar.gz
skiboot-ba5d1e1f89c2c0d36d077275a147d1c73b74a81b.tar.bz2
core/pldm: Decode the SetStateEffecterStates request
The SetStateEffecterStates command is used to set the state of one or more effecters within a PLDM State Effecter. The field comp_effecter_count indicates the number of individual sets of state effecter information that are accessed by this 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-responder.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/core/pldm/pldm-responder.c b/core/pldm/pldm-responder.c
index 9183b09..1589514 100644
--- a/core/pldm/pldm-responder.c
+++ b/core/pldm/pldm-responder.c
@@ -6,11 +6,13 @@
#include <bitmap.h>
#include <cpu.h>
#include <opal.h>
+#include <opal-msg.h>
#include <stdio.h>
#include <string.h>
#include <debug_descriptor.h>
#include <libpldm/platform.h>
#include <libpldm/platform_oem_ibm.h>
+#include <libpldm/state_set.h>
#include <libpldm/utils.h>
#include "pldm.h"
@@ -708,6 +710,120 @@ static struct pldm_cmd pldm_platform_get_state_sensor_readings = {
.handler = platform_get_state_sensor_readings,
};
+#define SOFT_OFF 0x00
+#define SOFT_REBOOT 0x01
+#define CHASSIS_PWR_DOWN 0x00
+#define DEFAULT_CHIP_ID 0
+
+/*
+ * SetStateEffecterStates (0x39)
+ * The SetStateEffecterStates command is used to set the state of one
+ * or more effecters within a PLDM State Effecter.
+ */
+static int platform_set_state_effecter_states_handler(const struct pldm_rx_data *rx)
+{
+ set_effecter_state_field field[8];
+ uint8_t comp_effecter_count;
+ uint16_t effecter_id;
+ int rc, i;
+
+ /* decode SetStateEffecterStates request data */
+ rc = decode_set_state_effecter_states_req(
+ rx->msg,
+ PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES,
+ &effecter_id,
+ &comp_effecter_count,
+ field);
+ if (rc) {
+ prlog(PR_ERR, "Failed to decode SetStateEffecterStates 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 - effecter_id: %d, comp_effecter_count: %d\n",
+ __func__, effecter_id, comp_effecter_count);
+
+ for (i = 0; i < comp_effecter_count; i++) {
+ /* other set_request not supported */
+ if (field[i].set_request != PLDM_REQUEST_SET) {
+ prlog(PR_ERR, "Got invalid set request 0x%x in "
+ "SetStateEffecterStates request\n",
+ field[i].set_request);
+ cc_resp(rx, rx->hdrinf.pldm_type,
+ rx->hdrinf.command,
+ PLDM_PLATFORM_INVALID_STATE_VALUE);
+ return OPAL_PARAMETER;
+ }
+
+ switch (field[i].effecter_state) {
+ case PLDM_SW_TERM_GRACEFUL_SHUTDOWN_REQUESTED:
+ case PLDM_STATE_SET_SYS_POWER_STATE_OFF_SOFT_GRACEFUL:
+ prlog(PR_NOTICE, "Soft shutdown requested\n");
+ cc_resp(rx, PLDM_PLATFORM,
+ PLDM_SET_STATE_EFFECTER_STATES,
+ PLDM_SUCCESS);
+
+ if (opal_booting() && platform.cec_power_down) {
+ prlog(PR_NOTICE, "Host not up, shutting down now\n");
+ platform.cec_power_down(CHASSIS_PWR_DOWN);
+ } else {
+ opal_queue_msg(OPAL_MSG_SHUTDOWN,
+ NULL, NULL,
+ cpu_to_be64(SOFT_OFF));
+ }
+
+ break;
+
+ case PLDM_SW_TERM_GRACEFUL_RESTART_REQUESTED:
+ prlog(PR_NOTICE, "Soft reboot requested\n");
+ cc_resp(rx, PLDM_PLATFORM,
+ PLDM_SET_STATE_EFFECTER_STATES,
+ PLDM_SUCCESS);
+
+ if (opal_booting() && platform.cec_reboot) {
+ prlog(PR_NOTICE, "Host not up, rebooting now\n");
+ platform.cec_reboot();
+ } else {
+ opal_queue_msg(OPAL_MSG_SHUTDOWN,
+ NULL, NULL,
+ cpu_to_be64(SOFT_REBOOT));
+ }
+
+ break;
+
+ case PLDM_STATE_SET_BOOT_RESTART_CAUSE_WARM_RESET:
+ case PLDM_STATE_SET_BOOT_RESTART_CAUSE_HARD_RESET:
+ prlog(PR_NOTICE, "OCC reset requested\n");
+ cc_resp(rx, PLDM_PLATFORM,
+ PLDM_SET_STATE_EFFECTER_STATES,
+ PLDM_SUCCESS);
+
+ /* invoke the appropriate callback handler */
+ prd_occ_reset(DEFAULT_CHIP_ID); /* FIXME, others chip ? */
+ break;
+
+ default:
+ prlog(PR_ERR, "Got invalid effecter state 0x%x in "
+ "SetStateEffecterStates request\n",
+ field[i].effecter_state);
+ cc_resp(rx, rx->hdrinf.pldm_type,
+ rx->hdrinf.command,
+ PLDM_PLATFORM_INVALID_STATE_VALUE);
+ return OPAL_PARAMETER;
+ }
+ }
+
+ return OPAL_SUCCESS;
+}
+
+static struct pldm_cmd pldm_platform_set_state_effecter_states = {
+ .name = "PLDM_SET_STATE_EFFECTER_STATES",
+ .pldm_cmd_id = PLDM_SET_STATE_EFFECTER_STATES,
+ .handler = platform_set_state_effecter_states_handler,
+};
+
int pldm_responder_handle_request(struct pldm_rx_data *rx)
{
const struct pldm_type *type;
@@ -753,6 +869,7 @@ int pldm_responder_init(void)
add_cmd(&pldm_platform_type, &pldm_platform_set_event_receiver);
add_cmd(&pldm_platform_type, &pldm_platform_event_message);
add_cmd(&pldm_platform_type, &pldm_platform_get_state_sensor_readings);
+ add_cmd(&pldm_platform_type, &pldm_platform_set_state_effecter_states);
return OPAL_SUCCESS;
}