2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2009, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2009, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #ifndef __DEVICES_PCI_TYPES_H__
21 #define __DEVICES_PCI_TYPES_H__
24 #include <palacios/vmm_types.h>
26 // struct pci_device_config
27 struct pci_config_header {
40 uint8_t cache_line_size;
42 uint8_t header_type; // bits 6-0: 00: other, 01: pci-pci bridge, 02: pci-cardbus; bit 7: 1=multifunction
52 uint32_t cardbus_cis_pointer;
53 uint16_t subsystem_vendor_id;
54 uint16_t subsystem_id;
55 uint32_t expansion_rom_address;
56 uint8_t cap_ptr; // capabilities list offset in config space
59 uint8_t intr_line; // 00=none, 01=IRQ1, etc.
60 uint8_t intr_pin; // 00=none, otherwise INTA# to INTD#
61 uint8_t min_grant; // min busmaster time - units of 250ns
62 uint8_t max_latency; // units of 250ns - busmasters
63 } __attribute__((packed));
70 uint16_t io_enable : 1;
71 uint16_t mem_enable : 1;
72 uint16_t dma_enable : 1;
73 uint16_t special_cycles : 1;
74 uint16_t mem_wr_inv_enable : 1;
75 uint16_t vga_snoop : 1;
76 uint16_t parity_err_resp : 1;
78 uint16_t serr_enable : 1;
79 uint16_t fast_b2b_enable : 1;
80 uint16_t intx_disable : 1;
82 } __attribute__((packed));
83 } __attribute__((packed));
85 } __attribute__((packed));
88 typedef enum { PCI_CLASS_PRE2 = 0x00,
89 PCI_CLASS_STORAGE = 0x01,
90 PCI_CLASS_NETWORK = 0x02,
91 PCI_CLASS_DISPLAY = 0x03,
92 PCI_CLASS_MMEDIA = 0x04,
93 PCI_CLASS_MEMORY = 0x05,
94 PCI_CLASS_BRIDGE = 0x06,
95 PCI_CLASS_COMM_CTRL = 0x07,
96 PCI_CLASS_BASE_PERIPH = 0x08,
97 PCI_CLASS_INPUT = 0x09,
98 PCI_CLASS_DOCK = 0x0a,
99 PCI_CLASS_PROC = 0x0b,
100 PCI_CLASS_SERIAL = 0x0c,
101 PCI_CLASS_MISC = 0xff } pci_class_t;
103 typedef enum { PCI_STORAGE_SUBCLASS_SCSI = 0x00,
104 PCI_STORAGE_SUBCLASS_IDE = 0x01,
105 PCI_STORAGE_SUBCLASS_FLOPPY = 0x02,
106 PCI_STORAGE_SUBCLASS_IPI = 0x03,
107 PCI_STORAGE_SUBCLASS_RAID = 0x04,
108 PCI_STORAGE_SUBCLASS_SATA = 0x06,
109 PCI_STORAGE_SUBCLASS_SAS = 0x07,
110 PCI_STORAGE_SUBCLASS_OTHER = 0x80 } pci_storage_subclass_t;
114 typedef enum { PCI_NET_SUBCLASS_ETHER = 0x00,
115 PCI_NET_SUBCLASS_TOKRING = 0x01,
116 PCI_NET_SUBCLASS_FDDI = 0x02,
117 PCI_NET_SUBCLASS_ATM = 0x03,
118 PCI_NET_SUBCLASS_OTHER = 0x80 } pci_network_subclass_t;
120 typedef enum { PCI_DISPLAY_SUBCLASS_VGA = 0x00,
121 PCI_DISPLAY_SUBCLASS_XGA = 0x01,
122 PCI_DISPLAY_SUBCLASS_OTHER = 0x80 } pci_display_subclass_t;
124 typedef enum { PCI_MMEDIA_SUBCLASS_VIDEO = 0x00,
125 PCI_MMEDIA_SUBCLASS_AUDIO = 0x01,
126 PCI_MMEDIA_SUBCLASS_OTHER = 0x80 } pci_multimedia_subclass_t;
128 typedef enum { PCI_MEM_SUBCLASS_RAM = 0x00,
129 PCI_MEM_SUBCLASS_FLASH = 0x01,
130 PCI_MEM_SUBCLASS_OTHER = 0x80 } pci_memory_subclass_t;
132 typedef enum { PCI_BRIDGE_SUBCLASS_HOST_PCI = 0x00,
133 PCI_BRIDGE_SUBCLASS_PCI_ISA = 0x01,
134 PCI_BRIDGE_SUBCLASS_PCI_EISA = 0x02,
135 PCI_BRIDGE_SUBCLASS_PCI_MICRO = 0x03,
136 PCI_BRIDGE_SUBCLASS_PCI_PCI = 0x04,
137 PCI_BRIDGE_SUBCLASS_PCI_PCMCIA = 0x05,
138 PCI_BRIDGE_SUBCLASS_PCI_NUBUS = 0x06,
139 PCI_BRIDGE_SUBCLASS_PCI_CARDBUS = 0x07,
140 PCI_BRIDGE_SUBCLASS_PCI_OTHER = 0x80 } pci_bridge_subclass_t;
145 struct pci_class_desc {
150 static struct pci_class_desc pci_class_descriptions[] = {
151 { 0x0100, "SCSI controller"},
152 { 0x0101, "IDE controller"},
153 { 0x0102, "Floppy controller"},
154 { 0x0103, "IPI controller"},
155 { 0x0104, "RAID controller"},
156 { 0x0106, "SATA controller"},
157 { 0x0107, "SAS controller"},
158 { 0x0180, "Storage controller"},
159 { 0x0200, "Ethernet controller"},
160 { 0x0201, "Token Ring controller"},
161 { 0x0202, "FDDI controller"},
162 { 0x0203, "ATM controller"},
163 { 0x0280, "Network controller"},
164 { 0x0300, "VGA controller"},
165 { 0x0301, "XGA controller"},
166 { 0x0302, "3D controller"},
167 { 0x0380, "Display controller"},
168 { 0x0400, "Video controller"},
169 { 0x0401, "Audio controller"},
171 { 0x0480, "Multimedia controller"},
172 { 0x0500, "RAM controller"},
173 { 0x0501, "Flash controller"},
174 { 0x0580, "Memory controller"},
175 { 0x0600, "Host bridge"},
176 { 0x0601, "ISA bridge"},
177 { 0x0602, "EISA bridge"},
178 { 0x0603, "MC bridge"},
179 { 0x0604, "PCI bridge"},
180 { 0x0605, "PCMCIA bridge"},
181 { 0x0606, "NUBUS bridge"},
182 { 0x0607, "CARDBUS bridge"},
183 { 0x0608, "RACEWAY bridge"},
185 { 0x0c03, "USB controller"},
197 uint32_t dst_mode : 1;
198 uint32_t redir_hint : 1;
201 uint32_t fixaddr : 12;
202 } __attribute__((packed));
203 } __attribute__((packed));
204 } __attribute__((packed));
212 uint16_t del_mode : 3;
215 uint16_t trig_mode : 1;
216 } __attribute__((packed));;
217 } __attribute__((packed));
218 } __attribute__((packed));
221 struct msi_msg_ctrl {
225 uint16_t msi_enable : 1;
226 uint16_t mult_msg_capable : 3;
227 uint16_t mult_msg_enable : 3;
228 uint16_t cap_64bit : 1;
229 uint16_t per_vect_mask : 1;
231 } __attribute__((packed));
232 } __attribute__((packed));
233 } __attribute__((packed));
236 struct msi32_msg_addr {
237 struct msi_msg_ctrl msg_ctrl;
238 struct msi_addr addr;
239 struct msi_data data;
240 } __attribute__((packed));
243 struct msi64_msg_addr {
244 struct msi_msg_ctrl msg_ctrl;
245 struct msi_addr addr;
247 struct msi_data data;
248 } __attribute__((packed));
251 struct msi64_pervec_msg_addr {
252 struct msi_msg_ctrl msg_ctrl;
253 struct msi_addr addr;
255 struct msi_data data;
259 } __attribute__((packed));
262 struct msix_msg_ctrl {
263 uint16_t table_size : 11;
265 uint16_t msix_enable : 1;
266 } __attribute__((packed));
269 struct msix_msg_ctrl msg_ctrl;
272 uint32_t table_offset : 29;
273 } __attribute__((packed));
278 struct msi_data data;
279 struct msi_addr addr;
280 } __attribute__((packed)) entries[0];
281 } __attribute__((packed));
285 // See PCI power management specification (1.2)
288 uint16_t version : 3;
289 uint16_t pme_clock : 1;
292 uint16_t aux_current : 3;
293 uint16_t d1_support : 1;
294 uint16_t d2_support : 1;
295 uint16_t pme_support : 5;
296 } __attribute__((packed)) pmc;
299 uint16_t power_state : 2;
301 uint16_t no_soft_reset : 1;
304 uint16_t data_select : 4;
305 uint16_t data_scale : 2;
306 uint16_t pme_status : 1;
307 } __attribute__((packed)) pmcsr;
313 } __attribute__((packed)) pmcsr_bse;
316 } __attribute__((packed));
319 struct pcie_cap_reg {
320 uint16_t version : 4;
322 uint16_t slot_impl : 1;
323 uint16_t irq_msg_num : 5;
325 } __attribute__((packed));
328 struct pcie_cap_reg pcie_cap;
333 uint32_t max_payload : 3;
334 uint32_t phantom_fns : 2;
335 uint32_t ext_tag_support : 1;
336 uint32_t endpt_L0_latency : 3;
337 uint32_t endpt_L1_latency : 3;
338 uint32_t maybe_rsvd1 : 3;
339 uint32_t role_err_reporting : 1;
341 uint32_t slot_pwr_lim_val : 8;
342 uint32_t slot_pwr_lim_scale : 2;
344 } __attribute__((packed));
345 } __attribute__((packed)) dev_cap;
350 uint16_t correctable_err_enable : 1;
351 uint16_t non_fatal_err_enable : 1;
352 uint16_t fatal_err_enable : 1;
353 uint16_t unsupp_req_enable : 1;
354 uint16_t relaxed_order_enable : 1;
355 uint16_t max_payload_size : 3;
356 uint16_t ext_tag_field_enable : 1;
357 uint16_t phantom_fn_enable : 1;
358 uint16_t aux_pwr_enable : 1;
359 uint16_t no_snoop_enable : 1;
360 uint16_t max_read_req_size : 3;
361 uint16_t bridge_cfg_retry_enable : 1;
362 } __attribute__((packed));
363 } __attribute__((packed)) dev_ctrl;
368 uint16_t correctable_err : 1;
369 uint16_t non_fatal_err : 1;
370 uint16_t fatal_err : 1;
371 uint16_t unsupp_req : 1;
372 uint16_t aux_pwr : 1;
373 uint16_t transaction_pending : 1;
375 } __attribute__((packed));
376 } __attribute__((packed)) dev_status;
381 uint32_t max_link_speed : 4;
382 uint32_t max_link_width : 6;
383 uint32_t aspm_support : 2; /* Active State Power Management Support */
384 uint32_t L0_exit_latency : 3;
385 uint32_t L1_exit_latency : 3;
386 uint32_t clk_pwr_mngmt : 1;
387 uint32_t surprise_pwr_down_capable : 1;
388 uint32_t data_link_active_capable : 1;
390 uint32_t port_number : 8;
391 } __attribute__((packed));
392 } __attribute__((packed)) link_cap;
398 uint16_t aspm_ctrl : 2;
400 uint16_t rd_cmpl_bndry : 1;
401 uint16_t link_disable : 1;
402 uint16_t retrain_link : 1;
403 uint16_t common_clk_cfg : 1;
404 uint16_t ext_synch : 1;
405 uint16_t clk_pwr_mngmt_enable : 1;
407 } __attribute__((packed));
408 } __attribute__((packed)) link_ctrl;
414 uint16_t link_speed : 4;
415 uint16_t negotiate_link_width : 6;
417 uint16_t link_training : 1;
418 uint16_t slot_clk_cfg : 1;
419 uint16_t data_link_layer_active : 1;
421 } __attribute__((packed));
422 } __attribute__((packed)) link_status;
424 } __attribute__((packed));
430 struct pcie_cap_reg pcie_cap;
435 uint32_t max_payload : 3;
436 uint32_t phantom_fns : 2;
437 uint32_t ext_tag_support : 1;
438 uint32_t endpt_L0_latency : 3;
439 uint32_t endpt_L1_latency : 3;
440 uint32_t maybe_rsvd1 : 3;
441 uint32_t role_err_reporting : 1;
443 uint32_t slot_pwr_lim_val : 8;
444 uint32_t slot_pwr_lim_scale : 2;
445 uint32_t fn_level_reset : 1;
447 } __attribute__((packed));
448 } __attribute__((packed)) dev_cap;
453 uint16_t correctable_err_enable : 1;
454 uint16_t non_fatal_err_enable : 1;
455 uint16_t fatal_err_enable : 1;
456 uint16_t unsupp_req_enable : 1;
457 uint16_t relaxed_order_enable : 1;
458 uint16_t max_payload_size : 3;
459 uint16_t ext_tag_field_enable : 1;
460 uint16_t phantom_fn_enable : 1;
461 uint16_t aux_pwr_enable : 1;
462 uint16_t no_snoop_enable : 1;
463 uint16_t max_read_req_size : 3;
464 uint16_t bridge_cfg_retry_enable : 1;
465 } __attribute__((packed));
466 } __attribute__((packed)) dev_ctrl;
471 uint16_t correctable_err : 1;
472 uint16_t non_fatal_err : 1;
473 uint16_t fatal_err : 1;
474 uint16_t unsupp_req : 1;
475 uint16_t aux_pwr : 1;
476 uint16_t transaction_pending : 1;
478 } __attribute__((packed));
479 } __attribute__((packed)) dev_status;
484 uint32_t max_link_speed : 4;
485 uint32_t max_link_width : 6;
486 uint32_t aspm_support : 2; /* Active State Power Management Support */
487 uint32_t L0_exit_latency : 3;
488 uint32_t L1_exit_latency : 3;
489 uint32_t clk_pwr_mngmt : 1;
490 uint32_t surprise_pwr_down_capable : 1;
491 uint32_t data_link_active_capable : 1;
493 uint32_t port_number : 8;
494 } __attribute__((packed));
495 } __attribute__((packed)) link_cap;
501 uint16_t aspm_ctrl : 2;
503 uint16_t rd_cmpl_bndry : 1;
504 uint16_t link_disable : 1;
505 uint16_t retrain_link : 1;
506 uint16_t common_clk_cfg : 1;
507 uint16_t ext_synch : 1;
508 uint16_t clk_pwr_mngmt_enable : 1;
510 } __attribute__((packed));
511 } __attribute__((packed)) link_ctrl;
517 uint16_t link_speed : 4;
518 uint16_t negotiate_link_width : 6;
520 uint16_t link_training : 1;
521 uint16_t slot_clk_cfg : 1;
522 uint16_t data_link_layer_active : 1;
524 } __attribute__((packed));
525 } __attribute__((packed)) link_status;
528 /* Some crap whose format we don't know because the PCI-SIG sucks */
532 uint16_t slot_status;
536 uint32_t root_status;
538 } __attribute__((packed));