versatile_pci.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * ARM Versatile/PB PCI host controller
  3. *
  4. * Copyright (c) 2006-2009 CodeSourcery.
  5. * Written by Paul Brook
  6. *
  7. * This code is licensed under the LGPL.
  8. */
  9. #include "sysbus.h"
  10. #include "pci/pci.h"
  11. #include "pci/pci_host.h"
  12. #include "exec-memory.h"
  13. typedef struct {
  14. SysBusDevice busdev;
  15. qemu_irq irq[4];
  16. int realview;
  17. MemoryRegion mem_config;
  18. MemoryRegion mem_config2;
  19. MemoryRegion isa;
  20. } PCIVPBState;
  21. static inline uint32_t vpb_pci_config_addr(hwaddr addr)
  22. {
  23. return addr & 0xffffff;
  24. }
  25. static void pci_vpb_config_write(void *opaque, hwaddr addr,
  26. uint64_t val, unsigned size)
  27. {
  28. pci_data_write(opaque, vpb_pci_config_addr(addr), val, size);
  29. }
  30. static uint64_t pci_vpb_config_read(void *opaque, hwaddr addr,
  31. unsigned size)
  32. {
  33. uint32_t val;
  34. val = pci_data_read(opaque, vpb_pci_config_addr(addr), size);
  35. return val;
  36. }
  37. static const MemoryRegionOps pci_vpb_config_ops = {
  38. .read = pci_vpb_config_read,
  39. .write = pci_vpb_config_write,
  40. .endianness = DEVICE_NATIVE_ENDIAN,
  41. };
  42. static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
  43. {
  44. return irq_num;
  45. }
  46. static void pci_vpb_set_irq(void *opaque, int irq_num, int level)
  47. {
  48. qemu_irq *pic = opaque;
  49. qemu_set_irq(pic[irq_num], level);
  50. }
  51. static int pci_vpb_init(SysBusDevice *dev)
  52. {
  53. PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev);
  54. PCIBus *bus;
  55. int i;
  56. for (i = 0; i < 4; i++) {
  57. sysbus_init_irq(dev, &s->irq[i]);
  58. }
  59. bus = pci_register_bus(&dev->qdev, "pci",
  60. pci_vpb_set_irq, pci_vpb_map_irq, s->irq,
  61. get_system_memory(), get_system_io(),
  62. PCI_DEVFN(11, 0), 4);
  63. /* ??? Register memory space. */
  64. /* Our memory regions are:
  65. * 0 : PCI self config window
  66. * 1 : PCI config window
  67. * 2 : PCI IO window (realview_pci only)
  68. */
  69. memory_region_init_io(&s->mem_config, &pci_vpb_config_ops, bus,
  70. "pci-vpb-selfconfig", 0x1000000);
  71. sysbus_init_mmio(dev, &s->mem_config);
  72. memory_region_init_io(&s->mem_config2, &pci_vpb_config_ops, bus,
  73. "pci-vpb-config", 0x1000000);
  74. sysbus_init_mmio(dev, &s->mem_config2);
  75. if (s->realview) {
  76. isa_mmio_setup(&s->isa, 0x0100000);
  77. sysbus_init_mmio(dev, &s->isa);
  78. }
  79. pci_create_simple(bus, -1, "versatile_pci_host");
  80. return 0;
  81. }
  82. static int pci_realview_init(SysBusDevice *dev)
  83. {
  84. PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev);
  85. s->realview = 1;
  86. return pci_vpb_init(dev);
  87. }
  88. static int versatile_pci_host_init(PCIDevice *d)
  89. {
  90. pci_set_word(d->config + PCI_STATUS,
  91. PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM);
  92. pci_set_byte(d->config + PCI_LATENCY_TIMER, 0x10);
  93. return 0;
  94. }
  95. static void versatile_pci_host_class_init(ObjectClass *klass, void *data)
  96. {
  97. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  98. k->init = versatile_pci_host_init;
  99. k->vendor_id = PCI_VENDOR_ID_XILINX;
  100. k->device_id = PCI_DEVICE_ID_XILINX_XC2VP30;
  101. k->class_id = PCI_CLASS_PROCESSOR_CO;
  102. }
  103. static TypeInfo versatile_pci_host_info = {
  104. .name = "versatile_pci_host",
  105. .parent = TYPE_PCI_DEVICE,
  106. .instance_size = sizeof(PCIDevice),
  107. .class_init = versatile_pci_host_class_init,
  108. };
  109. static void pci_vpb_class_init(ObjectClass *klass, void *data)
  110. {
  111. SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
  112. sdc->init = pci_vpb_init;
  113. }
  114. static TypeInfo pci_vpb_info = {
  115. .name = "versatile_pci",
  116. .parent = TYPE_SYS_BUS_DEVICE,
  117. .instance_size = sizeof(PCIVPBState),
  118. .class_init = pci_vpb_class_init,
  119. };
  120. static void pci_realview_class_init(ObjectClass *klass, void *data)
  121. {
  122. SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
  123. sdc->init = pci_realview_init;
  124. }
  125. static TypeInfo pci_realview_info = {
  126. .name = "realview_pci",
  127. .parent = TYPE_SYS_BUS_DEVICE,
  128. .instance_size = sizeof(PCIVPBState),
  129. .class_init = pci_realview_class_init,
  130. };
  131. static void versatile_pci_register_types(void)
  132. {
  133. type_register_static(&pci_vpb_info);
  134. type_register_static(&pci_realview_info);
  135. type_register_static(&versatile_pci_host_info);
  136. }
  137. type_init(versatile_pci_register_types)