1*40a895fdSDave Jiang /* SPDX-License-Identifier: GPL-2.0 */ 2*40a895fdSDave Jiang /* Copyright(c) 2023 Intel Corporation. */ 3*40a895fdSDave Jiang #ifndef _LINUX_CXL_EVENT_H 4*40a895fdSDave Jiang #define _LINUX_CXL_EVENT_H 5*40a895fdSDave Jiang 6*40a895fdSDave Jiang #include <linux/types.h> 7*40a895fdSDave Jiang #include <linux/uuid.h> 8*40a895fdSDave Jiang #include <linux/workqueue_types.h> 9*40a895fdSDave Jiang 10*40a895fdSDave Jiang /* 11*40a895fdSDave Jiang * Common Event Record Format 12*40a895fdSDave Jiang * CXL rev 3.0 section 8.2.9.2.1; Table 8-42 13*40a895fdSDave Jiang */ 14*40a895fdSDave Jiang struct cxl_event_record_hdr { 15*40a895fdSDave Jiang u8 length; 16*40a895fdSDave Jiang u8 flags[3]; 17*40a895fdSDave Jiang __le16 handle; 18*40a895fdSDave Jiang __le16 related_handle; 19*40a895fdSDave Jiang __le64 timestamp; 20*40a895fdSDave Jiang u8 maint_op_class; 21*40a895fdSDave Jiang u8 reserved[15]; 22*40a895fdSDave Jiang } __packed; 23*40a895fdSDave Jiang 24*40a895fdSDave Jiang struct cxl_event_media_hdr { 25*40a895fdSDave Jiang struct cxl_event_record_hdr hdr; 26*40a895fdSDave Jiang __le64 phys_addr; 27*40a895fdSDave Jiang u8 descriptor; 28*40a895fdSDave Jiang u8 type; 29*40a895fdSDave Jiang u8 transaction_type; 30*40a895fdSDave Jiang /* 31*40a895fdSDave Jiang * The meaning of Validity Flags from bit 2 is 32*40a895fdSDave Jiang * different across DRAM and General Media records 33*40a895fdSDave Jiang */ 34*40a895fdSDave Jiang u8 validity_flags[2]; 35*40a895fdSDave Jiang u8 channel; 36*40a895fdSDave Jiang u8 rank; 37*40a895fdSDave Jiang } __packed; 38*40a895fdSDave Jiang 39*40a895fdSDave Jiang #define CXL_EVENT_RECORD_DATA_LENGTH 0x50 40*40a895fdSDave Jiang struct cxl_event_generic { 41*40a895fdSDave Jiang struct cxl_event_record_hdr hdr; 42*40a895fdSDave Jiang u8 data[CXL_EVENT_RECORD_DATA_LENGTH]; 43*40a895fdSDave Jiang } __packed; 44*40a895fdSDave Jiang 45*40a895fdSDave Jiang /* 46*40a895fdSDave Jiang * General Media Event Record 47*40a895fdSDave Jiang * CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43 48*40a895fdSDave Jiang */ 49*40a895fdSDave Jiang #define CXL_EVENT_GEN_MED_COMP_ID_SIZE 0x10 50*40a895fdSDave Jiang struct cxl_event_gen_media { 51*40a895fdSDave Jiang struct cxl_event_media_hdr media_hdr; 52*40a895fdSDave Jiang u8 device[3]; 53*40a895fdSDave Jiang u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE]; 54*40a895fdSDave Jiang u8 reserved[46]; 55*40a895fdSDave Jiang } __packed; 56*40a895fdSDave Jiang 57*40a895fdSDave Jiang /* 58*40a895fdSDave Jiang * DRAM Event Record - DER 59*40a895fdSDave Jiang * CXL rev 3.0 section 8.2.9.2.1.2; Table 3-44 60*40a895fdSDave Jiang */ 61*40a895fdSDave Jiang #define CXL_EVENT_DER_CORRECTION_MASK_SIZE 0x20 62*40a895fdSDave Jiang struct cxl_event_dram { 63*40a895fdSDave Jiang struct cxl_event_media_hdr media_hdr; 64*40a895fdSDave Jiang u8 nibble_mask[3]; 65*40a895fdSDave Jiang u8 bank_group; 66*40a895fdSDave Jiang u8 bank; 67*40a895fdSDave Jiang u8 row[3]; 68*40a895fdSDave Jiang u8 column[2]; 69*40a895fdSDave Jiang u8 correction_mask[CXL_EVENT_DER_CORRECTION_MASK_SIZE]; 70*40a895fdSDave Jiang u8 reserved[0x17]; 71*40a895fdSDave Jiang } __packed; 72*40a895fdSDave Jiang 73*40a895fdSDave Jiang /* 74*40a895fdSDave Jiang * Get Health Info Record 75*40a895fdSDave Jiang * CXL rev 3.0 section 8.2.9.8.3.1; Table 8-100 76*40a895fdSDave Jiang */ 77*40a895fdSDave Jiang struct cxl_get_health_info { 78*40a895fdSDave Jiang u8 health_status; 79*40a895fdSDave Jiang u8 media_status; 80*40a895fdSDave Jiang u8 add_status; 81*40a895fdSDave Jiang u8 life_used; 82*40a895fdSDave Jiang u8 device_temp[2]; 83*40a895fdSDave Jiang u8 dirty_shutdown_cnt[4]; 84*40a895fdSDave Jiang u8 cor_vol_err_cnt[4]; 85*40a895fdSDave Jiang u8 cor_per_err_cnt[4]; 86*40a895fdSDave Jiang } __packed; 87*40a895fdSDave Jiang 88*40a895fdSDave Jiang /* 89*40a895fdSDave Jiang * Memory Module Event Record 90*40a895fdSDave Jiang * CXL rev 3.0 section 8.2.9.2.1.3; Table 8-45 91*40a895fdSDave Jiang */ 92*40a895fdSDave Jiang struct cxl_event_mem_module { 93*40a895fdSDave Jiang struct cxl_event_record_hdr hdr; 94*40a895fdSDave Jiang u8 event_type; 95*40a895fdSDave Jiang struct cxl_get_health_info info; 96*40a895fdSDave Jiang u8 reserved[0x3d]; 97*40a895fdSDave Jiang } __packed; 98*40a895fdSDave Jiang 99*40a895fdSDave Jiang union cxl_event { 100*40a895fdSDave Jiang struct cxl_event_generic generic; 101*40a895fdSDave Jiang struct cxl_event_gen_media gen_media; 102*40a895fdSDave Jiang struct cxl_event_dram dram; 103*40a895fdSDave Jiang struct cxl_event_mem_module mem_module; 104*40a895fdSDave Jiang /* dram & gen_media event header */ 105*40a895fdSDave Jiang struct cxl_event_media_hdr media_hdr; 106*40a895fdSDave Jiang } __packed; 107*40a895fdSDave Jiang 108*40a895fdSDave Jiang /* 109*40a895fdSDave Jiang * Common Event Record Format; in event logs 110*40a895fdSDave Jiang * CXL rev 3.0 section 8.2.9.2.1; Table 8-42 111*40a895fdSDave Jiang */ 112*40a895fdSDave Jiang struct cxl_event_record_raw { 113*40a895fdSDave Jiang uuid_t id; 114*40a895fdSDave Jiang union cxl_event event; 115*40a895fdSDave Jiang } __packed; 116*40a895fdSDave Jiang 117*40a895fdSDave Jiang enum cxl_event_type { 118*40a895fdSDave Jiang CXL_CPER_EVENT_GENERIC, 119*40a895fdSDave Jiang CXL_CPER_EVENT_GEN_MEDIA, 120*40a895fdSDave Jiang CXL_CPER_EVENT_DRAM, 121*40a895fdSDave Jiang CXL_CPER_EVENT_MEM_MODULE, 122*40a895fdSDave Jiang }; 123*40a895fdSDave Jiang 124*40a895fdSDave Jiang #define CPER_CXL_DEVICE_ID_VALID BIT(0) 125*40a895fdSDave Jiang #define CPER_CXL_DEVICE_SN_VALID BIT(1) 126*40a895fdSDave Jiang #define CPER_CXL_COMP_EVENT_LOG_VALID BIT(2) 127*40a895fdSDave Jiang struct cxl_cper_event_rec { 128*40a895fdSDave Jiang struct { 129*40a895fdSDave Jiang u32 length; 130*40a895fdSDave Jiang u64 validation_bits; 131*40a895fdSDave Jiang struct cper_cxl_event_devid { 132*40a895fdSDave Jiang u16 vendor_id; 133*40a895fdSDave Jiang u16 device_id; 134*40a895fdSDave Jiang u8 func_num; 135*40a895fdSDave Jiang u8 device_num; 136*40a895fdSDave Jiang u8 bus_num; 137*40a895fdSDave Jiang u16 segment_num; 138*40a895fdSDave Jiang u16 slot_num; /* bits 2:0 reserved */ 139*40a895fdSDave Jiang u8 reserved; 140*40a895fdSDave Jiang } __packed device_id; 141*40a895fdSDave Jiang struct cper_cxl_event_sn { 142*40a895fdSDave Jiang u32 lower_dw; 143*40a895fdSDave Jiang u32 upper_dw; 144*40a895fdSDave Jiang } __packed dev_serial_num; 145*40a895fdSDave Jiang } __packed hdr; 146*40a895fdSDave Jiang 147*40a895fdSDave Jiang union cxl_event event; 148*40a895fdSDave Jiang } __packed; 149*40a895fdSDave Jiang 150*40a895fdSDave Jiang struct cxl_cper_work_data { 151*40a895fdSDave Jiang enum cxl_event_type event_type; 152*40a895fdSDave Jiang struct cxl_cper_event_rec rec; 153*40a895fdSDave Jiang }; 154*40a895fdSDave Jiang 155*40a895fdSDave Jiang #ifdef CONFIG_ACPI_APEI_GHES 156*40a895fdSDave Jiang int cxl_cper_register_work(struct work_struct *work); 157*40a895fdSDave Jiang int cxl_cper_unregister_work(struct work_struct *work); 158*40a895fdSDave Jiang int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd); 159*40a895fdSDave Jiang #else 160*40a895fdSDave Jiang static inline int cxl_cper_register_work(struct work_struct *work) 161*40a895fdSDave Jiang { 162*40a895fdSDave Jiang return 0; 163*40a895fdSDave Jiang } 164*40a895fdSDave Jiang 165*40a895fdSDave Jiang static inline int cxl_cper_unregister_work(struct work_struct *work) 166*40a895fdSDave Jiang { 167*40a895fdSDave Jiang return 0; 168*40a895fdSDave Jiang } 169*40a895fdSDave Jiang static inline int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd) 170*40a895fdSDave Jiang { 171*40a895fdSDave Jiang return 0; 172*40a895fdSDave Jiang } 173*40a895fdSDave Jiang #endif 174*40a895fdSDave Jiang 175*40a895fdSDave Jiang #endif /* _LINUX_CXL_EVENT_H */ 176