sh_pci.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*
  2. * SuperH on-chip PCIC emulation.
  3. *
  4. * Copyright (c) 2008 Takashi YOSHII
  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 "qemu/osdep.h"
  25. #include "hw/sysbus.h"
  26. #include "hw/sh4/sh.h"
  27. #include "hw/irq.h"
  28. #include "hw/pci/pci.h"
  29. #include "hw/pci/pci_host.h"
  30. #include "qemu/bswap.h"
  31. #include "qemu/module.h"
  32. #include "exec/address-spaces.h"
  33. #define TYPE_SH_PCI_HOST_BRIDGE "sh_pci"
  34. #define SH_PCI_HOST_BRIDGE(obj) \
  35. OBJECT_CHECK(SHPCIState, (obj), TYPE_SH_PCI_HOST_BRIDGE)
  36. typedef struct SHPCIState {
  37. PCIHostState parent_obj;
  38. PCIDevice *dev;
  39. qemu_irq irq[4];
  40. MemoryRegion memconfig_p4;
  41. MemoryRegion memconfig_a7;
  42. MemoryRegion isa;
  43. uint32_t par;
  44. uint32_t mbr;
  45. uint32_t iobr;
  46. } SHPCIState;
  47. static void sh_pci_reg_write (void *p, hwaddr addr, uint64_t val,
  48. unsigned size)
  49. {
  50. SHPCIState *pcic = p;
  51. PCIHostState *phb = PCI_HOST_BRIDGE(pcic);
  52. switch(addr) {
  53. case 0 ... 0xfc:
  54. stl_le_p(pcic->dev->config + addr, val);
  55. break;
  56. case 0x1c0:
  57. pcic->par = val;
  58. break;
  59. case 0x1c4:
  60. pcic->mbr = val & 0xff000001;
  61. break;
  62. case 0x1c8:
  63. pcic->iobr = val & 0xfffc0001;
  64. memory_region_set_alias_offset(&pcic->isa, val & 0xfffc0000);
  65. break;
  66. case 0x220:
  67. pci_data_write(phb->bus, pcic->par, val, 4);
  68. break;
  69. }
  70. }
  71. static uint64_t sh_pci_reg_read (void *p, hwaddr addr,
  72. unsigned size)
  73. {
  74. SHPCIState *pcic = p;
  75. PCIHostState *phb = PCI_HOST_BRIDGE(pcic);
  76. switch(addr) {
  77. case 0 ... 0xfc:
  78. return ldl_le_p(pcic->dev->config + addr);
  79. case 0x1c0:
  80. return pcic->par;
  81. case 0x1c4:
  82. return pcic->mbr;
  83. case 0x1c8:
  84. return pcic->iobr;
  85. case 0x220:
  86. return pci_data_read(phb->bus, pcic->par, 4);
  87. }
  88. return 0;
  89. }
  90. static const MemoryRegionOps sh_pci_reg_ops = {
  91. .read = sh_pci_reg_read,
  92. .write = sh_pci_reg_write,
  93. .endianness = DEVICE_NATIVE_ENDIAN,
  94. .valid = {
  95. .min_access_size = 4,
  96. .max_access_size = 4,
  97. },
  98. };
  99. static int sh_pci_map_irq(PCIDevice *d, int irq_num)
  100. {
  101. return (d->devfn >> 3);
  102. }
  103. static void sh_pci_set_irq(void *opaque, int irq_num, int level)
  104. {
  105. qemu_irq *pic = opaque;
  106. qemu_set_irq(pic[irq_num], level);
  107. }
  108. static void sh_pci_device_realize(DeviceState *dev, Error **errp)
  109. {
  110. SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
  111. SHPCIState *s = SH_PCI_HOST_BRIDGE(dev);
  112. PCIHostState *phb = PCI_HOST_BRIDGE(s);
  113. int i;
  114. for (i = 0; i < 4; i++) {
  115. sysbus_init_irq(sbd, &s->irq[i]);
  116. }
  117. phb->bus = pci_register_root_bus(dev, "pci",
  118. sh_pci_set_irq, sh_pci_map_irq,
  119. s->irq,
  120. get_system_memory(),
  121. get_system_io(),
  122. PCI_DEVFN(0, 0), 4, TYPE_PCI_BUS);
  123. memory_region_init_io(&s->memconfig_p4, OBJECT(s), &sh_pci_reg_ops, s,
  124. "sh_pci", 0x224);
  125. memory_region_init_alias(&s->memconfig_a7, OBJECT(s), "sh_pci.2",
  126. &s->memconfig_p4, 0, 0x224);
  127. memory_region_init_alias(&s->isa, OBJECT(s), "sh_pci.isa",
  128. get_system_io(), 0, 0x40000);
  129. sysbus_init_mmio(sbd, &s->memconfig_p4);
  130. sysbus_init_mmio(sbd, &s->memconfig_a7);
  131. memory_region_add_subregion(get_system_memory(), 0xfe240000, &s->isa);
  132. s->dev = pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "sh_pci_host");
  133. }
  134. static void sh_pci_host_realize(PCIDevice *d, Error **errp)
  135. {
  136. pci_set_word(d->config + PCI_COMMAND, PCI_COMMAND_WAIT);
  137. pci_set_word(d->config + PCI_STATUS, PCI_STATUS_CAP_LIST |
  138. PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
  139. }
  140. static void sh_pci_host_class_init(ObjectClass *klass, void *data)
  141. {
  142. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  143. DeviceClass *dc = DEVICE_CLASS(klass);
  144. k->realize = sh_pci_host_realize;
  145. k->vendor_id = PCI_VENDOR_ID_HITACHI;
  146. k->device_id = PCI_DEVICE_ID_HITACHI_SH7751R;
  147. /*
  148. * PCI-facing part of the host bridge, not usable without the
  149. * host-facing part, which can't be device_add'ed, yet.
  150. */
  151. dc->user_creatable = false;
  152. }
  153. static const TypeInfo sh_pci_host_info = {
  154. .name = "sh_pci_host",
  155. .parent = TYPE_PCI_DEVICE,
  156. .instance_size = sizeof(PCIDevice),
  157. .class_init = sh_pci_host_class_init,
  158. .interfaces = (InterfaceInfo[]) {
  159. { INTERFACE_CONVENTIONAL_PCI_DEVICE },
  160. { },
  161. },
  162. };
  163. static void sh_pci_device_class_init(ObjectClass *klass, void *data)
  164. {
  165. DeviceClass *dc = DEVICE_CLASS(klass);
  166. dc->realize = sh_pci_device_realize;
  167. }
  168. static const TypeInfo sh_pci_device_info = {
  169. .name = TYPE_SH_PCI_HOST_BRIDGE,
  170. .parent = TYPE_PCI_HOST_BRIDGE,
  171. .instance_size = sizeof(SHPCIState),
  172. .class_init = sh_pci_device_class_init,
  173. };
  174. static void sh_pci_register_types(void)
  175. {
  176. type_register_static(&sh_pci_device_info);
  177. type_register_static(&sh_pci_host_info);
  178. }
  179. type_init(sh_pci_register_types)