The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 1 | #ifndef QEMU_PCI_H |
| 2 | #define QEMU_PCI_H |
| 3 | |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 4 | #include "qemu-common.h" |
| 5 | |
| 6 | #include "qdev.h" |
| 7 | |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 8 | /* PCI includes legacy ISA access. */ |
| 9 | #include "isa.h" |
| 10 | |
| 11 | /* PCI bus */ |
| 12 | |
| 13 | extern target_phys_addr_t pci_mem_base; |
| 14 | |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [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 | |
| 19 | /* Class, Vendor and Device IDs from Linux's pci_ids.h */ |
| 20 | #include "pci_ids.h" |
| 21 | |
| 22 | /* QEMU-specific Vendor and Device ID definitions */ |
| 23 | |
| 24 | /* IBM (0x1014) */ |
| 25 | #define PCI_DEVICE_ID_IBM_440GX 0x027f |
| 26 | #define PCI_DEVICE_ID_IBM_OPENPIC2 0xffff |
| 27 | |
| 28 | /* Hitachi (0x1054) */ |
| 29 | #define PCI_VENDOR_ID_HITACHI 0x1054 |
| 30 | #define PCI_DEVICE_ID_HITACHI_SH7751R 0x350e |
| 31 | |
| 32 | /* Apple (0x106b) */ |
| 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 |
| 36 | #define PCI_DEVICE_ID_APPLE_UNI_N_KEYL 0x0022 |
| 37 | #define PCI_DEVICE_ID_APPLE_IPID_USB 0x003f |
| 38 | |
| 39 | /* Realtek (0x10ec) */ |
| 40 | #define PCI_DEVICE_ID_REALTEK_8029 0x8029 |
| 41 | |
| 42 | /* Xilinx (0x10ee) */ |
| 43 | #define PCI_DEVICE_ID_XILINX_XC2VP30 0x0300 |
| 44 | |
| 45 | /* Marvell (0x11ab) */ |
| 46 | #define PCI_DEVICE_ID_MARVELL_GT6412X 0x4620 |
| 47 | |
| 48 | /* QEMU/Bochs VGA (0x1234) */ |
| 49 | #define PCI_VENDOR_ID_QEMU 0x1234 |
| 50 | #define PCI_DEVICE_ID_QEMU_VGA 0x1111 |
| 51 | |
| 52 | /* VMWare (0x15ad) */ |
| 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 | |
| 60 | /* Intel (0x8086) */ |
| 61 | #define PCI_DEVICE_ID_INTEL_82551IT 0x1209 |
| 62 | |
| 63 | /* Red Hat / Qumranet (for QEMU) -- see pci-ids.txt */ |
| 64 | #define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4 |
| 65 | #define PCI_SUBVENDOR_ID_REDHAT_QUMRANET 0x1af4 |
| 66 | #define PCI_SUBDEVICE_ID_QEMU 0x1100 |
| 67 | |
| 68 | #define PCI_DEVICE_ID_VIRTIO_NET 0x1000 |
| 69 | #define PCI_DEVICE_ID_VIRTIO_BLOCK 0x1001 |
| 70 | #define PCI_DEVICE_ID_VIRTIO_BALLOON 0x1002 |
| 71 | #define PCI_DEVICE_ID_VIRTIO_CONSOLE 0x1003 |
| 72 | |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 73 | typedef void PCIConfigWriteFunc(PCIDevice *pci_dev, |
| 74 | uint32_t address, uint32_t data, int len); |
| 75 | typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev, |
| 76 | uint32_t address, int len); |
| 77 | typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num, |
| 78 | uint32_t addr, uint32_t size, int type); |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 79 | typedef int PCIUnregisterFunc(PCIDevice *pci_dev); |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 80 | |
| 81 | #define PCI_ADDRESS_SPACE_MEM 0x00 |
| 82 | #define PCI_ADDRESS_SPACE_IO 0x01 |
| 83 | #define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08 |
| 84 | |
| 85 | typedef struct PCIIORegion { |
| 86 | uint32_t addr; /* current PCI mapping address. -1 means not mapped */ |
| 87 | uint32_t size; |
| 88 | uint8_t type; |
| 89 | PCIMapIORegionFunc *map_func; |
| 90 | } PCIIORegion; |
| 91 | |
| 92 | #define PCI_ROM_SLOT 6 |
| 93 | #define PCI_NUM_REGIONS 7 |
| 94 | |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 95 | /* Declarations from linux/pci_regs.h */ |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 96 | #define PCI_VENDOR_ID 0x00 /* 16 bits */ |
| 97 | #define PCI_DEVICE_ID 0x02 /* 16 bits */ |
| 98 | #define PCI_COMMAND 0x04 /* 16 bits */ |
| 99 | #define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ |
| 100 | #define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 101 | #define PCI_STATUS 0x06 /* 16 bits */ |
| 102 | #define PCI_REVISION_ID 0x08 /* 8 bits */ |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 103 | #define PCI_CLASS_DEVICE 0x0a /* Device class */ |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 104 | #define PCI_HEADER_TYPE 0x0e /* 8 bits */ |
| 105 | #define PCI_HEADER_TYPE_NORMAL 0 |
| 106 | #define PCI_HEADER_TYPE_BRIDGE 1 |
| 107 | #define PCI_HEADER_TYPE_CARDBUS 2 |
| 108 | #define PCI_HEADER_TYPE_MULTI_FUNCTION 0x80 |
| 109 | #define PCI_SUBSYSTEM_VENDOR_ID 0x2c /* 16 bits */ |
| 110 | #define PCI_SUBSYSTEM_ID 0x2e /* 16 bits */ |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 111 | #define PCI_INTERRUPT_LINE 0x3c /* 8 bits */ |
| 112 | #define PCI_INTERRUPT_PIN 0x3d /* 8 bits */ |
| 113 | #define PCI_MIN_GNT 0x3e /* 8 bits */ |
| 114 | #define PCI_MAX_LAT 0x3f /* 8 bits */ |
| 115 | |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 116 | #define PCI_REVISION 0x08 /* obsolete, use PCI_REVISION_ID */ |
| 117 | #define PCI_SUBVENDOR_ID 0x2c /* obsolete, use PCI_SUBSYSTEM_VENDOR_ID */ |
| 118 | #define PCI_SUBDEVICE_ID 0x2e /* obsolete, use PCI_SUBSYSTEM_ID */ |
| 119 | |
| 120 | /* Bits in the PCI Status Register (PCI 2.3 spec) */ |
| 121 | #define PCI_STATUS_RESERVED1 0x007 |
| 122 | #define PCI_STATUS_INT_STATUS 0x008 |
| 123 | #define PCI_STATUS_CAPABILITIES 0x010 |
| 124 | #define PCI_STATUS_66MHZ 0x020 |
| 125 | #define PCI_STATUS_RESERVED2 0x040 |
| 126 | #define PCI_STATUS_FAST_BACK 0x080 |
| 127 | #define PCI_STATUS_DEVSEL 0x600 |
| 128 | |
| 129 | #define PCI_STATUS_RESERVED_MASK_LO (PCI_STATUS_RESERVED1 | \ |
| 130 | PCI_STATUS_INT_STATUS | PCI_STATUS_CAPABILITIES | \ |
| 131 | PCI_STATUS_66MHZ | PCI_STATUS_RESERVED2 | PCI_STATUS_FAST_BACK) |
| 132 | |
| 133 | #define PCI_STATUS_RESERVED_MASK_HI (PCI_STATUS_DEVSEL >> 8) |
| 134 | |
| 135 | /* Bits in the PCI Command Register (PCI 2.3 spec) */ |
| 136 | #define PCI_COMMAND_RESERVED 0xf800 |
| 137 | |
| 138 | #define PCI_COMMAND_RESERVED_MASK_HI (PCI_COMMAND_RESERVED >> 8) |
| 139 | |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 140 | struct PCIDevice { |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 141 | DeviceState qdev; |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 142 | /* PCI config space */ |
| 143 | uint8_t config[256]; |
| 144 | |
| 145 | /* the following fields are read only */ |
| 146 | PCIBus *bus; |
| 147 | int devfn; |
| 148 | char name[64]; |
| 149 | PCIIORegion io_regions[PCI_NUM_REGIONS]; |
| 150 | |
| 151 | /* do not access the following fields */ |
| 152 | PCIConfigReadFunc *config_read; |
| 153 | PCIConfigWriteFunc *config_write; |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 154 | PCIUnregisterFunc *unregister; |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 155 | |
| 156 | /* IRQ objects for the INTA-INTD pins. */ |
| 157 | qemu_irq *irq; |
| 158 | |
| 159 | /* Current IRQ levels. Used internally by the generic PCI code. */ |
| 160 | int irq_state[4]; |
| 161 | }; |
| 162 | |
| 163 | PCIDevice *pci_register_device(PCIBus *bus, const char *name, |
| 164 | int instance_size, int devfn, |
| 165 | PCIConfigReadFunc *config_read, |
| 166 | PCIConfigWriteFunc *config_write); |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 167 | int pci_unregister_device(PCIDevice *pci_dev); |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 168 | |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 169 | void pci_register_bar(PCIDevice *pci_dev, int region_num, |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 170 | uint32_t size, int type, |
| 171 | PCIMapIORegionFunc *map_func); |
| 172 | |
| 173 | uint32_t pci_default_read_config(PCIDevice *d, |
| 174 | uint32_t address, int len); |
| 175 | void pci_default_write_config(PCIDevice *d, |
| 176 | uint32_t address, uint32_t val, int len); |
| 177 | void pci_device_save(PCIDevice *s, QEMUFile *f); |
| 178 | int pci_device_load(PCIDevice *s, QEMUFile *f); |
| 179 | |
| 180 | typedef void (*pci_set_irq_fn)(qemu_irq *pic, int irq_num, int level); |
| 181 | typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 182 | PCIBus *pci_register_bus(DeviceState *parent, const char *name, |
| 183 | pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 184 | qemu_irq *pic, int devfn_min, int nirq); |
| 185 | |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 186 | PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn, |
| 187 | const char *default_model); |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 188 | void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len); |
| 189 | uint32_t pci_data_read(void *opaque, uint32_t addr, int len); |
| 190 | int pci_bus_num(PCIBus *s); |
| 191 | void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d)); |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 192 | PCIBus *pci_find_bus(int bus_num); |
| 193 | PCIDevice *pci_find_device(int bus_num, int slot, int function); |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 194 | |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 195 | int pci_read_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp); |
| 196 | int pci_assign_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp); |
| 197 | |
| 198 | void pci_info(Monitor *mon); |
| 199 | PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did, |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 200 | pci_map_irq_fn map_irq, const char *name); |
| 201 | |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 202 | static inline void |
| 203 | pci_config_set_vendor_id(uint8_t *pci_config, uint16_t val) |
| 204 | { |
| 205 | cpu_to_le16wu((uint16_t *)&pci_config[PCI_VENDOR_ID], val); |
| 206 | } |
| 207 | |
| 208 | static inline void |
| 209 | pci_config_set_device_id(uint8_t *pci_config, uint16_t val) |
| 210 | { |
| 211 | cpu_to_le16wu((uint16_t *)&pci_config[PCI_DEVICE_ID], val); |
| 212 | } |
| 213 | |
| 214 | static inline void |
| 215 | pci_config_set_class(uint8_t *pci_config, uint16_t val) |
| 216 | { |
| 217 | cpu_to_le16wu((uint16_t *)&pci_config[PCI_CLASS_DEVICE], val); |
| 218 | } |
| 219 | |
| 220 | typedef void (*pci_qdev_initfn)(PCIDevice *dev); |
| 221 | void pci_qdev_register(const char *name, int size, pci_qdev_initfn init); |
| 222 | |
| 223 | PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name); |
| 224 | |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 225 | /* lsi53c895a.c */ |
| 226 | #define LSI_MAX_DEVS 7 |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 227 | void lsi_scsi_attach(DeviceState *host, BlockDriverState *bd, int id); |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 228 | |
| 229 | /* vmware_vga.c */ |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 230 | void pci_vmsvga_init(PCIBus *bus); |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 231 | |
| 232 | /* usb-uhci.c */ |
| 233 | void usb_uhci_piix3_init(PCIBus *bus, int devfn); |
| 234 | void usb_uhci_piix4_init(PCIBus *bus, int devfn); |
| 235 | |
| 236 | /* usb-ohci.c */ |
| 237 | void usb_ohci_init_pci(struct PCIBus *bus, int num_ports, int devfn); |
| 238 | |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 239 | /* prep_pci.c */ |
| 240 | PCIBus *pci_prep_init(qemu_irq *pic); |
| 241 | |
| 242 | /* apb_pci.c */ |
David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 243 | PCIBus *pci_apb_init(target_phys_addr_t special_base, |
| 244 | target_phys_addr_t mem_base, |
| 245 | qemu_irq *pic, PCIBus **bus2, PCIBus **bus3); |
| 246 | |
| 247 | /* sh_pci.c */ |
| 248 | PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, |
| 249 | qemu_irq *pic, int devfn_min, int nirq); |
The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 250 | |
| 251 | #endif |