prep_pci.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * QEMU PREP PCI host
  3. *
  4. * Copyright (c) 2006 Fabrice Bellard
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "hw.h"
  25. #include "pci/pci.h"
  26. #include "pci/pci_host.h"
  27. #include "pc.h"
  28. #include "exec-memory.h"
  29. #define TYPE_RAVEN_PCI_HOST_BRIDGE "raven-pcihost"
  30. #define RAVEN_PCI_HOST_BRIDGE(obj) \
  31. OBJECT_CHECK(PREPPCIState, (obj), TYPE_RAVEN_PCI_HOST_BRIDGE)
  32. typedef struct PRePPCIState {
  33. PCIHostState parent_obj;
  34. MemoryRegion intack;
  35. qemu_irq irq[4];
  36. } PREPPCIState;
  37. typedef struct RavenPCIState {
  38. PCIDevice dev;
  39. } RavenPCIState;
  40. static inline uint32_t PPC_PCIIO_config(hwaddr addr)
  41. {
  42. int i;
  43. for (i = 0; i < 11; i++) {
  44. if ((addr & (1 << (11 + i))) != 0) {
  45. break;
  46. }
  47. }
  48. return (addr & 0x7ff) | (i << 11);
  49. }
  50. static void ppc_pci_io_write(void *opaque, hwaddr addr,
  51. uint64_t val, unsigned int size)
  52. {
  53. PREPPCIState *s = opaque;
  54. PCIHostState *phb = PCI_HOST_BRIDGE(s);
  55. pci_data_write(phb->bus, PPC_PCIIO_config(addr), val, size);
  56. }
  57. static uint64_t ppc_pci_io_read(void *opaque, hwaddr addr,
  58. unsigned int size)
  59. {
  60. PREPPCIState *s = opaque;
  61. PCIHostState *phb = PCI_HOST_BRIDGE(s);
  62. return pci_data_read(phb->bus, PPC_PCIIO_config(addr), size);
  63. }
  64. static const MemoryRegionOps PPC_PCIIO_ops = {
  65. .read = ppc_pci_io_read,
  66. .write = ppc_pci_io_write,
  67. .endianness = DEVICE_LITTLE_ENDIAN,
  68. };
  69. static uint64_t ppc_intack_read(void *opaque, hwaddr addr,
  70. unsigned int size)
  71. {
  72. return pic_read_irq(isa_pic);
  73. }
  74. static const MemoryRegionOps PPC_intack_ops = {
  75. .read = ppc_intack_read,
  76. .valid = {
  77. .max_access_size = 1,
  78. },
  79. };
  80. static int prep_map_irq(PCIDevice *pci_dev, int irq_num)
  81. {
  82. return (irq_num + (pci_dev->devfn >> 3)) & 1;
  83. }
  84. static void prep_set_irq(void *opaque, int irq_num, int level)
  85. {
  86. qemu_irq *pic = opaque;
  87. qemu_set_irq(pic[irq_num] , level);
  88. }
  89. static int raven_pcihost_init(SysBusDevice *dev)
  90. {
  91. PCIHostState *h = PCI_HOST_BRIDGE(dev);
  92. PREPPCIState *s = RAVEN_PCI_HOST_BRIDGE(dev);
  93. MemoryRegion *address_space_mem = get_system_memory();
  94. MemoryRegion *address_space_io = get_system_io();
  95. PCIBus *bus;
  96. int i;
  97. for (i = 0; i < 4; i++) {
  98. sysbus_init_irq(dev, &s->irq[i]);
  99. }
  100. bus = pci_register_bus(DEVICE(dev), NULL,
  101. prep_set_irq, prep_map_irq, s->irq,
  102. address_space_mem, address_space_io, 0, 4);
  103. h->bus = bus;
  104. memory_region_init_io(&h->conf_mem, &pci_host_conf_be_ops, s,
  105. "pci-conf-idx", 1);
  106. sysbus_add_io(dev, 0xcf8, &h->conf_mem);
  107. sysbus_init_ioports(&h->busdev, 0xcf8, 1);
  108. memory_region_init_io(&h->data_mem, &pci_host_data_be_ops, s,
  109. "pci-conf-data", 1);
  110. sysbus_add_io(dev, 0xcfc, &h->data_mem);
  111. sysbus_init_ioports(&h->busdev, 0xcfc, 1);
  112. memory_region_init_io(&h->mmcfg, &PPC_PCIIO_ops, s, "pciio", 0x00400000);
  113. memory_region_add_subregion(address_space_mem, 0x80800000, &h->mmcfg);
  114. memory_region_init_io(&s->intack, &PPC_intack_ops, s, "pci-intack", 1);
  115. memory_region_add_subregion(address_space_mem, 0xbffffff0, &s->intack);
  116. pci_create_simple(bus, 0, "raven");
  117. return 0;
  118. }
  119. static int raven_init(PCIDevice *d)
  120. {
  121. d->config[0x0C] = 0x08; // cache_line_size
  122. d->config[0x0D] = 0x10; // latency_timer
  123. d->config[0x34] = 0x00; // capabilities_pointer
  124. return 0;
  125. }
  126. static const VMStateDescription vmstate_raven = {
  127. .name = "raven",
  128. .version_id = 0,
  129. .minimum_version_id = 0,
  130. .fields = (VMStateField[]) {
  131. VMSTATE_PCI_DEVICE(dev, RavenPCIState),
  132. VMSTATE_END_OF_LIST()
  133. },
  134. };
  135. static void raven_class_init(ObjectClass *klass, void *data)
  136. {
  137. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  138. DeviceClass *dc = DEVICE_CLASS(klass);
  139. k->init = raven_init;
  140. k->vendor_id = PCI_VENDOR_ID_MOTOROLA;
  141. k->device_id = PCI_DEVICE_ID_MOTOROLA_RAVEN;
  142. k->revision = 0x00;
  143. k->class_id = PCI_CLASS_BRIDGE_HOST;
  144. dc->desc = "PReP Host Bridge - Motorola Raven";
  145. dc->vmsd = &vmstate_raven;
  146. dc->no_user = 1;
  147. }
  148. static const TypeInfo raven_info = {
  149. .name = "raven",
  150. .parent = TYPE_PCI_DEVICE,
  151. .instance_size = sizeof(RavenPCIState),
  152. .class_init = raven_class_init,
  153. };
  154. static void raven_pcihost_class_init(ObjectClass *klass, void *data)
  155. {
  156. SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
  157. DeviceClass *dc = DEVICE_CLASS(klass);
  158. k->init = raven_pcihost_init;
  159. dc->fw_name = "pci";
  160. dc->no_user = 1;
  161. }
  162. static const TypeInfo raven_pcihost_info = {
  163. .name = TYPE_RAVEN_PCI_HOST_BRIDGE,
  164. .parent = TYPE_PCI_HOST_BRIDGE,
  165. .instance_size = sizeof(PREPPCIState),
  166. .class_init = raven_pcihost_class_init,
  167. };
  168. static void raven_register_types(void)
  169. {
  170. type_register_static(&raven_pcihost_info);
  171. type_register_static(&raven_info);
  172. }
  173. type_init(raven_register_types)