xref: /spdk/lib/vmd/vmd_spec.h (revision f0b52280df23cfcc17a2cd673923e0384f5784ca)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2019 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #ifndef VMD_SPEC_H
7 #define VMD_SPEC_H
8 
9 #define MAX_VMD_SUPPORTED 48  /* max number of vmd controllers in a system - */
10 
11 #define PCI_INVALID_VENDORID 0xFFFF
12 #define ONE_MB (1<<20)
13 #define PCI_OFFSET_OF(object, member)  ((uint32_t)&((object*)0)->member)
14 #define TWOS_COMPLEMENT(value) (~(value) + 1)
15 
16 #define VMD_UPPER_BASE_SIGNATURE  0xFFFFFFEF
17 #define VMD_UPPER_LIMIT_SIGNATURE 0xFFFFFFED
18 
19 /* VMD Registers */
20 #define PCI_VMD_VMCAP		0x40
21 #define PCI_VMD_VMCONFIG	0x44
22 
23 /*
24  *  BAR assignment constants
25  */
26 #define  PCI_DWORD_SHIFT            32
27 #define  PCI_BASE_ADDR_MASK         0xFFFFFFF0
28 #define  PCI_BAR_MEMORY_MASK        0x0000000F
29 #define  PCI_BAR_MEMORY_MEM_IND     0x1
30 #define  PCI_BAR_MEMORY_TYPE        0x6
31 #define  PCI_BAR_MEMORY_PREFETCH    0x8
32 #define  PCI_BAR_MEMORY_TYPE_32     0x0
33 #define  PCI_BAR_MEMORY_TYPE_64     0x4
34 #define  PCI_BAR_MB_MASK            0xFFFFF
35 #define  PCI_PCI_BRIDGE_ADDR_DEF    0xFFF0
36 #define  PCI_BRIDGE_MEMORY_MASK     0xFFF0
37 #define  PCI_BRIDGE_PREFETCH_64     0x0001
38 #define  PCI_BRIDGE_MEMORY_SHIFT    16
39 #define  PCI_CONFIG_ACCESS_DELAY    500
40 
41 #define PCI_BAR0_OFFSET			0x10
42 #define PCI_BAR_SIZE			4
43 #define PCI_BAR_MEMORY_ADDR_OFFSET	(~0xfull)
44 
45 #define PCI_MAX_CFG_SIZE            0x1000
46 
47 #define PCI_HEADER_TYPE             0x0e
48 #define PCI_HEADER_TYPE_NORMAL   0
49 #define PCI_HEADER_TYPE_BRIDGE   1
50 #define PCI_MULTI_FUNCTION 0x80
51 
52 #define PCI_COMMAND_MEMORY 0x2
53 #define PCI_COMMAND_MASTER 0x4
54 
55 #define PCIE_TYPE_FLAGS 0xf0
56 #define PCIE_TYPE_SHIFT 4
57 #define PCIE_TYPE_ROOT_PORT 0x4
58 #define PCIE_TYPE_DOWNSTREAM 0x6
59 
60 #define PCI_CLASS_STORAGE_EXPRESS   0x010802
61 #define ADDR_ELEM_COUNT 32
62 #define PCI_MAX_BUS_NUMBER 0x7F
63 #define RESERVED_HOTPLUG_BUSES 1
64 #define isHotPlugCapable(slotCap)  ((slotCap) & (1<<6))
65 #define CONFIG_OFFSET_ADDR(bus, device, function, reg) (((bus)<<20) | (device)<<15 | (function<<12) | (reg))
66 #define BRIDGE_BASEREG(reg)  (0xFFF0 & ((reg)>>16))
67 
68 #define MISCCTRLSTS_0_OFFSET  0x188
69 #define ENABLE_ACPI_MODE_FOR_HOTPLUG  (1 << 3)
70 
71 /* Bit encodings for Command Register */
72 #define IO_SPACE_ENABLE               0x0001
73 #define MEMORY_SPACE_ENABLE           0x0002
74 #define BUS_MASTER_ENABLE             0x0004
75 
76 /* Bit encodings for Status Register */
77 #define PCI_CAPABILITIES_LIST        0x0010
78 #define PCI_RECEIVED_TARGET_ABORT    0x1000
79 #define PCI_RECEIVED_MASTER_ABORT    0x2000
80 #define PCI_SIGNALED_SYSTEM_ERROR    0x4000
81 #define PCI_DETECTED_PARITY_ERROR    0x8000
82 
83 /* Capability IDs */
84 #define CAPABILITY_ID_POWER_MANAGEMENT  0x01
85 #define CAPABILITY_ID_MSI   0x05
86 #define CAPABILITY_ID_PCI_EXPRESS   0x10
87 #define CAPABILITY_ID_MSIX  0x11
88 
89 #define  PCI_MSIX_ENABLE (1 << 15)          /* bit 15 of MSIX Message Control */
90 #define  PCI_MSIX_FUNCTION_MASK (1 << 14)   /* bit 14 of MSIX Message Control */
91 
92 /* extended capability */
93 #define EXTENDED_CAPABILITY_OFFSET 0x100
94 #define DEVICE_SERIAL_NUMBER_CAP_ID  0x3
95 
96 #define BAR_SIZE (1 << 20)
97 
98 struct pci_enhanced_capability_header {
99 	uint16_t capability_id;
100 	uint16_t version: 4;
101 	uint16_t next: 12;
102 };
103 
104 struct serial_number_capability {
105 	struct pci_enhanced_capability_header hdr;
106 	uint32_t sn_low;
107 	uint32_t sn_hi;
108 };
109 
110 struct pci_header_common {
111 	uint16_t  vendor_id;
112 	uint16_t  device_id;
113 	uint16_t  command;
114 	uint16_t  status;
115 	uint32_t  rev_class;
116 	uint8_t   cache_line_size;
117 	uint8_t   master_lat_timer;
118 	uint8_t   header_type;
119 	uint8_t   BIST;
120 	uint8_t   rsvd12[36];
121 	uint8_t   cap_pointer;
122 	uint8_t   rsvd53[7];
123 	uint8_t   int_line;
124 	uint8_t   int_pin;
125 	uint8_t   rsvd62[2];
126 };
127 
128 struct pci_header_zero {
129 	uint16_t  vendor_id;
130 	uint16_t  device_id;
131 	uint16_t  command;
132 	uint16_t  status;
133 	uint32_t  rev_class;
134 	uint8_t   cache_line_size;
135 	uint8_t   master_lat_timer;
136 	uint8_t   header_type;
137 	uint8_t   BIST;
138 	uint32_t  BAR[6];
139 	uint32_t  carbus_cis_pointer;
140 	uint16_t  ssvid;
141 	uint16_t  ssid;
142 	uint32_t  exp_rom_base_addr;
143 	uint8_t   cap_pointer;
144 	uint8_t   rsvd53[7];
145 	uint8_t   intLine;
146 	uint8_t   int_pin;
147 	uint8_t   min_gnt;
148 	uint8_t   max_lat;
149 };
150 
151 struct pci_header_one {
152 	uint16_t  vendor_id;
153 	uint16_t  device_id;
154 	uint16_t  command;
155 	uint16_t  status;
156 	uint32_t  rev_class;
157 	uint8_t   cache_line_size;
158 	uint8_t   master_lat_timer;
159 	uint8_t   header_type;
160 	uint8_t   BIST;
161 	uint32_t  BAR[2];
162 	uint8_t   primary;
163 	uint8_t   secondary;
164 	uint8_t   subordinate;
165 	uint8_t   secondary_lat_timer;
166 	uint8_t   io_base;
167 	uint8_t   io_limit;
168 	uint16_t  secondary_status;
169 	uint16_t  mem_base;
170 	uint16_t  mem_limit;
171 	uint16_t  prefetch_base;
172 	uint16_t  prefetch_limit;
173 	uint32_t  prefetch_base_upper;
174 	uint32_t  prefetch_limit_upper;
175 	uint16_t  io_base_upper;
176 	uint16_t  io_limit_upper;
177 	uint8_t   cap_pointer;
178 	uint8_t   rsvd53[3];
179 	uint32_t  exp_romBase_addr;
180 	uint8_t   int_line;
181 	uint8_t   int_pin;
182 	uint16_t  bridge_control;
183 };
184 
185 struct pci_capabilities_header {
186 	uint8_t   capability_id;
187 	uint8_t   next;
188 };
189 
190 /*
191  * MSI capability structure for msi interrupt vectors
192  */
193 #define MAX_MSIX_TABLE_SIZE 0x800
194 #define MSIX_ENTRY_VECTOR_CTRL_MASKBIT 1
195 #define PORT_INT_VECTOR  0;
196 #define CLEAR_MSIX_DESTINATION_ID 0xfff00fff
197 struct pci_msi_cap {
198 	struct pci_capabilities_header header;
199 	union _MsiControl {
200 		uint16_t as_uint16_t;
201 		struct _PCI_MSI_MESSAGE_CONTROL {
202 			uint16_t msi_enable : 1;
203 			uint16_t multiple_message_capable : 3;
204 			uint16_t multiple_message_enable : 3;
205 			uint16_t capable_of_64bits : 1;
206 			uint16_t per_vector_mask_capable : 1;
207 			uint16_t reserved : 7;
208 		} bit;
209 	} message_control;
210 	union {
211 		struct _PCI_MSI_MESSAGE_ADDRESS {
212 			uint32_t reserved : 2;
213 			uint32_t address : 30;
214 		} reg;
215 		uint32_t  raw;
216 	} message_address_lower;
217 	union {
218 		struct _Option32_bit {
219 			uint16_t message_data;
220 		} option32_bit;
221 		struct _Option64_bit {
222 			uint32_t  message_address_upper;
223 			uint16_t  message_data;
224 			uint16_t  reserved;
225 			uint32_t  mask_bits;
226 			uint32_t  pending_bits;
227 		} option64_bit;
228 	};
229 };
230 
231 struct pcix_table_pointer {
232 	union {
233 		struct {
234 			uint32_t BaseIndexRegister : 3;
235 			uint32_t Reserved : 29;
236 		} TableBIR;
237 		uint32_t  TableOffset;
238 	};
239 };
240 
241 struct pci_msix_capability {
242 	struct pci_capabilities_header header;
243 	union _MsixControl {
244 		uint16_t as_uint16_t;
245 		struct msg_ctrl {
246 			uint16_t table_size : 11;
247 			uint16_t reserved : 3;
248 			uint16_t function_mask : 1;
249 			uint16_t msix_enable : 1;
250 		} bit;
251 	} message_control;
252 
253 	struct pcix_table_pointer message_table;
254 	struct pcix_table_pointer   pba_table;
255 };
256 
257 struct pci_msix_table_entry {
258 	volatile uint32_t  message_addr_lo;
259 	volatile uint32_t  message_addr_hi;
260 	volatile uint32_t  message_data;
261 	volatile uint32_t  vector_control;
262 };
263 
264 /*
265  * Pci express capability
266  */
267 enum PciExpressCapabilities {
268 	/* 0001b Legacy PCI Express Endpoint            */
269 	LegacyEndpoint       = 0x1,
270 	/* 0000b PCI Express Endpoint                   */
271 	ExpressEndpoint      = 0x0,
272 	/* 0100b Root Port of PCI Express Root Complex* */
273 	RootComplexRootPort  = 0x4,
274 	/* 0101b Upstream Port of PCI Express Switch*   */
275 	SwitchUpstreamPort   = 0x5,
276 	/* 0110b Downstream Port of PCI Express Switch* */
277 	SwitchDownStreamPort = 0x6,
278 	/* 0111b PCI Express to PCI/PCI-X Bridge*       */
279 	ExpressToPciBridge   = 0x7,
280 	/* 1000b PCI/PCI-X to PCI Express Bridge*       */
281 	PciToExpressBridge   = 0x8,
282 	/* 1001b Root Complex Integrated Endpoint       */
283 	RCIntegratedEndpoint = 0x9,
284 	/* 1010b Root Complex Event Collector           */
285 	RootComplexEventCollector = 0xa,
286 	InvalidCapability = 0xff
287 };
288 
289 union express_capability_register {
290 	struct {
291 		uint16_t capability_version : 4;
292 		uint16_t device_type : 4;
293 		uint16_t slot_implemented : 1;
294 		uint16_t interrupt_message_number : 5;
295 		uint16_t rsv : 2;
296 	} bit_field;
297 	uint16_t as_uint16_t;
298 };
299 
300 union express_slot_capabilities_register {
301 	struct {
302 		uint32_t attention_button_present : 1;
303 		uint32_t power_controller_present : 1;
304 		uint32_t MRL_sensor_present : 1;
305 		uint32_t attention_indicator_present : 1;
306 		uint32_t power_indicator_present : 1;
307 		uint32_t hotplug_surprise : 1;
308 		uint32_t hotplug_capable : 1;
309 		uint32_t slot_power_limit : 8;
310 		uint32_t slotPower_limit_scale : 2;
311 		uint32_t electromechanical_lock_present : 1;
312 		uint32_t no_command_completed_support : 1;
313 		uint32_t physical_slot_number : 13;
314 	} bit_field;
315 	uint32_t as_uint32_t;
316 };
317 
318 union express_slot_control_register {
319 	struct {
320 		uint16_t attention_button_enable : 1;
321 		uint16_t power_fault_detect_enable : 1;
322 		uint16_t MRLsensor_enable : 1;
323 		uint16_t presence_detect_enable : 1;
324 		uint16_t command_completed_enable : 1;
325 		uint16_t hotplug_interrupt_enable : 1;
326 		uint16_t attention_indicator_control : 2;
327 		uint16_t power_indicator_control : 2;
328 		uint16_t power_controller_control : 1;
329 		uint16_t electromechanical_lockcontrol : 1;
330 		uint16_t datalink_state_change_enable : 1;
331 		uint16_t Rsvd : 3;
332 	} bit_field;
333 	uint16_t as_uint16_t;
334 };
335 
336 union express_slot_status_register {
337 	struct {
338 		uint16_t attention_button_pressed : 1;
339 		uint16_t power_fault_detected : 1;
340 		uint16_t MRL_sensor_changed : 1;
341 		uint16_t presence_detect_changed : 1;
342 		uint16_t command_completed : 1;
343 		uint16_t MRL_sensor_state : 1;
344 		uint16_t presence_detect_state : 1;
345 		uint16_t electromechanical_lock_engaged : 1;
346 		uint16_t datalink_state_changed : 1;
347 		uint16_t rsvd : 7;
348 	} bit_field;
349 	uint16_t as_uint16_t;
350 };
351 
352 union express_root_control_register {
353 	struct {
354 		uint16_t CorrectableSerrEnable : 1;
355 		uint16_t NonFatalSerrEnable : 1;
356 		uint16_t FatalSerrEnable : 1;
357 		uint16_t PMEInterruptEnable : 1;
358 		uint16_t CRSSoftwareVisibilityEnable : 1;
359 		uint16_t Rsvd : 11;
360 	} bit_field;
361 	uint16_t as_uint16_t;
362 };
363 
364 union express_link_capability_register {
365 	struct {
366 		uint32_t maximum_link_speed : 4;
367 		uint32_t maximum_link_width : 6;
368 		uint32_t active_state_pms_support : 2;
369 		uint32_t l0_exit_latency : 3;
370 		uint32_t l1_exit_latency : 3;
371 		uint32_t clock_power_management : 1;
372 		uint32_t surprise_down_error_reporting_capable : 1;
373 		uint32_t datalink_layer_active_reporting_capable : 1;
374 		uint32_t link_bandwidth_notification_capability : 1;
375 		uint32_t aspm_optionality_compliance : 1;
376 		uint32_t rsvd : 1;
377 		uint32_t port_number : 8;
378 	} bit_field;
379 	uint32_t as_uint32_t;
380 };
381 
382 union express_link_control_register {
383 	struct {
384 		uint16_t active_state_pm_control : 2;
385 		uint16_t rsvd1 : 1;
386 		uint16_t read_completion_boundary : 1;
387 		uint16_t link_disable : 1;
388 		uint16_t retrain_link : 1;
389 		uint16_t common_clock_config : 1;
390 		uint16_t extended_synch : 1;
391 		uint16_t enable_clock_power_management : 1;
392 		uint16_t rsvd2 : 7;
393 	} bit_field;
394 	uint16_t as_uint16_t;
395 };
396 
397 union express_link_status_register {
398 	struct {
399 		uint16_t link_speed : 4;
400 		uint16_t link_width : 6;
401 		uint16_t undefined : 1;
402 		uint16_t link_training : 1;
403 		uint16_t slot_clock_config : 1;
404 		uint16_t datalink_layer_active : 1;
405 		uint16_t asvd : 2;
406 	} bit_field;
407 	uint16_t as_uint16_t;
408 };
409 
410 struct pci_express_cap {
411 	uint8_t capid;
412 	uint8_t next_cap;
413 	union express_capability_register express_cap_register;
414 	uint32_t device_cap;
415 	uint16_t device_control;
416 	uint16_t device_status;
417 	union express_link_capability_register link_cap;
418 	union express_link_control_register link_control;
419 	union express_link_status_register link_status;
420 	union express_slot_capabilities_register slot_cap;
421 	union express_slot_control_register slot_control;
422 	union express_slot_status_register slot_status;
423 	uint32_t root_status;
424 	uint32_t deviceCap2;
425 	uint16_t deviceControl2;
426 	uint16_t deviceStatus2;
427 	uint32_t linkCap2;
428 	uint16_t linkControl2;
429 	uint16_t linkStatus2;
430 	uint32_t slotCap2;
431 	uint16_t slotControl2;
432 	uint16_t slotStatus2;
433 };
434 
435 struct pci_msix_cap {
436 	uint8_t   cap_idd;
437 	uint8_t   next_cap;
438 	uint16_t  msg_control_reg;
439 	uint32_t  msix_table_offset;
440 	uint32_t  pba_offset;
441 };
442 
443 struct pci_header {
444 	union {
445 		struct pci_header_common common;
446 		struct pci_header_zero zero;
447 		struct pci_header_one one;
448 	};
449 };
450 
451 #endif /* VMD_SPEC_H */
452