diff options
author | Christophe Lombard <clombard@linux.ibm.com> | 2023-08-29 11:23:29 +0200 |
---|---|---|
committer | Reza Arbab <arbab@linux.ibm.com> | 2023-09-12 14:22:11 -0500 |
commit | bb6b93f75169a439f5ac5d97a6a011245702b90f (patch) | |
tree | 3193787538350807253e69f8737aa5ca1f71ec9f /core/pldm/pldm-platform-requests.c | |
parent | fdf104ea741ee8c0d575c61f75db8b49bbfced2b (diff) | |
download | skiboot-bb6b93f75169a439f5ac5d97a6a011245702b90f.zip skiboot-bb6b93f75169a439f5ac5d97a6a011245702b90f.tar.gz skiboot-bb6b93f75169a439f5ac5d97a6a011245702b90f.tar.bz2 |
core/pldm: Send a system firmware Graceful Restart request
Set the state information of the PLDM effecter identified by:
the entity type (PLDM_ENTITY_SYS_FIRMWARE) and the state set
PLDM_STATE_SET_SW_TERMINATION_STATUS with the effecter state:
PLDM_SW_TERM_GRACEFUL_RESTART_REQUESTED to request a platform restart.
Reviewed-by: Abhishek Singh Tomar <abhishek@linux.ibm.com>
Signed-off-by: Christophe Lombard <clombard@linux.ibm.com>
Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
Diffstat (limited to 'core/pldm/pldm-platform-requests.c')
-rw-r--r-- | core/pldm/pldm-platform-requests.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/core/pldm/pldm-platform-requests.c b/core/pldm/pldm-platform-requests.c index 5bbdd01..f456209 100644 --- a/core/pldm/pldm-platform-requests.c +++ b/core/pldm/pldm-platform-requests.c @@ -44,6 +44,51 @@ static void pdr_init_complete(bool success) pdr_ready = true; } +/* + * Search the matching record and return the effecter id. + * PDR type = PLDM_STATE_EFFECTER_PDR + */ +static int find_effecter_id_by_state_set_Id(uint16_t entity_type, + uint16_t state_set_id, + uint16_t *effecter_id, + uint16_t terminus_handle) +{ + struct state_effecter_possible_states *possible_states; + struct pldm_state_effecter_pdr *state_effecter_pdr; + const pldm_pdr_record *record = NULL; + uint8_t *outData = NULL; + uint32_t size; + + do { + /* Find (first) PDR record by PLDM_STATE_EFFECTER_PDR type + * if record not NULL, then search will begin from this + * record's next record + */ + record = pldm_pdr_find_record_by_type( + pdrs_repo, /* PDR repo handle */ + PLDM_STATE_EFFECTER_PDR, + record, /* PDR record handle */ + &outData, &size); + + if (record) { + state_effecter_pdr = (struct pldm_state_effecter_pdr *) outData; + + *effecter_id = le16_to_cpu(state_effecter_pdr->effecter_id); + + possible_states = (struct state_effecter_possible_states *) + state_effecter_pdr->possible_states; + + if ((le16_to_cpu(state_effecter_pdr->entity_type) == entity_type) && + (le16_to_cpu(state_effecter_pdr->terminus_handle) == terminus_handle) && + (le16_to_cpu(possible_states->state_set_id) == state_set_id)) + return OPAL_SUCCESS; + } + + } while (record); + + return OPAL_PARAMETER; +} + struct set_effecter_state_response { uint8_t completion_code; }; @@ -126,6 +171,38 @@ static int set_state_effecter_states_req(uint16_t effecter_id, return OPAL_SUCCESS; } +/* + * entity_type: System Firmware + * state_set: Software Termination Status(129) + * states: Graceful Restart Requested(6) + */ +int pldm_platform_restart(void) +{ + set_effecter_state_field field; + uint16_t effecter_id; + int rc; + + if (!pdr_ready) + return OPAL_HARDWARE; + + rc = find_effecter_id_by_state_set_Id( + PLDM_ENTITY_SYS_FIRMWARE, + PLDM_STATE_SET_SW_TERMINATION_STATUS, + &effecter_id, BMC_TID); + if (rc) { + prlog(PR_ERR, "%s - effecter id not found\n", __func__); + return rc; + } + + field.set_request = PLDM_REQUEST_SET; + field.effecter_state = PLDM_SW_TERM_GRACEFUL_RESTART_REQUESTED; + + prlog(PR_INFO, "sending system firmware Graceful Restart request (effecter_id: %d)\n", + effecter_id); + + return set_state_effecter_states_req(effecter_id, &field, true); +} + struct get_pdr_response { uint8_t completion_code; uint32_t next_record_hndl; |