xref: /linux/include/cxl/event.h (revision f10f46a0ee53420f707195fe33b7c235a1c0e48a)
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;
221f4f8166SShiju Jose 	__le16 ld_id;
231f4f8166SShiju Jose 	u8 head_id;
241f4f8166SShiju Jose 	u8 reserved[11];
2526a1a86dSIra Weiny } __packed;
2626a1a86dSIra Weiny 
27675e979dSFabio M. De Francesco struct cxl_event_media_hdr {
28675e979dSFabio M. De Francesco 	struct cxl_event_record_hdr hdr;
29675e979dSFabio M. De Francesco 	__le64 phys_addr;
30675e979dSFabio M. De Francesco 	u8 descriptor;
31675e979dSFabio M. De Francesco 	u8 type;
32675e979dSFabio M. De Francesco 	u8 transaction_type;
33675e979dSFabio M. De Francesco 	/*
34675e979dSFabio M. De Francesco 	 * The meaning of Validity Flags from bit 2 is
35675e979dSFabio M. De Francesco 	 * different across DRAM and General Media records
36675e979dSFabio M. De Francesco 	 */
37675e979dSFabio M. De Francesco 	u8 validity_flags[2];
38675e979dSFabio M. De Francesco 	u8 channel;
39675e979dSFabio M. De Francesco 	u8 rank;
40675e979dSFabio M. De Francesco } __packed;
41675e979dSFabio M. De Francesco 
4226a1a86dSIra Weiny #define CXL_EVENT_RECORD_DATA_LENGTH 0x50
43f9c68338SIra Weiny struct cxl_event_generic {
4426a1a86dSIra Weiny 	struct cxl_event_record_hdr hdr;
4526a1a86dSIra Weiny 	u8 data[CXL_EVENT_RECORD_DATA_LENGTH];
4626a1a86dSIra Weiny } __packed;
4726a1a86dSIra Weiny 
4826a1a86dSIra Weiny /*
4926a1a86dSIra Weiny  * General Media Event Record
50ae834131SShiju Jose  * CXL rev 3.1 Section 8.2.9.2.1.1; Table 8-45
5126a1a86dSIra Weiny  */
5226a1a86dSIra Weiny #define CXL_EVENT_GEN_MED_COMP_ID_SIZE	0x10
5326a1a86dSIra Weiny struct cxl_event_gen_media {
54675e979dSFabio M. De Francesco 	struct cxl_event_media_hdr media_hdr;
5526a1a86dSIra Weiny 	u8 device[3];
5626a1a86dSIra Weiny 	u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
57ae834131SShiju Jose 	u8 cme_threshold_ev_flags;
58ae834131SShiju Jose 	u8 cme_count[3];
59ae834131SShiju Jose 	u8 sub_type;
60ae834131SShiju Jose 	u8 reserved[41];
6126a1a86dSIra Weiny } __packed;
6226a1a86dSIra Weiny 
6326a1a86dSIra Weiny /*
6426a1a86dSIra Weiny  * DRAM Event Record - DER
6524ec41f7SShiju Jose  * CXL rev 3.1 section 8.2.9.2.1.2; Table 8-46
6626a1a86dSIra Weiny  */
6726a1a86dSIra Weiny #define CXL_EVENT_DER_CORRECTION_MASK_SIZE	0x20
6826a1a86dSIra Weiny struct cxl_event_dram {
69675e979dSFabio M. De Francesco 	struct cxl_event_media_hdr media_hdr;
7026a1a86dSIra Weiny 	u8 nibble_mask[3];
7126a1a86dSIra Weiny 	u8 bank_group;
7226a1a86dSIra Weiny 	u8 bank;
7326a1a86dSIra Weiny 	u8 row[3];
7426a1a86dSIra Weiny 	u8 column[2];
7526a1a86dSIra Weiny 	u8 correction_mask[CXL_EVENT_DER_CORRECTION_MASK_SIZE];
7624ec41f7SShiju Jose 	u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
7724ec41f7SShiju Jose 	u8 sub_channel;
7824ec41f7SShiju Jose 	u8 cme_threshold_ev_flags;
7924ec41f7SShiju Jose 	u8 cvme_count[3];
8024ec41f7SShiju Jose 	u8 sub_type;
8124ec41f7SShiju Jose 	u8 reserved;
8226a1a86dSIra Weiny } __packed;
8326a1a86dSIra Weiny 
8426a1a86dSIra Weiny /*
8526a1a86dSIra Weiny  * Get Health Info Record
864c6e20ebSShiju Jose  * CXL rev 3.1 section 8.2.9.9.3.1; Table 8-133
8726a1a86dSIra Weiny  */
8826a1a86dSIra Weiny struct cxl_get_health_info {
8926a1a86dSIra Weiny 	u8 health_status;
9026a1a86dSIra Weiny 	u8 media_status;
9126a1a86dSIra Weiny 	u8 add_status;
9226a1a86dSIra Weiny 	u8 life_used;
9326a1a86dSIra Weiny 	u8 device_temp[2];
9426a1a86dSIra Weiny 	u8 dirty_shutdown_cnt[4];
9526a1a86dSIra Weiny 	u8 cor_vol_err_cnt[4];
9626a1a86dSIra Weiny 	u8 cor_per_err_cnt[4];
9726a1a86dSIra Weiny } __packed;
9826a1a86dSIra Weiny 
9926a1a86dSIra Weiny /*
10026a1a86dSIra Weiny  * Memory Module Event Record
1014c6e20ebSShiju Jose  * CXL rev 3.1 section 8.2.9.2.1.3; Table 8-47
10226a1a86dSIra Weiny  */
10326a1a86dSIra Weiny struct cxl_event_mem_module {
10426a1a86dSIra Weiny 	struct cxl_event_record_hdr hdr;
10526a1a86dSIra Weiny 	u8 event_type;
10626a1a86dSIra Weiny 	struct cxl_get_health_info info;
1074c6e20ebSShiju Jose 	u8 validity_flags[2];
1084c6e20ebSShiju Jose 	u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
1094c6e20ebSShiju Jose 	u8 event_sub_type;
1104c6e20ebSShiju Jose 	u8 reserved[0x2a];
11126a1a86dSIra Weiny } __packed;
11226a1a86dSIra Weiny 
113*f10f46a0SShiju Jose /*
114*f10f46a0SShiju Jose  * Memory Sparing Event Record - MSER
115*f10f46a0SShiju Jose  * CXL rev 3.2 section 8.2.10.2.1.4; Table 8-60
116*f10f46a0SShiju Jose  */
117*f10f46a0SShiju Jose struct cxl_event_mem_sparing {
118*f10f46a0SShiju Jose 	struct cxl_event_record_hdr hdr;
119*f10f46a0SShiju Jose 	/*
120*f10f46a0SShiju Jose 	 * The fields maintenance operation class and maintenance operation
121*f10f46a0SShiju Jose 	 * subclass defined in the Memory Sparing Event Record are the
122*f10f46a0SShiju Jose 	 * duplication of the same in the common event record. Thus defined
123*f10f46a0SShiju Jose 	 * as reserved and to be removed after the spec correction.
124*f10f46a0SShiju Jose 	 */
125*f10f46a0SShiju Jose 	u8 rsv1;
126*f10f46a0SShiju Jose 	u8 rsv2;
127*f10f46a0SShiju Jose 	u8 flags;
128*f10f46a0SShiju Jose 	u8 result;
129*f10f46a0SShiju Jose 	__le16 validity_flags;
130*f10f46a0SShiju Jose 	u8 reserved1[6];
131*f10f46a0SShiju Jose 	__le16 res_avail;
132*f10f46a0SShiju Jose 	u8 channel;
133*f10f46a0SShiju Jose 	u8 rank;
134*f10f46a0SShiju Jose 	u8 nibble_mask[3];
135*f10f46a0SShiju Jose 	u8 bank_group;
136*f10f46a0SShiju Jose 	u8 bank;
137*f10f46a0SShiju Jose 	u8 row[3];
138*f10f46a0SShiju Jose 	__le16 column;
139*f10f46a0SShiju Jose 	u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
140*f10f46a0SShiju Jose 	u8 sub_channel;
141*f10f46a0SShiju Jose 	u8 reserved2[0x25];
142*f10f46a0SShiju Jose } __packed;
143*f10f46a0SShiju Jose 
144f9c68338SIra Weiny union cxl_event {
145f9c68338SIra Weiny 	struct cxl_event_generic generic;
146f9c68338SIra Weiny 	struct cxl_event_gen_media gen_media;
147f9c68338SIra Weiny 	struct cxl_event_dram dram;
148f9c68338SIra Weiny 	struct cxl_event_mem_module mem_module;
149*f10f46a0SShiju Jose 	struct cxl_event_mem_sparing mem_sparing;
150675e979dSFabio M. De Francesco 	/* dram & gen_media event header */
151675e979dSFabio M. De Francesco 	struct cxl_event_media_hdr media_hdr;
152f9c68338SIra Weiny } __packed;
153f9c68338SIra Weiny 
154f9c68338SIra Weiny /*
155f9c68338SIra Weiny  * Common Event Record Format; in event logs
156f9c68338SIra Weiny  * CXL rev 3.0 section 8.2.9.2.1; Table 8-42
157f9c68338SIra Weiny  */
158f9c68338SIra Weiny struct cxl_event_record_raw {
159f9c68338SIra Weiny 	uuid_t id;
160f9c68338SIra Weiny 	union cxl_event event;
161f9c68338SIra Weiny } __packed;
162f9c68338SIra Weiny 
163671a794cSIra Weiny enum cxl_event_type {
164dc97f634SIra Weiny 	CXL_CPER_EVENT_GENERIC,
165671a794cSIra Weiny 	CXL_CPER_EVENT_GEN_MEDIA,
166671a794cSIra Weiny 	CXL_CPER_EVENT_DRAM,
167671a794cSIra Weiny 	CXL_CPER_EVENT_MEM_MODULE,
168*f10f46a0SShiju Jose 	CXL_CPER_EVENT_MEM_SPARING,
169671a794cSIra Weiny };
170671a794cSIra Weiny 
171671a794cSIra Weiny #define CPER_CXL_DEVICE_ID_VALID		BIT(0)
172671a794cSIra Weiny #define CPER_CXL_DEVICE_SN_VALID		BIT(1)
173671a794cSIra Weiny #define CPER_CXL_COMP_EVENT_LOG_VALID		BIT(2)
174671a794cSIra Weiny struct cxl_cper_event_rec {
175671a794cSIra Weiny 	struct {
176671a794cSIra Weiny 		u32 length;
177671a794cSIra Weiny 		u64 validation_bits;
178671a794cSIra Weiny 		struct cper_cxl_event_devid {
179671a794cSIra Weiny 			u16 vendor_id;
180671a794cSIra Weiny 			u16 device_id;
181671a794cSIra Weiny 			u8 func_num;
182671a794cSIra Weiny 			u8 device_num;
183671a794cSIra Weiny 			u8 bus_num;
184671a794cSIra Weiny 			u16 segment_num;
185671a794cSIra Weiny 			u16 slot_num; /* bits 2:0 reserved */
186671a794cSIra Weiny 			u8 reserved;
187671a794cSIra Weiny 		} __packed device_id;
188671a794cSIra Weiny 		struct cper_cxl_event_sn {
189671a794cSIra Weiny 			u32 lower_dw;
190671a794cSIra Weiny 			u32 upper_dw;
191671a794cSIra Weiny 		} __packed dev_serial_num;
192671a794cSIra Weiny 	} __packed hdr;
193671a794cSIra Weiny 
194671a794cSIra Weiny 	union cxl_event event;
195671a794cSIra Weiny } __packed;
196671a794cSIra Weiny 
1975e4a264bSIra Weiny struct cxl_cper_work_data {
1985e4a264bSIra Weiny 	enum cxl_event_type event_type;
1995e4a264bSIra Weiny 	struct cxl_cper_event_rec rec;
2005e4a264bSIra Weiny };
2015e4a264bSIra Weiny 
202958c3a67SSmita Koralahalli #define PROT_ERR_VALID_AGENT_TYPE		BIT_ULL(0)
203958c3a67SSmita Koralahalli #define PROT_ERR_VALID_AGENT_ADDRESS		BIT_ULL(1)
204958c3a67SSmita Koralahalli #define PROT_ERR_VALID_DEVICE_ID		BIT_ULL(2)
205958c3a67SSmita Koralahalli #define PROT_ERR_VALID_SERIAL_NUMBER		BIT_ULL(3)
206958c3a67SSmita Koralahalli #define PROT_ERR_VALID_CAPABILITY		BIT_ULL(4)
207958c3a67SSmita Koralahalli #define PROT_ERR_VALID_DVSEC			BIT_ULL(5)
208958c3a67SSmita Koralahalli #define PROT_ERR_VALID_ERROR_LOG		BIT_ULL(6)
209958c3a67SSmita Koralahalli 
210958c3a67SSmita Koralahalli /*
211958c3a67SSmita Koralahalli  * The layout of the enumeration and the values matches CXL Agent Type
212958c3a67SSmita Koralahalli  * field in the UEFI 2.10 Section N.2.13,
213958c3a67SSmita Koralahalli  */
214958c3a67SSmita Koralahalli enum {
215958c3a67SSmita Koralahalli 	RCD,	/* Restricted CXL Device */
216958c3a67SSmita Koralahalli 	RCH_DP,	/* Restricted CXL Host Downstream Port */
217958c3a67SSmita Koralahalli 	DEVICE,	/* CXL Device */
218958c3a67SSmita Koralahalli 	LD,	/* CXL Logical Device */
219958c3a67SSmita Koralahalli 	FMLD,	/* CXL Fabric Manager managed Logical Device */
220958c3a67SSmita Koralahalli 	RP,	/* CXL Root Port */
221958c3a67SSmita Koralahalli 	DSP,	/* CXL Downstream Switch Port */
222958c3a67SSmita Koralahalli 	USP,	/* CXL Upstream Switch Port */
223958c3a67SSmita Koralahalli };
224958c3a67SSmita Koralahalli 
225958c3a67SSmita Koralahalli #pragma pack(1)
226958c3a67SSmita Koralahalli 
227958c3a67SSmita Koralahalli /* Compute Express Link Protocol Error Section, UEFI v2.10 sec N.2.13 */
228958c3a67SSmita Koralahalli struct cxl_cper_sec_prot_err {
229958c3a67SSmita Koralahalli 	u64 valid_bits;
230958c3a67SSmita Koralahalli 	u8 agent_type;
231958c3a67SSmita Koralahalli 	u8 reserved[7];
232958c3a67SSmita Koralahalli 
233958c3a67SSmita Koralahalli 	/*
234958c3a67SSmita Koralahalli 	 * Except for RCH Downstream Port, all the remaining CXL Agent
235958c3a67SSmita Koralahalli 	 * types are uniquely identified by the PCIe compatible SBDF number.
236958c3a67SSmita Koralahalli 	 */
237958c3a67SSmita Koralahalli 	union {
238958c3a67SSmita Koralahalli 		u64 rcrb_base_addr;
239958c3a67SSmita Koralahalli 		struct {
240958c3a67SSmita Koralahalli 			u8 function;
241958c3a67SSmita Koralahalli 			u8 device;
242958c3a67SSmita Koralahalli 			u8 bus;
243958c3a67SSmita Koralahalli 			u16 segment;
244958c3a67SSmita Koralahalli 			u8 reserved_1[3];
245958c3a67SSmita Koralahalli 		};
246958c3a67SSmita Koralahalli 	} agent_addr;
247958c3a67SSmita Koralahalli 
248958c3a67SSmita Koralahalli 	struct {
249958c3a67SSmita Koralahalli 		u16 vendor_id;
250958c3a67SSmita Koralahalli 		u16 device_id;
251958c3a67SSmita Koralahalli 		u16 subsystem_vendor_id;
252958c3a67SSmita Koralahalli 		u16 subsystem_id;
253958c3a67SSmita Koralahalli 		u8 class_code[2];
254958c3a67SSmita Koralahalli 		u16 slot;
255958c3a67SSmita Koralahalli 		u8 reserved_1[4];
256958c3a67SSmita Koralahalli 	} device_id;
257958c3a67SSmita Koralahalli 
258958c3a67SSmita Koralahalli 	struct {
259958c3a67SSmita Koralahalli 		u32 lower_dw;
260958c3a67SSmita Koralahalli 		u32 upper_dw;
261958c3a67SSmita Koralahalli 	} dev_serial_num;
262958c3a67SSmita Koralahalli 
263958c3a67SSmita Koralahalli 	u8 capability[60];
264958c3a67SSmita Koralahalli 	u16 dvsec_len;
265958c3a67SSmita Koralahalli 	u16 err_len;
266958c3a67SSmita Koralahalli 	u8 reserved_2[4];
267958c3a67SSmita Koralahalli };
268958c3a67SSmita Koralahalli 
269958c3a67SSmita Koralahalli #pragma pack()
270958c3a67SSmita Koralahalli 
271958c3a67SSmita Koralahalli /* CXL RAS Capability Structure, CXL v3.0 sec 8.2.4.16 */
272958c3a67SSmita Koralahalli struct cxl_ras_capability_regs {
273958c3a67SSmita Koralahalli 	u32 uncor_status;
274958c3a67SSmita Koralahalli 	u32 uncor_mask;
275958c3a67SSmita Koralahalli 	u32 uncor_severity;
276958c3a67SSmita Koralahalli 	u32 cor_status;
277958c3a67SSmita Koralahalli 	u32 cor_mask;
278958c3a67SSmita Koralahalli 	u32 cap_control;
279958c3a67SSmita Koralahalli 	u32 header_log[16];
280958c3a67SSmita Koralahalli };
281958c3a67SSmita Koralahalli 
282315c2f0bSSmita Koralahalli struct cxl_cper_prot_err_work_data {
283315c2f0bSSmita Koralahalli 	struct cxl_cper_sec_prot_err prot_err;
284315c2f0bSSmita Koralahalli 	struct cxl_ras_capability_regs ras_cap;
285315c2f0bSSmita Koralahalli 	int severity;
286315c2f0bSSmita Koralahalli };
287315c2f0bSSmita Koralahalli 
2885e4a264bSIra Weiny #ifdef CONFIG_ACPI_APEI_GHES
2895e4a264bSIra Weiny int cxl_cper_register_work(struct work_struct *work);
2905e4a264bSIra Weiny int cxl_cper_unregister_work(struct work_struct *work);
2915e4a264bSIra Weiny int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd);
29236f257e3SSmita Koralahalli int cxl_cper_register_prot_err_work(struct work_struct *work);
29336f257e3SSmita Koralahalli int cxl_cper_unregister_prot_err_work(struct work_struct *work);
29436f257e3SSmita Koralahalli int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data *wd);
2955e4a264bSIra Weiny #else
cxl_cper_register_work(struct work_struct * work)29655111470SIra Weiny static inline int cxl_cper_register_work(struct work_struct *work)
2975e4a264bSIra Weiny {
2985e4a264bSIra Weiny 	return 0;
2995e4a264bSIra Weiny }
3005e4a264bSIra Weiny 
cxl_cper_unregister_work(struct work_struct * work)30155111470SIra Weiny static inline int cxl_cper_unregister_work(struct work_struct *work)
3025e4a264bSIra Weiny {
3035e4a264bSIra Weiny 	return 0;
3045e4a264bSIra Weiny }
cxl_cper_kfifo_get(struct cxl_cper_work_data * wd)3055e4a264bSIra Weiny static inline int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd)
3065e4a264bSIra Weiny {
3075e4a264bSIra Weiny 	return 0;
3085e4a264bSIra Weiny }
cxl_cper_register_prot_err_work(struct work_struct * work)30936f257e3SSmita Koralahalli static inline int cxl_cper_register_prot_err_work(struct work_struct *work)
31036f257e3SSmita Koralahalli {
31136f257e3SSmita Koralahalli 	return 0;
31236f257e3SSmita Koralahalli }
cxl_cper_unregister_prot_err_work(struct work_struct * work)31336f257e3SSmita Koralahalli static inline int cxl_cper_unregister_prot_err_work(struct work_struct *work)
31436f257e3SSmita Koralahalli {
31536f257e3SSmita Koralahalli 	return 0;
31636f257e3SSmita Koralahalli }
cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data * wd)31736f257e3SSmita Koralahalli static inline int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data *wd)
31836f257e3SSmita Koralahalli {
31936f257e3SSmita Koralahalli 	return 0;
32036f257e3SSmita Koralahalli }
3215e4a264bSIra Weiny #endif
3225e4a264bSIra Weiny 
32326a1a86dSIra Weiny #endif /* _LINUX_CXL_EVENT_H */
324