pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 1 | #ifndef QEMU_PCI_H |
| 2 | #define QEMU_PCI_H |
| 3 | |
aliguori | 376253e | 2009-03-05 23:01:23 +0000 | [diff] [blame] | 4 | #include "qemu-common.h" |
| 5 | |
Paul Brook | 6b1b92d | 2009-05-14 22:35:07 +0100 | [diff] [blame] | 6 | #include "qdev.h" |
| 7 | |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 8 | /* PCI includes legacy ISA access. */ |
| 9 | #include "isa.h" |
| 10 | |
| 11 | /* PCI bus */ |
| 12 | |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 13 | extern target_phys_addr_t pci_mem_base; |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 14 | |
aliguori | 3ae8061 | 2009-02-11 15:19:46 +0000 | [diff] [blame] | 15 | #define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07)) |
| 16 | #define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) |
| 17 | #define PCI_FUNC(devfn) ((devfn) & 0x07) |
| 18 | |
aliguori | a770dc7 | 2009-03-13 15:02:23 +0000 | [diff] [blame] | 19 | /* Class, Vendor and Device IDs from Linux's pci_ids.h */ |
| 20 | #include "pci_ids.h" |
blueswir1 | 173a543 | 2009-02-01 19:26:20 +0000 | [diff] [blame] | 21 | |
aliguori | a770dc7 | 2009-03-13 15:02:23 +0000 | [diff] [blame] | 22 | /* QEMU-specific Vendor and Device ID definitions */ |
aliguori | 6f338c3 | 2009-02-11 15:21:54 +0000 | [diff] [blame] | 23 | |
aliguori | a770dc7 | 2009-03-13 15:02:23 +0000 | [diff] [blame] | 24 | /* IBM (0x1014) */ |
| 25 | #define PCI_DEVICE_ID_IBM_440GX 0x027f |
blueswir1 | 4ebcf88 | 2009-02-01 12:01:04 +0000 | [diff] [blame] | 26 | #define PCI_DEVICE_ID_IBM_OPENPIC2 0xffff |
aliguori | deb5439 | 2009-01-26 15:37:35 +0000 | [diff] [blame] | 27 | |
aliguori | a770dc7 | 2009-03-13 15:02:23 +0000 | [diff] [blame] | 28 | /* Hitachi (0x1054) */ |
aliguori | deb5439 | 2009-01-26 15:37:35 +0000 | [diff] [blame] | 29 | #define PCI_VENDOR_ID_HITACHI 0x1054 |
aliguori | a770dc7 | 2009-03-13 15:02:23 +0000 | [diff] [blame] | 30 | #define PCI_DEVICE_ID_HITACHI_SH7751R 0x350e |
aliguori | deb5439 | 2009-01-26 15:37:35 +0000 | [diff] [blame] | 31 | |
aliguori | a770dc7 | 2009-03-13 15:02:23 +0000 | [diff] [blame] | 32 | /* Apple (0x106b) */ |
blueswir1 | 4ebcf88 | 2009-02-01 12:01:04 +0000 | [diff] [blame] | 33 | #define PCI_DEVICE_ID_APPLE_343S1201 0x0010 |
| 34 | #define PCI_DEVICE_ID_APPLE_UNI_N_I_PCI 0x001e |
| 35 | #define PCI_DEVICE_ID_APPLE_UNI_N_PCI 0x001f |
blueswir1 | 4ebcf88 | 2009-02-01 12:01:04 +0000 | [diff] [blame] | 36 | #define PCI_DEVICE_ID_APPLE_UNI_N_KEYL 0x0022 |
aliguori | a770dc7 | 2009-03-13 15:02:23 +0000 | [diff] [blame] | 37 | #define PCI_DEVICE_ID_APPLE_IPID_USB 0x003f |
aliguori | deb5439 | 2009-01-26 15:37:35 +0000 | [diff] [blame] | 38 | |
aliguori | a770dc7 | 2009-03-13 15:02:23 +0000 | [diff] [blame] | 39 | /* Realtek (0x10ec) */ |
| 40 | #define PCI_DEVICE_ID_REALTEK_8029 0x8029 |
aliguori | deb5439 | 2009-01-26 15:37:35 +0000 | [diff] [blame] | 41 | |
aliguori | a770dc7 | 2009-03-13 15:02:23 +0000 | [diff] [blame] | 42 | /* Xilinx (0x10ee) */ |
| 43 | #define PCI_DEVICE_ID_XILINX_XC2VP30 0x0300 |
aliguori | deb5439 | 2009-01-26 15:37:35 +0000 | [diff] [blame] | 44 | |
aliguori | a770dc7 | 2009-03-13 15:02:23 +0000 | [diff] [blame] | 45 | /* Marvell (0x11ab) */ |
| 46 | #define PCI_DEVICE_ID_MARVELL_GT6412X 0x4620 |
aliguori | deb5439 | 2009-01-26 15:37:35 +0000 | [diff] [blame] | 47 | |
aliguori | a770dc7 | 2009-03-13 15:02:23 +0000 | [diff] [blame] | 48 | /* QEMU/Bochs VGA (0x1234) */ |
blueswir1 | 4ebcf88 | 2009-02-01 12:01:04 +0000 | [diff] [blame] | 49 | #define PCI_VENDOR_ID_QEMU 0x1234 |
| 50 | #define PCI_DEVICE_ID_QEMU_VGA 0x1111 |
| 51 | |
aliguori | a770dc7 | 2009-03-13 15:02:23 +0000 | [diff] [blame] | 52 | /* VMWare (0x15ad) */ |
aliguori | deb5439 | 2009-01-26 15:37:35 +0000 | [diff] [blame] | 53 | #define PCI_VENDOR_ID_VMWARE 0x15ad |
| 54 | #define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405 |
| 55 | #define PCI_DEVICE_ID_VMWARE_SVGA 0x0710 |
| 56 | #define PCI_DEVICE_ID_VMWARE_NET 0x0720 |
| 57 | #define PCI_DEVICE_ID_VMWARE_SCSI 0x0730 |
| 58 | #define PCI_DEVICE_ID_VMWARE_IDE 0x1729 |
| 59 | |
aliguori | cef3017 | 2009-03-28 17:29:07 +0000 | [diff] [blame] | 60 | /* Intel (0x8086) */ |
aliguori | a770dc7 | 2009-03-13 15:02:23 +0000 | [diff] [blame] | 61 | #define PCI_DEVICE_ID_INTEL_82551IT 0x1209 |
Stefan Weil | d6fd1e6 | 2009-09-01 22:16:10 +0200 | [diff] [blame] | 62 | #define PCI_DEVICE_ID_INTEL_82557 0x1229 |
aurel32 | 74c62ba | 2009-03-02 16:42:23 +0000 | [diff] [blame] | 63 | |
aliguori | deb5439 | 2009-01-26 15:37:35 +0000 | [diff] [blame] | 64 | /* Red Hat / Qumranet (for QEMU) -- see pci-ids.txt */ |
aliguori | d350d97 | 2008-12-11 21:15:42 +0000 | [diff] [blame] | 65 | #define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4 |
| 66 | #define PCI_SUBVENDOR_ID_REDHAT_QUMRANET 0x1af4 |
| 67 | #define PCI_SUBDEVICE_ID_QEMU 0x1100 |
| 68 | |
| 69 | #define PCI_DEVICE_ID_VIRTIO_NET 0x1000 |
| 70 | #define PCI_DEVICE_ID_VIRTIO_BLOCK 0x1001 |
| 71 | #define PCI_DEVICE_ID_VIRTIO_BALLOON 0x1002 |
aliguori | 14d50be | 2009-01-26 15:22:46 +0000 | [diff] [blame] | 72 | #define PCI_DEVICE_ID_VIRTIO_CONSOLE 0x1003 |
aliguori | d350d97 | 2008-12-11 21:15:42 +0000 | [diff] [blame] | 73 | |
Isaku Yamahata | 4f8589e | 2009-10-30 21:21:10 +0900 | [diff] [blame] | 74 | typedef uint64_t pcibus_t; |
| 75 | #define FMT_PCIBUS PRIx64 |
Isaku Yamahata | 6e355d9 | 2009-10-30 21:21:08 +0900 | [diff] [blame] | 76 | |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 77 | typedef void PCIConfigWriteFunc(PCIDevice *pci_dev, |
| 78 | uint32_t address, uint32_t data, int len); |
| 79 | typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev, |
| 80 | uint32_t address, int len); |
| 81 | typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num, |
Isaku Yamahata | 6e355d9 | 2009-10-30 21:21:08 +0900 | [diff] [blame] | 82 | pcibus_t addr, pcibus_t size, int type); |
aliguori | 5851e08 | 2009-02-11 15:21:10 +0000 | [diff] [blame] | 83 | typedef int PCIUnregisterFunc(PCIDevice *pci_dev); |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 84 | |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 85 | typedef struct PCIIORegion { |
Isaku Yamahata | 6e355d9 | 2009-10-30 21:21:08 +0900 | [diff] [blame] | 86 | pcibus_t addr; /* current PCI mapping address. -1 means not mapped */ |
| 87 | #define PCI_BAR_UNMAPPED (~(pcibus_t)0) |
| 88 | pcibus_t size; |
Isaku Yamahata | a0c7a97 | 2009-10-30 21:21:25 +0900 | [diff] [blame] | 89 | pcibus_t filtered_size; |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 90 | uint8_t type; |
| 91 | PCIMapIORegionFunc *map_func; |
| 92 | } PCIIORegion; |
| 93 | |
| 94 | #define PCI_ROM_SLOT 6 |
| 95 | #define PCI_NUM_REGIONS 7 |
| 96 | |
aliguori | cef3017 | 2009-03-28 17:29:07 +0000 | [diff] [blame] | 97 | /* Declarations from linux/pci_regs.h */ |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 98 | #define PCI_VENDOR_ID 0x00 /* 16 bits */ |
| 99 | #define PCI_DEVICE_ID 0x02 /* 16 bits */ |
| 100 | #define PCI_COMMAND 0x04 /* 16 bits */ |
| 101 | #define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ |
| 102 | #define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ |
Michael S. Tsirkin | b7ee160 | 2009-06-21 19:45:18 +0300 | [diff] [blame] | 103 | #define PCI_COMMAND_MASTER 0x4 /* Enable bus master */ |
Isaku Yamahata | fb23162 | 2009-10-30 21:21:22 +0900 | [diff] [blame] | 104 | #define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */ |
| 105 | #define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */ |
| 106 | #define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */ |
| 107 | #define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */ |
| 108 | #define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */ |
| 109 | #define PCI_COMMAND_SERR 0x100 /* Enable SERR */ |
| 110 | #define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */ |
| 111 | #define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */ |
aliguori | cef3017 | 2009-03-28 17:29:07 +0000 | [diff] [blame] | 112 | #define PCI_STATUS 0x06 /* 16 bits */ |
| 113 | #define PCI_REVISION_ID 0x08 /* 8 bits */ |
Michael S. Tsirkin | bd4b65e | 2009-06-21 19:49:40 +0300 | [diff] [blame] | 114 | #define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */ |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 115 | #define PCI_CLASS_DEVICE 0x0a /* Device class */ |
Michael S. Tsirkin | b7ee160 | 2009-06-21 19:45:18 +0300 | [diff] [blame] | 116 | #define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */ |
| 117 | #define PCI_LATENCY_TIMER 0x0d /* 8 bits */ |
aliguori | cef3017 | 2009-03-28 17:29:07 +0000 | [diff] [blame] | 118 | #define PCI_HEADER_TYPE 0x0e /* 8 bits */ |
Isaku Yamahata | 6407f37 | 2009-05-03 19:03:00 +0000 | [diff] [blame] | 119 | #define PCI_HEADER_TYPE_NORMAL 0 |
| 120 | #define PCI_HEADER_TYPE_BRIDGE 1 |
| 121 | #define PCI_HEADER_TYPE_CARDBUS 2 |
| 122 | #define PCI_HEADER_TYPE_MULTI_FUNCTION 0x80 |
Michael S. Tsirkin | b7ee160 | 2009-06-21 19:45:18 +0300 | [diff] [blame] | 123 | #define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */ |
Isaku Yamahata | 0392a01 | 2009-10-30 21:21:03 +0900 | [diff] [blame] | 124 | #define PCI_BASE_ADDRESS_SPACE_IO 0x01 |
| 125 | #define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00 |
Isaku Yamahata | 1442125 | 2009-10-30 21:21:11 +0900 | [diff] [blame] | 126 | #define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */ |
Isaku Yamahata | 0392a01 | 2009-10-30 21:21:03 +0900 | [diff] [blame] | 127 | #define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */ |
Michael S. Tsirkin | b7ee160 | 2009-06-21 19:45:18 +0300 | [diff] [blame] | 128 | #define PCI_PRIMARY_BUS 0x18 /* Primary bus number */ |
| 129 | #define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */ |
Isaku Yamahata | e822a52 | 2009-10-30 21:21:13 +0900 | [diff] [blame] | 130 | #define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */ |
Isaku Yamahata | fb23162 | 2009-10-30 21:21:22 +0900 | [diff] [blame] | 131 | #define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */ |
| 132 | #define PCI_IO_BASE 0x1c /* I/O range behind the bridge */ |
| 133 | #define PCI_IO_LIMIT 0x1d |
Isaku Yamahata | a0c7a97 | 2009-10-30 21:21:25 +0900 | [diff] [blame] | 134 | #define PCI_IO_RANGE_TYPE_32 0x01 |
Isaku Yamahata | fb23162 | 2009-10-30 21:21:22 +0900 | [diff] [blame] | 135 | #define PCI_IO_RANGE_MASK (~0x0fUL) |
Michael S. Tsirkin | b7ee160 | 2009-06-21 19:45:18 +0300 | [diff] [blame] | 136 | #define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */ |
Isaku Yamahata | fb23162 | 2009-10-30 21:21:22 +0900 | [diff] [blame] | 137 | #define PCI_MEMORY_BASE 0x20 /* Memory range behind */ |
| 138 | #define PCI_MEMORY_LIMIT 0x22 |
| 139 | #define PCI_MEMORY_RANGE_MASK (~0x0fUL) |
| 140 | #define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */ |
| 141 | #define PCI_PREF_MEMORY_LIMIT 0x26 |
| 142 | #define PCI_PREF_RANGE_MASK (~0x0fUL) |
| 143 | #define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */ |
Isaku Yamahata | a0c7a97 | 2009-10-30 21:21:25 +0900 | [diff] [blame] | 144 | #define PCI_PREF_LIMIT_UPPER32 0x2c |
aliguori | cef3017 | 2009-03-28 17:29:07 +0000 | [diff] [blame] | 145 | #define PCI_SUBSYSTEM_VENDOR_ID 0x2c /* 16 bits */ |
| 146 | #define PCI_SUBSYSTEM_ID 0x2e /* 16 bits */ |
Michael S. Tsirkin | 5330de0 | 2009-09-16 13:40:57 +0300 | [diff] [blame] | 147 | #define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */ |
| 148 | #define PCI_ROM_ADDRESS_ENABLE 0x01 |
Isaku Yamahata | fb23162 | 2009-10-30 21:21:22 +0900 | [diff] [blame] | 149 | #define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */ |
| 150 | #define PCI_IO_LIMIT_UPPER16 0x32 |
Michael S. Tsirkin | b7ee160 | 2009-06-21 19:45:18 +0300 | [diff] [blame] | 151 | #define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */ |
Isaku Yamahata | b3b1169 | 2009-10-30 21:21:05 +0900 | [diff] [blame] | 152 | #define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */ |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 153 | #define PCI_INTERRUPT_LINE 0x3c /* 8 bits */ |
| 154 | #define PCI_INTERRUPT_PIN 0x3d /* 8 bits */ |
| 155 | #define PCI_MIN_GNT 0x3e /* 8 bits */ |
Isaku Yamahata | fb23162 | 2009-10-30 21:21:22 +0900 | [diff] [blame] | 156 | #define PCI_BRIDGE_CONTROL 0x3e |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 157 | #define PCI_MAX_LAT 0x3f /* 8 bits */ |
| 158 | |
Michael S. Tsirkin | 6f4cbd3 | 2009-06-21 19:45:40 +0300 | [diff] [blame] | 159 | /* Capability lists */ |
| 160 | #define PCI_CAP_LIST_ID 0 /* Capability ID */ |
| 161 | #define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */ |
| 162 | |
aliguori | cef3017 | 2009-03-28 17:29:07 +0000 | [diff] [blame] | 163 | #define PCI_REVISION 0x08 /* obsolete, use PCI_REVISION_ID */ |
| 164 | #define PCI_SUBVENDOR_ID 0x2c /* obsolete, use PCI_SUBSYSTEM_VENDOR_ID */ |
| 165 | #define PCI_SUBDEVICE_ID 0x2e /* obsolete, use PCI_SUBSYSTEM_ID */ |
| 166 | |
aurel32 | 8098ed4 | 2008-12-18 22:43:33 +0000 | [diff] [blame] | 167 | /* Bits in the PCI Status Register (PCI 2.3 spec) */ |
| 168 | #define PCI_STATUS_RESERVED1 0x007 |
| 169 | #define PCI_STATUS_INT_STATUS 0x008 |
Michael S. Tsirkin | 6f4cbd3 | 2009-06-21 19:45:40 +0300 | [diff] [blame] | 170 | #define PCI_STATUS_CAP_LIST 0x010 |
aurel32 | 8098ed4 | 2008-12-18 22:43:33 +0000 | [diff] [blame] | 171 | #define PCI_STATUS_66MHZ 0x020 |
| 172 | #define PCI_STATUS_RESERVED2 0x040 |
| 173 | #define PCI_STATUS_FAST_BACK 0x080 |
| 174 | #define PCI_STATUS_DEVSEL 0x600 |
| 175 | |
| 176 | #define PCI_STATUS_RESERVED_MASK_LO (PCI_STATUS_RESERVED1 | \ |
| 177 | PCI_STATUS_INT_STATUS | PCI_STATUS_CAPABILITIES | \ |
| 178 | PCI_STATUS_66MHZ | PCI_STATUS_RESERVED2 | PCI_STATUS_FAST_BACK) |
| 179 | |
| 180 | #define PCI_STATUS_RESERVED_MASK_HI (PCI_STATUS_DEVSEL >> 8) |
| 181 | |
aurel32 | 475dc65 | 2008-12-18 22:43:40 +0000 | [diff] [blame] | 182 | /* Bits in the PCI Command Register (PCI 2.3 spec) */ |
| 183 | #define PCI_COMMAND_RESERVED 0xf800 |
| 184 | |
| 185 | #define PCI_COMMAND_RESERVED_MASK_HI (PCI_COMMAND_RESERVED >> 8) |
| 186 | |
Michael S. Tsirkin | b7ee160 | 2009-06-21 19:45:18 +0300 | [diff] [blame] | 187 | /* Size of the standard PCI config header */ |
| 188 | #define PCI_CONFIG_HEADER_SIZE 0x40 |
| 189 | /* Size of the standard PCI config space */ |
| 190 | #define PCI_CONFIG_SPACE_SIZE 0x100 |
Isaku Yamahata | a9f4994 | 2009-10-30 21:21:18 +0900 | [diff] [blame] | 191 | /* Size of the standart PCIe config space: 4KB */ |
| 192 | #define PCIE_CONFIG_SPACE_SIZE 0x1000 |
Michael S. Tsirkin | b7ee160 | 2009-06-21 19:45:18 +0300 | [diff] [blame] | 193 | |
Isaku Yamahata | e369cad | 2009-10-30 21:20:56 +0900 | [diff] [blame] | 194 | #define PCI_NUM_PINS 4 /* A-D */ |
| 195 | |
Michael S. Tsirkin | 02eb84d | 2009-06-21 19:49:54 +0300 | [diff] [blame] | 196 | /* Bits in cap_present field. */ |
| 197 | enum { |
| 198 | QEMU_PCI_CAP_MSIX = 0x1, |
Isaku Yamahata | a9f4994 | 2009-10-30 21:21:18 +0900 | [diff] [blame] | 199 | QEMU_PCI_CAP_EXPRESS = 0x2, |
Michael S. Tsirkin | 02eb84d | 2009-06-21 19:49:54 +0300 | [diff] [blame] | 200 | }; |
| 201 | |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 202 | struct PCIDevice { |
Paul Brook | 6b1b92d | 2009-05-14 22:35:07 +0100 | [diff] [blame] | 203 | DeviceState qdev; |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 204 | /* PCI config space */ |
Isaku Yamahata | a9f4994 | 2009-10-30 21:21:18 +0900 | [diff] [blame] | 205 | uint8_t *config; |
Michael S. Tsirkin | b7ee160 | 2009-06-21 19:45:18 +0300 | [diff] [blame] | 206 | |
Michael S. Tsirkin | bd4b65e | 2009-06-21 19:49:40 +0300 | [diff] [blame] | 207 | /* Used to enable config checks on load. Note that writeable bits are |
| 208 | * never checked even if set in cmask. */ |
Isaku Yamahata | a9f4994 | 2009-10-30 21:21:18 +0900 | [diff] [blame] | 209 | uint8_t *cmask; |
Michael S. Tsirkin | bd4b65e | 2009-06-21 19:49:40 +0300 | [diff] [blame] | 210 | |
Michael S. Tsirkin | b7ee160 | 2009-06-21 19:45:18 +0300 | [diff] [blame] | 211 | /* Used to implement R/W bytes */ |
Isaku Yamahata | a9f4994 | 2009-10-30 21:21:18 +0900 | [diff] [blame] | 212 | uint8_t *wmask; |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 213 | |
Michael S. Tsirkin | 6f4cbd3 | 2009-06-21 19:45:40 +0300 | [diff] [blame] | 214 | /* Used to allocate config space for capabilities. */ |
Isaku Yamahata | a9f4994 | 2009-10-30 21:21:18 +0900 | [diff] [blame] | 215 | uint8_t *used; |
Michael S. Tsirkin | 6f4cbd3 | 2009-06-21 19:45:40 +0300 | [diff] [blame] | 216 | |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 217 | /* the following fields are read only */ |
| 218 | PCIBus *bus; |
Gerd Hoffmann | 54586bd | 2009-08-03 17:35:19 +0200 | [diff] [blame] | 219 | uint32_t devfn; |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 220 | char name[64]; |
| 221 | PCIIORegion io_regions[PCI_NUM_REGIONS]; |
| 222 | |
| 223 | /* do not access the following fields */ |
| 224 | PCIConfigReadFunc *config_read; |
| 225 | PCIConfigWriteFunc *config_write; |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 226 | |
| 227 | /* IRQ objects for the INTA-INTD pins. */ |
| 228 | qemu_irq *irq; |
| 229 | |
| 230 | /* Current IRQ levels. Used internally by the generic PCI code. */ |
Isaku Yamahata | e369cad | 2009-10-30 21:20:56 +0900 | [diff] [blame] | 231 | int irq_state[PCI_NUM_PINS]; |
Michael S. Tsirkin | 02eb84d | 2009-06-21 19:49:54 +0300 | [diff] [blame] | 232 | |
| 233 | /* Capability bits */ |
| 234 | uint32_t cap_present; |
| 235 | |
| 236 | /* Offset of MSI-X capability in config space */ |
| 237 | uint8_t msix_cap; |
| 238 | |
| 239 | /* MSI-X entries */ |
| 240 | int msix_entries_nr; |
| 241 | |
| 242 | /* Space to store MSIX table */ |
| 243 | uint8_t *msix_table_page; |
| 244 | /* MMIO index used to map MSIX table and pending bit entries. */ |
| 245 | int msix_mmio_index; |
| 246 | /* Reference-count for entries actually in use by driver. */ |
| 247 | unsigned *msix_entry_used; |
| 248 | /* Region including the MSI-X table */ |
| 249 | uint32_t msix_bar_size; |
Juan Quintela | f16c4ab | 2009-08-20 19:42:38 +0200 | [diff] [blame] | 250 | /* Version id needed for VMState */ |
| 251 | int32_t version_id; |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 252 | }; |
| 253 | |
| 254 | PCIDevice *pci_register_device(PCIBus *bus, const char *name, |
| 255 | int instance_size, int devfn, |
| 256 | PCIConfigReadFunc *config_read, |
| 257 | PCIConfigWriteFunc *config_write); |
| 258 | |
Avi Kivity | 28c2c26 | 2009-06-14 11:38:53 +0300 | [diff] [blame] | 259 | void pci_register_bar(PCIDevice *pci_dev, int region_num, |
Isaku Yamahata | 6e355d9 | 2009-10-30 21:21:08 +0900 | [diff] [blame] | 260 | pcibus_t size, int type, |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 261 | PCIMapIORegionFunc *map_func); |
| 262 | |
Michael S. Tsirkin | 6f4cbd3 | 2009-06-21 19:45:40 +0300 | [diff] [blame] | 263 | int pci_add_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size); |
| 264 | |
| 265 | void pci_del_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size); |
| 266 | |
| 267 | void pci_reserve_capability(PCIDevice *pci_dev, uint8_t offset, uint8_t size); |
| 268 | |
| 269 | uint8_t pci_find_capability(PCIDevice *pci_dev, uint8_t cap_id); |
| 270 | |
| 271 | |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 272 | uint32_t pci_default_read_config(PCIDevice *d, |
| 273 | uint32_t address, int len); |
| 274 | void pci_default_write_config(PCIDevice *d, |
| 275 | uint32_t address, uint32_t val, int len); |
| 276 | void pci_device_save(PCIDevice *s, QEMUFile *f); |
| 277 | int pci_device_load(PCIDevice *s, QEMUFile *f); |
| 278 | |
Juan Quintela | 5d4e84c | 2009-08-28 15:28:17 +0200 | [diff] [blame] | 279 | typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level); |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 280 | typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); |
Gerd Hoffmann | ee995ff | 2009-09-25 21:42:44 +0200 | [diff] [blame] | 281 | typedef int (*pci_hotplug_fn)(PCIDevice *pci_dev, int state); |
Gerd Hoffmann | 21eea4b | 2009-09-16 22:25:31 +0200 | [diff] [blame] | 282 | void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent, |
| 283 | const char *name, int devfn_min); |
| 284 | PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min); |
| 285 | void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, |
| 286 | void *irq_opaque, int nirq); |
Gerd Hoffmann | ee995ff | 2009-09-25 21:42:44 +0200 | [diff] [blame] | 287 | void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug); |
Paul Brook | 02e2da4 | 2009-05-23 00:05:19 +0100 | [diff] [blame] | 288 | PCIBus *pci_register_bus(DeviceState *parent, const char *name, |
| 289 | pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, |
Juan Quintela | 5d4e84c | 2009-08-28 15:28:17 +0200 | [diff] [blame] | 290 | void *irq_opaque, int devfn_min, int nirq); |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 291 | |
Markus Armbruster | 5607c38 | 2009-06-18 15:14:08 +0200 | [diff] [blame] | 292 | PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model, |
| 293 | const char *default_devaddr); |
Markus Armbruster | 07caea3 | 2009-09-25 03:53:51 +0200 | [diff] [blame] | 294 | PCIDevice *pci_nic_init_nofail(NICInfo *nd, const char *default_model, |
| 295 | const char *default_devaddr); |
Isaku Yamahata | ce195fb | 2009-10-30 21:21:16 +0900 | [diff] [blame] | 296 | void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len); |
| 297 | uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len); |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 298 | int pci_bus_num(PCIBus *s); |
Isaku Yamahata | e822a52 | 2009-10-30 21:21:13 +0900 | [diff] [blame] | 299 | void pci_for_each_device(PCIBus *bus, int bus_num, void (*fn)(PCIBus *bus, PCIDevice *d)); |
| 300 | PCIBus *pci_find_host_bus(int domain); |
| 301 | PCIBus *pci_find_bus(PCIBus *bus, int bus_num); |
| 302 | PCIDevice *pci_find_device(PCIBus *bus, int bus_num, int slot, int function); |
Markus Armbruster | 49bd145 | 2009-09-25 03:53:49 +0200 | [diff] [blame] | 303 | PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr); |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 304 | |
Jan Kiszka | e9283f8 | 2009-06-26 00:04:00 +0200 | [diff] [blame] | 305 | int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp, |
| 306 | unsigned *slotp); |
aliguori | 880345c | 2009-02-11 15:21:48 +0000 | [diff] [blame] | 307 | |
aliguori | 376253e | 2009-03-05 23:01:23 +0000 | [diff] [blame] | 308 | void pci_info(Monitor *mon); |
blueswir1 | 480b9f2 | 2009-01-27 19:15:31 +0000 | [diff] [blame] | 309 | PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did, |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 310 | pci_map_irq_fn map_irq, const char *name); |
| 311 | |
aliguori | deb5439 | 2009-01-26 15:37:35 +0000 | [diff] [blame] | 312 | static inline void |
Michael S. Tsirkin | 64d50b8 | 2009-06-21 19:50:57 +0300 | [diff] [blame] | 313 | pci_set_byte(uint8_t *config, uint8_t val) |
| 314 | { |
| 315 | *config = val; |
| 316 | } |
| 317 | |
| 318 | static inline uint8_t |
| 319 | pci_get_byte(uint8_t *config) |
| 320 | { |
| 321 | return *config; |
| 322 | } |
| 323 | |
| 324 | static inline void |
Michael S. Tsirkin | 14e1255 | 2009-06-21 19:45:30 +0300 | [diff] [blame] | 325 | pci_set_word(uint8_t *config, uint16_t val) |
| 326 | { |
| 327 | cpu_to_le16wu((uint16_t *)config, val); |
| 328 | } |
| 329 | |
| 330 | static inline uint16_t |
| 331 | pci_get_word(uint8_t *config) |
| 332 | { |
| 333 | return le16_to_cpupu((uint16_t *)config); |
| 334 | } |
| 335 | |
| 336 | static inline void |
| 337 | pci_set_long(uint8_t *config, uint32_t val) |
| 338 | { |
| 339 | cpu_to_le32wu((uint32_t *)config, val); |
| 340 | } |
| 341 | |
| 342 | static inline uint32_t |
| 343 | pci_get_long(uint8_t *config) |
| 344 | { |
| 345 | return le32_to_cpupu((uint32_t *)config); |
| 346 | } |
| 347 | |
| 348 | static inline void |
Isaku Yamahata | fb5ce7d | 2009-10-30 21:20:59 +0900 | [diff] [blame] | 349 | pci_set_quad(uint8_t *config, uint64_t val) |
| 350 | { |
| 351 | cpu_to_le64w((uint64_t *)config, val); |
| 352 | } |
| 353 | |
| 354 | static inline uint64_t |
| 355 | pci_get_quad(uint8_t *config) |
| 356 | { |
| 357 | return le64_to_cpup((uint64_t *)config); |
| 358 | } |
| 359 | |
| 360 | static inline void |
aliguori | deb5439 | 2009-01-26 15:37:35 +0000 | [diff] [blame] | 361 | pci_config_set_vendor_id(uint8_t *pci_config, uint16_t val) |
| 362 | { |
Michael S. Tsirkin | 14e1255 | 2009-06-21 19:45:30 +0300 | [diff] [blame] | 363 | pci_set_word(&pci_config[PCI_VENDOR_ID], val); |
aliguori | deb5439 | 2009-01-26 15:37:35 +0000 | [diff] [blame] | 364 | } |
| 365 | |
| 366 | static inline void |
| 367 | pci_config_set_device_id(uint8_t *pci_config, uint16_t val) |
| 368 | { |
Michael S. Tsirkin | 14e1255 | 2009-06-21 19:45:30 +0300 | [diff] [blame] | 369 | pci_set_word(&pci_config[PCI_DEVICE_ID], val); |
aliguori | deb5439 | 2009-01-26 15:37:35 +0000 | [diff] [blame] | 370 | } |
| 371 | |
blueswir1 | 173a543 | 2009-02-01 19:26:20 +0000 | [diff] [blame] | 372 | static inline void |
| 373 | pci_config_set_class(uint8_t *pci_config, uint16_t val) |
| 374 | { |
Michael S. Tsirkin | 14e1255 | 2009-06-21 19:45:30 +0300 | [diff] [blame] | 375 | pci_set_word(&pci_config[PCI_CLASS_DEVICE], val); |
blueswir1 | 173a543 | 2009-02-01 19:26:20 +0000 | [diff] [blame] | 376 | } |
| 377 | |
Gerd Hoffmann | 81a322d | 2009-08-14 10:36:05 +0200 | [diff] [blame] | 378 | typedef int (*pci_qdev_initfn)(PCIDevice *dev); |
Gerd Hoffmann | 0aab0d3 | 2009-06-30 14:12:07 +0200 | [diff] [blame] | 379 | typedef struct { |
| 380 | DeviceInfo qdev; |
| 381 | pci_qdev_initfn init; |
Gerd Hoffmann | e3936fa | 2009-09-25 21:42:38 +0200 | [diff] [blame] | 382 | PCIUnregisterFunc *exit; |
Gerd Hoffmann | 0aab0d3 | 2009-06-30 14:12:07 +0200 | [diff] [blame] | 383 | PCIConfigReadFunc *config_read; |
| 384 | PCIConfigWriteFunc *config_write; |
Isaku Yamahata | a9f4994 | 2009-10-30 21:21:18 +0900 | [diff] [blame] | 385 | |
Isaku Yamahata | fb23162 | 2009-10-30 21:21:22 +0900 | [diff] [blame] | 386 | /* pci config header type */ |
| 387 | uint8_t header_type; /* this is necessary for initialization |
| 388 | * code to know its header type before |
| 389 | * device specific code can initialize |
| 390 | * configuration space. |
| 391 | */ |
| 392 | |
Isaku Yamahata | a9f4994 | 2009-10-30 21:21:18 +0900 | [diff] [blame] | 393 | /* pcie stuff */ |
| 394 | int is_express; /* is this device pci express? |
| 395 | * initialization code needs to know this before |
| 396 | * each specific device initialization. |
| 397 | */ |
Gerd Hoffmann | 0aab0d3 | 2009-06-30 14:12:07 +0200 | [diff] [blame] | 398 | } PCIDeviceInfo; |
| 399 | |
| 400 | void pci_qdev_register(PCIDeviceInfo *info); |
| 401 | void pci_qdev_register_many(PCIDeviceInfo *info); |
Paul Brook | 6b1b92d | 2009-05-14 22:35:07 +0100 | [diff] [blame] | 402 | |
Markus Armbruster | 499cf10 | 2009-09-25 03:53:53 +0200 | [diff] [blame] | 403 | PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name); |
Paul Brook | 6b1b92d | 2009-05-14 22:35:07 +0100 | [diff] [blame] | 404 | PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name); |
| 405 | |
Isaku Yamahata | a9f4994 | 2009-10-30 21:21:18 +0900 | [diff] [blame] | 406 | static inline int pci_is_express(PCIDevice *d) |
| 407 | { |
| 408 | return d->cap_present & QEMU_PCI_CAP_EXPRESS; |
| 409 | } |
| 410 | |
| 411 | static inline uint32_t pci_config_size(PCIDevice *d) |
| 412 | { |
| 413 | return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE; |
| 414 | } |
| 415 | |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 416 | /* lsi53c895a.c */ |
ths | e4bcb14 | 2007-12-02 04:51:10 +0000 | [diff] [blame] | 417 | #define LSI_MAX_DEVS 7 |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 418 | |
| 419 | /* vmware_vga.c */ |
Paul Brook | fbe1b59 | 2009-05-13 17:56:25 +0100 | [diff] [blame] | 420 | void pci_vmsvga_init(PCIBus *bus); |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 421 | |
| 422 | /* usb-uhci.c */ |
| 423 | void usb_uhci_piix3_init(PCIBus *bus, int devfn); |
| 424 | void usb_uhci_piix4_init(PCIBus *bus, int devfn); |
| 425 | |
| 426 | /* usb-ohci.c */ |
Gerd Hoffmann | 5b19d9a | 2009-08-31 14:24:03 +0200 | [diff] [blame] | 427 | void usb_ohci_init_pci(struct PCIBus *bus, int devfn); |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 428 | |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 429 | /* prep_pci.c */ |
| 430 | PCIBus *pci_prep_init(qemu_irq *pic); |
| 431 | |
| 432 | /* apb_pci.c */ |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 433 | PCIBus *pci_apb_init(target_phys_addr_t special_base, |
| 434 | target_phys_addr_t mem_base, |
blueswir1 | c190ea0 | 2009-01-10 11:33:32 +0000 | [diff] [blame] | 435 | qemu_irq *pic, PCIBus **bus2, PCIBus **bus3); |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 436 | |
aurel32 | b79e175 | 2008-12-07 22:46:42 +0000 | [diff] [blame] | 437 | /* sh_pci.c */ |
| 438 | PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, |
Juan Quintela | 5d4e84c | 2009-08-28 15:28:17 +0200 | [diff] [blame] | 439 | void *pic, int devfn_min, int nirq); |
aurel32 | b79e175 | 2008-12-07 22:46:42 +0000 | [diff] [blame] | 440 | |
Isaku Yamahata | f49db80 | 2009-10-30 21:21:19 +0900 | [diff] [blame] | 441 | /* These are not pci specific. Should move into a separate header. |
| 442 | * Only pci.c uses them, so keep them here for now. |
| 443 | */ |
| 444 | |
| 445 | /* Get last byte of a range from offset + length. |
| 446 | * Undefined for ranges that wrap around 0. */ |
| 447 | static inline uint64_t range_get_last(uint64_t offset, uint64_t len) |
| 448 | { |
| 449 | return offset + len - 1; |
| 450 | } |
| 451 | |
| 452 | /* Check whether a given range covers a given byte. */ |
| 453 | static inline int range_covers_byte(uint64_t offset, uint64_t len, |
| 454 | uint64_t byte) |
| 455 | { |
| 456 | return offset <= byte && byte <= range_get_last(offset, len); |
| 457 | } |
| 458 | |
| 459 | /* Check whether 2 given ranges overlap. |
| 460 | * Undefined if ranges that wrap around 0. */ |
| 461 | static inline int ranges_overlap(uint64_t first1, uint64_t len1, |
| 462 | uint64_t first2, uint64_t len2) |
| 463 | { |
| 464 | uint64_t last1 = range_get_last(first1, len1); |
| 465 | uint64_t last2 = range_get_last(first2, len2); |
| 466 | |
| 467 | return !(last2 < first1 || last1 < first2); |
| 468 | } |
| 469 | |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 470 | #endif |