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; 21*5e31e347SShiju Jose u8 maint_op_sub_class; 22*5e31e347SShiju 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 4840a895fdSDave Jiang * CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43 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]; 5540a895fdSDave Jiang u8 reserved[46]; 5640a895fdSDave Jiang } __packed; 5740a895fdSDave Jiang 5840a895fdSDave Jiang /* 5940a895fdSDave Jiang * DRAM Event Record - DER 6040a895fdSDave Jiang * CXL rev 3.0 section 8.2.9.2.1.2; Table 3-44 6140a895fdSDave Jiang */ 6240a895fdSDave Jiang #define CXL_EVENT_DER_CORRECTION_MASK_SIZE 0x20 6340a895fdSDave Jiang struct cxl_event_dram { 6440a895fdSDave Jiang struct cxl_event_media_hdr media_hdr; 6540a895fdSDave Jiang u8 nibble_mask[3]; 6640a895fdSDave Jiang u8 bank_group; 6740a895fdSDave Jiang u8 bank; 6840a895fdSDave Jiang u8 row[3]; 6940a895fdSDave Jiang u8 column[2]; 7040a895fdSDave Jiang u8 correction_mask[CXL_EVENT_DER_CORRECTION_MASK_SIZE]; 7140a895fdSDave Jiang u8 reserved[0x17]; 7240a895fdSDave Jiang } __packed; 7340a895fdSDave Jiang 7440a895fdSDave Jiang /* 7540a895fdSDave Jiang * Get Health Info Record 7640a895fdSDave Jiang * CXL rev 3.0 section 8.2.9.8.3.1; Table 8-100 7740a895fdSDave Jiang */ 7840a895fdSDave Jiang struct cxl_get_health_info { 7940a895fdSDave Jiang u8 health_status; 8040a895fdSDave Jiang u8 media_status; 8140a895fdSDave Jiang u8 add_status; 8240a895fdSDave Jiang u8 life_used; 8340a895fdSDave Jiang u8 device_temp[2]; 8440a895fdSDave Jiang u8 dirty_shutdown_cnt[4]; 8540a895fdSDave Jiang u8 cor_vol_err_cnt[4]; 8640a895fdSDave Jiang u8 cor_per_err_cnt[4]; 8740a895fdSDave Jiang } __packed; 8840a895fdSDave Jiang 8940a895fdSDave Jiang /* 9040a895fdSDave Jiang * Memory Module Event Record 9140a895fdSDave Jiang * CXL rev 3.0 section 8.2.9.2.1.3; Table 8-45 9240a895fdSDave Jiang */ 9340a895fdSDave Jiang struct cxl_event_mem_module { 9440a895fdSDave Jiang struct cxl_event_record_hdr hdr; 9540a895fdSDave Jiang u8 event_type; 9640a895fdSDave Jiang struct cxl_get_health_info info; 9740a895fdSDave Jiang u8 reserved[0x3d]; 9840a895fdSDave Jiang } __packed; 9940a895fdSDave Jiang 10040a895fdSDave Jiang union cxl_event { 10140a895fdSDave Jiang struct cxl_event_generic generic; 10240a895fdSDave Jiang struct cxl_event_gen_media gen_media; 10340a895fdSDave Jiang struct cxl_event_dram dram; 10440a895fdSDave Jiang struct cxl_event_mem_module mem_module; 10540a895fdSDave Jiang /* dram & gen_media event header */ 10640a895fdSDave Jiang struct cxl_event_media_hdr media_hdr; 10740a895fdSDave Jiang } __packed; 10840a895fdSDave Jiang 10940a895fdSDave Jiang /* 11040a895fdSDave Jiang * Common Event Record Format; in event logs 11140a895fdSDave Jiang * CXL rev 3.0 section 8.2.9.2.1; Table 8-42 11240a895fdSDave Jiang */ 11340a895fdSDave Jiang struct cxl_event_record_raw { 11440a895fdSDave Jiang uuid_t id; 11540a895fdSDave Jiang union cxl_event event; 11640a895fdSDave Jiang } __packed; 11740a895fdSDave Jiang 11840a895fdSDave Jiang enum cxl_event_type { 11940a895fdSDave Jiang CXL_CPER_EVENT_GENERIC, 12040a895fdSDave Jiang CXL_CPER_EVENT_GEN_MEDIA, 12140a895fdSDave Jiang CXL_CPER_EVENT_DRAM, 12240a895fdSDave Jiang CXL_CPER_EVENT_MEM_MODULE, 12340a895fdSDave Jiang }; 12440a895fdSDave Jiang 12540a895fdSDave Jiang #define CPER_CXL_DEVICE_ID_VALID BIT(0) 12640a895fdSDave Jiang #define CPER_CXL_DEVICE_SN_VALID BIT(1) 12740a895fdSDave Jiang #define CPER_CXL_COMP_EVENT_LOG_VALID BIT(2) 12840a895fdSDave Jiang struct cxl_cper_event_rec { 12940a895fdSDave Jiang struct { 13040a895fdSDave Jiang u32 length; 13140a895fdSDave Jiang u64 validation_bits; 13240a895fdSDave Jiang struct cper_cxl_event_devid { 13340a895fdSDave Jiang u16 vendor_id; 13440a895fdSDave Jiang u16 device_id; 13540a895fdSDave Jiang u8 func_num; 13640a895fdSDave Jiang u8 device_num; 13740a895fdSDave Jiang u8 bus_num; 13840a895fdSDave Jiang u16 segment_num; 13940a895fdSDave Jiang u16 slot_num; /* bits 2:0 reserved */ 14040a895fdSDave Jiang u8 reserved; 14140a895fdSDave Jiang } __packed device_id; 14240a895fdSDave Jiang struct cper_cxl_event_sn { 14340a895fdSDave Jiang u32 lower_dw; 14440a895fdSDave Jiang u32 upper_dw; 14540a895fdSDave Jiang } __packed dev_serial_num; 14640a895fdSDave Jiang } __packed hdr; 14740a895fdSDave Jiang 14840a895fdSDave Jiang union cxl_event event; 14940a895fdSDave Jiang } __packed; 15040a895fdSDave Jiang 15140a895fdSDave Jiang struct cxl_cper_work_data { 15240a895fdSDave Jiang enum cxl_event_type event_type; 15340a895fdSDave Jiang struct cxl_cper_event_rec rec; 15440a895fdSDave Jiang }; 15540a895fdSDave Jiang 15640a895fdSDave Jiang #ifdef CONFIG_ACPI_APEI_GHES 15740a895fdSDave Jiang int cxl_cper_register_work(struct work_struct *work); 15840a895fdSDave Jiang int cxl_cper_unregister_work(struct work_struct *work); 15940a895fdSDave Jiang int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd); 16040a895fdSDave Jiang #else 16140a895fdSDave Jiang static inline int cxl_cper_register_work(struct work_struct *work) 16240a895fdSDave Jiang { 16340a895fdSDave Jiang return 0; 16440a895fdSDave Jiang } 16540a895fdSDave Jiang 16640a895fdSDave Jiang static inline int cxl_cper_unregister_work(struct work_struct *work) 16740a895fdSDave Jiang { 16840a895fdSDave Jiang return 0; 16940a895fdSDave Jiang } 17040a895fdSDave Jiang static inline int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd) 17140a895fdSDave Jiang { 17240a895fdSDave Jiang return 0; 17340a895fdSDave Jiang } 17440a895fdSDave Jiang #endif 17540a895fdSDave Jiang 17640a895fdSDave Jiang #endif /* _LINUX_CXL_EVENT_H */ 177