diff options
Diffstat (limited to 'include/ipmitool/ipmi_mc.h')
| -rw-r--r-- | include/ipmitool/ipmi_mc.h | 182 | 
1 files changed, 157 insertions, 25 deletions
| diff --git a/include/ipmitool/ipmi_mc.h b/include/ipmitool/ipmi_mc.h index 0e3c59f..65cba84 100644 --- a/include/ipmitool/ipmi_mc.h +++ b/include/ipmitool/ipmi_mc.h @@ -30,10 +30,19 @@   * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.   */ -#ifndef IPMI_MC_H -#define IPMI_MC_H +#pragma once + +#include <stdbool.h>  #include <ipmitool/ipmi.h> +#include <ipmitool/helper.h> +#include <ipmitool/ipmi_strings.h> + +#define OEM_MFG_STRING(oem) val2str(IPM_DEV_MANUFACTURER_ID(oem),\ +                                    ipmi_oem_info) +#define OEM_PROD_STRING(oem, p) oemval2str(IPM_DEV_MANUFACTURER_ID(oem),\ +                                           ipmi16toh(p),\ +                                           ipmi_oem_product_info)  #define BMC_GET_DEVICE_ID	0x01  #define BMC_COLD_RESET		0x02 @@ -74,7 +83,7 @@ struct ipm_devid_rsp {  #define IPM_DEV_DEVICE_ID_REV_MASK     (0x0F)	/* BCD-enoded             */  #define IPM_DEV_FWREV1_AVAIL_MASK      (0x80)	/* 0 = normal operation   */ -#define IPM_DEV_FWREV1_MAJOR_MASK      (0x3f)	/* Major rev, BCD-encoded */ +#define IPM_DEV_FWREV1_MAJOR_MASK      (0x7f)	/* Major rev, BCD-encoded */  #define IPM_DEV_IPMI_VER_MAJOR_MASK    (0x0F)	/* Major rev, BCD-encoded */  #define IPM_DEV_IPMI_VER_MINOR_MASK    (0xF0)	/* Minor rev, BCD-encoded */ @@ -84,29 +93,125 @@ struct ipm_devid_rsp {  #define IPM_DEV_IPMI_VERSION_MINOR(x) \  	((x & IPM_DEV_IPMI_VER_MINOR_MASK) >> IPM_DEV_IPMI_VER_MINOR_SHIFT) -#define IPM_DEV_MANUFACTURER_ID(x) \ -	((uint32_t) ((x[2] & 0x0F) << 16 | x[1] << 8 | x[0])) +#define IPM_DEV_MANUFACTURER_ID_RESERVED 0x0FFFFF +#define IPM_DEV_MANUFACTURER_ID(x) ipmi24toh(x)  #define IPM_DEV_ADTL_SUPPORT_BITS      (8) -/* Structure follow the IPMI V.2 Rev 1.0 - * See Table 20-10 */ +/* There are lots of BMC implementations that don't follow the IPMI + * specification for GUID encoding. Some send data encoded as in + * RFC4122, some follow SMBIOS specification. We support all users + * of those buggy implementations here. + * + * Most implementations like AMI MegaRAC do it the SMBIOS way. + * This is the legacy behavior we don't want to break yet. + * That's why the last real mode is GUID_SMBIOS. If automatic + * detection finds more than one possible candidate, and + * GUID_SMBIOS is one of them, then it will take precedence. + * + * For the same reason GUID_IPMI is right before GUID_SMBIOS. + * If both RFC4122 and IPMI encodings have a valid version + * field, then IPMI takes precedence. + */ +typedef enum { +	/* Real modes, in reverse precedence order */ +	GUID_RFC4122, +	GUID_IPMI, +	GUID_SMBIOS, +	GUID_REAL_MODES, /* Real mode count*/ +	/* Pseudo modes start here */ +	GUID_AUTO = GUID_REAL_MODES, /* Automatically detect mode */ +	GUID_DUMP, /* Just dump the data */ +	GUID_TOTAL_MODES +} ipmi_guid_mode_t; + +#define GUID_NODE_SZ 6 + +#define GUID_VER_MASK 0x0F +#define GUID_VER_SHIFT 12 +#define GUID_VERSION(t_hi) (((t_hi) >> GUID_VER_SHIFT) & GUID_VER_MASK) +#define GUID_TIME_HI(t_hi) ((t_hi) & ~(GUID_VER_MASK << GUID_VER_SHIFT)) + +typedef enum { +	GUID_VERSION_UNKNOWN = 0, /* Not valid according to any specification */ + +	/* The following are according to IPMI/SMBIOS/RFC4122 */ +	GUID_VERSION_TIME, /* Time-based, recommended for IPMI */ +	GUID_VERSION_DCE,  /* DCE Security with POSIX UIDs, not for IPMI */ +	GUID_VERSION_MD5,  /* Name-based, using MD5 */ +	GUID_VERSION_RND,  /* Randomly generated */ +	GUID_VERSION_SHA1, /* Name-based, using SHA-1 */ + +	GUID_VERSION_MAX = GUID_VERSION_SHA1, /* The maximum supported version */ +	GUID_VERSION_COUNT /* The number of supported versions */ +} guid_version_t; + +static inline bool is_guid_version_valid(guid_version_t ver) +{ +	return (ver > GUID_VERSION_UNKNOWN) && (ver <= GUID_VERSION_MAX); +} + +/* The structure follows IPMI v2.0, rev 1.1 + * See section 20.8 */  #ifdef HAVE_PRAGMA_PACK  #pragma pack(1)  #endif -struct ipmi_guid_t { -	uint32_t  time_low;	/* timestamp low field */ -	uint16_t  time_mid;	/* timestamp middle field */ -	uint16_t  time_hi_and_version; /* timestamp high field and version number */ -	uint8_t   clock_seq_hi_variant;/* clock sequence high field and variant */ -	uint8_t   clock_seq_low; /* clock sequence low field */ -	uint8_t   node[6];	/* node */ -} ATTRIBUTE_PACKING; +typedef struct { +	uint8_t node[GUID_NODE_SZ]; /* Byte 0 is LSB */ +	union { +		struct { +			uint8_t clock_seq_low; /* clock sequence low field */ +			uint8_t clock_seq_hi_and_rsvd;/* clock sequence high field */ +		}; +		uint16_t clock_seq_and_rsvd; +	}; +	uint16_t time_hi_and_version; /* timestamp high field and version number */ +	uint16_t time_mid; /* timestamp middle field */ +	uint32_t time_low; /* timestamp low field */ +} ATTRIBUTE_PACKING ipmi_guid_t; +#ifdef HAVE_PRAGMA_PACK +#pragma pack(0) +#endif + +/* The structure follows RFC4122 (section 4.1.2) + * and SMBIOS v3.0.0 (section 7.2.1) */ +#ifdef HAVE_PRAGMA_PACK +#pragma pack(1) +#endif +typedef struct { +	uint32_t time_low; /* timestamp low field */ +	uint16_t time_mid; /* timestamp middle field */ +	uint16_t time_hi_and_version; /* timestamp high field and version number */ +	union { +		struct { +			uint8_t clock_seq_hi_and_rsvd;/* clock sequence high field */ +			uint8_t clock_seq_low; /* clock sequence low field */ +		}; +		uint16_t clock_seq_and_rsvd; +	}; +	uint8_t node[GUID_NODE_SZ]; /* Byte 0 is MSB */ +} ATTRIBUTE_PACKING rfc_guid_t;  #ifdef HAVE_PRAGMA_PACK  #pragma pack(0)  #endif -int _ipmi_mc_get_guid(struct ipmi_intf *, struct ipmi_guid_t *); +/* Parsed GUID structure */ +typedef struct { +	uint8_t node[GUID_NODE_SZ]; /* MSB first */ +	/* These are architecture-specific for easy output with printf() */ +	uint16_t clock_seq_and_rsvd; +	uint64_t time_hi_and_version; +	uint64_t time_mid; +	uint64_t time_low; +	/* These are the parsed values */ +	time_t time; +	ipmi_guid_mode_t mode; +	guid_version_t ver; /* Version from time_hi_and_version, if valid */ +} parsed_guid_t; + +parsed_guid_t ipmi_parse_guid(void *guid, ipmi_guid_mode_t guid_mode); + +int _ipmi_mc_get_guid(struct ipmi_intf *intf, ipmi_guid_t *guid);  #ifdef HAVE_PRAGMA_PACK  #pragma pack(1) @@ -138,14 +243,24 @@ struct ipm_selftest_rsp {  #pragma pack(1)  #endif  struct ipm_get_watchdog_rsp { -	unsigned char timer_use; -	unsigned char timer_actions; +	unsigned char use; +	unsigned char intr_action;  	unsigned char pre_timeout; -	unsigned char timer_use_exp; -	unsigned char initial_countdown_lsb; -	unsigned char initial_countdown_msb; -	unsigned char present_countdown_lsb; -	unsigned char present_countdown_msb; +	unsigned char exp_flags; +	union { +		struct { +			unsigned char initial_countdown_lsb; +			unsigned char initial_countdown_msb; +		}; +		uint16_t init_cnt_le; +	}; +	union { +		struct { +			unsigned char present_countdown_lsb; +			unsigned char present_countdown_msb; +		}; +		uint16_t pres_cnt_le; +	};  } ATTRIBUTE_PACKING;  #ifdef HAVE_PRAGMA_PACK  #pragma pack(0) @@ -170,6 +285,25 @@ struct ipm_get_watchdog_rsp {  #define IPM_WATCHDOG_CLEAR_BIOS_POST	0x04  #define IPM_WATCHDOG_CLEAR_BIOS_FRB2	0x02 +/* Use */ +#define IPMI_WDT_USE_NOLOG_SHIFT    7 +#define IPMI_WDT_USE_DONTSTOP_SHIFT 6 /* For 'set' */ +#define IPMI_WDT_USE_RUNNING_SHIFT  6 /* For 'get' */ +#define IPMI_WDT_USE_SHIFT          0 +#define IPMI_WDT_USE_MASK           0x07 + +/* Pre-timeout interrupt type */ +#define IPMI_WDT_INTR_SHIFT     4 +#define IPMI_WDT_INTR_MASK      0x07 /* Apply to the intr value, not to the data byte */ + +/* Action */ +#define IPMI_WDT_ACTION_SHIFT   0 +#define IPMI_WDT_ACTION_MASK    0x07 + +#define IPMI_WDT_GET(b, s) (((b) >> (IPMI_WDT_##s##_SHIFT)) & (IPMI_WDT_##s##_MASK)) + +#define IS_WDT_BIT(b, s) IS_SET((b), IPMI_WDT_##s##_SHIFT) +  /* IPMI 2.0 command for system information*/  #define IPMI_SET_SYS_INFO                  0x58  #define IPMI_GET_SYS_INFO                  0x59 @@ -190,5 +324,3 @@ struct ipm_get_watchdog_rsp {  int ipmi_mc_getsysinfo(struct ipmi_intf * intf, int param, int block, int set,   		    int len, void *buffer);  int ipmi_mc_setsysinfo(struct ipmi_intf * intf, int len, void *buffer); - -#endif				/*IPMI_MC_H */ | 
