xref: /linux/include/cxl/event.h (revision 4c6e20eb564e0d77497f452ab1ae1b40b1de3ab7)
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
48ae834131SShiju 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];
55ae834131SShiju Jose 	u8 cme_threshold_ev_flags;
56ae834131SShiju Jose 	u8 cme_count[3];
57ae834131SShiju Jose 	u8 sub_type;
58ae834131SShiju Jose 	u8 reserved[41];
5926a1a86dSIra Weiny } __packed;
6026a1a86dSIra Weiny 
6126a1a86dSIra Weiny /*
6226a1a86dSIra Weiny  * DRAM Event Record - DER
6324ec41f7SShiju Jose  * CXL rev 3.1 section 8.2.9.2.1.2; Table 8-46
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];
7424ec41f7SShiju Jose 	u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
7524ec41f7SShiju Jose 	u8 sub_channel;
7624ec41f7SShiju Jose 	u8 cme_threshold_ev_flags;
7724ec41f7SShiju Jose 	u8 cvme_count[3];
7824ec41f7SShiju Jose 	u8 sub_type;
7924ec41f7SShiju Jose 	u8 reserved;
8026a1a86dSIra Weiny } __packed;
8126a1a86dSIra Weiny 
8226a1a86dSIra Weiny /*
8326a1a86dSIra Weiny  * Get Health Info Record
84*4c6e20ebSShiju Jose  * CXL rev 3.1 section 8.2.9.9.3.1; Table 8-133
8526a1a86dSIra Weiny  */
8626a1a86dSIra Weiny struct cxl_get_health_info {
8726a1a86dSIra Weiny 	u8 health_status;
8826a1a86dSIra Weiny 	u8 media_status;
8926a1a86dSIra Weiny 	u8 add_status;
9026a1a86dSIra Weiny 	u8 life_used;
9126a1a86dSIra Weiny 	u8 device_temp[2];
9226a1a86dSIra Weiny 	u8 dirty_shutdown_cnt[4];
9326a1a86dSIra Weiny 	u8 cor_vol_err_cnt[4];
9426a1a86dSIra Weiny 	u8 cor_per_err_cnt[4];
9526a1a86dSIra Weiny } __packed;
9626a1a86dSIra Weiny 
9726a1a86dSIra Weiny /*
9826a1a86dSIra Weiny  * Memory Module Event Record
99*4c6e20ebSShiju Jose  * CXL rev 3.1 section 8.2.9.2.1.3; Table 8-47
10026a1a86dSIra Weiny  */
10126a1a86dSIra Weiny struct cxl_event_mem_module {
10226a1a86dSIra Weiny 	struct cxl_event_record_hdr hdr;
10326a1a86dSIra Weiny 	u8 event_type;
10426a1a86dSIra Weiny 	struct cxl_get_health_info info;
105*4c6e20ebSShiju Jose 	u8 validity_flags[2];
106*4c6e20ebSShiju Jose 	u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
107*4c6e20ebSShiju Jose 	u8 event_sub_type;
108*4c6e20ebSShiju Jose 	u8 reserved[0x2a];
10926a1a86dSIra Weiny } __packed;
11026a1a86dSIra Weiny 
111f9c68338SIra Weiny union cxl_event {
112f9c68338SIra Weiny 	struct cxl_event_generic generic;
113f9c68338SIra Weiny 	struct cxl_event_gen_media gen_media;
114f9c68338SIra Weiny 	struct cxl_event_dram dram;
115f9c68338SIra Weiny 	struct cxl_event_mem_module mem_module;
116675e979dSFabio M. De Francesco 	/* dram & gen_media event header */
117675e979dSFabio M. De Francesco 	struct cxl_event_media_hdr media_hdr;
118f9c68338SIra Weiny } __packed;
119f9c68338SIra Weiny 
120f9c68338SIra Weiny /*
121f9c68338SIra Weiny  * Common Event Record Format; in event logs
122f9c68338SIra Weiny  * CXL rev 3.0 section 8.2.9.2.1; Table 8-42
123f9c68338SIra Weiny  */
124f9c68338SIra Weiny struct cxl_event_record_raw {
125f9c68338SIra Weiny 	uuid_t id;
126f9c68338SIra Weiny 	union cxl_event event;
127f9c68338SIra Weiny } __packed;
128f9c68338SIra Weiny 
129671a794cSIra Weiny enum cxl_event_type {
130dc97f634SIra Weiny 	CXL_CPER_EVENT_GENERIC,
131671a794cSIra Weiny 	CXL_CPER_EVENT_GEN_MEDIA,
132671a794cSIra Weiny 	CXL_CPER_EVENT_DRAM,
133671a794cSIra Weiny 	CXL_CPER_EVENT_MEM_MODULE,
134671a794cSIra Weiny };
135671a794cSIra Weiny 
136671a794cSIra Weiny #define CPER_CXL_DEVICE_ID_VALID		BIT(0)
137671a794cSIra Weiny #define CPER_CXL_DEVICE_SN_VALID		BIT(1)
138671a794cSIra Weiny #define CPER_CXL_COMP_EVENT_LOG_VALID		BIT(2)
139671a794cSIra Weiny struct cxl_cper_event_rec {
140671a794cSIra Weiny 	struct {
141671a794cSIra Weiny 		u32 length;
142671a794cSIra Weiny 		u64 validation_bits;
143671a794cSIra Weiny 		struct cper_cxl_event_devid {
144671a794cSIra Weiny 			u16 vendor_id;
145671a794cSIra Weiny 			u16 device_id;
146671a794cSIra Weiny 			u8 func_num;
147671a794cSIra Weiny 			u8 device_num;
148671a794cSIra Weiny 			u8 bus_num;
149671a794cSIra Weiny 			u16 segment_num;
150671a794cSIra Weiny 			u16 slot_num; /* bits 2:0 reserved */
151671a794cSIra Weiny 			u8 reserved;
152671a794cSIra Weiny 		} __packed device_id;
153671a794cSIra Weiny 		struct cper_cxl_event_sn {
154671a794cSIra Weiny 			u32 lower_dw;
155671a794cSIra Weiny 			u32 upper_dw;
156671a794cSIra Weiny 		} __packed dev_serial_num;
157671a794cSIra Weiny 	} __packed hdr;
158671a794cSIra Weiny 
159671a794cSIra Weiny 	union cxl_event event;
160671a794cSIra Weiny } __packed;
161671a794cSIra Weiny 
1625e4a264bSIra Weiny struct cxl_cper_work_data {
1635e4a264bSIra Weiny 	enum cxl_event_type event_type;
1645e4a264bSIra Weiny 	struct cxl_cper_event_rec rec;
1655e4a264bSIra Weiny };
1665e4a264bSIra Weiny 
1675e4a264bSIra Weiny #ifdef CONFIG_ACPI_APEI_GHES
1685e4a264bSIra Weiny int cxl_cper_register_work(struct work_struct *work);
1695e4a264bSIra Weiny int cxl_cper_unregister_work(struct work_struct *work);
1705e4a264bSIra Weiny int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd);
1715e4a264bSIra Weiny #else
17255111470SIra Weiny static inline int cxl_cper_register_work(struct work_struct *work)
1735e4a264bSIra Weiny {
1745e4a264bSIra Weiny 	return 0;
1755e4a264bSIra Weiny }
1765e4a264bSIra Weiny 
17755111470SIra Weiny static inline int cxl_cper_unregister_work(struct work_struct *work)
1785e4a264bSIra Weiny {
1795e4a264bSIra Weiny 	return 0;
1805e4a264bSIra Weiny }
1815e4a264bSIra Weiny static inline int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd)
1825e4a264bSIra Weiny {
1835e4a264bSIra Weiny 	return 0;
1845e4a264bSIra Weiny }
1855e4a264bSIra Weiny #endif
1865e4a264bSIra Weiny 
18726a1a86dSIra Weiny #endif /* _LINUX_CXL_EVENT_H */
188