[Skiboot] [PATCH V2 05/15] core/pldm: Decode the SetStateEffecterStates request
Frederic Barrat
fbarrat at linux.ibm.com
Wed Apr 26 23:39:12 AEST 2023
On 29/04/2022 11:47, Christophe Lombard wrote:
> 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 at linux.vnet.ibm.com>
> ---
> core/pldm/pldm-responder.c | 130 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 130 insertions(+)
>
> diff --git a/core/pldm/pldm-responder.c b/core/pldm/pldm-responder.c
> index e44bb509..8c543b6c 100644
> --- a/core/pldm/pldm-responder.c
> +++ b/core/pldm/pldm-responder.c
> @@ -8,8 +8,11 @@
> #include <opal.h>
> #include <stdio.h>
> #include <string.h>
> +#include <opal-msg.h>
> +#include <debug_descriptor.h>
> #include <pldm/ibm/libpldm/platform_oem_ibm.h>
> #include <pldm/libpldm/platform.h>
> +#include <pldm/libpldm/state_set.h>
> #include <pldm/libpldm/utils.h>
> #include "pldm.h"
>
> @@ -647,6 +650,132 @@ 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
> +
> +struct effecter_states_req {
> + uint16_t effecter_id;
> + uint8_t comp_effecter_count;
> + set_effecter_state_field field[8];
> +};
> +
> +/*
> + * 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 *req)
> +{
> + struct effecter_states_req states_req;
> + set_effecter_state_field *field;
> + int rc, i;
> +
> + /* decode SetStateEffecterStates request data */
> + rc = decode_set_state_effecter_states_req(
> + req->msg,
> + PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES,
> + &states_req.effecter_id,
> + &states_req.comp_effecter_count,
> + states_req.field);
> + if (rc) {
> + prlog(PR_ERR, "Failed to decode SetStateEffecterStates request, rc = %d\n", rc);
> + pldm_cc_resp(req, req->hdrinf.pldm_type,
> + req->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__,
> + states_req.effecter_id,
> + states_req.comp_effecter_count);
> +
Should we check that we match the value of states_req.effecter_id? How
do we find out our own effecter ID?
> + for (i = 0; i < states_req.comp_effecter_count; i++) {
> + field = states_req.field;
This will force to always look at the first effecter state (see below).
> +
> + /* other set_request not supported */
> + if (field->set_request != PLDM_REQUEST_SET) {
> + prlog(PR_ERR, "Got invalid set request 0x%x in "
> + "SetStateEffecterStates request\n",
> + field->set_request);
> + pldm_cc_resp(req, req->hdrinf.pldm_type,
> + req->hdrinf.command,
> + PLDM_PLATFORM_INVALID_STATE_VALUE);
> + return OPAL_PARAMETER;
> + }
> +
> + switch (field->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");
> + pldm_cc_resp(req, 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");
> + pldm_cc_resp(req, 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");
I didn't see those in my logs. Did you manage to test those? From the
FIXME below, it seems we still have to worry about multiple chips.
> + pldm_cc_resp(req, 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->effecter_state);
> + pldm_cc_resp(req, req->hdrinf.pldm_type,
> + req->hdrinf.command,
> + PLDM_PLATFORM_INVALID_STATE_VALUE);
> + return OPAL_PARAMETER;
> + }
> +
> + /* next */
> + field++;
This is overwritten at the top of the loop so it's useless (and we
process the same element over and over).
Fred
> + }
> +
> + 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_rx_handle_request(struct pldm_rx_data *rx)
> {
> const struct pldm_type *t;
> @@ -692,6 +821,7 @@ int pldm_mctp_responder_init(void)
> pldm_add_cmd(&pldm_platform_type, &pldm_platform_set_event_receiver);
> pldm_add_cmd(&pldm_platform_type, &pldm_platform_event_message);
> pldm_add_cmd(&pldm_platform_type, &pldm_platform_get_state_sensor_readings);
> + pldm_add_cmd(&pldm_platform_type, &pldm_platform_set_state_effecter_states);
>
> return OPAL_SUCCESS;
> }
More information about the Skiboot
mailing list