xref: /linux/include/cxl/event.h (revision ae8341313058f76f3ce4169c780af4cf5cb05e1e)
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