summaryrefslogtreecommitdiffstats
path: root/src/spdk/lib/vmd/vmd_spec.h
blob: 07a4a113d5eaab1e03cca83d1109ca849758fc82 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
/*-
 *   BSD LICENSE
 *
 *   Copyright (c) Intel Corporation.
 *   All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
 *   are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


#ifndef VMD_SPEC_H
#define VMD_SPEC_H

#define MAX_VMD_SUPPORTED 48  /* max number of vmd controllers in a system - */
#define VMD_DOMAIN_START 0x201D

#define PCI_INVALID_VENDORID 0xFFFF
#define ONE_MB (1<<20)
#define PCI_OFFSET_OF(object, member)  ((uint32_t)&((object*)0)->member)
#define TWOS_COMPLEMENT(value) (~(value) + 1)

#define VMD_UPPER_BASE_SIGNATURE  0xFFFFFFEF
#define VMD_UPPER_LIMIT_SIGNATURE 0xFFFFFFED

/*
 *  BAR assignment constants
 */
#define  PCI_DWORD_SHIFT            32
#define  PCI_BASE_ADDR_MASK         0xFFFFFFF0
#define  PCI_BAR_MEMORY_MASK        0x0000000F
#define  PCI_BAR_MEMORY_MEM_IND     0x1
#define  PCI_BAR_MEMORY_TYPE        0x6
#define  PCI_BAR_MEMORY_PREFETCH    0x8
#define  PCI_BAR_MEMORY_TYPE_32     0x0
#define  PCI_BAR_MEMORY_TYPE_64     0x4
#define  PCI_BAR_MB_MASK            0xFFFFF
#define  PCI_PCI_BRIDGE_ADDR_DEF    0xFFF0
#define  PCI_BRIDGE_MEMORY_MASK     0xFFF0
#define  PCI_BRIDGE_PREFETCH_64     0x0001
#define  PCI_BRIDGE_MEMORY_SHIFT    16
#define  PCI_CONFIG_ACCESS_DELAY    500

#define PCI_MAX_CFG_SIZE            0x1000

#define PCI_HEADER_TYPE             0x0e
#define PCI_HEADER_TYPE_NORMAL   0
#define PCI_HEADER_TYPE_BRIDGE   1
#define PCI_MULTI_FUNCTION 0x80

#define PCI_COMMAND_MEMORY 0x2
#define PCI_COMMAND_MASTER 0x4

#define PCIE_TYPE_FLAGS 0xf0
#define PCIE_TYPE_SHIFT 4
#define PCIE_TYPE_ROOT_PORT 0x4
#define PCIE_TYPE_DOWNSTREAM 0x6

#define PCI_CLASS_STORAGE_EXPRESS   0x010802
#define ADDR_ELEM_COUNT 32
#define PCI_MAX_BUS_NUMBER 0x7F
#define RESERVED_HOTPLUG_BUSES 1
#define isHotPlugCapable(slotCap)  ((slotCap) & (1<<6))
#define CONFIG_OFFSET_ADDR(bus, device, function, reg) (((bus)<<20) | (device)<<15 | (function<<12) | (reg))
#define BRIDGE_BASEREG(reg)  (0xFFF0 & ((reg)>>16))

#define MISCCTRLSTS_0_OFFSET  0x188
#define ENABLE_ACPI_MODE_FOR_HOTPLUG  (1 << 3)

/* Bit encodings for Command Register */
#define IO_SPACE_ENABLE               0x0001
#define MEMORY_SPACE_ENABLE           0x0002
#define BUS_MASTER_ENABLE             0x0004

/* Bit encodings for Status Register */
#define PCI_CAPABILITIES_LIST        0x0010
#define PCI_RECEIVED_TARGET_ABORT    0x1000
#define PCI_RECEIVED_MASTER_ABORT    0x2000
#define PCI_SIGNALED_SYSTEM_ERROR    0x4000
#define PCI_DETECTED_PARITY_ERROR    0x8000

/* Capability IDs */
#define CAPABILITY_ID_POWER_MANAGEMENT  0x01
#define CAPABILITY_ID_MSI   0x05
#define CAPABILITY_ID_PCI_EXPRESS   0x10
#define CAPABILITY_ID_MSIX  0x11

#define  PCI_MSIX_ENABLE (1 << 15)          /* bit 15 of MSIX Message Control */
#define  PCI_MSIX_FUNCTION_MASK (1 << 14)   /* bit 14 of MSIX Message Control */

/* extended capability */
#define EXTENDED_CAPABILITY_OFFSET 0x100
#define DEVICE_SERIAL_NUMBER_CAP_ID  0x3

#define BAR_SIZE (1 << 20)

struct pci_enhanced_capability_header {
	uint16_t capability_id;
	uint16_t version: 4;
	uint16_t next: 12;
};

struct serial_number_capability {
	struct pci_enhanced_capability_header hdr;
	uint32_t sn_low;
	uint32_t sn_hi;
};

struct pci_header_common {
	uint16_t  vendor_id;
	uint16_t  device_id;
	uint16_t  command;
	uint16_t  status;
	uint32_t  rev_class;
	uint8_t   cache_line_size;
	uint8_t   master_lat_timer;
	uint8_t   header_type;
	uint8_t   BIST;
	uint8_t   rsvd12[36];
	uint8_t   cap_pointer;
	uint8_t   rsvd53[7];
	uint8_t   int_line;
	uint8_t   int_pin;
	uint8_t   rsvd62[2];
};

struct pci_header_zero {
	uint16_t  vendor_id;
	uint16_t  device_id;
	uint16_t  command;
	uint16_t  status;
	uint32_t  rev_class;
	uint8_t   cache_line_size;
	uint8_t   master_lat_timer;
	uint8_t   header_type;
	uint8_t   BIST;
	uint32_t  BAR[6];
	uint32_t  carbus_cis_pointer;
	uint16_t  ssvid;
	uint16_t  ssid;
	uint32_t  exp_rom_base_addr;
	uint8_t   cap_pointer;
	uint8_t   rsvd53[7];
	uint8_t   intLine;
	uint8_t   int_pin;
	uint8_t   min_gnt;
	uint8_t   max_lat;
};

struct pci_header_one {
	uint16_t  vendor_id;
	uint16_t  device_id;
	uint16_t  command;
	uint16_t  status;
	uint32_t  rev_class;
	uint8_t   cache_line_size;
	uint8_t   master_lat_timer;
	uint8_t   header_type;
	uint8_t   BIST;
	uint32_t  BAR[2];
	uint8_t   primary;
	uint8_t   secondary;
	uint8_t   subordinate;
	uint8_t   secondary_lat_timer;
	uint8_t   io_base;
	uint8_t   io_limit;
	uint16_t  secondary_status;
	uint16_t  mem_base;
	uint16_t  mem_limit;
	uint16_t  prefetch_base;
	uint16_t  prefetch_limit;
	uint32_t  prefetch_base_upper;
	uint32_t  prefetch_limit_upper;
	uint16_t  io_base_upper;
	uint16_t  io_limit_upper;
	uint8_t   cap_pointer;
	uint8_t   rsvd53[3];
	uint32_t  exp_romBase_addr;
	uint8_t   int_line;
	uint8_t   int_pin;
	uint16_t  bridge_control;
};

struct pci_capabilities_header {
	uint8_t   capability_id;
	uint8_t   next;
};

/*
 * MSI capability structure for msi interrupt vectors
 */
#define MAX_MSIX_TABLE_SIZE 0x800
#define MSIX_ENTRY_VECTOR_CTRL_MASKBIT 1
#define PORT_INT_VECTOR  0;
#define CLEAR_MSIX_DESTINATION_ID 0xfff00fff
struct pci_msi_cap {
	struct pci_capabilities_header header;
	union _MsiControl {
		uint16_t as_uint16_t;
		struct _PCI_MSI_MESSAGE_CONTROL {
			uint16_t msi_enable : 1;
			uint16_t multiple_message_capable : 3;
			uint16_t multiple_message_enable : 3;
			uint16_t capable_of_64bits : 1;
			uint16_t per_vector_mask_capable : 1;
			uint16_t reserved : 7;
		} bit;
	} message_control;
	union {
		struct _PCI_MSI_MESSAGE_ADDRESS {
			uint32_t reserved : 2;
			uint32_t address : 30;
		} reg;
		uint32_t  raw;
	} message_address_lower;
	union {
		struct _Option32_bit {
			uint16_t message_data;
		} option32_bit;
		struct _Option64_bit {
			uint32_t  message_address_upper;
			uint16_t  message_data;
			uint16_t  reserved;
			uint32_t  mask_bits;
			uint32_t  pending_bits;
		} option64_bit;
	};
};

struct pcix_table_pointer {
	union {
		struct {
			uint32_t BaseIndexRegister : 3;
			uint32_t Reserved : 29;
		} TableBIR;
		uint32_t  TableOffset;
	};
};

struct pci_msix_capability {
	struct pci_capabilities_header header;
	union _MsixControl {
		uint16_t as_uint16_t;
		struct msg_ctrl {
			uint16_t table_size : 11;
			uint16_t reserved : 3;
			uint16_t function_mask : 1;
			uint16_t msix_enable : 1;
		} bit;
	} message_control;

	struct pcix_table_pointer message_table;
	struct pcix_table_pointer   pba_table;
};

struct pci_msix_table_entry {
	volatile uint32_t  message_addr_lo;
	volatile uint32_t  message_addr_hi;
	volatile uint32_t  message_data;
	volatile uint32_t  vector_control;
};

/*
 * Pci express capability
 */
enum PciExpressCapabilities {
	/* 0001b Legacy PCI Express Endpoint            */
	LegacyEndpoint       = 0x1,
	/* 0000b PCI Express Endpoint                   */
	ExpressEndpoint      = 0x0,
	/* 0100b Root Port of PCI Express Root Complex* */
	RootComplexRootPort  = 0x4,
	/* 0101b Upstream Port of PCI Express Switch*   */
	SwitchUpstreamPort   = 0x5,
	/* 0110b Downstream Port of PCI Express Switch* */
	SwitchDownStreamPort = 0x6,
	/* 0111b PCI Express to PCI/PCI-X Bridge*       */
	ExpressToPciBridge   = 0x7,
	/* 1000b PCI/PCI-X to PCI Express Bridge*       */
	PciToExpressBridge   = 0x8,
	/* 1001b Root Complex Integrated Endpoint       */
	RCIntegratedEndpoint = 0x9,
	/* 1010b Root Complex Event Collector           */
	RootComplexEventCollector = 0xa,
	InvalidCapability = 0xff
};

union express_capability_register {
	struct {
		uint16_t capability_version : 4;
		uint16_t device_type : 4;
		uint16_t slot_implemented : 1;
		uint16_t interrupt_message_number : 5;
		uint16_t rsv : 2;
	} bit_field;
	uint16_t as_uint16_t;
};

union express_slot_capabilities_register {
	struct {
		uint32_t attention_button_present : 1;
		uint32_t power_controller_present : 1;
		uint32_t MRL_sensor_present : 1;
		uint32_t attention_indicator_present : 1;
		uint32_t power_indicator_present : 1;
		uint32_t hotplug_surprise : 1;
		uint32_t hotplug_capable : 1;
		uint32_t slot_power_limit : 8;
		uint32_t slotPower_limit_scale : 2;
		uint32_t electromechanical_lock_present : 1;
		uint32_t no_command_completed_support : 1;
		uint32_t physical_slot_number : 13;
	} bit_field;
	uint32_t as_uint32_t;
};

union express_slot_control_register {
	struct {
		uint16_t attention_button_enable : 1;
		uint16_t power_fault_detect_enable : 1;
		uint16_t MRLsensor_enable : 1;
		uint16_t presence_detect_enable : 1;
		uint16_t command_completed_enable : 1;
		uint16_t hotplug_interrupt_enable : 1;
		uint16_t attention_indicator_control : 2;
		uint16_t power_indicator_control : 2;
		uint16_t power_controller_control : 1;
		uint16_t electromechanical_lockcontrol : 1;
		uint16_t datalink_state_change_enable : 1;
		uint16_t Rsvd : 3;
	} bit_field;
	uint16_t as_uint16_t;
};

union express_slot_status_register {
	struct {
		uint16_t attention_button_pressed : 1;
		uint16_t power_fault_detected : 1;
		uint16_t MRL_sensor_changed : 1;
		uint16_t presence_detect_changed : 1;
		uint16_t command_completed : 1;
		uint16_t MRL_sensor_state : 1;
		uint16_t presence_detect_state : 1;
		uint16_t electromechanical_lock_engaged : 1;
		uint16_t datalink_state_changed : 1;
		uint16_t rsvd : 7;
	} bit_field;
	uint16_t as_uint16_t;
};

union express_root_control_register {
	struct {
		uint16_t CorrectableSerrEnable : 1;
		uint16_t NonFatalSerrEnable : 1;
		uint16_t FatalSerrEnable : 1;
		uint16_t PMEInterruptEnable : 1;
		uint16_t CRSSoftwareVisibilityEnable : 1;
		uint16_t Rsvd : 11;
	} bit_field;
	uint16_t as_uint16_t;
};

union express_link_capability_register {
	struct {
		uint32_t maximum_link_speed : 4;
		uint32_t maximum_link_width : 6;
		uint32_t active_state_pms_support : 2;
		uint32_t l0_exit_latency : 3;
		uint32_t l1_exit_latency : 3;
		uint32_t clock_power_management : 1;
		uint32_t surprise_down_error_reporting_capable : 1;
		uint32_t datalink_layer_active_reporting_capable : 1;
		uint32_t link_bandwidth_notification_capability : 1;
		uint32_t aspm_optionality_compliance : 1;
		uint32_t rsvd : 1;
		uint32_t port_number : 8;
	} bit_field;
	uint32_t as_uint32_t;
};

union express_link_control_register {
	struct {
		uint16_t active_state_pm_control : 2;
		uint16_t rsvd1 : 1;
		uint16_t read_completion_boundary : 1;
		uint16_t link_disable : 1;
		uint16_t retrain_link : 1;
		uint16_t common_clock_config : 1;
		uint16_t extended_synch : 1;
		uint16_t enable_clock_power_management : 1;
		uint16_t rsvd2 : 7;
	} bit_field;
	uint16_t as_uint16_t;
};

union express_link_status_register {
	struct {
		uint16_t link_speed : 4;
		uint16_t link_width : 6;
		uint16_t undefined : 1;
		uint16_t link_training : 1;
		uint16_t slot_clock_config : 1;
		uint16_t datalink_layer_active : 1;
		uint16_t asvd : 2;
	} bit_field;
	uint16_t as_uint16_t;
};

struct pci_express_cap {
	uint8_t capid;
	uint8_t next_cap;
	union express_capability_register express_cap_register;
	uint32_t device_cap;
	uint16_t device_control;
	uint16_t device_status;
	union express_link_capability_register link_cap;
	union express_link_control_register link_control;
	union express_link_status_register link_status;
	union express_slot_capabilities_register slot_cap;
	union express_slot_control_register slot_control;
	union express_slot_status_register slot_status;
	uint32_t root_status;
	uint32_t deviceCap2;
	uint16_t deviceControl2;
	uint16_t deviceStatus2;
	uint32_t linkCap2;
	uint16_t linkControl2;
	uint16_t linkStatus2;
	uint32_t slotCap2;
	uint16_t slotControl2;
	uint16_t slotStatus2;
};

struct pci_msix_cap {
	uint8_t   cap_idd;
	uint8_t   next_cap;
	uint16_t  msg_control_reg;
	uint32_t  msix_table_offset;
	uint32_t  pba_offset;
};

struct pci_header {
	union {
		struct pci_header_common common;
		struct pci_header_zero zero;
		struct pci_header_one one;
	};
};

#endif /* VMD_SPEC_H */