// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
// Copyright 2022 IBM Corp.

#define pr_fmt(fmt) "PLDM: " fmt

#include <cpu.h>
#include <opal.h>
#include <stdio.h>
#include <string.h>
#include <timebase.h>
#include <inttypes.h>
#include <libpldm/entity.h>
#include <libpldm/pdr.h>
#include <libpldm/state_set.h>
#include <libpldm/platform.h>
#include "pldm.h"

#define NO_MORE_PDR_HANDLES 0

static pldm_pdr *pdrs_repo;
static bool pdr_ready;

struct pldm_pdrs {
	struct pldm_tx_data *tx;
	uint32_t record_hndl;
	bool done;
	int rc;
};

struct pldm_pdrs *pdrs;
/* assign specific sensor/effecter IDs */
#define PLDM_SENSOR_SE_ID_RANGE_START 0x6666
static int sensor_effecter_id = PLDM_SENSOR_SE_ID_RANGE_START;

static void pdr_init_complete(bool success)
{
	/* Read not successful, error out and free the buffer */
	if (!success) {
		pdr_ready = false;

		if (pdrs_repo)
			pldm_pdr_destroy(pdrs_repo);
		return;
	}

	/* Mark ready */
	pdr_ready = true;
}

/*
 * Find PDR record by record handle.
 */
int pldm_platform_pdr_find_record(uint32_t record_handle,
				  uint8_t **pdr_data,
				  uint32_t *pdr_data_size,
				  uint32_t *next_record_handle)
{
	const pldm_pdr_record *pdr_record;

	if (!pdr_ready)
		return OPAL_HARDWARE;

	pdr_record = pldm_pdr_find_record(pdrs_repo,
					  record_handle,
					  pdr_data,
					  pdr_data_size,
					  next_record_handle);

	if (!pdr_record)
		return OPAL_PARAMETER;

	return OPAL_SUCCESS;
}

/*
 * Search the matching record and return the sensor id.
 * PDR type = PLDM_STATE_SENSOR_PDR
 */
static int find_sensor_id_by_state_set_Id(uint16_t entity_type,
					  uint16_t state_set_id,
					  uint16_t *sensor_id,
					  uint16_t terminus_handle)
{
	struct state_sensor_possible_states *possible_states;
	struct pldm_state_sensor_pdr *state_sensor_pdr;
	const pldm_pdr_record *record = NULL;
	uint8_t *outData = NULL;
	uint32_t size;

	do {
		/* Find (first) PDR record by PLDM_STATE_SENSOR_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_SENSOR_PDR,
				record, /* PDR record handle */
				&outData, &size);

		if (record) {
			state_sensor_pdr = (struct pldm_state_sensor_pdr *) outData;

			*sensor_id = le16_to_cpu(state_sensor_pdr->sensor_id);

			possible_states = (struct state_sensor_possible_states *)
				state_sensor_pdr->possible_states;

			if ((le16_to_cpu(state_sensor_pdr->entity_type) == entity_type) &&
			    (le16_to_cpu(state_sensor_pdr->terminus_handle) == terminus_handle) &&
			    (le16_to_cpu(possible_states->state_set_id) == state_set_id))
				return OPAL_SUCCESS;
		}

	} while (record);

	return OPAL_PARAMETER;
}

/*
 * 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;
};

/*
 * Create and send a PLDM request message for SetStateEffecterStates.
 */
static int set_state_effecter_states_req(uint16_t effecter_id,
					 set_effecter_state_field *field,
					 bool no_timeout)
{
	size_t data_size = PLDM_MSG_SIZE(struct pldm_set_state_effecter_states_req);
	struct set_effecter_state_response response;
	size_t response_len, payload_len;
	struct pldm_tx_data *tx = NULL;
	void *response_msg;
	int rc;

	struct pldm_set_state_effecter_states_req states_req = {
		.effecter_id = effecter_id,
		.comp_effecter_count = 1
	};

	/* Encode the state effecter states request */
	tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
	if (!tx)
		return OPAL_NO_MEM;
	tx->data_size = data_size;

	rc = encode_set_state_effecter_states_req(
			DEFAULT_INSTANCE_ID,
			states_req.effecter_id,
			states_req.comp_effecter_count,
			field,
			(struct pldm_msg *)tx->data);
	if (rc != PLDM_SUCCESS) {
		prlog(PR_ERR, "Encode SetStateEffecter Error, rc: %d\n",
			      rc);
		free(tx);
		return OPAL_PARAMETER;
	}

	/* Send and get the response message bytes.
	 * It may happen that for some commands, the responder does not
	 * have time to respond.
	 */
	if (no_timeout) {
		rc = pldm_mctp_message_tx(tx);
		if (rc)
			prlog(PR_ERR, "Failed to send SetStateEffecter request, rc = %d\n", rc);
		free(tx);
		return rc;
	}

	/* Send and get the response message bytes */
	rc = pldm_requester_queue_and_wait(tx, &response_msg, &response_len);
	if (rc) {
		prlog(PR_ERR, "Communication Error, req: SetStateEffecter, rc: %d\n", rc);
		free(tx);
		return rc;
	}

	/* Decode the message */
	payload_len = response_len - sizeof(struct pldm_msg_hdr);

	rc = decode_set_state_effecter_states_resp(
				response_msg,
				payload_len,
				&response.completion_code);
	if (rc != PLDM_SUCCESS || response.completion_code != PLDM_SUCCESS) {
		prlog(PR_ERR, "Decode SetStateEffecter Error, rc: %d, cc: %d\n",
			      rc, response.completion_code);
		free(tx);
		free(response_msg);
		return OPAL_PARAMETER;
	}

	free(tx);
	free(response_msg);
	return OPAL_SUCCESS;
}

/*
 * entity_type:  System chassis (main enclosure)
 * state_set:    System Power State (260)
 * states:       Off-Soft Graceful(9)
 */
int pldm_platform_power_off(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_SYSTEM_CHASSIS,
				PLDM_STATE_SET_SYSTEM_POWER_STATE,
				&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_STATE_SET_SYS_POWER_STATE_OFF_SOFT_GRACEFUL;

	prlog(PR_INFO, "sending system chassis Off-Soft Graceful request (effecter_id: %d)\n",
			effecter_id);

	return set_state_effecter_states_req(effecter_id, &field, true);
}

/*
 * 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);
}

static int send_sensor_state_changed_event(uint16_t state_set_id,
					   uint16_t sensor_id,
					   uint8_t sensor_offset,
					   uint8_t sensor_state,
					   bool no_timeout)
{
	size_t event_data_size = 0, actual_event_data_size;
	size_t response_len, payload_len, data_size;
	uint8_t *event_data = NULL;
	struct pldm_tx_data *tx;
	void *response_msg;
	int rc, i;

	struct pldm_platform_event_message_req event_message_req = {
		.format_version = PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION,
		.tid = HOST_TID,
		.event_class = PLDM_SENSOR_EVENT,
	};

	struct pldm_platform_event_message_resp response;

	prlog(PR_DEBUG, "%s - state_set_id: %d, sensor_id: %d, sensor_state: %d\n",
			__func__, state_set_id, sensor_id, sensor_state);

	/*
	 * The first time around this loop, event_data is nullptr which
	 * instructs the encoder to not actually do the encoding, but
	 * rather fill out actual_change_records_size with the correct
	 * size, stop and return PLDM_SUCCESS. Then we allocate the
	 * proper amount of memory and call the encoder again, which
	 * will cause it to actually encode the message.
	 */
	for (i = 0; i < 2; i++) {
		rc = encode_sensor_event_data(
			(struct pldm_sensor_event_data *)event_data,
			event_data_size,
			sensor_id,
			PLDM_STATE_SENSOR_STATE,
			sensor_offset,
			sensor_state,
			sensor_state,
			&actual_event_data_size);
		if (rc) {
			prlog(PR_ERR, "encode PldmSensorChgEventData Error, rc: %d\n", rc);
			return OPAL_PARAMETER;
		}

		if (event_data == NULL) {
			event_data_size = actual_event_data_size;
			event_data = zalloc(event_data_size);
			if (!event_data) {
				prlog(PR_ERR, "failed to allocate event data (size: 0x%lx)\n", event_data_size);
				return OPAL_NO_MEM;
			}
		}
	}

	/* Send the event request */
	payload_len = PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_size;

	data_size = sizeof(struct pldm_msg_hdr) +
		    sizeof(struct pldm_platform_event_message_req) +
		    event_data_size;
	tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
	if (!tx)
		return OPAL_NO_MEM;
	tx->data_size = data_size - 1;

	/* Encode the platform event message request */
	rc = encode_platform_event_message_req(
			DEFAULT_INSTANCE_ID,
			event_message_req.format_version,
			event_message_req.tid,
			event_message_req.event_class,
			(const uint8_t *)event_data,
			event_data_size,
			(struct pldm_msg *)tx->data,
			payload_len);
	if (rc != PLDM_SUCCESS) {
		prlog(PR_ERR, "Encode PlatformEventMessage Error, rc: %d\n", rc);
		free(event_data);
		free(tx);
		return OPAL_PARAMETER;
	}
	free(event_data);

	/* Send and get the response message bytes.
	 * It may happen that for some commands, the responder does not
	 * have time to respond.
	 */
	if (no_timeout) {
		rc = pldm_mctp_message_tx(tx);
		if (rc)
			prlog(PR_ERR, "Failed to send PlatformEventMessage request, rc = %d\n", rc);
		free(tx);
		return rc;
	}

	/* Send and get the response message bytes */
	rc = pldm_requester_queue_and_wait(tx,
					   &response_msg, &response_len);
	if (rc) {
		prlog(PR_ERR, "Communication Error, req: PlatformEventMessage, rc: %d\n", rc);
		free(tx);
		return rc;
	}
	free(tx);

	/* Decode the message */
	payload_len = response_len - sizeof(struct pldm_msg_hdr);
	rc = decode_platform_event_message_resp(
				response_msg,
				payload_len,
				&response.completion_code,
				&response.platform_event_status);
	if (rc != PLDM_SUCCESS || response.completion_code != PLDM_SUCCESS) {
		prlog(PR_ERR, "Decode PlatformEventMessage Error, rc: %d, cc: %d, pes: %d\n",
			      rc, response.completion_code,
			      response.platform_event_status);
		free(response_msg);
		return OPAL_PARAMETER;
	}

	free(response_msg);

	return OPAL_SUCCESS;
}

#define BOOT_STATE_SENSOR_INDEX 0

int pldm_platform_send_progress_state_change(
		enum pldm_state_set_boot_progress_state_values state)
{
	struct state_sensor_possible_states *possible_states;
	struct pldm_state_sensor_pdr *sensor_pdr = NULL;
	const pldm_pdr_record *record = NULL;
	uint16_t terminus_handle;
	uint8_t *outData = NULL;
	uint16_t sensor_id = 0;
	uint32_t size;

	if (!pdr_ready)
		return OPAL_HARDWARE;

	prlog(PR_INFO, "Setting boot progress, state: %d\n", state);

	do {
		/* Find (first) PDR record by PLDM_STATE_SENSOR_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_SENSOR_PDR,
				record, /* PDR record handle */
				&outData, &size);

		if (record) {
			sensor_pdr = (struct pldm_state_sensor_pdr *) outData;
			terminus_handle = le16_to_cpu(sensor_pdr->terminus_handle);

			if ((le16_to_cpu(sensor_pdr->entity_type) == PLDM_ENTITY_SYS_BOARD) &&
			    (terminus_handle == HOST_TID)) {
				possible_states = (struct state_sensor_possible_states *)
							sensor_pdr->possible_states;

				if (le16_to_cpu(possible_states->state_set_id) ==
						PLDM_STATE_SET_BOOT_PROGRESS){
					sensor_id = le16_to_cpu(sensor_pdr->sensor_id);
					break;
				}
			}
		}

	} while (record);

	if (sensor_id == 0)
		return OPAL_PARAMETER;

	return send_sensor_state_changed_event(
			PLDM_STATE_SET_BOOT_PROGRESS,
			sensor_id,
			BOOT_STATE_SENSOR_INDEX,
			state,
			false);
}

#define SW_TERM_GRACEFUL_SHUTDOWN_INDEX 0

/*
 * entity_type:  System Firmware
 * state_set:    Software Termination Status(129)
 * states:       Graceful Shutdown Requested(7)
 */
int pldm_platform_initiate_shutdown(void)
{
	uint16_t sensor_id;
	int rc;

	if (!pdr_ready)
		return OPAL_HARDWARE;

	rc = find_sensor_id_by_state_set_Id(
				PLDM_ENTITY_SYSTEM_CHASSIS,
				PLDM_STATE_SET_SW_TERMINATION_STATUS,
				&sensor_id, HOST_TID);
	if (rc) {
		prlog(PR_ERR, "%s - sensor id not found\n", __func__);
		return rc;
	}

	prlog(PR_INFO, "sending system firmware Graceful Shutdown request (sensor_id: %d)\n",
			sensor_id);

	return send_sensor_state_changed_event(
			PLDM_STATE_SET_SW_TERMINATION_STATUS,
			sensor_id,
			SW_TERM_GRACEFUL_SHUTDOWN_INDEX,
			PLDM_SW_TERM_GRACEFUL_SHUTDOWN,
			true);
}

static int add_state_sensor_pdr(pldm_pdr *repo,
				uint32_t *record_handle,
				uint16_t entity_type,
				uint16_t state_set_id,
				uint32_t states)
{
	struct state_sensor_possible_states *possible_states;
	struct pldm_state_sensor_pdr *pdr;
	uint8_t DEFAULT_CONTAINER_ID = 0;
	size_t state_size, pdr_size, actual_pdr_size = 0;
	uint8_t *state_storage;
	uint32_t swapped;
	int rc;

	/* fill in possible states structure */
	state_size = sizeof(struct state_sensor_possible_states)
		     + sizeof(states)
		     - sizeof(bitfield8_t);
	state_storage = zalloc(state_size);
	if (!state_storage) {
		prlog(PR_ERR, "failed to allocate storage data (size: 0x%lx)\n", state_size);
		return OPAL_NO_MEM;
	}

	possible_states = (struct state_sensor_possible_states *) state_storage;
	possible_states->state_set_id = state_set_id;
	possible_states->possible_states_size = sizeof(states);

	/* need to swap the byte order for little endian order */
	swapped = htole32(states);
	memcpy(possible_states->states, &swapped, sizeof(swapped));

	pdr_size = sizeof(struct pldm_state_sensor_pdr) + state_size;
	pdr = zalloc(pdr_size);
	if (!pdr) {
		prlog(PR_ERR, "failed to allocate sensor pdr (size: 0x%lx)\n", pdr_size);
		free(state_storage);
		return OPAL_NO_MEM;
	}

	/* header */
	pdr->hdr.record_handle = 0; /* ask libpldm to fill this out */
	pdr->hdr.version = 0; /* will be filled out by the encoder */
	pdr->hdr.type = 0; /* will be filled out by the encoder */
	pdr->hdr.record_change_num = 0;
	pdr->hdr.length = 0; /* will be filled out by the encoder */

	/* body */
	pdr->terminus_handle = HOST_TID;
	pdr->sensor_id = sensor_effecter_id++;
	pdr->entity_type = entity_type;
	pdr->entity_instance = 1;
	pdr->container_id = DEFAULT_CONTAINER_ID;
	pdr->sensor_init = PLDM_NO_INIT;
	pdr->sensor_auxiliary_names_pdr = false;
	pdr->composite_sensor_count = 1;

	rc = encode_state_sensor_pdr(pdr, pdr_size,
				     possible_states,
				     state_size,
				     &actual_pdr_size);

	if (rc != PLDM_SUCCESS) {
		prlog(PR_ERR, "%s - Failed to encode state sensor PDR, rc: %d\n",
			      __func__, rc);
		free(state_storage);
		free(pdr);
		return rc;
	}

	*record_handle = pldm_pdr_add(repo,
				      (const uint8_t *) pdr,
				      actual_pdr_size,
				      0, false, HOST_TID);

	free(state_storage);
	free(pdr);

	return OPAL_SUCCESS;
}

/*
 * Add boot progress record in the repository.
 */
static uint32_t add_sensor_sw_term_pdr(pldm_pdr *repo,
				       uint32_t *record_handle)
{
	int rc;

	rc = add_state_sensor_pdr(
			repo,
			record_handle,
			PLDM_ENTITY_SYSTEM_CHASSIS,
			PLDM_STATE_SET_SW_TERMINATION_STATUS,
			enum_bit(PLDM_SW_TERM_NORMAL) |
			enum_bit(PLDM_SW_TERM_GRACEFUL_SHUTDOWN_REQUESTED) |
			enum_bit(PLDM_SW_TERM_GRACEFUL_SHUTDOWN));
	if (rc) {
		prlog(PR_ERR, "%s - Failed to add states sensor PDR, rc: %d\n",
			      __func__, rc);
		return rc;
	}

	prlog(PR_DEBUG, "Add state sensor pdr (record handle: %d)\n",
			*record_handle);

	return OPAL_SUCCESS;
}

/*
 * Add boot progress record in the repository.
 */
static uint32_t add_boot_progress_pdr(pldm_pdr *repo,
				      uint32_t *record_handle)
{
	int rc;

	rc = add_state_sensor_pdr(
			repo,
			record_handle,
			PLDM_ENTITY_SYS_BOARD,
			PLDM_STATE_SET_BOOT_PROGRESS,
			enum_bit(PLDM_STATE_SET_BOOT_PROG_STATE_COMPLETED) |
			enum_bit(PLDM_STATE_SET_BOOT_PROG_STATE_PCI_RESORUCE_CONFIG) |
			enum_bit(PLDM_STATE_SET_BOOT_PROG_STATE_STARTING_OP_SYS));
	if (rc) {
		prlog(PR_ERR, "%s - Failed to add boot progress PDR, rc: %d\n",
			      __func__, rc);
		return rc;
	}

	prlog(PR_DEBUG, "Add boot progress pdr (record handle: %d)\n",
			*record_handle);

	return OPAL_SUCCESS;
}

static int add_state_effecter_pdr(pldm_pdr *repo,
				  uint32_t *record_handle,
				  uint16_t entity_type,
				  uint16_t state_set_id,
				  uint32_t states)
{
	struct state_effecter_possible_states *possible_states;
	struct pldm_state_effecter_pdr *pdr;
	uint8_t DEFAULT_CONTAINER_ID = 0;
	size_t state_size, pdr_size, actual_pdr_size = 0;
	uint8_t *state_storage;
	uint32_t swapped;
	int rc;

	/* fill in possible states structure */
	state_size = sizeof(struct state_effecter_possible_states)
		     + sizeof(states)
		     - sizeof(bitfield8_t);
	state_storage = zalloc(state_size);
	if (!state_storage) {
		prlog(PR_ERR, "failed to allocate storage data (size: 0x%lx)\n", state_size);
		return OPAL_NO_MEM;
	}

	possible_states = (struct state_effecter_possible_states *) state_storage;
	possible_states->state_set_id = state_set_id;
	possible_states->possible_states_size = sizeof(states);

	/* need to swap the byte order for little endian order */
	swapped = htole32(states);
	memcpy(possible_states->states, &swapped, sizeof(swapped));

	pdr_size = sizeof(struct pldm_state_effecter_pdr) + state_size;
	pdr = zalloc(pdr_size);
	if (!pdr) {
		prlog(PR_ERR, "failed to allocate sensor pdr (size: 0x%lx)\n", pdr_size);
		free(state_storage);
		return OPAL_NO_MEM;
	}

	/* header */
	pdr->hdr.record_handle = 0; /* ask libpldm to fill this out */
	pdr->hdr.version = 0; /* will be filled out by the encoder */
	pdr->hdr.type = 0; /* will be filled out by the encoder */
	pdr->hdr.record_change_num = 0;
	pdr->hdr.length = 0; /* will be filled out by the encoder */

	/* body */
	pdr->terminus_handle = HOST_TID;
	pdr->effecter_id = sensor_effecter_id++;
	pdr->entity_type = entity_type;
	pdr->entity_instance = 1;
	pdr->container_id = DEFAULT_CONTAINER_ID;
	pdr->effecter_semantic_id = 0; /* PLDM defines no semantic IDs yet */
	pdr->effecter_init = PLDM_NO_INIT;
	pdr->has_description_pdr = false;
	pdr->composite_effecter_count = 1;

	rc = encode_state_effecter_pdr(pdr, pdr_size, possible_states,
				       state_size, &actual_pdr_size);
	if (rc != PLDM_SUCCESS) {
		prlog(PR_ERR, "%s - Failed to encode state effecter PDR, rc: %d\n",
			      __func__, rc);
		free(state_storage);
		free(pdr);
		return rc;
	}

	*record_handle = pldm_pdr_add(repo,
				      (const uint8_t *) pdr,
				      actual_pdr_size,
				      0, false, HOST_TID);

	free(state_storage);
	free(pdr);

	return OPAL_SUCCESS;
}

/*
 * Add state software termination record in the repository.
 */
static uint32_t add_state_sw_term_pdr(pldm_pdr *repo,
				      uint32_t *record_handle)
{
	int rc;

	rc = add_state_effecter_pdr(
			repo,
			record_handle,
			PLDM_ENTITY_SYSTEM_CHASSIS,
			PLDM_STATE_SET_SW_TERMINATION_STATUS,
			enum_bit(PLDM_SW_TERM_GRACEFUL_SHUTDOWN_REQUESTED));
	if (rc) {
		prlog(PR_ERR, "%s - Failed to add boot progress PDR, rc: %d\n",
			      __func__, rc);
		return rc;
	}

	prlog(PR_DEBUG, "Add state software termination pdr (record handle: %d)\n",
			*record_handle);

	return OPAL_SUCCESS;
}

/*
 * Add terminus locator record in the repository.
 */
static int add_terminus_locator_pdr(pldm_pdr *repo,
				    uint32_t *record_handle)
{
	struct pldm_terminus_locator_type_mctp_eid *locator_value;
	struct pldm_terminus_locator_pdr pdr;
	uint8_t DEFAULT_CONTAINER_ID = 0;
	uint32_t size;

	pdr.hdr.record_handle = 0; /* record_handle will be generated for us */
	pdr.hdr.version = 1;
	pdr.hdr.type = PLDM_TERMINUS_LOCATOR_PDR;
	pdr.hdr.record_change_num = 0;
	pdr.hdr.length = htole16(sizeof(struct pldm_terminus_locator_pdr) -
				  sizeof(struct pldm_pdr_hdr));
	pdr.terminus_handle = htole16(HOST_TID);
	pdr.validity = PLDM_TL_PDR_VALID;
	pdr.tid = HOST_TID;
	pdr.container_id = DEFAULT_CONTAINER_ID;
	pdr.terminus_locator_type = PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID;
	pdr.terminus_locator_value_size = sizeof(struct pldm_terminus_locator_type_mctp_eid);
	locator_value = (struct pldm_terminus_locator_type_mctp_eid *)pdr.terminus_locator_value;
	locator_value->eid = HOST_EID;

	size = sizeof(struct pldm_terminus_locator_pdr) +
	       sizeof(struct pldm_terminus_locator_type_mctp_eid);

	*record_handle = pldm_pdr_add(repo,
				      (const uint8_t *)(&pdr), size,
				      0, false, HOST_TID);

	prlog(PR_DEBUG, "Add terminus locator pdr (record handle: %d)\n",
			 *record_handle);

	return OPAL_SUCCESS;
}

static int send_repository_changed_event(uint32_t num_changed_pdrs,
					 uint32_t *record_handle)
{
	size_t actual_change_records_size = 0;
	uint8_t number_of_change_entries[1];
	size_t max_change_records_size = 0;
	size_t response_len, payload_len;
	uint8_t event_data_operation[1];
	uint32_t *change_entries[1];
	uint8_t *event_data = NULL;
	struct pldm_tx_data *tx;
	void *response_msg;
	size_t data_size;
	int rc, i;

	struct pldm_platform_event_message_req event_message_req = {
		.format_version = PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION,
		.tid = HOST_TID,
		.event_class = PLDM_PDR_REPOSITORY_CHG_EVENT,
	};

	struct pldm_platform_event_message_resp response;

	prlog(PR_DEBUG, "%s - num_changed_pdrs: %d\n", __func__, num_changed_pdrs);

	if (num_changed_pdrs == 0)
		return OPAL_PARAMETER;

	/* encode the platform change event data */
	event_data_operation[0] = PLDM_RECORDS_ADDED;
	number_of_change_entries[0] = num_changed_pdrs;
	change_entries[0] = record_handle;

	/*
	 * The first time around this loop, event_data is nullptr which
	 * instructs the encoder to not actually do the encoding, but
	 * rather fill out actual_change_records_size with the correct
	 * size, stop and return PLDM_SUCCESS. Then we allocate the
	 * proper amount of memory and call the encoder again, which
	 * will cause it to actually encode the message.
	 */
	for (i = 0; i < 2; i++) {
		rc = encode_pldm_pdr_repository_chg_event_data(
					FORMAT_IS_PDR_HANDLES,
					1, /* only one change record (RECORDS_ADDED) */
					event_data_operation,
					number_of_change_entries,
					(const uint32_t * const*)change_entries,
					(struct pldm_pdr_repository_chg_event_data *)event_data,
					&actual_change_records_size,
					max_change_records_size);
		if (rc) {
			prlog(PR_ERR, "Encode PldmPdrRepositoryChgEventData Error, rc: %d\n", rc);
			return OPAL_PARAMETER;
		}

		if (event_data == NULL) {
			max_change_records_size = actual_change_records_size;
			event_data = zalloc(max_change_records_size);
			if (!event_data) {
				prlog(PR_ERR, "failed to allocate event data (size: 0x%lx)\n", max_change_records_size);
				return OPAL_NO_MEM;
			}
		}
	}

	/* Send the event request */
	payload_len = PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + max_change_records_size;

	data_size = sizeof(struct pldm_msg_hdr) +
		    sizeof(struct pldm_platform_event_message_req) +
		    max_change_records_size;
	tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
	if (!tx)
		return OPAL_NO_MEM;
	tx->data_size = data_size - 1;

	/* Encode the platform event message request */
	rc = encode_platform_event_message_req(
			DEFAULT_INSTANCE_ID,
			event_message_req.format_version,
			event_message_req.tid,
			event_message_req.event_class,
			(const uint8_t *)event_data,
			max_change_records_size,
			(struct pldm_msg *)tx->data,
			payload_len);
	if (rc != PLDM_SUCCESS) {
		prlog(PR_ERR, "Encode PlatformEventMessage Error, rc: %d\n", rc);
		free(event_data);
		free(tx);
		return OPAL_PARAMETER;
	}
	free(event_data);

	/* Send and get the response message bytes */
	rc = pldm_requester_queue_and_wait(tx, &response_msg, &response_len);
	if (rc) {
		prlog(PR_ERR, "Communication Error, req: PlatformEventMessage, rc: %d\n", rc);
		free(tx);
		return rc;
	}
	free(tx);

	/* Decode the message */
	payload_len = response_len - sizeof(struct pldm_msg_hdr);
	rc = decode_platform_event_message_resp(
				response_msg,
				payload_len,
				&response.completion_code,
				&response.platform_event_status);
	if (rc != PLDM_SUCCESS || response.completion_code != PLDM_SUCCESS) {
		prlog(PR_ERR, "Decode PlatformEventMessage Error, rc: %d, cc: %d, pes: %d\n",
			      rc, response.completion_code,
			      response.platform_event_status);
		free(response_msg);
		return OPAL_PARAMETER;
	}

	free(response_msg);

	return OPAL_SUCCESS;
}

static int add_hosted_pdrs(pldm_pdr *repo)
{
	static uint32_t records_handle[2];
	uint8_t hosted_pdrs = 0;
	uint32_t record_handle;
	int rc = OPAL_SUCCESS;

	rc = add_state_sw_term_pdr(repo, &record_handle);
	if (!rc) {
		records_handle[hosted_pdrs] = record_handle;
		hosted_pdrs++;
	}

	rc = add_sensor_sw_term_pdr(repo, &record_handle);
	if (!rc) {
		records_handle[hosted_pdrs] = record_handle;
		hosted_pdrs++;
	}

	rc = add_boot_progress_pdr(repo, &record_handle);
	if (!rc) {
		records_handle[hosted_pdrs] = record_handle;
		hosted_pdrs++;
	}

	rc = add_terminus_locator_pdr(repo, &record_handle);
	if (!rc) {
		records_handle[hosted_pdrs] = record_handle;
		hosted_pdrs++;
	}

	/* tell BMC that these PDRs have changed */
	rc = send_repository_changed_event(hosted_pdrs, records_handle);
	if (rc)
		prlog(PR_ERR, "%s - Failed to update hosted PDRs\n", __func__);

	return rc;
}

struct get_pdr_response {
	uint8_t completion_code;
	uint32_t next_record_hndl;
	uint32_t next_data_transfer_hndl;
	uint8_t transfer_flag;
	uint16_t resp_cnt;
	uint8_t *record_data;
	size_t record_data_length;
	uint8_t transfer_crc;
};

static int encode_and_queue_get_pdr_req(struct pldm_pdrs *pdrs);

static void get_pdr_req_complete(struct pldm_rx_data *rx,
				 void *data)
{
	struct pldm_pdrs *pdrs = (struct pldm_pdrs *)data;
	uint32_t record_hndl = pdrs->record_hndl;
	struct get_pdr_response response;
	size_t payload_len;
	int rc, i;

	prlog(PR_DEBUG, "%s - record_hndl: %d\n", __func__, record_hndl);

	if (rx == NULL) {
		pdrs->rc = OPAL_PARAMETER;
		pdrs->done = true;
	}

	/* Decode the message twice; the first time, the payload buffer
	 * will be null so that the decoder will simply tell us how big
	 * the buffer should be. Then we create a suitable payload
	 * buffer and call the decoder again, this time with the real
	 * buffer so that it can fill it with data from the message.
	 *
	 * transfer_crc is not used in case of PLDM_START_AND_END.
	 */
	payload_len = rx->msg_len - sizeof(struct pldm_msg_hdr);
	response.record_data_length = 0;
	response.record_data = NULL;

	for (i = 0; i < 2; i++) {
		rc = decode_get_pdr_resp(
				rx->msg, payload_len,
				&response.completion_code,
				&response.next_record_hndl,
				&response.next_data_transfer_hndl,
				&response.transfer_flag,
				&response.resp_cnt,
				response.record_data,
				response.record_data_length,
				&response.transfer_crc);

		if (rc != PLDM_SUCCESS || response.completion_code != PLDM_SUCCESS) {
			/* Message decoding failed */
			prlog(PR_ERR, "Decode GetPDRResp Error (rc: %d, cc: %d)\n",
				      rc, response.completion_code);

			/* BMC is not ready, try again. This behavior can be
			 * encountered when the BMC reboots and the host is
			 * still operational.
			 * The host receives a GET VERSION request indicating
			 * that we must rehcrage the pdrs.
			 */
			if (response.completion_code == PLDM_ERROR_NOT_READY) {
				time_wait_ms(500);
				encode_and_queue_get_pdr_req(pdrs);
				return;
			}

			pdrs->rc = OPAL_PARAMETER;
			pdrs->done = true;
			return;
		}

		if (response.record_data == NULL) {
			response.record_data_length = response.resp_cnt;
			response.record_data = zalloc(response.resp_cnt);
			if (!response.record_data) {
				prlog(PR_ERR, "failed to allocate record data (size: 0x%lx)\n", response.record_data_length);
				pdrs->rc = OPAL_NO_MEM;
				pdrs->done = true;
				return;
			}
		}
	}

	/* we do not support multipart transfer */
	if (response.transfer_flag != PLDM_START_AND_END)
		prlog(PR_ERR, "Transfert GetPDRResp not complete, transfer_flag: %d\n",
			      response.transfer_flag);

	prlog(PR_DEBUG, "%s - record_hndl: %d, next_record_hndl: %d, resp_cnt: %d\n",
			__func__, record_hndl,
			response.next_record_hndl,
			response.resp_cnt);

	/* Add a PDR record to a PDR repository.
	 * Use HOST_TID as terminus handle
	 */
	pldm_pdr_add(pdrs_repo,
		     response.record_data,
		     response.resp_cnt,
		     record_hndl,
		     false,
		     HOST_TID);

	free(response.record_data);

	if (response.next_record_hndl != NO_MORE_PDR_HANDLES) {
		pdrs->record_hndl = response.next_record_hndl;
		encode_and_queue_get_pdr_req(pdrs);
	} else {
		/* We have to indicate the end of the initialization when we
		 * reload the pdrs in background
		 */
		pdr_init_complete(true);
		pdrs->done = true;
		pdrs->rc = OPAL_SUCCESS;
		prlog(PR_DEBUG, "%s - done\n", __func__);
	}
}

/*
 * Send/receive a PLDM GetPDR stateEffecter request message
 * Get platform descriptor records.
 *
 * pldmtool platform GetPDR -t stateEffecter
 * ...
 * {
 * "nextRecordHandle": 138,
 * "responseCount": 30,
 * "recordHandle": 137,
 * "PDRHeaderVersion": 1,
 * "PDRType": "State Effecter PDR",
 * "recordChangeNumber": 0,
 * "dataLength": 20,
 * "PLDMTerminusHandle": 1,
 * "effecterID": 43,
 * "entityType": "[Physical] System chassis (main enclosure)",
 * ...
 * "Off-Soft Graceful(9)"
 * }
 * ...
 */
static int encode_and_queue_get_pdr_req(struct pldm_pdrs *pdrs)
{
	uint32_t record_hndl = pdrs->record_hndl;
	int rc;

	struct pldm_get_pdr_req pdr_req = {
		.record_handle = record_hndl, /* record change number (0 for first request) */
		.data_transfer_handle = 0, /* (0 if transfer op is FIRSTPART) */
		.transfer_op_flag = PLDM_GET_FIRSTPART, /* transfer op flag */
		.request_count = SHRT_MAX, /* Don't limit the size of the PDR */
		.record_change_number = 0 /* record change number (0 for first request) */
	};

	prlog(PR_DEBUG, "%s - record_hndl: %d\n", __func__, record_hndl);

	/* Encode the get_PDR request */
	rc = encode_get_pdr_req(DEFAULT_INSTANCE_ID,
				pdr_req.record_handle,
				pdr_req.data_transfer_handle,
				pdr_req.transfer_op_flag,
				pdr_req.request_count,
				pdr_req.record_change_number,
				(struct pldm_msg *)pdrs->tx->data,
				PLDM_GET_PDR_REQ_BYTES);
	if (rc != PLDM_SUCCESS) {
		prlog(PR_ERR, "Encode GetPDRReq Error, rc: %d\n", rc);
		pdrs->done = true;
		pdrs->rc = OPAL_PARAMETER;
		return OPAL_PARAMETER;
	}

	/* Queue the first getpdr request */
	rc = pldm_requester_queue(pdrs->tx, get_pdr_req_complete, pdrs);
	if (rc) {
		prlog(PR_ERR, "Communication Error, req: GetPDRReq, rc: %d\n", rc);
		pdrs->done = true;
		pdrs->rc = OPAL_PARAMETER;
	}

	return rc;
}

static int pldm_platform_load_pdrs(void)
{
	/* destroy current repo and mark repo not ready */
	pdr_init_complete(false);

	/* make a new PDR repository */
	pdrs_repo = pldm_pdr_init();

	/* collect all PDrs into a PDR Repository */
	pdrs->record_hndl = 0;
	pdrs->done = false;
	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;

	rc = pldm_platform_load_pdrs();
	if (rc)
		return rc;

	/* wait for the end of pdrs received */
	for (;;) {
		if (pdrs->done)
			break;

		time_wait_ms(5);
	}
	return pdrs->rc;
}

int pldm_platform_init(void)
{
	size_t data_size = PLDM_MSG_SIZE(struct pldm_get_pdr_req);
	int rc;

	pdrs = zalloc(sizeof(struct pldm_pdrs));
	if (!pdrs) {
		prlog(PR_ERR, "failed to allocate pdrs\n");
		return OPAL_NO_MEM;
	}

	pdrs->tx = zalloc(sizeof(struct pldm_tx_data) + data_size);
	if (!pdrs->tx)
		return OPAL_NO_MEM;
	pdrs->tx->data_size = data_size;

	/* retrieve all PDRs */
	rc = pdrs_init();
	if (rc)
		goto err;

	/* add hosted pdrs */
	rc = add_hosted_pdrs(pdrs_repo);
	if (rc)
		goto err;

	pdr_init_complete(true);
	prlog(PR_DEBUG, "%s - done\n", __func__);

	return OPAL_SUCCESS;

err:
	prlog(PR_ERR, "%s - failed to initialize pdrs, rc: %d\n", __func__, rc);
	pdr_init_complete(false);
	free(pdrs->tx);
	free(pdrs);
	return rc;
}

void pldm_platform_exit(void)
{
	if (pdr_ready)
		pldm_pdr_destroy(pdrs_repo);

	if (pdrs) {
		free(pdrs->tx);
		free(pdrs);
	}
}
