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