140a895fdSDave Jiang /* SPDX-License-Identifier: GPL-2.0 */ 240a895fdSDave Jiang /* Copyright(c) 2023 Intel Corporation. */ 340a895fdSDave Jiang #ifndef _LINUX_CXL_EVENT_H 440a895fdSDave Jiang #define _LINUX_CXL_EVENT_H 540a895fdSDave Jiang 640a895fdSDave Jiang #include <linux/types.h> 740a895fdSDave Jiang #include <linux/uuid.h> 840a895fdSDave Jiang #include <linux/workqueue_types.h> 940a895fdSDave Jiang 1040a895fdSDave Jiang /* 1140a895fdSDave Jiang * Common Event Record Format 1240a895fdSDave Jiang * CXL rev 3.0 section 8.2.9.2.1; Table 8-42 1340a895fdSDave Jiang */ 1440a895fdSDave Jiang struct cxl_event_record_hdr { 1540a895fdSDave Jiang u8 length; 1640a895fdSDave Jiang u8 flags[3]; 1740a895fdSDave Jiang __le16 handle; 1840a895fdSDave Jiang __le16 related_handle; 1940a895fdSDave Jiang __le64 timestamp; 2040a895fdSDave Jiang u8 maint_op_class; 215e31e347SShiju Jose u8 maint_op_sub_class; 225e31e347SShiju Jose u8 reserved[14]; 2340a895fdSDave Jiang } __packed; 2440a895fdSDave Jiang 2540a895fdSDave Jiang struct cxl_event_media_hdr { 2640a895fdSDave Jiang struct cxl_event_record_hdr hdr; 2740a895fdSDave Jiang __le64 phys_addr; 2840a895fdSDave Jiang u8 descriptor; 2940a895fdSDave Jiang u8 type; 3040a895fdSDave Jiang u8 transaction_type; 3140a895fdSDave Jiang /* 3240a895fdSDave Jiang * The meaning of Validity Flags from bit 2 is 3340a895fdSDave Jiang * different across DRAM and General Media records 3440a895fdSDave Jiang */ 3540a895fdSDave Jiang u8 validity_flags[2]; 3640a895fdSDave Jiang u8 channel; 3740a895fdSDave Jiang u8 rank; 3840a895fdSDave Jiang } __packed; 3940a895fdSDave Jiang 4040a895fdSDave Jiang #define CXL_EVENT_RECORD_DATA_LENGTH 0x50 4140a895fdSDave Jiang struct cxl_event_generic { 4240a895fdSDave Jiang struct cxl_event_record_hdr hdr; 4340a895fdSDave Jiang u8 data[CXL_EVENT_RECORD_DATA_LENGTH]; 4440a895fdSDave Jiang } __packed; 4540a895fdSDave Jiang 4640a895fdSDave Jiang /* 4740a895fdSDave Jiang * General Media Event Record 48ae834131SShiju Jose * CXL rev 3.1 Section 8.2.9.2.1.1; Table 8-45 4940a895fdSDave Jiang */ 5040a895fdSDave Jiang #define CXL_EVENT_GEN_MED_COMP_ID_SIZE 0x10 5140a895fdSDave Jiang struct cxl_event_gen_media { 5240a895fdSDave Jiang struct cxl_event_media_hdr media_hdr; 5340a895fdSDave Jiang u8 device[3]; 5440a895fdSDave Jiang u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE]; 55ae834131SShiju Jose u8 cme_threshold_ev_flags; 56ae834131SShiju Jose u8 cme_count[3]; 57ae834131SShiju Jose u8 sub_type; 58ae834131SShiju Jose u8 reserved[41]; 5940a895fdSDave Jiang } __packed; 6040a895fdSDave Jiang 6140a895fdSDave Jiang /* 6240a895fdSDave Jiang * DRAM Event Record - DER 6324ec41f7SShiju Jose * CXL rev 3.1 section 8.2.9.2.1.2; Table 8-46 6440a895fdSDave Jiang */ 6540a895fdSDave Jiang #define CXL_EVENT_DER_CORRECTION_MASK_SIZE 0x20 6640a895fdSDave Jiang struct cxl_event_dram { 6740a895fdSDave Jiang struct cxl_event_media_hdr media_hdr; 6840a895fdSDave Jiang u8 nibble_mask[3]; 6940a895fdSDave Jiang u8 bank_group; 7040a895fdSDave Jiang u8 bank; 7140a895fdSDave Jiang u8 row[3]; 7240a895fdSDave Jiang u8 column[2]; 7340a895fdSDave Jiang u8 correction_mask[CXL_EVENT_DER_CORRECTION_MASK_SIZE]; 7424ec41f7SShiju Jose u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE]; 7524ec41f7SShiju Jose u8 sub_channel; 7624ec41f7SShiju Jose u8 cme_threshold_ev_flags; 7724ec41f7SShiju Jose u8 cvme_count[3]; 7824ec41f7SShiju Jose u8 sub_type; 7924ec41f7SShiju Jose u8 reserved; 8040a895fdSDave Jiang } __packed; 8140a895fdSDave Jiang 8240a895fdSDave Jiang /* 8340a895fdSDave Jiang * Get Health Info Record 84*4c6e20ebSShiju Jose * CXL rev 3.1 section 8.2.9.9.3.1; Table 8-133 8540a895fdSDave Jiang */ 8640a895fdSDave Jiang struct cxl_get_health_info { 8740a895fdSDave Jiang u8 health_status; 8840a895fdSDave Jiang u8 media_status; 8940a895fdSDave Jiang u8 add_status; 9040a895fdSDave Jiang u8 life_used; 9140a895fdSDave Jiang u8 device_temp[2]; 9240a895fdSDave Jiang u8 dirty_shutdown_cnt[4]; 9340a895fdSDave Jiang u8 cor_vol_err_cnt[4]; 9440a895fdSDave Jiang u8 cor_per_err_cnt[4]; 9540a895fdSDave Jiang } __packed; 9640a895fdSDave Jiang 9740a895fdSDave Jiang /* 9840a895fdSDave Jiang * Memory Module Event Record 99*4c6e20ebSShiju Jose * CXL rev 3.1 section 8.2.9.2.1.3; Table 8-47 10040a895fdSDave Jiang */ 10140a895fdSDave Jiang struct cxl_event_mem_module { 10240a895fdSDave Jiang struct cxl_event_record_hdr hdr; 10340a895fdSDave Jiang u8 event_type; 10440a895fdSDave Jiang struct cxl_get_health_info info; 105*4c6e20ebSShiju Jose u8 validity_flags[2]; 106*4c6e20ebSShiju Jose u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE]; 107*4c6e20ebSShiju Jose u8 event_sub_type; 108*4c6e20ebSShiju Jose u8 reserved[0x2a]; 10940a895fdSDave Jiang } __packed; 11040a895fdSDave Jiang 11140a895fdSDave Jiang union cxl_event { 11240a895fdSDave Jiang struct cxl_event_generic generic; 11340a895fdSDave Jiang struct cxl_event_gen_media gen_media; 11440a895fdSDave Jiang struct cxl_event_dram dram; 11540a895fdSDave Jiang struct cxl_event_mem_module mem_module; 11640a895fdSDave Jiang /* dram & gen_media event header */ 11740a895fdSDave Jiang struct cxl_event_media_hdr media_hdr; 11840a895fdSDave Jiang } __packed; 11940a895fdSDave Jiang 12040a895fdSDave Jiang /* 12140a895fdSDave Jiang * Common Event Record Format; in event logs 12240a895fdSDave Jiang * CXL rev 3.0 section 8.2.9.2.1; Table 8-42 12340a895fdSDave Jiang */ 12440a895fdSDave Jiang struct cxl_event_record_raw { 12540a895fdSDave Jiang uuid_t id; 12640a895fdSDave Jiang union cxl_event event; 12740a895fdSDave Jiang } __packed; 12840a895fdSDave Jiang 12940a895fdSDave Jiang enum cxl_event_type { 13040a895fdSDave Jiang CXL_CPER_EVENT_GENERIC, 13140a895fdSDave Jiang CXL_CPER_EVENT_GEN_MEDIA, 13240a895fdSDave Jiang CXL_CPER_EVENT_DRAM, 13340a895fdSDave Jiang CXL_CPER_EVENT_MEM_MODULE, 13440a895fdSDave Jiang }; 13540a895fdSDave Jiang 13640a895fdSDave Jiang #define CPER_CXL_DEVICE_ID_VALID BIT(0) 13740a895fdSDave Jiang #define CPER_CXL_DEVICE_SN_VALID BIT(1) 13840a895fdSDave Jiang #define CPER_CXL_COMP_EVENT_LOG_VALID BIT(2) 13940a895fdSDave Jiang struct cxl_cper_event_rec { 14040a895fdSDave Jiang struct { 14140a895fdSDave Jiang u32 length; 14240a895fdSDave Jiang u64 validation_bits; 14340a895fdSDave Jiang struct cper_cxl_event_devid { 14440a895fdSDave Jiang u16 vendor_id; 14540a895fdSDave Jiang u16 device_id; 14640a895fdSDave Jiang u8 func_num; 14740a895fdSDave Jiang u8 device_num; 14840a895fdSDave Jiang u8 bus_num; 14940a895fdSDave Jiang u16 segment_num; 15040a895fdSDave Jiang u16 slot_num; /* bits 2:0 reserved */ 15140a895fdSDave Jiang u8 reserved; 15240a895fdSDave Jiang } __packed device_id; 15340a895fdSDave Jiang struct cper_cxl_event_sn { 15440a895fdSDave Jiang u32 lower_dw; 15540a895fdSDave Jiang u32 upper_dw; 15640a895fdSDave Jiang } __packed dev_serial_num; 15740a895fdSDave Jiang } __packed hdr; 15840a895fdSDave Jiang 15940a895fdSDave Jiang union cxl_event event; 16040a895fdSDave Jiang } __packed; 16140a895fdSDave Jiang 16240a895fdSDave Jiang struct cxl_cper_work_data { 16340a895fdSDave Jiang enum cxl_event_type event_type; 16440a895fdSDave Jiang struct cxl_cper_event_rec rec; 16540a895fdSDave Jiang }; 16640a895fdSDave Jiang 16740a895fdSDave Jiang #ifdef CONFIG_ACPI_APEI_GHES 16840a895fdSDave Jiang int cxl_cper_register_work(struct work_struct *work); 16940a895fdSDave Jiang int cxl_cper_unregister_work(struct work_struct *work); 17040a895fdSDave Jiang int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd); 17140a895fdSDave Jiang #else 17240a895fdSDave Jiang static inline int cxl_cper_register_work(struct work_struct *work) 17340a895fdSDave Jiang { 17440a895fdSDave Jiang return 0; 17540a895fdSDave Jiang } 17640a895fdSDave Jiang 17740a895fdSDave Jiang static inline int cxl_cper_unregister_work(struct work_struct *work) 17840a895fdSDave Jiang { 17940a895fdSDave Jiang return 0; 18040a895fdSDave Jiang } 18140a895fdSDave Jiang static inline int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd) 18240a895fdSDave Jiang { 18340a895fdSDave Jiang return 0; 18440a895fdSDave Jiang } 18540a895fdSDave Jiang #endif 18640a895fdSDave Jiang 18740a895fdSDave Jiang #endif /* _LINUX_CXL_EVENT_H */ 188