diff options
author | Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com> | 2023-10-10 14:33:42 +0000 |
---|---|---|
committer | Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com> | 2023-10-10 14:33:42 +0000 |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/skiboot/include/ipmi.h | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/skiboot/include/ipmi.h')
-rw-r--r-- | roms/skiboot/include/ipmi.h | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/roms/skiboot/include/ipmi.h b/roms/skiboot/include/ipmi.h new file mode 100644 index 000000000..3e629ba40 --- /dev/null +++ b/roms/skiboot/include/ipmi.h @@ -0,0 +1,298 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2013-2019 IBM Corp. */ + +#ifndef __IPMI_H +#define __IPMI_H + +#include <stdint.h> +#include <ccan/list/list.h> +#include <stdbool.h> +#include <types.h> + +#define MAX_IPMI_SENSORS 255 + +/* + * IPMI codes as defined by the standard. + */ +#define IPMI_GET_DEVICE_ID_CMD 0x01 +#define IPMI_COLD_RESET_CMD 0x02 +#define IPMI_WARM_RESET_CMD 0x03 +#define IPMI_CLEAR_MSG_FLAGS_CMD 0x30 +#define IPMI_GET_DEVICE_GUID_CMD 0x08 +#define IPMI_GET_MSG_FLAGS_CMD 0x31 +#define IPMI_SEND_MSG_CMD 0x34 +#define IPMI_GET_MSG_CMD 0x33 +#define IPMI_SET_BMC_GLOBAL_ENABLES_CMD 0x2e +#define IPMI_GET_BMC_GLOBAL_ENABLES_CMD 0x2f +#define IPMI_READ_EVENT_MSG_BUFFER_CMD 0x35 +#define IPMI_GET_CHANNEL_INFO_CMD 0x42 + +/* + * 28. Chassis Commands + */ +#define IPMI_CHASSIS_GET_CAP_CMD 0x00 +#define IPMI_CHASSIS_GET_STATUS_CMD 0x01 +#define IPMI_CHASSIS_CONTROL_CMD 0x02 +#define IPMI_CHASSIS_RESET_CMD 0x03 +#define IPMI_CHASSIS_IDENTIFY_CMD 0x04 +#define IPMI_CHASSIS_SET_PANEL_BUTTON_EN_CMD 0x0a +#define IPMI_CHASSIS_SET_CAP_CMD 0x05 +#define IPMI_CHASSIS_SET_PWR_RESTORE_CMD 0x06 +#define IPMI_CHASSIS_SET_PWR_CYCLE_CMD 0x0b +#define IPMI_CHASSIS_GET_SYS_RESTART_CAUSE_CMD 0x07 +#define IPMI_CHASSIS_SET_SYS_BOOT_OPT_CMD 0x08 +#define IPMI_CHASSIS_GET_SYS_BOOT_OPT_CMD 0x09 +#define IPMI_CHASSIS_GET_POH_COUNTER_CMD 0x0f + + +/* 28.3. Chassis Control Command */ +#define IPMI_CHASSIS_PWR_DOWN 0x00 +#define IPMI_CHASSIS_PWR_UP 0x01 +#define IPMI_CHASSIS_PWR_CYCLE 0x02 +#define IPMI_CHASSIS_HARD_RESET 0x03 +#define IPMI_CHASSIS_PULSE_DIAG 0x04 +#define IPMI_CHASSIS_SOFT_SHUTDOWN 0x05 + +/* 20.7. ACPI Power State Command */ +#define IPMI_PWR_SYS_S0_WORKING 0x00 +#define IPMI_PWR_SYS_S1 0x01 +#define IPMI_PWR_SYS_S2 0x02 +#define IPMI_PWR_SYS_S3_SUSPEND_TO_RAM 0x03 +#define IPMI_PWR_SYS_S4_SUSPEND_TO_DISK 0x04 +#define IPMI_PWR_SYS_S5_SOFT_OFF 0x05 +#define IPMI_PWR_SYS_SUSPEND 0x06 +#define IPMI_PWR_SYS_LEGACY_ON 0x20 +#define IPMI_PWR_SYS_LEGACY_OFF 0x21 +#define IPMI_PWR_SYS_UNKNOWN 0x2a +#define IPMI_PWR_NOCHANGE 0x7f + +/* 22.{3,4} Clear / Get message flags */ +#define IPMI_MESSAGE_FLAGS_RX_MESSAGE_QUEUE (1<<0) +#define IPMI_MESSAGE_FLAGS_EVENT_BUFFER (1<<1) +#define IPMI_MESSAGE_FLAGS_WATCHDOG_PRE_TIMEOUT (1<<3) +#define IPMI_MESSAGE_FLAGS_OEM0 (1<<5) +#define IPMI_MESSAGE_FLAGS_OEM1 (1<<6) +#define IPMI_MESSAGE_FLAGS_OEM2 (1<<7) + +/* Firmware Progress Sensor states */ +#define IPMI_FW_PCI_INIT 0x07 +#define IPMI_FW_OS_BOOT 0x13 +#define IPMI_FW_MOTHERBOARD_INIT 0x14 + +#define IPMI_CODE(netfn, cmd) ((netfn) << 8 | (cmd)) +#define IPMI_CMD(code) ((code) & 0xff) +#define IPMI_NETFN(code) ((code) >> 8 & 0xff) + +#define IPMI_NETFN_RETURN_CODE(netfn) ((netfn) | 0x4) + +#define IPMI_NETFN_CHASSIS 0x00 +#define IPMI_NETFN_SE 0x04 +#define IPMI_NETFN_STORAGE 0x0a +#define IPMI_NETFN_APP 0x06 + +#define IPMI_WRITE_FRU IPMI_CODE(IPMI_NETFN_STORAGE, 0x12) +#define IPMI_GET_SEL_INFO IPMI_CODE(IPMI_NETFN_STORAGE, 0x40) +#define IPMI_RESERVE_SEL IPMI_CODE(IPMI_NETFN_STORAGE, 0x42) +#define IPMI_ADD_SEL_EVENT IPMI_CODE(IPMI_NETFN_STORAGE, 0x44) +#define IPMI_GET_SEL_TIME IPMI_CODE(IPMI_NETFN_STORAGE, 0x48) +#define IPMI_SET_SEL_TIME IPMI_CODE(IPMI_NETFN_STORAGE, 0x49) +#define IPMI_CHASSIS_CONTROL IPMI_CODE(IPMI_NETFN_CHASSIS, 0x02) +#define IPMI_CHASSIS_GET_BOOT_OPT IPMI_CODE(IPMI_NETFN_CHASSIS, 0x09) +#define IPMI_BMC_GET_DEVICE_ID IPMI_CODE(IPMI_NETFN_APP, 0x01) +#define IPMI_SET_POWER_STATE IPMI_CODE(IPMI_NETFN_APP, 0x06) +#define IPMI_GET_POWER_STATE IPMI_CODE(IPMI_NETFN_APP, 0x07) +#define IPMI_RESET_WDT IPMI_CODE(IPMI_NETFN_APP, 0x22) +#define IPMI_SET_WDT IPMI_CODE(IPMI_NETFN_APP, 0x24) +#define IPMI_SET_ENABLES IPMI_CODE(IPMI_NETFN_APP, 0x2E) +#define IPMI_GET_ENABLES IPMI_CODE(IPMI_NETFN_APP, 0x2F) +#define IPMI_CLEAR_MESSAGE_FLAGS IPMI_CODE(IPMI_NETFN_APP, 0x30) +#define IPMI_GET_MESSAGE_FLAGS IPMI_CODE(IPMI_NETFN_APP, 0x31) +#define IPMI_GET_MESSAGE IPMI_CODE(IPMI_NETFN_APP, 0x33) +#define IPMI_READ_EVENT IPMI_CODE(IPMI_NETFN_APP, 0x35) +#define IPMI_GET_BT_CAPS IPMI_CODE(IPMI_NETFN_APP, 0x36) +#define IPMI_SET_SENSOR_READING IPMI_CODE(IPMI_NETFN_SE, 0x30) + +/* + * IPMI response codes. + */ +#define IPMI_CC_NO_ERROR 0x00 +#define IPMI_NODE_BUSY_ERR 0xc0 +#define IPMI_INVALID_COMMAND_ERR 0xc1 +#define IPMI_TIMEOUT_ERR 0xc3 +#define IPMI_ERR_MSG_TRUNCATED 0xc6 +#define IPMI_REQ_LEN_INVALID_ERR 0xc7 +#define IPMI_REQ_LEN_EXCEEDED_ERR 0xc8 +#define IPMI_NOT_IN_MY_STATE_ERR 0xd5 /* IPMI 2.0 */ +#define IPMI_LOST_ARBITRATION_ERR 0x81 +#define IPMI_BUS_ERR 0x82 +#define IPMI_NAK_ON_WRITE_ERR 0x83 +#define IPMI_ERR_UNSPECIFIED 0xff + +#define IPMI_DEFAULT_INTERFACE 0 + +#define IPMI_MAX_REQ_SIZE 60 +#define IPMI_MAX_RESP_SIZE 60 + +/* + * As far as I can tell the size of PEL record is unbounded (due to + * the possible presence of the user defined section). We chose this + * size because it's what hostboot also uses and most of the OPAL logs + * are few hundred bytes. + */ +#define IPMI_MAX_PEL_SIZE 0x800 + +struct ipmi_backend; +struct ipmi_msg { + /* Can be used by command implementations to track requests */ + struct list_node link; + + struct ipmi_backend *backend; + uint8_t netfn; + uint8_t cmd; + uint8_t cc; + + /* Called when a response is received to the ipmi message */ + void (*complete)(struct ipmi_msg *); + + /* Called if non-NULL when the ipmi layer detects an error */ + void (*error)(struct ipmi_msg *); + void *user_data; + + uint8_t req_size; + uint8_t resp_size; + uint8_t *data; +}; + +struct ipmi_backend { + uint64_t opal_event_ipmi_recv; + struct ipmi_msg *(*alloc_msg)(size_t, size_t); + void (*free_msg)(struct ipmi_msg *); + int (*queue_msg)(struct ipmi_msg *); + int (*queue_msg_head)(struct ipmi_msg *); + int (*dequeue_msg)(struct ipmi_msg *); + void (*disable_retry)(struct ipmi_msg *); + /* + * When processing a synchronous IPMI message, pollers may not run, and + * neither may timers (as the synchronous IPMI message may be being + * done with locks held, which a timer may then try to also take). + * + * So, ensure we have a way to drive any state machines that an IPMI + * backend may neeed to crank to ensure forward progress. + */ + void (*poll)(void); +}; + +extern struct ipmi_backend *ipmi_backend; + +/* Initialise the IPMI interface */ +void ipmi_init(void); + +bool ipmi_present(void); + +void ipmi_free_msg(struct ipmi_msg *msg); + +struct ipmi_msg *ipmi_mkmsg_simple(uint32_t code, void *req_data, size_t req_size); +struct ipmi_msg *ipmi_mkmsg(int interface, uint32_t code, + void (*complete)(struct ipmi_msg *), + void *user_data, void *req_data, size_t req_size, + size_t resp_size); + +/* Initialise a previously allocated message with the required +fields. The caller must ensure the message is large enough to hold the +request and response data. */ +void ipmi_init_msg(struct ipmi_msg *msg, int interface, + uint32_t code, void (*complete)(struct ipmi_msg *), + void *user_data, size_t req_size, size_t resp_size); + +/* called by backend code to indicate a SMS_ATN event */ +void ipmi_sms_attention(void); + +/* Add an ipmi message to the queue */ +int ipmi_queue_msg(struct ipmi_msg *msg); + +/* Add an ipmi message to the start of the queue */ +int ipmi_queue_msg_head(struct ipmi_msg *msg); + +/* Synchronously send an ipmi message. This won't return until the + * messages callback has been called. */ +void ipmi_queue_msg_sync(struct ipmi_msg *msg); + +/* Removes the message from the list, queued previously */ +int ipmi_dequeue_msg(struct ipmi_msg *msg); + +/* Process a completed message */ +void ipmi_cmd_done(uint8_t cmd, uint8_t netfn, uint8_t cc, struct ipmi_msg *msg); + +/* 28.3 Chassis Control Command. Changes the power state of the P8. */ +int ipmi_chassis_control(uint8_t request); + +/* 20.7 ACPI Power State Command (without the ACPI part). Informative only, + * use chassis control to perform power off and reboot. */ +int ipmi_set_power_state(uint8_t system, uint8_t device); + +/* 35.17 Set Sensor Reading Command */ +int ipmi_set_sensor(uint8_t sensor, uint8_t *reading, size_t len); +int ipmi_set_fw_progress_sensor(uint8_t state); + +/* Register a backend with the ipmi core. Currently we only support one. */ +void ipmi_register_backend(struct ipmi_backend *backend); + +/* Allocate IPMI SEL panic message */ +void ipmi_sel_init(void); + +/* Register SEL handler with IPMI core */ +int ipmi_sel_register(uint8_t oem_cmd, + void (*handler)(uint8_t data, void *context), + void *context); + +/* Register rtc ipmi commands with as opal callbacks. */ +void ipmi_rtc_init(void); + +/* Register ipmi host interface access callbacks */ +void ipmi_opal_init(void); + +/* Populate fru data */ +void ipmi_fru_init(uint8_t fru_dev_id); + +/* Commit an error log to the bmc using the OEM add eSEL commands */ +struct errorlog; +int ipmi_elog_commit(struct errorlog *elog_buf); + +/* Callback to parse an OEM SEL message */ +void ipmi_parse_sel(struct ipmi_msg *msg); + +/* Starts the watchdog timer */ +void ipmi_wdt_init(void); + +/* Stop the wdt */ +void ipmi_wdt_stop(void); + +/* Reset the watchdog timer. Does not return until the timer has been + * reset and does not schedule future resets. */ +void ipmi_wdt_final_reset(void); + +/* Discover id of settable ipmi sensors */ +void ipmi_sensor_init(void); + +/* Get sensor number for given sensor type */ +uint8_t ipmi_get_sensor_number(uint8_t sensor_type); + +/* Set the boot count once the OS is up and running */ +int ipmi_set_boot_count(void); + +/* Terminate immediate */ +void __attribute__((noreturn)) ipmi_terminate(const char *msg); + +/* Get BMC firmware info */ +extern int ipmi_get_bmc_info_request(void); + +/* Add BMC firmware info to device tree */ +extern void ipmi_dt_add_bmc_info(void); + +/* Get BMC Boot Options info (specifically OEM param 0x62) */ +int ipmi_get_chassis_boot_opt_request(void); + +/* Get OEM Boot Option 0x62 for SBE validation flag */ +int ipmi_chassis_check_sbe_validation(void); + +#endif |