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