xref: /linux/include/linux/intel_vsec.h (revision ab93e0dd72c37d378dd936f031ffb83ff2bd87ce)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _INTEL_VSEC_H
3 #define _INTEL_VSEC_H
4 
5 #include <linux/auxiliary_bus.h>
6 #include <linux/bits.h>
7 #include <linux/err.h>
8 #include <linux/intel_pmt_features.h>
9 
10 /*
11  * VSEC_CAP_UNUSED is reserved. It exists to prevent zero initialized
12  * intel_vsec devices from being automatically set to a known
13  * capability with ID 0
14  */
15 #define VSEC_CAP_UNUSED		BIT(0)
16 #define VSEC_CAP_TELEMETRY	BIT(1)
17 #define VSEC_CAP_WATCHER	BIT(2)
18 #define VSEC_CAP_CRASHLOG	BIT(3)
19 #define VSEC_CAP_SDSI		BIT(4)
20 #define VSEC_CAP_TPMI		BIT(5)
21 #define VSEC_CAP_DISCOVERY	BIT(6)
22 #define VSEC_FEATURE_COUNT	7
23 
24 /* Intel DVSEC offsets */
25 #define INTEL_DVSEC_ENTRIES		0xA
26 #define INTEL_DVSEC_SIZE		0xB
27 #define INTEL_DVSEC_TABLE		0xC
28 #define INTEL_DVSEC_TABLE_BAR(x)	((x) & GENMASK(2, 0))
29 #define INTEL_DVSEC_TABLE_OFFSET(x)	((x) & GENMASK(31, 3))
30 #define TABLE_OFFSET_SHIFT		3
31 
32 struct pci_dev;
33 struct resource;
34 
35 enum intel_vsec_id {
36 	VSEC_ID_TELEMETRY	= 2,
37 	VSEC_ID_WATCHER		= 3,
38 	VSEC_ID_CRASHLOG	= 4,
39 	VSEC_ID_DISCOVERY	= 12,
40 	VSEC_ID_SDSI		= 65,
41 	VSEC_ID_TPMI		= 66,
42 };
43 
44 /**
45  * struct intel_vsec_header - Common fields of Intel VSEC and DVSEC registers.
46  * @rev:         Revision ID of the VSEC/DVSEC register space
47  * @length:      Length of the VSEC/DVSEC register space
48  * @id:          ID of the feature
49  * @num_entries: Number of instances of the feature
50  * @entry_size:  Size of the discovery table for each feature
51  * @tbir:        BAR containing the discovery tables
52  * @offset:      BAR offset of start of the first discovery table
53  */
54 struct intel_vsec_header {
55 	u8	rev;
56 	u16	length;
57 	u16	id;
58 	u8	num_entries;
59 	u8	entry_size;
60 	u8	tbir;
61 	u32	offset;
62 };
63 
64 enum intel_vsec_quirks {
65 	/* Watcher feature not supported */
66 	VSEC_QUIRK_NO_WATCHER	= BIT(0),
67 
68 	/* Crashlog feature not supported */
69 	VSEC_QUIRK_NO_CRASHLOG	= BIT(1),
70 
71 	/* Use shift instead of mask to read discovery table offset */
72 	VSEC_QUIRK_TABLE_SHIFT	= BIT(2),
73 
74 	/* DVSEC not present (provided in driver data) */
75 	VSEC_QUIRK_NO_DVSEC	= BIT(3),
76 
77 	/* Platforms requiring quirk in the auxiliary driver */
78 	VSEC_QUIRK_EARLY_HW     = BIT(4),
79 };
80 
81 /**
82  * struct pmt_callbacks - Callback infrastructure for PMT devices
83  * ->read_telem() when specified, called by client driver to access PMT data (instead
84  * of direct copy).
85  * @pdev:  PCI device reference for the callback's use
86  * @guid:  ID of data to acccss
87  * @data:  buffer for the data to be copied
88  * @off:   offset into the requested buffer
89  * @count: size of buffer
90  */
91 struct pmt_callbacks {
92 	int (*read_telem)(struct pci_dev *pdev, u32 guid, u64 *data, loff_t off, u32 count);
93 };
94 
95 struct vsec_feature_dependency {
96 	unsigned long feature;
97 	unsigned long supplier_bitmap;
98 };
99 
100 /**
101  * struct intel_vsec_platform_info - Platform specific data
102  * @parent:    parent device in the auxbus chain
103  * @headers:   list of headers to define the PMT client devices to create
104  * @deps:      array of feature dependencies
105  * @priv_data: private data, usable by parent devices, currently a callback
106  * @caps:      bitmask of PMT capabilities for the given headers
107  * @quirks:    bitmask of VSEC device quirks
108  * @base_addr: allow a base address to be specified (rather than derived)
109  * @num_deps:  Count feature dependencies
110  */
111 struct intel_vsec_platform_info {
112 	struct device *parent;
113 	struct intel_vsec_header **headers;
114 	const struct vsec_feature_dependency *deps;
115 	void *priv_data;
116 	unsigned long caps;
117 	unsigned long quirks;
118 	u64 base_addr;
119 	int num_deps;
120 };
121 
122 /**
123  * struct intel_sec_device - Auxbus specific device information
124  * @auxdev:        auxbus device struct for auxbus access
125  * @pcidev:        pci device associated with the device
126  * @resource:      any resources shared by the parent
127  * @ida:           id reference
128  * @num_resources: number of resources
129  * @id:            xarray id
130  * @priv_data:     any private data needed
131  * @quirks:        specified quirks
132  * @base_addr:     base address of entries (if specified)
133  * @cap_id:        the enumerated id of the vsec feature
134  */
135 struct intel_vsec_device {
136 	struct auxiliary_device auxdev;
137 	struct pci_dev *pcidev;
138 	struct resource *resource;
139 	struct ida *ida;
140 	int num_resources;
141 	int id; /* xa */
142 	void *priv_data;
143 	size_t priv_data_size;
144 	unsigned long quirks;
145 	u64 base_addr;
146 	unsigned long cap_id;
147 };
148 
149 /**
150  * struct oobmsm_plat_info - Platform information for a device instance
151  * @cdie_mask:       Mask of all compute dies in the partition
152  * @package_id:      CPU Package id
153  * @partition:       Package partition id when multiple VSEC PCI devices per package
154  * @segment:         PCI segment ID
155  * @bus_number:      PCI bus number
156  * @device_number:   PCI device number
157  * @function_number: PCI function number
158  *
159  * Structure to store platform data for a OOBMSM device instance.
160  */
161 struct oobmsm_plat_info {
162 	u16 cdie_mask;
163 	u8 package_id;
164 	u8 partition;
165 	u8 segment;
166 	u8 bus_number;
167 	u8 device_number;
168 	u8 function_number;
169 };
170 
171 struct telemetry_region {
172 	struct oobmsm_plat_info	plat_info;
173 	void __iomem		*addr;
174 	size_t			size;
175 	u32			guid;
176 	u32			num_rmids;
177 };
178 
179 struct pmt_feature_group {
180 	enum pmt_feature_id	id;
181 	int			count;
182 	struct kref		kref;
183 	struct telemetry_region	regions[];
184 };
185 
186 int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent,
187 		       struct intel_vsec_device *intel_vsec_dev,
188 		       const char *name);
189 
dev_to_ivdev(struct device * dev)190 static inline struct intel_vsec_device *dev_to_ivdev(struct device *dev)
191 {
192 	return container_of(dev, struct intel_vsec_device, auxdev.dev);
193 }
194 
auxdev_to_ivdev(struct auxiliary_device * auxdev)195 static inline struct intel_vsec_device *auxdev_to_ivdev(struct auxiliary_device *auxdev)
196 {
197 	return container_of(auxdev, struct intel_vsec_device, auxdev);
198 }
199 
200 #if IS_ENABLED(CONFIG_INTEL_VSEC)
201 int intel_vsec_register(struct pci_dev *pdev,
202 			 struct intel_vsec_platform_info *info);
203 int intel_vsec_set_mapping(struct oobmsm_plat_info *plat_info,
204 			   struct intel_vsec_device *vsec_dev);
205 struct oobmsm_plat_info *intel_vsec_get_mapping(struct pci_dev *pdev);
206 #else
intel_vsec_register(struct pci_dev * pdev,struct intel_vsec_platform_info * info)207 static inline int intel_vsec_register(struct pci_dev *pdev,
208 				       struct intel_vsec_platform_info *info)
209 {
210 	return -ENODEV;
211 }
intel_vsec_set_mapping(struct oobmsm_plat_info * plat_info,struct intel_vsec_device * vsec_dev)212 static inline int intel_vsec_set_mapping(struct oobmsm_plat_info *plat_info,
213 					 struct intel_vsec_device *vsec_dev)
214 {
215 	return -ENODEV;
216 }
intel_vsec_get_mapping(struct pci_dev * pdev)217 static inline struct oobmsm_plat_info *intel_vsec_get_mapping(struct pci_dev *pdev)
218 {
219 	return ERR_PTR(-ENODEV);
220 }
221 #endif
222 
223 #if IS_ENABLED(CONFIG_INTEL_PMT_TELEMETRY)
224 struct pmt_feature_group *
225 intel_pmt_get_regions_by_feature(enum pmt_feature_id id);
226 
227 void intel_pmt_put_feature_group(struct pmt_feature_group *feature_group);
228 #else
229 static inline struct pmt_feature_group *
intel_pmt_get_regions_by_feature(enum pmt_feature_id id)230 intel_pmt_get_regions_by_feature(enum pmt_feature_id id)
231 {
232 	return ERR_PTR(-ENODEV);
233 }
234 
235 static inline void
intel_pmt_put_feature_group(struct pmt_feature_group * feature_group)236 intel_pmt_put_feature_group(struct pmt_feature_group *feature_group) {}
237 #endif
238 
239 #endif
240