xref: /linux/include/cxl/event.h (revision 5e31e3477f1661ebbbec1cbf141f91ad3cffafc3)
140a895fdSDave Jiang /* SPDX-License-Identifier: GPL-2.0 */
240a895fdSDave Jiang /* Copyright(c) 2023 Intel Corporation. */
340a895fdSDave Jiang #ifndef _LINUX_CXL_EVENT_H
440a895fdSDave Jiang #define _LINUX_CXL_EVENT_H
540a895fdSDave Jiang 
640a895fdSDave Jiang #include <linux/types.h>
740a895fdSDave Jiang #include <linux/uuid.h>
840a895fdSDave Jiang #include <linux/workqueue_types.h>
940a895fdSDave Jiang 
1040a895fdSDave Jiang /*
1140a895fdSDave Jiang  * Common Event Record Format
1240a895fdSDave Jiang  * CXL rev 3.0 section 8.2.9.2.1; Table 8-42
1340a895fdSDave Jiang  */
1440a895fdSDave Jiang struct cxl_event_record_hdr {
1540a895fdSDave Jiang 	u8 length;
1640a895fdSDave Jiang 	u8 flags[3];
1740a895fdSDave Jiang 	__le16 handle;
1840a895fdSDave Jiang 	__le16 related_handle;
1940a895fdSDave Jiang 	__le64 timestamp;
2040a895fdSDave Jiang 	u8 maint_op_class;
21*5e31e347SShiju Jose 	u8 maint_op_sub_class;
22*5e31e347SShiju Jose 	u8 reserved[14];
2340a895fdSDave Jiang } __packed;
2440a895fdSDave Jiang 
2540a895fdSDave Jiang struct cxl_event_media_hdr {
2640a895fdSDave Jiang 	struct cxl_event_record_hdr hdr;
2740a895fdSDave Jiang 	__le64 phys_addr;
2840a895fdSDave Jiang 	u8 descriptor;
2940a895fdSDave Jiang 	u8 type;
3040a895fdSDave Jiang 	u8 transaction_type;
3140a895fdSDave Jiang 	/*
3240a895fdSDave Jiang 	 * The meaning of Validity Flags from bit 2 is
3340a895fdSDave Jiang 	 * different across DRAM and General Media records
3440a895fdSDave Jiang 	 */
3540a895fdSDave Jiang 	u8 validity_flags[2];
3640a895fdSDave Jiang 	u8 channel;
3740a895fdSDave Jiang 	u8 rank;
3840a895fdSDave Jiang } __packed;
3940a895fdSDave Jiang 
4040a895fdSDave Jiang #define CXL_EVENT_RECORD_DATA_LENGTH 0x50
4140a895fdSDave Jiang struct cxl_event_generic {
4240a895fdSDave Jiang 	struct cxl_event_record_hdr hdr;
4340a895fdSDave Jiang 	u8 data[CXL_EVENT_RECORD_DATA_LENGTH];
4440a895fdSDave Jiang } __packed;
4540a895fdSDave Jiang 
4640a895fdSDave Jiang /*
4740a895fdSDave Jiang  * General Media Event Record
4840a895fdSDave Jiang  * CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43
4940a895fdSDave Jiang  */
5040a895fdSDave Jiang #define CXL_EVENT_GEN_MED_COMP_ID_SIZE	0x10
5140a895fdSDave Jiang struct cxl_event_gen_media {
5240a895fdSDave Jiang 	struct cxl_event_media_hdr media_hdr;
5340a895fdSDave Jiang 	u8 device[3];
5440a895fdSDave Jiang 	u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
5540a895fdSDave Jiang 	u8 reserved[46];
5640a895fdSDave Jiang } __packed;
5740a895fdSDave Jiang 
5840a895fdSDave Jiang /*
5940a895fdSDave Jiang  * DRAM Event Record - DER
6040a895fdSDave Jiang  * CXL rev 3.0 section 8.2.9.2.1.2; Table 3-44
6140a895fdSDave Jiang  */
6240a895fdSDave Jiang #define CXL_EVENT_DER_CORRECTION_MASK_SIZE	0x20
6340a895fdSDave Jiang struct cxl_event_dram {
6440a895fdSDave Jiang 	struct cxl_event_media_hdr media_hdr;
6540a895fdSDave Jiang 	u8 nibble_mask[3];
6640a895fdSDave Jiang 	u8 bank_group;
6740a895fdSDave Jiang 	u8 bank;
6840a895fdSDave Jiang 	u8 row[3];
6940a895fdSDave Jiang 	u8 column[2];
7040a895fdSDave Jiang 	u8 correction_mask[CXL_EVENT_DER_CORRECTION_MASK_SIZE];
7140a895fdSDave Jiang 	u8 reserved[0x17];
7240a895fdSDave Jiang } __packed;
7340a895fdSDave Jiang 
7440a895fdSDave Jiang /*
7540a895fdSDave Jiang  * Get Health Info Record
7640a895fdSDave Jiang  * CXL rev 3.0 section 8.2.9.8.3.1; Table 8-100
7740a895fdSDave Jiang  */
7840a895fdSDave Jiang struct cxl_get_health_info {
7940a895fdSDave Jiang 	u8 health_status;
8040a895fdSDave Jiang 	u8 media_status;
8140a895fdSDave Jiang 	u8 add_status;
8240a895fdSDave Jiang 	u8 life_used;
8340a895fdSDave Jiang 	u8 device_temp[2];
8440a895fdSDave Jiang 	u8 dirty_shutdown_cnt[4];
8540a895fdSDave Jiang 	u8 cor_vol_err_cnt[4];
8640a895fdSDave Jiang 	u8 cor_per_err_cnt[4];
8740a895fdSDave Jiang } __packed;
8840a895fdSDave Jiang 
8940a895fdSDave Jiang /*
9040a895fdSDave Jiang  * Memory Module Event Record
9140a895fdSDave Jiang  * CXL rev 3.0 section 8.2.9.2.1.3; Table 8-45
9240a895fdSDave Jiang  */
9340a895fdSDave Jiang struct cxl_event_mem_module {
9440a895fdSDave Jiang 	struct cxl_event_record_hdr hdr;
9540a895fdSDave Jiang 	u8 event_type;
9640a895fdSDave Jiang 	struct cxl_get_health_info info;
9740a895fdSDave Jiang 	u8 reserved[0x3d];
9840a895fdSDave Jiang } __packed;
9940a895fdSDave Jiang 
10040a895fdSDave Jiang union cxl_event {
10140a895fdSDave Jiang 	struct cxl_event_generic generic;
10240a895fdSDave Jiang 	struct cxl_event_gen_media gen_media;
10340a895fdSDave Jiang 	struct cxl_event_dram dram;
10440a895fdSDave Jiang 	struct cxl_event_mem_module mem_module;
10540a895fdSDave Jiang 	/* dram & gen_media event header */
10640a895fdSDave Jiang 	struct cxl_event_media_hdr media_hdr;
10740a895fdSDave Jiang } __packed;
10840a895fdSDave Jiang 
10940a895fdSDave Jiang /*
11040a895fdSDave Jiang  * Common Event Record Format; in event logs
11140a895fdSDave Jiang  * CXL rev 3.0 section 8.2.9.2.1; Table 8-42
11240a895fdSDave Jiang  */
11340a895fdSDave Jiang struct cxl_event_record_raw {
11440a895fdSDave Jiang 	uuid_t id;
11540a895fdSDave Jiang 	union cxl_event event;
11640a895fdSDave Jiang } __packed;
11740a895fdSDave Jiang 
11840a895fdSDave Jiang enum cxl_event_type {
11940a895fdSDave Jiang 	CXL_CPER_EVENT_GENERIC,
12040a895fdSDave Jiang 	CXL_CPER_EVENT_GEN_MEDIA,
12140a895fdSDave Jiang 	CXL_CPER_EVENT_DRAM,
12240a895fdSDave Jiang 	CXL_CPER_EVENT_MEM_MODULE,
12340a895fdSDave Jiang };
12440a895fdSDave Jiang 
12540a895fdSDave Jiang #define CPER_CXL_DEVICE_ID_VALID		BIT(0)
12640a895fdSDave Jiang #define CPER_CXL_DEVICE_SN_VALID		BIT(1)
12740a895fdSDave Jiang #define CPER_CXL_COMP_EVENT_LOG_VALID		BIT(2)
12840a895fdSDave Jiang struct cxl_cper_event_rec {
12940a895fdSDave Jiang 	struct {
13040a895fdSDave Jiang 		u32 length;
13140a895fdSDave Jiang 		u64 validation_bits;
13240a895fdSDave Jiang 		struct cper_cxl_event_devid {
13340a895fdSDave Jiang 			u16 vendor_id;
13440a895fdSDave Jiang 			u16 device_id;
13540a895fdSDave Jiang 			u8 func_num;
13640a895fdSDave Jiang 			u8 device_num;
13740a895fdSDave Jiang 			u8 bus_num;
13840a895fdSDave Jiang 			u16 segment_num;
13940a895fdSDave Jiang 			u16 slot_num; /* bits 2:0 reserved */
14040a895fdSDave Jiang 			u8 reserved;
14140a895fdSDave Jiang 		} __packed device_id;
14240a895fdSDave Jiang 		struct cper_cxl_event_sn {
14340a895fdSDave Jiang 			u32 lower_dw;
14440a895fdSDave Jiang 			u32 upper_dw;
14540a895fdSDave Jiang 		} __packed dev_serial_num;
14640a895fdSDave Jiang 	} __packed hdr;
14740a895fdSDave Jiang 
14840a895fdSDave Jiang 	union cxl_event event;
14940a895fdSDave Jiang } __packed;
15040a895fdSDave Jiang 
15140a895fdSDave Jiang struct cxl_cper_work_data {
15240a895fdSDave Jiang 	enum cxl_event_type event_type;
15340a895fdSDave Jiang 	struct cxl_cper_event_rec rec;
15440a895fdSDave Jiang };
15540a895fdSDave Jiang 
15640a895fdSDave Jiang #ifdef CONFIG_ACPI_APEI_GHES
15740a895fdSDave Jiang int cxl_cper_register_work(struct work_struct *work);
15840a895fdSDave Jiang int cxl_cper_unregister_work(struct work_struct *work);
15940a895fdSDave Jiang int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd);
16040a895fdSDave Jiang #else
16140a895fdSDave Jiang static inline int cxl_cper_register_work(struct work_struct *work)
16240a895fdSDave Jiang {
16340a895fdSDave Jiang 	return 0;
16440a895fdSDave Jiang }
16540a895fdSDave Jiang 
16640a895fdSDave Jiang static inline int cxl_cper_unregister_work(struct work_struct *work)
16740a895fdSDave Jiang {
16840a895fdSDave Jiang 	return 0;
16940a895fdSDave Jiang }
17040a895fdSDave Jiang static inline int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd)
17140a895fdSDave Jiang {
17240a895fdSDave Jiang 	return 0;
17340a895fdSDave Jiang }
17440a895fdSDave Jiang #endif
17540a895fdSDave Jiang 
17640a895fdSDave Jiang #endif /* _LINUX_CXL_EVENT_H */
177