126a1a86dSIra Weiny /* SPDX-License-Identifier: GPL-2.0 */ 226a1a86dSIra Weiny /* Copyright(c) 2023 Intel Corporation. */ 326a1a86dSIra Weiny #ifndef _LINUX_CXL_EVENT_H 426a1a86dSIra Weiny #define _LINUX_CXL_EVENT_H 526a1a86dSIra Weiny 60e081a0eSSangyun Kim #include <linux/types.h> 70e081a0eSSangyun Kim #include <linux/uuid.h> 85e4a264bSIra Weiny #include <linux/workqueue_types.h> 90e081a0eSSangyun Kim 1026a1a86dSIra Weiny /* 1126a1a86dSIra Weiny * Common Event Record Format 1226a1a86dSIra Weiny * CXL rev 3.0 section 8.2.9.2.1; Table 8-42 1326a1a86dSIra Weiny */ 1426a1a86dSIra Weiny struct cxl_event_record_hdr { 1526a1a86dSIra Weiny u8 length; 1626a1a86dSIra Weiny u8 flags[3]; 1726a1a86dSIra Weiny __le16 handle; 1826a1a86dSIra Weiny __le16 related_handle; 1926a1a86dSIra Weiny __le64 timestamp; 2026a1a86dSIra Weiny u8 maint_op_class; 215e31e347SShiju Jose u8 maint_op_sub_class; 225e31e347SShiju Jose u8 reserved[14]; 2326a1a86dSIra Weiny } __packed; 2426a1a86dSIra Weiny 25675e979dSFabio M. De Francesco struct cxl_event_media_hdr { 26675e979dSFabio M. De Francesco struct cxl_event_record_hdr hdr; 27675e979dSFabio M. De Francesco __le64 phys_addr; 28675e979dSFabio M. De Francesco u8 descriptor; 29675e979dSFabio M. De Francesco u8 type; 30675e979dSFabio M. De Francesco u8 transaction_type; 31675e979dSFabio M. De Francesco /* 32675e979dSFabio M. De Francesco * The meaning of Validity Flags from bit 2 is 33675e979dSFabio M. De Francesco * different across DRAM and General Media records 34675e979dSFabio M. De Francesco */ 35675e979dSFabio M. De Francesco u8 validity_flags[2]; 36675e979dSFabio M. De Francesco u8 channel; 37675e979dSFabio M. De Francesco u8 rank; 38675e979dSFabio M. De Francesco } __packed; 39675e979dSFabio M. De Francesco 4026a1a86dSIra Weiny #define CXL_EVENT_RECORD_DATA_LENGTH 0x50 41f9c68338SIra Weiny struct cxl_event_generic { 4226a1a86dSIra Weiny struct cxl_event_record_hdr hdr; 4326a1a86dSIra Weiny u8 data[CXL_EVENT_RECORD_DATA_LENGTH]; 4426a1a86dSIra Weiny } __packed; 4526a1a86dSIra Weiny 4626a1a86dSIra Weiny /* 4726a1a86dSIra Weiny * General Media Event Record 48*ae834131SShiju Jose * CXL rev 3.1 Section 8.2.9.2.1.1; Table 8-45 4926a1a86dSIra Weiny */ 5026a1a86dSIra Weiny #define CXL_EVENT_GEN_MED_COMP_ID_SIZE 0x10 5126a1a86dSIra Weiny struct cxl_event_gen_media { 52675e979dSFabio M. De Francesco struct cxl_event_media_hdr media_hdr; 5326a1a86dSIra Weiny u8 device[3]; 5426a1a86dSIra Weiny u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE]; 55*ae834131SShiju Jose u8 cme_threshold_ev_flags; 56*ae834131SShiju Jose u8 cme_count[3]; 57*ae834131SShiju Jose u8 sub_type; 58*ae834131SShiju Jose u8 reserved[41]; 5926a1a86dSIra Weiny } __packed; 6026a1a86dSIra Weiny 6126a1a86dSIra Weiny /* 6226a1a86dSIra Weiny * DRAM Event Record - DER 6326a1a86dSIra Weiny * CXL rev 3.0 section 8.2.9.2.1.2; Table 3-44 6426a1a86dSIra Weiny */ 6526a1a86dSIra Weiny #define CXL_EVENT_DER_CORRECTION_MASK_SIZE 0x20 6626a1a86dSIra Weiny struct cxl_event_dram { 67675e979dSFabio M. De Francesco struct cxl_event_media_hdr media_hdr; 6826a1a86dSIra Weiny u8 nibble_mask[3]; 6926a1a86dSIra Weiny u8 bank_group; 7026a1a86dSIra Weiny u8 bank; 7126a1a86dSIra Weiny u8 row[3]; 7226a1a86dSIra Weiny u8 column[2]; 7326a1a86dSIra Weiny u8 correction_mask[CXL_EVENT_DER_CORRECTION_MASK_SIZE]; 7426a1a86dSIra Weiny u8 reserved[0x17]; 7526a1a86dSIra Weiny } __packed; 7626a1a86dSIra Weiny 7726a1a86dSIra Weiny /* 7826a1a86dSIra Weiny * Get Health Info Record 7926a1a86dSIra Weiny * CXL rev 3.0 section 8.2.9.8.3.1; Table 8-100 8026a1a86dSIra Weiny */ 8126a1a86dSIra Weiny struct cxl_get_health_info { 8226a1a86dSIra Weiny u8 health_status; 8326a1a86dSIra Weiny u8 media_status; 8426a1a86dSIra Weiny u8 add_status; 8526a1a86dSIra Weiny u8 life_used; 8626a1a86dSIra Weiny u8 device_temp[2]; 8726a1a86dSIra Weiny u8 dirty_shutdown_cnt[4]; 8826a1a86dSIra Weiny u8 cor_vol_err_cnt[4]; 8926a1a86dSIra Weiny u8 cor_per_err_cnt[4]; 9026a1a86dSIra Weiny } __packed; 9126a1a86dSIra Weiny 9226a1a86dSIra Weiny /* 9326a1a86dSIra Weiny * Memory Module Event Record 9426a1a86dSIra Weiny * CXL rev 3.0 section 8.2.9.2.1.3; Table 8-45 9526a1a86dSIra Weiny */ 9626a1a86dSIra Weiny struct cxl_event_mem_module { 9726a1a86dSIra Weiny struct cxl_event_record_hdr hdr; 9826a1a86dSIra Weiny u8 event_type; 9926a1a86dSIra Weiny struct cxl_get_health_info info; 10026a1a86dSIra Weiny u8 reserved[0x3d]; 10126a1a86dSIra Weiny } __packed; 10226a1a86dSIra Weiny 103f9c68338SIra Weiny union cxl_event { 104f9c68338SIra Weiny struct cxl_event_generic generic; 105f9c68338SIra Weiny struct cxl_event_gen_media gen_media; 106f9c68338SIra Weiny struct cxl_event_dram dram; 107f9c68338SIra Weiny struct cxl_event_mem_module mem_module; 108675e979dSFabio M. De Francesco /* dram & gen_media event header */ 109675e979dSFabio M. De Francesco struct cxl_event_media_hdr media_hdr; 110f9c68338SIra Weiny } __packed; 111f9c68338SIra Weiny 112f9c68338SIra Weiny /* 113f9c68338SIra Weiny * Common Event Record Format; in event logs 114f9c68338SIra Weiny * CXL rev 3.0 section 8.2.9.2.1; Table 8-42 115f9c68338SIra Weiny */ 116f9c68338SIra Weiny struct cxl_event_record_raw { 117f9c68338SIra Weiny uuid_t id; 118f9c68338SIra Weiny union cxl_event event; 119f9c68338SIra Weiny } __packed; 120f9c68338SIra Weiny 121671a794cSIra Weiny enum cxl_event_type { 122dc97f634SIra Weiny CXL_CPER_EVENT_GENERIC, 123671a794cSIra Weiny CXL_CPER_EVENT_GEN_MEDIA, 124671a794cSIra Weiny CXL_CPER_EVENT_DRAM, 125671a794cSIra Weiny CXL_CPER_EVENT_MEM_MODULE, 126671a794cSIra Weiny }; 127671a794cSIra Weiny 128671a794cSIra Weiny #define CPER_CXL_DEVICE_ID_VALID BIT(0) 129671a794cSIra Weiny #define CPER_CXL_DEVICE_SN_VALID BIT(1) 130671a794cSIra Weiny #define CPER_CXL_COMP_EVENT_LOG_VALID BIT(2) 131671a794cSIra Weiny struct cxl_cper_event_rec { 132671a794cSIra Weiny struct { 133671a794cSIra Weiny u32 length; 134671a794cSIra Weiny u64 validation_bits; 135671a794cSIra Weiny struct cper_cxl_event_devid { 136671a794cSIra Weiny u16 vendor_id; 137671a794cSIra Weiny u16 device_id; 138671a794cSIra Weiny u8 func_num; 139671a794cSIra Weiny u8 device_num; 140671a794cSIra Weiny u8 bus_num; 141671a794cSIra Weiny u16 segment_num; 142671a794cSIra Weiny u16 slot_num; /* bits 2:0 reserved */ 143671a794cSIra Weiny u8 reserved; 144671a794cSIra Weiny } __packed device_id; 145671a794cSIra Weiny struct cper_cxl_event_sn { 146671a794cSIra Weiny u32 lower_dw; 147671a794cSIra Weiny u32 upper_dw; 148671a794cSIra Weiny } __packed dev_serial_num; 149671a794cSIra Weiny } __packed hdr; 150671a794cSIra Weiny 151671a794cSIra Weiny union cxl_event event; 152671a794cSIra Weiny } __packed; 153671a794cSIra Weiny 1545e4a264bSIra Weiny struct cxl_cper_work_data { 1555e4a264bSIra Weiny enum cxl_event_type event_type; 1565e4a264bSIra Weiny struct cxl_cper_event_rec rec; 1575e4a264bSIra Weiny }; 1585e4a264bSIra Weiny 1595e4a264bSIra Weiny #ifdef CONFIG_ACPI_APEI_GHES 1605e4a264bSIra Weiny int cxl_cper_register_work(struct work_struct *work); 1615e4a264bSIra Weiny int cxl_cper_unregister_work(struct work_struct *work); 1625e4a264bSIra Weiny int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd); 1635e4a264bSIra Weiny #else 16455111470SIra Weiny static inline int cxl_cper_register_work(struct work_struct *work) 1655e4a264bSIra Weiny { 1665e4a264bSIra Weiny return 0; 1675e4a264bSIra Weiny } 1685e4a264bSIra Weiny 16955111470SIra Weiny static inline int cxl_cper_unregister_work(struct work_struct *work) 1705e4a264bSIra Weiny { 1715e4a264bSIra Weiny return 0; 1725e4a264bSIra Weiny } 1735e4a264bSIra Weiny static inline int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd) 1745e4a264bSIra Weiny { 1755e4a264bSIra Weiny return 0; 1765e4a264bSIra Weiny } 1775e4a264bSIra Weiny #endif 1785e4a264bSIra Weiny 17926a1a86dSIra Weiny #endif /* _LINUX_CXL_EVENT_H */ 180