/* Copyright 2013-2014 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdint.h>

/* Hostboot runtime interface */
/* Derived from src/include/runtime/interface.h in Hostboot */

#define HOSTBOOT_RUNTIME_INTERFACE_VERSION 0x9002

/** Memory error types defined for memory_error() interface. */
enum MemoryError_t
{
	/** Hardware has reported a solid memory CE that is
	 * correctable, but continues to report errors on subsequent
	 * reads. A second CE on that cache line will result in memory
	 * UE. Therefore, it is advised to migrate off of the address
	 * range as soon as possible. */
	MEMORY_ERROR_CE = 0,

	/** Hardware has reported an uncorrectable error in memory
	 * (memory UE, channel failure, etc). The hypervisor should
	 * migrate any partitions off this address range as soon as
	 * possible. Note that these kind of errors will most likely
	 * result in partition failures. It is advised that the
	 * hypervisor waits some time for PRD to handle hardware
	 * attentions so that the hypervisor will know all areas of
	 * memory that are impacted by the failure. */
	MEMORY_ERROR_UE = 1,

	/** Firmware has predictively requested service on a part in the memory
	 * subsystem. The partitions may not have been affected, but it is
	 * advised to migrate off of the address range as soon as possible to
	 * avoid potential partition outages. */
	MEMORY_ERROR_PREDICTIVE = 2,
};

/* Capability sets, for get_interface_capabilities */
#define HBRT_CAPS_SET0_COMMON		0
#define HBRT_CAPS_SET1_OPAL		1
#define HBRT_CAPS_SET2_PHYP		2

/* Capability flags */

/**
 * xscom_read and xscom_write return proper return codes on error.
 * Previous implementations may have incorrectly ignored failures.
 */
#define HBRT_CAPS_OPAL_HAS_XSCOM_RC   (1ul << 0)

/**
 *  Load types for the load_pm_complex() interface
 *      HBRT_PM_LOAD: initial load of all lids/sections from scratch,
 *                    preserve nothing
 *      HBRT_PM_RELOAD: concurrent reload of all lids/sections,
 *                      but preserve runtime updates
 */
#define HBRT_PM_LOAD    0
#define HBRT_PM_RELOAD  1

struct host_interfaces {
	/** Interface version. */
	uint64_t interface_version;

	/** Put a string to the console. */
	void (*puts)(const char*);
	/** Critical failure in runtime execution. */
	void (*assert)(void);

	/** OPTIONAL. Hint to environment that the page may be executed. */
	int (*set_page_execute)(void*);

	/** malloc */
	void *(*malloc)(size_t);
	/** free */
	void (*free)(void*);
	/** realloc */
	void *(*realloc)(void*, size_t);

	/**
	 * @brief Send a PEL to the FSP
	 * @param[in] plid Platform Log identifier
	 * @param[in] data size in bytes
	 * @param[in] pointer to data
	 * @return 0 on success else error code
	 * @platform FSP
	 */
	int (*send_error_log)(uint32_t,uint32_t,void *);

	/**
	 * @brief Scan communication read
	 * @param[in] chip_id (based on devtree defn)
	 * @param[in] address
	 * @param[in] pointer to 8-byte data buffer
	 * @return 0 on success else return code
	 * @platform FSP,OpenPOWER
	 */
	int (*scom_read)(uint64_t, uint64_t, void*);

	/**
	 * @brief Scan communication write
	 * @param[in] chip_id (based on devtree defn)
	 * @param[in] address
	 * @param[in] pointer to 8-byte data buffer
	 * @return 0 on success else return code
	 * @platform FSP,OpenPOWER
	 */
	int (*scom_write)(uint64_t, uint64_t, const void *);

	/**
	 *  @brief Load a LID from PNOR, FSP, etc.
	 *
	 *  @param[in] LID number.
	 *  @param[out] Allocated buffer for LID.
	 *  @param[out] Size of LID (in bytes).
	 *
	 *  @return 0 on success, else RC.
	 *  @platform FSP
	 */
	int (*lid_load)(uint32_t lid, void **buf, size_t *len);

	/**
	 *  @brief Release memory from previously loaded LID.
	 *
	 *  @param[in] Allocated buffer for LID to release.
	 *
	 *  @return 0 on success, else RC.
	 *  @platform FSP
	 */
	int (*lid_unload)(void *buf);

	/**
	 *  @brief Get the address of a reserved memory region by its devtree
	 *  name.
	 *
	 *  @param[in] Devtree name (ex. "ibm,hbrt-vpd-image")
	 *  @param[in] Devtree instance
	 *  @return physical address of region (or NULL).
	 *  @platform FSP,OpenPOWER
	 */
	uint64_t (*get_reserved_mem)(const char *name, uint32_t instance);

	/**
	 * @brief  Force a core to be awake, or clear the force
	 * @param[in] i_core  Core to wake up (pid)
	 * @param[in] i_mode  0=force awake
	 *				1=clear force
	 *				2=clear all previous forces
	 * @return rc  non-zero on error
	 * @platform FSP
	 */
	int (*wakeup)( uint32_t i_core, uint32_t i_mode );

	/**
	 * @brief Delay/sleep for at least the time given
	 *
	 * The sleep time must be normalised; i_nano_seconds should be between
	 * 0 and 999999999.
	 *
	 * @param[in] seconds
	 * @param[in] nano seconds
	 * @platform FSP,OpenPOWER
	 */
	void (*nanosleep)(uint64_t i_seconds, uint64_t i_nano_seconds);

	/**
	 * @brief Report an OCC error to the host
	 * @param[in] Failing status that identifies the nature of the fail
	 * @param[in] Identifier that specifies the failing part
	 * @platform FSP
	 */
	void (*report_occ_failure)( uint64_t i_status, uint64_t i_partId );

	/**
	 *  @brief Reads the clock value from a POSIX clock.
	 *  @param[in]  i_clkId - The clock ID to read.
	 *  @param[out] o_tp - The timespec struct to store the clock value in.
	 *
	 *  @return 0 or -(errno).
	 *  @retval 0 - SUCCESS.
	 *  @retval -EINVAL - Invalid clock requested.
	 *  @retval -EFAULT - NULL ptr given for timespec struct.
	 *
	 * @platform OpenPOWER
	 */
	int (*clock_gettime)( clockid_t i_clkId, struct timespec* o_tp );

	/**
	 * @brief Read Pnor
	 * @param[in] i_proc: processor Id
	 * @param[in] i_partitionName: name of the partition to read
	 * @param[in] i_offset: offset within the partition
	 * @param[out] o_data: pointer to the data read
	 * @param[in] i_sizeBytes: size of data to read
	 * @retval rc - number of bytes read, or non-zero on error
	 * @platform OpenPOWER
	 */
	int (*pnor_read) ( uint32_t i_proc, const char* i_partitionName,
			uint64_t i_offset, void* o_data, size_t i_sizeBytes );

	/**
	 * @brief Write to Pnor
	 * @param[in] i_proc: processor Id
	 * @param[in] i_partitionName: name of the partition to write
	 * @param[in] i_offset: offset within the partition
	 * @param[in] i_data: pointer to the data to write
	 * @param[in] i_sizeBytes: size of data to write
	 * @retval rc - number of bytes written, or non-zero on error
	 * @platform OpenPOWER
	 */
	int (*pnor_write) ( uint32_t i_proc, const char* i_partitionName,
			uint64_t i_offset, void* i_data, size_t i_sizeBytes );


	/**
	 * i2c master description: chip, engine and port packed into
	 * a single 64-bit argument
	 *
	 * ---------------------------------------------------
	 * |         chip         |  reserved  |  eng | port |
         * |         (32)         |    (16)    |  (8) | (8)  |
	 * ---------------------------------------------------
	 */
#define HBRT_I2C_MASTER_CHIP_SHIFT	32
#define HBRT_I2C_MASTER_CHIP_MASK	(0xfffffffful << 32)
#define HBRT_I2C_MASTER_ENGINE_SHIFT	8
#define HBRT_I2C_MASTER_ENGINE_MASK	(0xfful << 8)
#define HBRT_I2C_MASTER_PORT_SHIFT	0
#define HBRT_I2C_MASTER_PORT_MASK	(0xfful)

	/**
	 * @brief Read data from an i2c device
	 * @param[in] i_master - Chip/engine/port of i2c bus
	 * @param[in] i_devAddr - I2C address of device
	 * @param[in] i_offsetSize - Length of offset (in bytes)
	 * @param[in] i_offset - Offset within device to read
	 * @param[in] i_length - Number of bytes to read
	 * @param[out] o_data - Data that was read
	 * @return 0 on success else return code
	 * @platform OpenPOWER
	 */
	int (*i2c_read)( uint64_t i_master, uint16_t i_devAddr,
			 uint32_t i_offsetSize, uint32_t i_offset,
			 uint32_t i_length, void* o_data );

	/**
	 * @brief Write data to an i2c device
	 * @param[in] i_master - Chip/engine/port of i2c bus
	 * @param[in] i_devAddr - I2C address of device
	 * @param[in] i_offsetSize - Length of offset (in bytes)
	 * @param[in] i_offset - Offset within device to write
	 * @param[in] i_length - Number of bytes to write
	 * @param[in] Data to write
	 * @return 0 on success else return code
	 * @platform OpenPOWER
	 */
	int (*i2c_write)( uint64_t i_master, uint16_t i_devAddr,
			  uint32_t i_offsetSize, uint32_t i_offset,
			  uint32_t i_length, void* i_data );

	/**
	 * Perform an IPMI transaction
	 * @param[in] netfn The IPMI netfn byte
	 * @param[in] cmd The IPMI cmd byte
	 * @param[in] tx_buf The IPMI packet to send to the host
	 * @param[in] tx_size The number of bytes, to send
	 * @param[in] rx_buf A buffer to be populated with the IPMI
	 *		response.
	 * @param[inout] rx_size The allocated size of the rx buffer on
	 *		input, updated to the size of the response on output.
	 *		This should always begin with the IPMI completion
	 *		code.
	 */
	int (*ipmi_msg)(uint8_t netfn, uint8_t cmd,
			void *tx_buf, size_t tx_size,
			void *rx_buf, size_t *rx_size);


	/**
	 * @brief Hardware has reported a memory error. This function requests
	 * the hypervisor to remove the all addresses within the address range
	 * given (including endpoints) from the available memory space.
	 *
	 * It is understood that the hypervisor may not be able to immediately
	 * deallocate the memory because it may be in use by a partition.
	 * Therefore, the hypervisor should cache all requests and deallocate
	 * the memory once it has been freed.
	 *
	 * @param  i_startAddr The beginning address of the range.
	 * @param  i_endAddr   The end address of the range.
	 * @param  i_errorType See enum MemoryError_t.
	 *
	 * @return 0 if the request is successfully received. Any value other
	 *	than 0 on failure. The hypervisor should cache the request and
	 *	return immediately. It should not wait for the request to be
	 *	applied. See note above.
	 */
	int (*memory_error)( uint64_t i_startAddr, uint64_t i_endAddr,
					  enum MemoryError_t i_errorType );

	/**
	 * @brief Query the prd infrastructure for interface capabilities.
	 * @param[in] i_set The set of capabilites to retrieve
	 *
	 * @return a bitmask containing the relevant HBRT_CAPS_* for
	 *	this implementation and the specified set.
	 */
	uint64_t (*get_interface_capabilities)(uint64_t i_set);

	/**
	 *  @brief Map a physical address space into usable memory
	 *  @note Repeated calls to map the same memory should not return an
	 *        error
	 *  @param[in]  i_physMem  Physical address
	 *  @param[in]  i_bytes    Number of bytes to map in
	 *  @return NULL on error, else pointer to usable memory
	 *  @platform FSP, OpenPOWER
	 */
	void* (*map_phys_mem)(uint64_t i_physMem, size_t i_bytes);

	/**
	 *  @brief Unmap a physical address space from usable memory
	 *  @param[in]  i_ptr  Previously mapped pointer
	 *  @return 0 on success, else RC
	 *  @platform FSP, OpenPOWER
	 */
	int (*unmap_phys_mem)(void* i_ptr);

	/**
	 *  @brief Modify the SCOM restore section of the HCODE image with the
	 *         given register data
	 *
	 *  @note The Hypervisor should perform the following actions:
	 *        - insert the data into the HCODE image (p9_stop_api)
	 *
	 *  @pre HBRT is responsible for enabling special wakeup on the
	 *       associated core(s) before calling this interface
	 *
	 *  @param  i_chipId    processor chip ID
	 *                       plus ID type, always proc (0x0)
	 *  @param  i_section   runtime section to update
	 *                      (passthru to pore_gen_scom)
	 *  @param  i_operation type of operation to perform
	 *                      (passthru to pore_gen_scom)
	 *  @param  i_scomAddr  fully qualified scom address
	 *  @param  i_scomData  data for operation
	 *
	 *  @return 0 if the request is successfully received.
	 *          Any value other than 0 on failure.
	 *  @platform FSP, OpenPOWER
	 */
	int (*hcode_scom_update)(uint64_t i_chipId,
			uint32_t i_section,
			uint32_t i_operation,
			uint64_t i_scomAddr,
			uint64_t i_scomData);

	/**
	 * @brief Send a request to firmware, and receive a response
	 * @details
	 *   req_len bytes are sent to runtime firmware, and resp_len
	 *   bytes received in response.
	 *
	 *   Both req and resp are allocated by the caller. If resp_len
	 *   is not large enough to contain the full response, an error
	 *   is returned.
	 *
	 * @param[in]  i_reqLen       length of request data
	 * @param[in]  i_req          request data
	 * @param[inout] o_respLen    in: size of request data buffer
	 *                            out: length of request data
	 * @param[in]  o_resp         response data
	 * @return 0 on success, else RC
	 * @platform FSP, OpenPOWER
	 */
	int (*firmware_request)(uint64_t i_reqLen, void *i_req,
			uint64_t *o_respLen, void *o_resp);

	/* Reserve some space for future growth. */
	void (*reserved[27])(void);
};

struct runtime_interfaces {
	/** Interface version. */
	uint64_t interface_version;

	/**
	 * @brief Execute CxxTests that may be contained in the image.
	 *
	 * @param[in] - Pointer to CxxTestStats structure for results reporting.
	 */
	void (*cxxtestExecute)(void *);

	/**
	 * @brief Get a list of lids numbers of the lids known to HostBoot
	 *
	 * @param[out] o_num - the number of lids in the list
	 * @return a pointer to the list
	 * @platform FSP
	 */
	const uint32_t * (*get_lid_list)(size_t * o_num);

	/**
	 * @brief Load OCC Image and common data into mainstore, also setup OCC
	 * BARSs
	 *
	 * @param[in] i_homer_addr_phys - The physical mainstore address of the
	 *	start of the HOMER image
	 * @param[in] i_homer_addr_va - Virtual memory address of the HOMER
	 *	image
	 * @param[in] i_common_addr_phys - The physical mainstore address
	 *	of the OCC common area.
	 * @param[in] i_common_addr_va - Virtual memory address of the common
	 *	area
	 * @param[in] i_chip - The HW chip id (XSCOM chip ID)
	 * @return 0 on success else return code
	 * @platform FSP
	 */
	int (*occ_load)(uint64_t i_homer_addr_phys,
			 uint64_t i_homer_addr_va,
			 uint64_t i_common_addr_phys,
			 uint64_t i_common_addr_va,
			 uint64_t i_chip);

	/**
	 * @brief Start OCC on all chips, by module
	 *
	 *  @param[in] i_chip - Array of functional HW chip ids
	 *  @Note The caller must include a complete modules worth of chips
	 *  @param[in] i_num_chips - Number of chips in the array
	 *  @return 0 on success else return code
	 *  @platform FSP
	 */
	int (*occ_start)(uint64_t* i_chip, size_t i_num_chips);

	/**
	 * @brief Stop OCC hold OCCs in reset
	 *
	 *  @param[in] i_chip - Array of functional HW chip ids
	 *  @Note The caller must include a complete modules worth of chips
	 *  @param[in] i_num_chips - Number of chips in the array
	 *  @return 0 on success else return code
	 *  @platform FSP
	 */
	int (*occ_stop)(uint64_t* i_chip, size_t i_num_chips);

	/**
	 * @brief Notify HTMGT that an OCC has an error to report
	 *
	 * @details  When an OCC has encountered an error that it wants to
	 *		   be reported, this interface will be called to trigger
	 *		   HTMGT to collect and commit the error.
	 *
	 * @param[i] i_chipId - Id of processor with failing OCC
	 * @platform OpenPower
	 */
	void (*process_occ_error) (uint64_t i_chipId);

	/**
	 *  @brief Enable chip attentions
	 *
	 *  @return 0 on success else return code
	 *  @platform OpenPower
	 */
	int (*enable_attns)(void);

	/**
	 *  @brief Disable chip attentions
	 *
	 *  @return 0 on success else return code
	 *  @platform OpenPower
	 */
	int (*disable_attns)(void);

	/**
	 *  @brief handle chip attentions
	 *
	 *  @param[in] i_proc - processor chip id at attention XSCOM chip id
	 *	based on devtree defn
	 *  @param[in] i_ipollStatus - processor chip Ipoll status
	 *  @param[in] i_ipollMask   - processor chip Ipoll mask
	 *  @return 0 on success else return code
	 *  @platform OpenPower
	 */
	int (*handle_attns)(uint64_t i_proc, uint64_t i_ipollStatus,
			uint64_t i_ipollMask);

	/**
	 * @brief Notify HTMGT that an OCC has failed and needs to be reset
	 *
	 * @details  When BMC detects an OCC failure that requires a reset,
	 * this interface will be called to trigger the OCC reset.  HTMGT
	 * maintains a reset count and if there are additional resets
	 * available, the OCCs get reset/reloaded.  If the recovery attempts
	 * have been exhauseted or the OCC fails to go active, an unrecoverable
	 * error will be logged and the system will remain in safe mode.
	 *
	 * @param[in]  i_chipId  ChipID which identifies the OCC reporting an
	 *	error
	 * @platform OpenPOWER
	 */
	void (*process_occ_reset)(uint64_t  i_chipId);

	/**
	 * @brief Change the OCC state
	 *
	 * @details  This is a blocking call that will change the OCC state.
	 * The OCCs will only actuate (update processor frequency/ voltages)
	 * when in Active state.  The OCC will only be monitoring/observing
	 * when in Observation state.
	 *
	 * @note When the OCCs are initially started, the state will
	 * default to Active.  If the state is changed to Observation, that
	 * state will be retained until the next IPL. (If the OCC would get
	 * reset, it would return to the last requested state)
	 *
	 * @param[in]  i_occActivation  set to true to move OCC to Active state
	 *	or false to move OCC to Observation state
	 *
	 * @return  0 on success, or return code if the state did not change.
	 * @platform OpenPower
	 */
	int (*enable_occ_actuation)(bool i_occActivation);

	/**
	 * @brief	Apply a set of attribute overrides
	 *
	 * @param[in]	pointer to binary override data
	 * @param[in]	length of override data (bytes)
	 * @returns	0 on success, or return code if the command failed
	 *
	 * @platform	OpenPower
	 */
	int (*apply_attr_override)(uint8_t *i_data, size_t size);

	/**
	 * @brief	Send a pass-through command to HTMGT
	 *
	 * @details	This is a blocking call that will send a command to
	 *		HTMGT.
	 *
	 * @note	If o_rspLength is returned with a non-zero value, the
	 *		data at the o_rspData should be dumped to stdout in a
	 *		hex dump format.
	 * @note	The maximum response data returned will be 4096 bytes
	 *
	 * @param[in]	i_cmdLength	number of bytes in pass-thru command data
	 * @param[in]	*i_cmdData	pointer to pass-thru command data
	 * @param[out]	*o_rspLength	pointer to number of bytes returned in
	 *				o_rspData
	 * @param[out]	*o_rspData	pointer to a 4096 byte buffer that will
	 *				contain the response data from the command
	 *
	 * @returns	0 on success, or return code if the command failed
	 * @platform	OpenPower
	 */
	int (*mfg_htmgt_pass_thru)(uint16_t i_cmdLength, uint8_t *i_cmdData,
				   uint16_t *o_rspLength, uint8_t *o_rspData);

	/**
	 * @brief	Execute an arbitrary command inside hostboot runtime
	 * @param[in]	Number of arguments (standard C args)
	 * @param[in]	Array of argument values (standard C args)
	 * @param[out]	Response message (NULL terminated), memory allocated
	 *		by hbrt, if o_outString is NULL then no response will
	 *		be sent
	 * @return	0 on success, else error code
	 */
	int (*run_command)(int argc, const char **argv, char **o_outString);

	/**
	 *  @brief Verify integrity of a secure container
	 *  @param[in] i_pContainer Pointer to a valid secure container,
	 *      Must not be NULL.  Container is assumed to be stripped of any
	 *      ECC and must start with a valid secure header (which contains
	 *      the container size information)
	 *  @param[in] i_pHwKeyHash Pointer to a valid hardware keys' hash.
	 *      Must not be NULL.
	 *  @param[in] i_hwKeyHashSize Size of the hardware keys' hash.
	 *      A value which incorrectly states the size of the hardware keys'
	 *      hash will be detected as a verification error or worse, an
	 *      illegal memory access.  Must not be 0.
	 *  @note If secureboot is compiled out, the function pointer will be
	 *      set to NULL.  If caller's secureboot support is compiled in and
	 *      secureboot is enabled by policy, then caller should treat a NULL
	 *      pointer as a verification failure.
	 *  @return Integer error code indicating success or failure
	 *  @retval 0 Container verified correctly
	 *  @retval !0 API error or otherwise failed to verify container
	 *  @platform FSP, OpenPOWER
	 */
	int (*verify_container)(const void *i_pContainer,
			const void *i_pHwKeyHash,
			size_t i_hwKeyHashSize);

	/**
	 *  @brief SBE message passing
	 *
	 *  @details
	 *      This is a blocking call that will pass an SBE message
	 *      with a pass-through command through HBRT to code that
	 *      will process the command and provide a response.
	 *
	 *  @param[in] i_procChipId Chip ID of the processor whose SBE is
	 *      passing the message and sent the interrupt
	 *
	 *  @return 0 on success, or return code if the command failed
	 *  @platform FSP, OpenPOWER
	 */
	int (*sbe_message_passing)(uint32_t i_procChipId);

	/**
	 *  @brief Load OCC/HCODE images into mainstore
	 *
	 *  @param[in] i_chip            the HW chip id (XSCOM chip ID)
	 *  @param[in] i_homer_addr      the physical mainstore address of the
	 *                               start of the HOMER image,
	 *  @param[in] i_occ_common_addr the physical mainstore address of the
	 *                               OCC common area, 8MB, used for
	 *                               OCC-OCC communication (1 per node)
	 *  @param[in] i_mode            selects initial load vs concurrent
	 *                               reloads
	 *                               HBRT_PM_LOAD:
	 *                                  load all lids/sections from scratch,
	 *                                  preserve nothing
	 *                               HBRT_PM_RELOAD:
	 *                                  reload all lids/sections,
	 *                                  but preserve runtime updates
	 *  @return 0 on success else return code
	 *  @platform FSP, OpenPOWER
	 */
	int (*load_pm_complex)(uint64_t i_chip,
			uint64_t i_homer_addr,
			uint64_t i_occ_common_addr,
			uint32_t i_mode);

	/**
	 *  @brief Start OCC/HCODE on the specified chip
	 *  @param[in] i_chip the HW chip id
	 *  @return 0 on success else return code
	 *  @platform FSP, OpenPOWER
	 */
	int (*start_pm_complex)(uint64_t i_chip);

	/**
	 *  @brief Reset OCC/HCODE on the specified chip
	 *  @param[in] i_chip the HW chip id
	 *  @return 0 on success else return code
	 *  @platform FSP, OpenPOWER
	 */
	int (*reset_pm_complex)(uint64_t i_chip);

	/**
	 * @brief Query the IPOLL event mask supported by HBRT
	 *
	 * @details  This call allows the wrapper application to query
	 * the ipoll event mask to set when the HBRT instance is running. Bits
	 * that are *set* in this bitmask represent events that will be
	 * forwarded to the handle_attn() callback.
	 *
	 * @return        The IPOLL event bits to enable during HBRT execution
	 * @platform FSP, OpenPOWER
	 */
	uint64_t (*get_ipoll_events)(void);

	/**
	 * @brief Receive an async notification from firmware
	 * @param[in] i_len   length of notification data
	 * @param[in] i_data  notification data
	 * @platform FSP, OpenPOWER
	 */
	void (*firmware_notify)(uint64_t len, void *data);

	/* Reserve some space for future growth. */
	void (*reserved[22])(void);
};
