2
0

sh_pci.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. if ((val & 0xfffc0000) != (pcic->iobr & 0xfffc0000)) {
  64. memory_region_del_subregion(get_system_memory(), &pcic->isa);
  65. pcic->iobr = val & 0xfffc0001;
  66. memory_region_add_subregion(get_system_memory(),
  67. pcic->iobr & 0xfffc0000, &pcic->isa);
  68. }
  69. break;
  70. case 0x220:
  71. pci_data_write(phb->bus, pcic->par, val, 4);
  72. break;
  73. }
  74. }
  75. static uint64_t sh_pci_reg_read (void *p, hwaddr addr,
  76. unsigned size)
  77. {
  78. SHPCIState *pcic = p;
  79. PCIHostState *phb = PCI_HOST_BRIDGE(pcic);
  80. switch(addr) {
  81. case 0 ... 0xfc:
  82. return ldl_le_p(pcic->dev->config + addr);
  83. case 0x1c0:
  84. return pcic->par;
  85. case 0x1c4:
  86. return pcic->mbr;
  87. case 0x1c8:
  88. return pcic->iobr;
  89. case 0x220:
  90. return pci_data_read(phb->bus, pcic->par, 4);
  91. }
  92. return 0;
  93. }
  94. static const MemoryRegionOps sh_pci_reg_ops = {
  95. .read = sh_pci_reg_read,
  96. .write = sh_pci_reg_write,
  97. .endianness = DEVICE_NATIVE_ENDIAN,
  98. .valid = {
  99. .min_access_size = 4,
  100. .max_access_size = 4,
  101. },
  102. };
  103. static int sh_pci_map_irq(PCIDevice *d, int irq_num)
  104. {
  105. return (d->devfn >> 3);
  106. }
  107. static void sh_pci_set_irq(void *opaque, int irq_num, int level)
  108. {
  109. qemu_irq *pic = opaque;
  110. qemu_set_irq(pic[irq_num], level);
  111. }
  112. static void sh_pci_device_realize(DeviceState *dev, Error **errp)
  113. {
  114. SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
  115. SHPCIState *s = SH_PCI_HOST_BRIDGE(dev);
  116. PCIHostState *phb = PCI_HOST_BRIDGE(s);
  117. int i;
  118. for (i = 0; i < 4; i++) {
  119. sysbus_init_irq(sbd, &s->irq[i]);
  120. }
  121. phb->bus = pci_register_root_bus(DEVICE(dev), "pci",
  122. sh_pci_set_irq, sh_pci_map_irq,
  123. s->irq,
  124. get_system_memory(),
  125. get_system_io(),
  126. PCI_DEVFN(0, 0), 4, TYPE_PCI_BUS);
  127. memory_region_init_io(&s->memconfig_p4, OBJECT(s), &sh_pci_reg_ops, s,
  128. "sh_pci", 0x224);
  129. memory_region_init_alias(&s->memconfig_a7, OBJECT(s), "sh_pci.2",
  130. &s->memconfig_p4, 0, 0x224);
  131. memory_region_init_alias(&s->isa, OBJECT(s), "sh_pci.isa",
  132. get_system_io(), 0, 0x40000);
  133. sysbus_init_mmio(sbd, &s->memconfig_p4);
  134. sysbus_init_mmio(sbd, &s->memconfig_a7);
  135. s->iobr = 0xfe240000;
  136. memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa);
  137. s->dev = pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "sh_pci_host");
  138. }
  139. static void sh_pci_host_realize(PCIDevice *d, Error **errp)
  140. {
  141. pci_set_word(d->config + PCI_COMMAND, PCI_COMMAND_WAIT);
  142. pci_set_word(d->config + PCI_STATUS, PCI_STATUS_CAP_LIST |
  143. PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
  144. }
  145. static void sh_pci_host_class_init(ObjectClass *klass, void *data)
  146. {
  147. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  148. DeviceClass *dc = DEVICE_CLASS(klass);
  149. k->realize = sh_pci_host_realize;
  150. k->vendor_id = PCI_VENDOR_ID_HITACHI;
  151. k->device_id = PCI_DEVICE_ID_HITACHI_SH7751R;
  152. /*
  153. * PCI-facing part of the host bridge, not usable without the
  154. * host-facing part, which can't be device_add'ed, yet.
  155. */
  156. dc->user_creatable = false;
  157. }
  158. static const TypeInfo sh_pci_host_info = {
  159. .name = "sh_pci_host",
  160. .parent = TYPE_PCI_DEVICE,
  161. .instance_size = sizeof(PCIDevice),
  162. .class_init = sh_pci_host_class_init,
  163. .interfaces = (InterfaceInfo[]) {
  164. { INTERFACE_CONVENTIONAL_PCI_DEVICE },
  165. { },
  166. },
  167. };
  168. static void sh_pci_device_class_init(ObjectClass *klass, void *data)
  169. {
  170. DeviceClass *dc = DEVICE_CLASS(klass);
  171. dc->realize = sh_pci_device_realize;
  172. }
  173. static const TypeInfo sh_pci_device_info = {
  174. .name = TYPE_SH_PCI_HOST_BRIDGE,
  175. .parent = TYPE_PCI_HOST_BRIDGE,
  176. .instance_size = sizeof(SHPCIState),
  177. .class_init = sh_pci_device_class_init,
  178. };
  179. static void sh_pci_register_types(void)
  180. {
  181. type_register_static(&sh_pci_device_info);
  182. type_register_static(&sh_pci_host_info);
  183. }
  184. type_init(sh_pci_register_types)