Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright(c) 2023 Intel Corporation. */
3#ifndef _LINUX_CXL_EVENT_H
4#define _LINUX_CXL_EVENT_H
5
6#include <linux/types.h>
7#include <linux/uuid.h>
8#include <linux/workqueue_types.h>
9
10/*
11 * Common Event Record Format
12 * CXL rev 3.0 section 8.2.9.2.1; Table 8-42
13 */
14struct cxl_event_record_hdr {
15 u8 length;
16 u8 flags[3];
17 __le16 handle;
18 __le16 related_handle;
19 __le64 timestamp;
20 u8 maint_op_class;
21 u8 maint_op_sub_class;
22 u8 reserved[14];
23} __packed;
24
25struct cxl_event_media_hdr {
26 struct cxl_event_record_hdr hdr;
27 __le64 phys_addr;
28 u8 descriptor;
29 u8 type;
30 u8 transaction_type;
31 /*
32 * The meaning of Validity Flags from bit 2 is
33 * different across DRAM and General Media records
34 */
35 u8 validity_flags[2];
36 u8 channel;
37 u8 rank;
38} __packed;
39
40#define CXL_EVENT_RECORD_DATA_LENGTH 0x50
41struct cxl_event_generic {
42 struct cxl_event_record_hdr hdr;
43 u8 data[CXL_EVENT_RECORD_DATA_LENGTH];
44} __packed;
45
46/*
47 * General Media Event Record
48 * CXL rev 3.1 Section 8.2.9.2.1.1; Table 8-45
49 */
50#define CXL_EVENT_GEN_MED_COMP_ID_SIZE 0x10
51struct cxl_event_gen_media {
52 struct cxl_event_media_hdr media_hdr;
53 u8 device[3];
54 u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
55 u8 cme_threshold_ev_flags;
56 u8 cme_count[3];
57 u8 sub_type;
58 u8 reserved[41];
59} __packed;
60
61/*
62 * DRAM Event Record - DER
63 * CXL rev 3.1 section 8.2.9.2.1.2; Table 8-46
64 */
65#define CXL_EVENT_DER_CORRECTION_MASK_SIZE 0x20
66struct cxl_event_dram {
67 struct cxl_event_media_hdr media_hdr;
68 u8 nibble_mask[3];
69 u8 bank_group;
70 u8 bank;
71 u8 row[3];
72 u8 column[2];
73 u8 correction_mask[CXL_EVENT_DER_CORRECTION_MASK_SIZE];
74 u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
75 u8 sub_channel;
76 u8 cme_threshold_ev_flags;
77 u8 cvme_count[3];
78 u8 sub_type;
79 u8 reserved;
80} __packed;
81
82/*
83 * Get Health Info Record
84 * CXL rev 3.1 section 8.2.9.9.3.1; Table 8-133
85 */
86struct cxl_get_health_info {
87 u8 health_status;
88 u8 media_status;
89 u8 add_status;
90 u8 life_used;
91 u8 device_temp[2];
92 u8 dirty_shutdown_cnt[4];
93 u8 cor_vol_err_cnt[4];
94 u8 cor_per_err_cnt[4];
95} __packed;
96
97/*
98 * Memory Module Event Record
99 * CXL rev 3.1 section 8.2.9.2.1.3; Table 8-47
100 */
101struct cxl_event_mem_module {
102 struct cxl_event_record_hdr hdr;
103 u8 event_type;
104 struct cxl_get_health_info info;
105 u8 validity_flags[2];
106 u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
107 u8 event_sub_type;
108 u8 reserved[0x2a];
109} __packed;
110
111union cxl_event {
112 struct cxl_event_generic generic;
113 struct cxl_event_gen_media gen_media;
114 struct cxl_event_dram dram;
115 struct cxl_event_mem_module mem_module;
116 /* dram & gen_media event header */
117 struct cxl_event_media_hdr media_hdr;
118} __packed;
119
120/*
121 * Common Event Record Format; in event logs
122 * CXL rev 3.0 section 8.2.9.2.1; Table 8-42
123 */
124struct cxl_event_record_raw {
125 uuid_t id;
126 union cxl_event event;
127} __packed;
128
129enum cxl_event_type {
130 CXL_CPER_EVENT_GENERIC,
131 CXL_CPER_EVENT_GEN_MEDIA,
132 CXL_CPER_EVENT_DRAM,
133 CXL_CPER_EVENT_MEM_MODULE,
134};
135
136#define CPER_CXL_DEVICE_ID_VALID BIT(0)
137#define CPER_CXL_DEVICE_SN_VALID BIT(1)
138#define CPER_CXL_COMP_EVENT_LOG_VALID BIT(2)
139struct cxl_cper_event_rec {
140 struct {
141 u32 length;
142 u64 validation_bits;
143 struct cper_cxl_event_devid {
144 u16 vendor_id;
145 u16 device_id;
146 u8 func_num;
147 u8 device_num;
148 u8 bus_num;
149 u16 segment_num;
150 u16 slot_num; /* bits 2:0 reserved */
151 u8 reserved;
152 } __packed device_id;
153 struct cper_cxl_event_sn {
154 u32 lower_dw;
155 u32 upper_dw;
156 } __packed dev_serial_num;
157 } __packed hdr;
158
159 union cxl_event event;
160} __packed;
161
162struct cxl_cper_work_data {
163 enum cxl_event_type event_type;
164 struct cxl_cper_event_rec rec;
165};
166
167#define PROT_ERR_VALID_AGENT_TYPE BIT_ULL(0)
168#define PROT_ERR_VALID_AGENT_ADDRESS BIT_ULL(1)
169#define PROT_ERR_VALID_DEVICE_ID BIT_ULL(2)
170#define PROT_ERR_VALID_SERIAL_NUMBER BIT_ULL(3)
171#define PROT_ERR_VALID_CAPABILITY BIT_ULL(4)
172#define PROT_ERR_VALID_DVSEC BIT_ULL(5)
173#define PROT_ERR_VALID_ERROR_LOG BIT_ULL(6)
174
175/*
176 * The layout of the enumeration and the values matches CXL Agent Type
177 * field in the UEFI 2.10 Section N.2.13,
178 */
179enum {
180 RCD, /* Restricted CXL Device */
181 RCH_DP, /* Restricted CXL Host Downstream Port */
182 DEVICE, /* CXL Device */
183 LD, /* CXL Logical Device */
184 FMLD, /* CXL Fabric Manager managed Logical Device */
185 RP, /* CXL Root Port */
186 DSP, /* CXL Downstream Switch Port */
187 USP, /* CXL Upstream Switch Port */
188};
189
190#pragma pack(1)
191
192/* Compute Express Link Protocol Error Section, UEFI v2.10 sec N.2.13 */
193struct cxl_cper_sec_prot_err {
194 u64 valid_bits;
195 u8 agent_type;
196 u8 reserved[7];
197
198 /*
199 * Except for RCH Downstream Port, all the remaining CXL Agent
200 * types are uniquely identified by the PCIe compatible SBDF number.
201 */
202 union {
203 u64 rcrb_base_addr;
204 struct {
205 u8 function;
206 u8 device;
207 u8 bus;
208 u16 segment;
209 u8 reserved_1[3];
210 };
211 } agent_addr;
212
213 struct {
214 u16 vendor_id;
215 u16 device_id;
216 u16 subsystem_vendor_id;
217 u16 subsystem_id;
218 u8 class_code[2];
219 u16 slot;
220 u8 reserved_1[4];
221 } device_id;
222
223 struct {
224 u32 lower_dw;
225 u32 upper_dw;
226 } dev_serial_num;
227
228 u8 capability[60];
229 u16 dvsec_len;
230 u16 err_len;
231 u8 reserved_2[4];
232};
233
234#pragma pack()
235
236/* CXL RAS Capability Structure, CXL v3.0 sec 8.2.4.16 */
237struct cxl_ras_capability_regs {
238 u32 uncor_status;
239 u32 uncor_mask;
240 u32 uncor_severity;
241 u32 cor_status;
242 u32 cor_mask;
243 u32 cap_control;
244 u32 header_log[16];
245};
246
247struct cxl_cper_prot_err_work_data {
248 struct cxl_cper_sec_prot_err prot_err;
249 struct cxl_ras_capability_regs ras_cap;
250 int severity;
251};
252
253#ifdef CONFIG_ACPI_APEI_GHES
254int cxl_cper_register_work(struct work_struct *work);
255int cxl_cper_unregister_work(struct work_struct *work);
256int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd);
257int cxl_cper_register_prot_err_work(struct work_struct *work);
258int cxl_cper_unregister_prot_err_work(struct work_struct *work);
259int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data *wd);
260#else
261static inline int cxl_cper_register_work(struct work_struct *work)
262{
263 return 0;
264}
265
266static inline int cxl_cper_unregister_work(struct work_struct *work)
267{
268 return 0;
269}
270static inline int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd)
271{
272 return 0;
273}
274static inline int cxl_cper_register_prot_err_work(struct work_struct *work)
275{
276 return 0;
277}
278static inline int cxl_cper_unregister_prot_err_work(struct work_struct *work)
279{
280 return 0;
281}
282static inline int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data *wd)
283{
284 return 0;
285}
286#endif
287
288#endif /* _LINUX_CXL_EVENT_H */