mv64361.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950
  1. /*
  2. * Marvell Discovery II MV64361 System Controller for
  3. * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator
  4. *
  5. * Copyright (c) 2018-2020 BALATON Zoltan
  6. *
  7. * This work is licensed under the GNU GPL license version 2 or later.
  8. *
  9. */
  10. #include "qemu/osdep.h"
  11. #include "qemu/units.h"
  12. #include "qapi/error.h"
  13. #include "hw/hw.h"
  14. #include "hw/sysbus.h"
  15. #include "hw/pci/pci.h"
  16. #include "hw/pci/pci_host.h"
  17. #include "hw/irq.h"
  18. #include "hw/intc/i8259.h"
  19. #include "hw/qdev-properties.h"
  20. #include "exec/address-spaces.h"
  21. #include "qemu/log.h"
  22. #include "qemu/error-report.h"
  23. #include "trace.h"
  24. #include "hw/pci-host/mv64361.h"
  25. #include "mv643xx.h"
  26. #define TYPE_MV64361_PCI_BRIDGE "mv64361-pcibridge"
  27. static void mv64361_pcibridge_class_init(ObjectClass *klass, void *data)
  28. {
  29. DeviceClass *dc = DEVICE_CLASS(klass);
  30. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  31. k->vendor_id = PCI_VENDOR_ID_MARVELL;
  32. k->device_id = PCI_DEVICE_ID_MARVELL_MV6436X;
  33. k->class_id = PCI_CLASS_BRIDGE_HOST;
  34. /*
  35. * PCI-facing part of the host bridge,
  36. * not usable without the host-facing part
  37. */
  38. dc->user_creatable = false;
  39. }
  40. static const TypeInfo mv64361_pcibridge_info = {
  41. .name = TYPE_MV64361_PCI_BRIDGE,
  42. .parent = TYPE_PCI_DEVICE,
  43. .instance_size = sizeof(PCIDevice),
  44. .class_init = mv64361_pcibridge_class_init,
  45. .interfaces = (InterfaceInfo[]) {
  46. { INTERFACE_CONVENTIONAL_PCI_DEVICE },
  47. { },
  48. },
  49. };
  50. #define TYPE_MV64361_PCI "mv64361-pcihost"
  51. OBJECT_DECLARE_SIMPLE_TYPE(MV64361PCIState, MV64361_PCI)
  52. struct MV64361PCIState {
  53. PCIHostState parent_obj;
  54. uint8_t index;
  55. MemoryRegion io;
  56. MemoryRegion mem;
  57. qemu_irq irq[PCI_NUM_PINS];
  58. uint32_t io_base;
  59. uint32_t io_size;
  60. uint32_t mem_base[4];
  61. uint32_t mem_size[4];
  62. uint64_t remap[5];
  63. };
  64. static int mv64361_pcihost_map_irq(PCIDevice *pci_dev, int n)
  65. {
  66. return (n + PCI_SLOT(pci_dev->devfn)) % PCI_NUM_PINS;
  67. }
  68. static void mv64361_pcihost_set_irq(void *opaque, int n, int level)
  69. {
  70. MV64361PCIState *s = opaque;
  71. qemu_set_irq(s->irq[n], level);
  72. }
  73. static void mv64361_pcihost_realize(DeviceState *dev, Error **errp)
  74. {
  75. MV64361PCIState *s = MV64361_PCI(dev);
  76. PCIHostState *h = PCI_HOST_BRIDGE(dev);
  77. char *name;
  78. name = g_strdup_printf("pci%d-io", s->index);
  79. memory_region_init(&s->io, OBJECT(dev), name, 0x10000);
  80. g_free(name);
  81. name = g_strdup_printf("pci%d-mem", s->index);
  82. memory_region_init(&s->mem, OBJECT(dev), name, 1ULL << 32);
  83. g_free(name);
  84. name = g_strdup_printf("pci.%d", s->index);
  85. h->bus = pci_register_root_bus(dev, name, mv64361_pcihost_set_irq,
  86. mv64361_pcihost_map_irq, dev,
  87. &s->mem, &s->io, 0, 4, TYPE_PCI_BUS);
  88. g_free(name);
  89. pci_create_simple(h->bus, 0, TYPE_MV64361_PCI_BRIDGE);
  90. }
  91. static Property mv64361_pcihost_props[] = {
  92. DEFINE_PROP_UINT8("index", MV64361PCIState, index, 0),
  93. DEFINE_PROP_END_OF_LIST()
  94. };
  95. static void mv64361_pcihost_class_init(ObjectClass *klass, void *data)
  96. {
  97. DeviceClass *dc = DEVICE_CLASS(klass);
  98. dc->realize = mv64361_pcihost_realize;
  99. device_class_set_props(dc, mv64361_pcihost_props);
  100. set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
  101. }
  102. static const TypeInfo mv64361_pcihost_info = {
  103. .name = TYPE_MV64361_PCI,
  104. .parent = TYPE_PCI_HOST_BRIDGE,
  105. .instance_size = sizeof(MV64361PCIState),
  106. .class_init = mv64361_pcihost_class_init,
  107. };
  108. static void mv64361_pci_register_types(void)
  109. {
  110. type_register_static(&mv64361_pcihost_info);
  111. type_register_static(&mv64361_pcibridge_info);
  112. }
  113. type_init(mv64361_pci_register_types)
  114. OBJECT_DECLARE_SIMPLE_TYPE(MV64361State, MV64361)
  115. struct MV64361State {
  116. SysBusDevice parent_obj;
  117. MemoryRegion regs;
  118. MV64361PCIState pci[2];
  119. MemoryRegion cpu_win[19];
  120. qemu_irq cpu_irq;
  121. /* registers state */
  122. uint32_t cpu_conf;
  123. uint32_t regs_base;
  124. uint32_t base_addr_enable;
  125. uint64_t main_int_cr;
  126. uint64_t cpu0_int_mask;
  127. uint32_t gpp_io;
  128. uint32_t gpp_level;
  129. uint32_t gpp_value;
  130. uint32_t gpp_int_cr;
  131. uint32_t gpp_int_mask;
  132. bool gpp_int_level;
  133. };
  134. enum mv64361_irq_cause {
  135. MV64361_IRQ_DEVERR = 1,
  136. MV64361_IRQ_DMAERR = 2,
  137. MV64361_IRQ_CPUERR = 3,
  138. MV64361_IRQ_IDMA0 = 4,
  139. MV64361_IRQ_IDMA1 = 5,
  140. MV64361_IRQ_IDMA2 = 6,
  141. MV64361_IRQ_IDMA3 = 7,
  142. MV64361_IRQ_TIMER0 = 8,
  143. MV64361_IRQ_TIMER1 = 9,
  144. MV64361_IRQ_TIMER2 = 10,
  145. MV64361_IRQ_TIMER3 = 11,
  146. MV64361_IRQ_PCI0 = 12,
  147. MV64361_IRQ_SRAMERR = 13,
  148. MV64361_IRQ_GBEERR = 14,
  149. MV64361_IRQ_CERR = 15,
  150. MV64361_IRQ_PCI1 = 16,
  151. MV64361_IRQ_DRAMERR = 17,
  152. MV64361_IRQ_WDNMI = 18,
  153. MV64361_IRQ_WDE = 19,
  154. MV64361_IRQ_PCI0IN = 20,
  155. MV64361_IRQ_PCI0OUT = 21,
  156. MV64361_IRQ_PCI1IN = 22,
  157. MV64361_IRQ_PCI1OUT = 23,
  158. MV64361_IRQ_P1_GPP0_7 = 24,
  159. MV64361_IRQ_P1_GPP8_15 = 25,
  160. MV64361_IRQ_P1_GPP16_23 = 26,
  161. MV64361_IRQ_P1_GPP24_31 = 27,
  162. MV64361_IRQ_P1_CPU_DB = 28,
  163. /* 29-31: reserved */
  164. MV64361_IRQ_GBE0 = 32,
  165. MV64361_IRQ_GBE1 = 33,
  166. MV64361_IRQ_GBE2 = 34,
  167. /* 35: reserved */
  168. MV64361_IRQ_SDMA0 = 36,
  169. MV64361_IRQ_TWSI = 37,
  170. MV64361_IRQ_SDMA1 = 38,
  171. MV64361_IRQ_BRG = 39,
  172. MV64361_IRQ_MPSC0 = 40,
  173. MV64361_IRQ_MPSC1 = 41,
  174. MV64361_IRQ_G0RX = 42,
  175. MV64361_IRQ_G0TX = 43,
  176. MV64361_IRQ_G0MISC = 44,
  177. MV64361_IRQ_G1RX = 45,
  178. MV64361_IRQ_G1TX = 46,
  179. MV64361_IRQ_G1MISC = 47,
  180. MV64361_IRQ_G2RX = 48,
  181. MV64361_IRQ_G2TX = 49,
  182. MV64361_IRQ_G2MISC = 50,
  183. /* 51-55: reserved */
  184. MV64361_IRQ_P0_GPP0_7 = 56,
  185. MV64361_IRQ_P0_GPP8_15 = 57,
  186. MV64361_IRQ_P0_GPP16_23 = 58,
  187. MV64361_IRQ_P0_GPP24_31 = 59,
  188. MV64361_IRQ_P0_CPU_DB = 60,
  189. /* 61-63: reserved */
  190. };
  191. PCIBus *mv64361_get_pci_bus(DeviceState *dev, int n)
  192. {
  193. MV64361State *mv = MV64361(dev);
  194. return PCI_HOST_BRIDGE(&mv->pci[n])->bus;
  195. }
  196. static void unmap_region(MemoryRegion *mr)
  197. {
  198. if (memory_region_is_mapped(mr)) {
  199. memory_region_del_subregion(get_system_memory(), mr);
  200. object_unparent(OBJECT(mr));
  201. }
  202. }
  203. static void map_pci_region(MemoryRegion *mr, MemoryRegion *parent,
  204. struct Object *owner, const char *name,
  205. hwaddr poffs, uint64_t size, hwaddr moffs)
  206. {
  207. memory_region_init_alias(mr, owner, name, parent, poffs, size);
  208. memory_region_add_subregion(get_system_memory(), moffs, mr);
  209. trace_mv64361_region_map(name, poffs, size, moffs);
  210. }
  211. static void set_mem_windows(MV64361State *s, uint32_t val)
  212. {
  213. MV64361PCIState *p;
  214. MemoryRegion *mr;
  215. uint32_t mask;
  216. int i;
  217. val &= 0x1fffff;
  218. for (mask = 1, i = 0; i < 21; i++, mask <<= 1) {
  219. if ((val & mask) != (s->base_addr_enable & mask)) {
  220. trace_mv64361_region_enable(!(val & mask) ? "enable" : "disable", i);
  221. /*
  222. * 0-3 are SDRAM chip selects but we map all RAM directly
  223. * 4-7 are device chip selects (not sure what those are)
  224. * 8 is Boot device (ROM) chip select but we map that directly too
  225. */
  226. if (i == 9) {
  227. p = &s->pci[0];
  228. mr = &s->cpu_win[i];
  229. unmap_region(mr);
  230. if (!(val & mask)) {
  231. map_pci_region(mr, &p->io, OBJECT(s), "pci0-io-win",
  232. p->remap[4], (p->io_size + 1) << 16,
  233. (p->io_base & 0xfffff) << 16);
  234. }
  235. } else if (i == 10) {
  236. p = &s->pci[0];
  237. mr = &s->cpu_win[i];
  238. unmap_region(mr);
  239. if (!(val & mask)) {
  240. map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem0-win",
  241. p->remap[0], (p->mem_size[0] + 1) << 16,
  242. (p->mem_base[0] & 0xfffff) << 16);
  243. }
  244. } else if (i == 11) {
  245. p = &s->pci[0];
  246. mr = &s->cpu_win[i];
  247. unmap_region(mr);
  248. if (!(val & mask)) {
  249. map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem1-win",
  250. p->remap[1], (p->mem_size[1] + 1) << 16,
  251. (p->mem_base[1] & 0xfffff) << 16);
  252. }
  253. } else if (i == 12) {
  254. p = &s->pci[0];
  255. mr = &s->cpu_win[i];
  256. unmap_region(mr);
  257. if (!(val & mask)) {
  258. map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem2-win",
  259. p->remap[2], (p->mem_size[2] + 1) << 16,
  260. (p->mem_base[2] & 0xfffff) << 16);
  261. }
  262. } else if (i == 13) {
  263. p = &s->pci[0];
  264. mr = &s->cpu_win[i];
  265. unmap_region(mr);
  266. if (!(val & mask)) {
  267. map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem3-win",
  268. p->remap[3], (p->mem_size[3] + 1) << 16,
  269. (p->mem_base[3] & 0xfffff) << 16);
  270. }
  271. } else if (i == 14) {
  272. p = &s->pci[1];
  273. mr = &s->cpu_win[i];
  274. unmap_region(mr);
  275. if (!(val & mask)) {
  276. map_pci_region(mr, &p->io, OBJECT(s), "pci1-io-win",
  277. p->remap[4], (p->io_size + 1) << 16,
  278. (p->io_base & 0xfffff) << 16);
  279. }
  280. } else if (i == 15) {
  281. p = &s->pci[1];
  282. mr = &s->cpu_win[i];
  283. unmap_region(mr);
  284. if (!(val & mask)) {
  285. map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem0-win",
  286. p->remap[0], (p->mem_size[0] + 1) << 16,
  287. (p->mem_base[0] & 0xfffff) << 16);
  288. }
  289. } else if (i == 16) {
  290. p = &s->pci[1];
  291. mr = &s->cpu_win[i];
  292. unmap_region(mr);
  293. if (!(val & mask)) {
  294. map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem1-win",
  295. p->remap[1], (p->mem_size[1] + 1) << 16,
  296. (p->mem_base[1] & 0xfffff) << 16);
  297. }
  298. } else if (i == 17) {
  299. p = &s->pci[1];
  300. mr = &s->cpu_win[i];
  301. unmap_region(mr);
  302. if (!(val & mask)) {
  303. map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem2-win",
  304. p->remap[2], (p->mem_size[2] + 1) << 16,
  305. (p->mem_base[2] & 0xfffff) << 16);
  306. }
  307. } else if (i == 18) {
  308. p = &s->pci[1];
  309. mr = &s->cpu_win[i];
  310. unmap_region(mr);
  311. if (!(val & mask)) {
  312. map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem3-win",
  313. p->remap[3], (p->mem_size[3] + 1) << 16,
  314. (p->mem_base[3] & 0xfffff) << 16);
  315. }
  316. /* 19 is integrated SRAM */
  317. } else if (i == 20) {
  318. mr = &s->regs;
  319. unmap_region(mr);
  320. if (!(val & mask)) {
  321. memory_region_add_subregion(get_system_memory(),
  322. (s->regs_base & 0xfffff) << 16, mr);
  323. }
  324. }
  325. }
  326. }
  327. s->base_addr_enable = val;
  328. }
  329. static void mv64361_update_irq(void *opaque, int n, int level)
  330. {
  331. MV64361State *s = opaque;
  332. uint64_t val = s->main_int_cr;
  333. if (level) {
  334. val |= BIT_ULL(n);
  335. } else {
  336. val &= ~BIT_ULL(n);
  337. }
  338. if ((s->main_int_cr & s->cpu0_int_mask) != (val & s->cpu0_int_mask)) {
  339. qemu_set_irq(s->cpu_irq, level);
  340. }
  341. s->main_int_cr = val;
  342. }
  343. static uint64_t mv64361_read(void *opaque, hwaddr addr, unsigned int size)
  344. {
  345. MV64361State *s = MV64361(opaque);
  346. uint32_t ret = 0;
  347. switch (addr) {
  348. case MV64340_CPU_CONFIG:
  349. ret = s->cpu_conf;
  350. break;
  351. case MV64340_PCI_0_IO_BASE_ADDR:
  352. ret = s->pci[0].io_base;
  353. break;
  354. case MV64340_PCI_0_IO_SIZE:
  355. ret = s->pci[0].io_size;
  356. break;
  357. case MV64340_PCI_0_IO_ADDR_REMAP:
  358. ret = s->pci[0].remap[4] >> 16;
  359. break;
  360. case MV64340_PCI_0_MEMORY0_BASE_ADDR:
  361. ret = s->pci[0].mem_base[0];
  362. break;
  363. case MV64340_PCI_0_MEMORY0_SIZE:
  364. ret = s->pci[0].mem_size[0];
  365. break;
  366. case MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP:
  367. ret = (s->pci[0].remap[0] & 0xffff0000) >> 16;
  368. break;
  369. case MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP:
  370. ret = s->pci[0].remap[0] >> 32;
  371. break;
  372. case MV64340_PCI_0_MEMORY1_BASE_ADDR:
  373. ret = s->pci[0].mem_base[1];
  374. break;
  375. case MV64340_PCI_0_MEMORY1_SIZE:
  376. ret = s->pci[0].mem_size[1];
  377. break;
  378. case MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP:
  379. ret = (s->pci[0].remap[1] & 0xffff0000) >> 16;
  380. break;
  381. case MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP:
  382. ret = s->pci[0].remap[1] >> 32;
  383. break;
  384. case MV64340_PCI_0_MEMORY2_BASE_ADDR:
  385. ret = s->pci[0].mem_base[2];
  386. break;
  387. case MV64340_PCI_0_MEMORY2_SIZE:
  388. ret = s->pci[0].mem_size[2];
  389. break;
  390. case MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP:
  391. ret = (s->pci[0].remap[2] & 0xffff0000) >> 16;
  392. break;
  393. case MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP:
  394. ret = s->pci[0].remap[2] >> 32;
  395. break;
  396. case MV64340_PCI_0_MEMORY3_BASE_ADDR:
  397. ret = s->pci[0].mem_base[3];
  398. break;
  399. case MV64340_PCI_0_MEMORY3_SIZE:
  400. ret = s->pci[0].mem_size[3];
  401. break;
  402. case MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP:
  403. ret = (s->pci[0].remap[3] & 0xffff0000) >> 16;
  404. break;
  405. case MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP:
  406. ret = s->pci[0].remap[3] >> 32;
  407. break;
  408. case MV64340_PCI_1_IO_BASE_ADDR:
  409. ret = s->pci[1].io_base;
  410. break;
  411. case MV64340_PCI_1_IO_SIZE:
  412. ret = s->pci[1].io_size;
  413. break;
  414. case MV64340_PCI_1_IO_ADDR_REMAP:
  415. ret = s->pci[1].remap[4] >> 16;
  416. break;
  417. case MV64340_PCI_1_MEMORY0_BASE_ADDR:
  418. ret = s->pci[1].mem_base[0];
  419. break;
  420. case MV64340_PCI_1_MEMORY0_SIZE:
  421. ret = s->pci[1].mem_size[0];
  422. break;
  423. case MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP:
  424. ret = (s->pci[1].remap[0] & 0xffff0000) >> 16;
  425. break;
  426. case MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP:
  427. ret = s->pci[1].remap[0] >> 32;
  428. break;
  429. case MV64340_PCI_1_MEMORY1_BASE_ADDR:
  430. ret = s->pci[1].mem_base[1];
  431. break;
  432. case MV64340_PCI_1_MEMORY1_SIZE:
  433. ret = s->pci[1].mem_size[1];
  434. break;
  435. case MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP:
  436. ret = (s->pci[1].remap[1] & 0xffff0000) >> 16;
  437. break;
  438. case MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP:
  439. ret = s->pci[1].remap[1] >> 32;
  440. break;
  441. case MV64340_PCI_1_MEMORY2_BASE_ADDR:
  442. ret = s->pci[1].mem_base[2];
  443. break;
  444. case MV64340_PCI_1_MEMORY2_SIZE:
  445. ret = s->pci[1].mem_size[2];
  446. break;
  447. case MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP:
  448. ret = (s->pci[1].remap[2] & 0xffff0000) >> 16;
  449. break;
  450. case MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP:
  451. ret = s->pci[1].remap[2] >> 32;
  452. break;
  453. case MV64340_PCI_1_MEMORY3_BASE_ADDR:
  454. ret = s->pci[1].mem_base[3];
  455. break;
  456. case MV64340_PCI_1_MEMORY3_SIZE:
  457. ret = s->pci[1].mem_size[3];
  458. break;
  459. case MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP:
  460. ret = (s->pci[1].remap[3] & 0xffff0000) >> 16;
  461. break;
  462. case MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP:
  463. ret = s->pci[1].remap[3] >> 32;
  464. break;
  465. case MV64340_INTERNAL_SPACE_BASE_ADDR:
  466. ret = s->regs_base;
  467. break;
  468. case MV64340_BASE_ADDR_ENABLE:
  469. ret = s->base_addr_enable;
  470. break;
  471. case MV64340_PCI_0_CONFIG_ADDR:
  472. ret = pci_host_conf_le_ops.read(PCI_HOST_BRIDGE(&s->pci[0]), 0, size);
  473. break;
  474. case MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG ...
  475. MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG + 3:
  476. ret = pci_host_data_le_ops.read(PCI_HOST_BRIDGE(&s->pci[0]),
  477. addr - MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG, size);
  478. break;
  479. case MV64340_PCI_1_CONFIG_ADDR:
  480. ret = pci_host_conf_le_ops.read(PCI_HOST_BRIDGE(&s->pci[1]), 0, size);
  481. break;
  482. case MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG ...
  483. MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG + 3:
  484. ret = pci_host_data_le_ops.read(PCI_HOST_BRIDGE(&s->pci[1]),
  485. addr - MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG, size);
  486. break;
  487. case MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG:
  488. /* FIXME: Should this be sent via the PCI bus somehow? */
  489. if (s->gpp_int_level && (s->gpp_value & BIT(31))) {
  490. ret = pic_read_irq(isa_pic);
  491. }
  492. break;
  493. case MV64340_MAIN_INTERRUPT_CAUSE_LOW:
  494. ret = s->main_int_cr;
  495. break;
  496. case MV64340_MAIN_INTERRUPT_CAUSE_HIGH:
  497. ret = s->main_int_cr >> 32;
  498. break;
  499. case MV64340_CPU_INTERRUPT0_MASK_LOW:
  500. ret = s->cpu0_int_mask;
  501. break;
  502. case MV64340_CPU_INTERRUPT0_MASK_HIGH:
  503. ret = s->cpu0_int_mask >> 32;
  504. break;
  505. case MV64340_CPU_INTERRUPT0_SELECT_CAUSE:
  506. ret = s->main_int_cr;
  507. if (s->main_int_cr & s->cpu0_int_mask) {
  508. if (!(s->main_int_cr & s->cpu0_int_mask & 0xffffffff)) {
  509. ret = s->main_int_cr >> 32 | BIT(30);
  510. } else if ((s->main_int_cr & s->cpu0_int_mask) >> 32) {
  511. ret |= BIT(31);
  512. }
  513. }
  514. break;
  515. case MV64340_CUNIT_ARBITER_CONTROL_REG:
  516. ret = 0x11ff0000 | (s->gpp_int_level << 10);
  517. break;
  518. case MV64340_GPP_IO_CONTROL:
  519. ret = s->gpp_io;
  520. break;
  521. case MV64340_GPP_LEVEL_CONTROL:
  522. ret = s->gpp_level;
  523. break;
  524. case MV64340_GPP_VALUE:
  525. ret = s->gpp_value;
  526. break;
  527. case MV64340_GPP_VALUE_SET:
  528. case MV64340_GPP_VALUE_CLEAR:
  529. ret = 0;
  530. break;
  531. case MV64340_GPP_INTERRUPT_CAUSE:
  532. ret = s->gpp_int_cr;
  533. break;
  534. case MV64340_GPP_INTERRUPT_MASK0:
  535. case MV64340_GPP_INTERRUPT_MASK1:
  536. ret = s->gpp_int_mask;
  537. break;
  538. default:
  539. qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register read 0x%"
  540. HWADDR_PRIx "\n", __func__, addr);
  541. break;
  542. }
  543. if (addr != MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG) {
  544. trace_mv64361_reg_read(addr, ret);
  545. }
  546. return ret;
  547. }
  548. static void warn_swap_bit(uint64_t val)
  549. {
  550. if ((val & 0x3000000ULL) >> 24 != 1) {
  551. qemu_log_mask(LOG_UNIMP, "%s: Data swap not implemented", __func__);
  552. }
  553. }
  554. static void mv64361_set_pci_mem_remap(MV64361State *s, int bus, int idx,
  555. uint64_t val, bool high)
  556. {
  557. if (high) {
  558. s->pci[bus].remap[idx] = val;
  559. } else {
  560. s->pci[bus].remap[idx] &= 0xffffffff00000000ULL;
  561. s->pci[bus].remap[idx] |= (val & 0xffffULL) << 16;
  562. }
  563. }
  564. static void mv64361_write(void *opaque, hwaddr addr, uint64_t val,
  565. unsigned int size)
  566. {
  567. MV64361State *s = MV64361(opaque);
  568. trace_mv64361_reg_write(addr, val);
  569. switch (addr) {
  570. case MV64340_CPU_CONFIG:
  571. s->cpu_conf = val & 0xe4e3bffULL;
  572. s->cpu_conf |= BIT(23);
  573. break;
  574. case MV64340_PCI_0_IO_BASE_ADDR:
  575. s->pci[0].io_base = val & 0x30fffffULL;
  576. warn_swap_bit(val);
  577. if (!(s->cpu_conf & BIT(27))) {
  578. s->pci[0].remap[4] = (val & 0xffffULL) << 16;
  579. }
  580. break;
  581. case MV64340_PCI_0_IO_SIZE:
  582. s->pci[0].io_size = val & 0xffffULL;
  583. break;
  584. case MV64340_PCI_0_IO_ADDR_REMAP:
  585. s->pci[0].remap[4] = (val & 0xffffULL) << 16;
  586. break;
  587. case MV64340_PCI_0_MEMORY0_BASE_ADDR:
  588. s->pci[0].mem_base[0] = val & 0x70fffffULL;
  589. warn_swap_bit(val);
  590. if (!(s->cpu_conf & BIT(27))) {
  591. mv64361_set_pci_mem_remap(s, 0, 0, val, false);
  592. }
  593. break;
  594. case MV64340_PCI_0_MEMORY0_SIZE:
  595. s->pci[0].mem_size[0] = val & 0xffffULL;
  596. break;
  597. case MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP:
  598. case MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP:
  599. mv64361_set_pci_mem_remap(s, 0, 0, val,
  600. (addr == MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP));
  601. break;
  602. case MV64340_PCI_0_MEMORY1_BASE_ADDR:
  603. s->pci[0].mem_base[1] = val & 0x70fffffULL;
  604. warn_swap_bit(val);
  605. if (!(s->cpu_conf & BIT(27))) {
  606. mv64361_set_pci_mem_remap(s, 0, 1, val, false);
  607. }
  608. break;
  609. case MV64340_PCI_0_MEMORY1_SIZE:
  610. s->pci[0].mem_size[1] = val & 0xffffULL;
  611. break;
  612. case MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP:
  613. case MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP:
  614. mv64361_set_pci_mem_remap(s, 0, 1, val,
  615. (addr == MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP));
  616. break;
  617. case MV64340_PCI_0_MEMORY2_BASE_ADDR:
  618. s->pci[0].mem_base[2] = val & 0x70fffffULL;
  619. warn_swap_bit(val);
  620. if (!(s->cpu_conf & BIT(27))) {
  621. mv64361_set_pci_mem_remap(s, 0, 2, val, false);
  622. }
  623. break;
  624. case MV64340_PCI_0_MEMORY2_SIZE:
  625. s->pci[0].mem_size[2] = val & 0xffffULL;
  626. break;
  627. case MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP:
  628. case MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP:
  629. mv64361_set_pci_mem_remap(s, 0, 2, val,
  630. (addr == MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP));
  631. break;
  632. case MV64340_PCI_0_MEMORY3_BASE_ADDR:
  633. s->pci[0].mem_base[3] = val & 0x70fffffULL;
  634. warn_swap_bit(val);
  635. if (!(s->cpu_conf & BIT(27))) {
  636. mv64361_set_pci_mem_remap(s, 0, 3, val, false);
  637. }
  638. break;
  639. case MV64340_PCI_0_MEMORY3_SIZE:
  640. s->pci[0].mem_size[3] = val & 0xffffULL;
  641. break;
  642. case MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP:
  643. case MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP:
  644. mv64361_set_pci_mem_remap(s, 0, 3, val,
  645. (addr == MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP));
  646. break;
  647. case MV64340_PCI_1_IO_BASE_ADDR:
  648. s->pci[1].io_base = val & 0x30fffffULL;
  649. warn_swap_bit(val);
  650. if (!(s->cpu_conf & BIT(27))) {
  651. s->pci[1].remap[4] = (val & 0xffffULL) << 16;
  652. }
  653. break;
  654. case MV64340_PCI_1_IO_SIZE:
  655. s->pci[1].io_size = val & 0xffffULL;
  656. break;
  657. case MV64340_PCI_1_MEMORY0_BASE_ADDR:
  658. s->pci[1].mem_base[0] = val & 0x70fffffULL;
  659. warn_swap_bit(val);
  660. if (!(s->cpu_conf & BIT(27))) {
  661. mv64361_set_pci_mem_remap(s, 1, 0, val, false);
  662. }
  663. break;
  664. case MV64340_PCI_1_MEMORY0_SIZE:
  665. s->pci[1].mem_size[0] = val & 0xffffULL;
  666. break;
  667. case MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP:
  668. case MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP:
  669. mv64361_set_pci_mem_remap(s, 1, 0, val,
  670. (addr == MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP));
  671. break;
  672. case MV64340_PCI_1_MEMORY1_BASE_ADDR:
  673. s->pci[1].mem_base[1] = val & 0x70fffffULL;
  674. warn_swap_bit(val);
  675. if (!(s->cpu_conf & BIT(27))) {
  676. mv64361_set_pci_mem_remap(s, 1, 1, val, false);
  677. }
  678. break;
  679. case MV64340_PCI_1_MEMORY1_SIZE:
  680. s->pci[1].mem_size[1] = val & 0xffffULL;
  681. break;
  682. case MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP:
  683. case MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP:
  684. mv64361_set_pci_mem_remap(s, 1, 1, val,
  685. (addr == MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP));
  686. break;
  687. case MV64340_PCI_1_MEMORY2_BASE_ADDR:
  688. s->pci[1].mem_base[2] = val & 0x70fffffULL;
  689. warn_swap_bit(val);
  690. if (!(s->cpu_conf & BIT(27))) {
  691. mv64361_set_pci_mem_remap(s, 1, 2, val, false);
  692. }
  693. break;
  694. case MV64340_PCI_1_MEMORY2_SIZE:
  695. s->pci[1].mem_size[2] = val & 0xffffULL;
  696. break;
  697. case MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP:
  698. case MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP:
  699. mv64361_set_pci_mem_remap(s, 1, 2, val,
  700. (addr == MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP));
  701. break;
  702. case MV64340_PCI_1_MEMORY3_BASE_ADDR:
  703. s->pci[1].mem_base[3] = val & 0x70fffffULL;
  704. warn_swap_bit(val);
  705. if (!(s->cpu_conf & BIT(27))) {
  706. mv64361_set_pci_mem_remap(s, 1, 3, val, false);
  707. }
  708. break;
  709. case MV64340_PCI_1_MEMORY3_SIZE:
  710. s->pci[1].mem_size[3] = val & 0xffffULL;
  711. break;
  712. case MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP:
  713. case MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP:
  714. mv64361_set_pci_mem_remap(s, 1, 3, val,
  715. (addr == MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP));
  716. break;
  717. case MV64340_INTERNAL_SPACE_BASE_ADDR:
  718. s->regs_base = val & 0xfffffULL;
  719. break;
  720. case MV64340_BASE_ADDR_ENABLE:
  721. set_mem_windows(s, val);
  722. break;
  723. case MV64340_PCI_0_CONFIG_ADDR:
  724. pci_host_conf_le_ops.write(PCI_HOST_BRIDGE(&s->pci[0]), 0, val, size);
  725. break;
  726. case MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG ...
  727. MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG + 3:
  728. pci_host_data_le_ops.write(PCI_HOST_BRIDGE(&s->pci[0]),
  729. addr - MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG, val, size);
  730. break;
  731. case MV64340_PCI_1_CONFIG_ADDR:
  732. pci_host_conf_le_ops.write(PCI_HOST_BRIDGE(&s->pci[1]), 0, val, size);
  733. break;
  734. case MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG ...
  735. MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG + 3:
  736. pci_host_data_le_ops.write(PCI_HOST_BRIDGE(&s->pci[1]),
  737. addr - MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG, val, size);
  738. break;
  739. case MV64340_CPU_INTERRUPT0_MASK_LOW:
  740. s->cpu0_int_mask &= 0xffffffff00000000ULL;
  741. s->cpu0_int_mask |= val & 0xffffffffULL;
  742. break;
  743. case MV64340_CPU_INTERRUPT0_MASK_HIGH:
  744. s->cpu0_int_mask &= 0xffffffffULL;
  745. s->cpu0_int_mask |= val << 32;
  746. break;
  747. case MV64340_CUNIT_ARBITER_CONTROL_REG:
  748. s->gpp_int_level = !!(val & BIT(10));
  749. break;
  750. case MV64340_GPP_IO_CONTROL:
  751. s->gpp_io = val;
  752. break;
  753. case MV64340_GPP_LEVEL_CONTROL:
  754. s->gpp_level = val;
  755. break;
  756. case MV64340_GPP_VALUE:
  757. s->gpp_value &= ~s->gpp_io;
  758. s->gpp_value |= val & s->gpp_io;
  759. break;
  760. case MV64340_GPP_VALUE_SET:
  761. s->gpp_value |= val & s->gpp_io;
  762. break;
  763. case MV64340_GPP_VALUE_CLEAR:
  764. s->gpp_value &= ~(val & s->gpp_io);
  765. break;
  766. case MV64340_GPP_INTERRUPT_CAUSE:
  767. if (!s->gpp_int_level && val != s->gpp_int_cr) {
  768. int i;
  769. uint32_t ch = s->gpp_int_cr ^ val;
  770. s->gpp_int_cr = val;
  771. for (i = 0; i < 4; i++) {
  772. if ((ch & 0xff << i) && !(val & 0xff << i)) {
  773. mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + i, 0);
  774. }
  775. }
  776. } else {
  777. s->gpp_int_cr = val;
  778. }
  779. break;
  780. case MV64340_GPP_INTERRUPT_MASK0:
  781. case MV64340_GPP_INTERRUPT_MASK1:
  782. s->gpp_int_mask = val;
  783. break;
  784. default:
  785. qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register write 0x%"
  786. HWADDR_PRIx " = %"PRIx64"\n", __func__, addr, val);
  787. break;
  788. }
  789. }
  790. static const MemoryRegionOps mv64361_ops = {
  791. .read = mv64361_read,
  792. .write = mv64361_write,
  793. .valid.min_access_size = 1,
  794. .valid.max_access_size = 4,
  795. .endianness = DEVICE_LITTLE_ENDIAN,
  796. };
  797. static void mv64361_gpp_irq(void *opaque, int n, int level)
  798. {
  799. MV64361State *s = opaque;
  800. uint32_t mask = BIT(n);
  801. uint32_t val = s->gpp_value & ~mask;
  802. if (s->gpp_level & mask) {
  803. level = !level;
  804. }
  805. val |= level << n;
  806. if (val > s->gpp_value) {
  807. s->gpp_value = val;
  808. s->gpp_int_cr |= mask;
  809. if (s->gpp_int_mask & mask) {
  810. mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + n / 8, 1);
  811. }
  812. } else if (val < s->gpp_value) {
  813. int b = n / 8;
  814. s->gpp_value = val;
  815. if (s->gpp_int_level && !(val & 0xff << b)) {
  816. mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + b, 0);
  817. }
  818. }
  819. }
  820. static void mv64361_realize(DeviceState *dev, Error **errp)
  821. {
  822. MV64361State *s = MV64361(dev);
  823. int i;
  824. s->base_addr_enable = 0x1fffff;
  825. memory_region_init_io(&s->regs, OBJECT(s), &mv64361_ops, s,
  826. TYPE_MV64361, 0x10000);
  827. sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->regs);
  828. for (i = 0; i < 2; i++) {
  829. g_autofree char *name = g_strdup_printf("pcihost%d", i);
  830. object_initialize_child(OBJECT(dev), name, &s->pci[i],
  831. TYPE_MV64361_PCI);
  832. DeviceState *pci = DEVICE(&s->pci[i]);
  833. qdev_prop_set_uint8(pci, "index", i);
  834. sysbus_realize_and_unref(SYS_BUS_DEVICE(pci), &error_fatal);
  835. }
  836. sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq);
  837. qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32);
  838. /* FIXME: PCI IRQ connections may be board specific */
  839. for (i = 0; i < PCI_NUM_PINS; i++) {
  840. s->pci[1].irq[i] = qdev_get_gpio_in_named(dev, "gpp", 12 + i);
  841. }
  842. }
  843. static void mv64361_reset(DeviceState *dev)
  844. {
  845. MV64361State *s = MV64361(dev);
  846. int i, j;
  847. /*
  848. * These values may be board specific
  849. * Real chip supports init from an eprom but that's not modelled
  850. */
  851. set_mem_windows(s, 0x1fffff);
  852. s->cpu_conf = 0x28000ff;
  853. s->regs_base = 0x100f100;
  854. s->pci[0].io_base = 0x100f800;
  855. s->pci[0].io_size = 0xff;
  856. s->pci[0].mem_base[0] = 0x100c000;
  857. s->pci[0].mem_size[0] = 0x1fff;
  858. s->pci[0].mem_base[1] = 0x100f900;
  859. s->pci[0].mem_size[1] = 0xff;
  860. s->pci[0].mem_base[2] = 0x100f400;
  861. s->pci[0].mem_size[2] = 0x1ff;
  862. s->pci[0].mem_base[3] = 0x100f600;
  863. s->pci[0].mem_size[3] = 0x1ff;
  864. s->pci[1].io_base = 0x100fe00;
  865. s->pci[1].io_size = 0xff;
  866. s->pci[1].mem_base[0] = 0x1008000;
  867. s->pci[1].mem_size[0] = 0x3fff;
  868. s->pci[1].mem_base[1] = 0x100fd00;
  869. s->pci[1].mem_size[1] = 0xff;
  870. s->pci[1].mem_base[2] = 0x1002600;
  871. s->pci[1].mem_size[2] = 0x1ff;
  872. s->pci[1].mem_base[3] = 0x100ff80;
  873. s->pci[1].mem_size[3] = 0x7f;
  874. for (i = 0; i < 2; i++) {
  875. for (j = 0; j < 4; j++) {
  876. s->pci[i].remap[j] = s->pci[i].mem_base[j] << 16;
  877. }
  878. }
  879. s->pci[0].remap[1] = 0;
  880. s->pci[1].remap[1] = 0;
  881. set_mem_windows(s, 0xfbfff);
  882. }
  883. static void mv64361_class_init(ObjectClass *klass, void *data)
  884. {
  885. DeviceClass *dc = DEVICE_CLASS(klass);
  886. dc->realize = mv64361_realize;
  887. dc->reset = mv64361_reset;
  888. }
  889. static const TypeInfo mv64361_type_info = {
  890. .name = TYPE_MV64361,
  891. .parent = TYPE_SYS_BUS_DEVICE,
  892. .instance_size = sizeof(MV64361State),
  893. .class_init = mv64361_class_init,
  894. };
  895. static void mv64361_register_types(void)
  896. {
  897. type_register_static(&mv64361_type_info);
  898. }
  899. type_init(mv64361_register_types)