xlnx-versal.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  1. /*
  2. * Xilinx Versal SoC model.
  3. *
  4. * Copyright (c) 2018 Xilinx Inc.
  5. * Written by Edgar E. Iglesias
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 or
  9. * (at your option) any later version.
  10. */
  11. #include "qemu/osdep.h"
  12. #include "qemu/units.h"
  13. #include "qapi/error.h"
  14. #include "qobject/qlist.h"
  15. #include "qemu/module.h"
  16. #include "hw/sysbus.h"
  17. #include "net/net.h"
  18. #include "system/system.h"
  19. #include "system/kvm.h"
  20. #include "hw/arm/boot.h"
  21. #include "kvm_arm.h"
  22. #include "hw/misc/unimp.h"
  23. #include "hw/arm/xlnx-versal.h"
  24. #include "qemu/log.h"
  25. #include "target/arm/cpu-qom.h"
  26. #include "target/arm/gtimer.h"
  27. #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
  28. #define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
  29. #define GEM_REVISION 0x40070106
  30. #define VERSAL_NUM_PMC_APB_IRQS 18
  31. #define NUM_OSPI_IRQ_LINES 3
  32. static void versal_create_apu_cpus(Versal *s)
  33. {
  34. int i;
  35. object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster,
  36. TYPE_CPU_CLUSTER);
  37. qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0);
  38. for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
  39. Object *obj;
  40. object_initialize_child(OBJECT(&s->fpd.apu.cluster),
  41. "apu-cpu[*]", &s->fpd.apu.cpu[i],
  42. XLNX_VERSAL_ACPU_TYPE);
  43. obj = OBJECT(&s->fpd.apu.cpu[i]);
  44. if (i) {
  45. /* Secondary CPUs start in powered-down state */
  46. object_property_set_bool(obj, "start-powered-off", true,
  47. &error_abort);
  48. }
  49. object_property_set_int(obj, "core-count", ARRAY_SIZE(s->fpd.apu.cpu),
  50. &error_abort);
  51. object_property_set_link(obj, "memory", OBJECT(&s->fpd.apu.mr),
  52. &error_abort);
  53. qdev_realize(DEVICE(obj), NULL, &error_fatal);
  54. }
  55. qdev_realize(DEVICE(&s->fpd.apu.cluster), NULL, &error_fatal);
  56. }
  57. static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
  58. {
  59. static const uint64_t addrs[] = {
  60. MM_GIC_APU_DIST_MAIN,
  61. MM_GIC_APU_REDIST_0
  62. };
  63. SysBusDevice *gicbusdev;
  64. DeviceState *gicdev;
  65. QList *redist_region_count;
  66. int nr_apu_cpus = ARRAY_SIZE(s->fpd.apu.cpu);
  67. int i;
  68. object_initialize_child(OBJECT(s), "apu-gic", &s->fpd.apu.gic,
  69. gicv3_class_name());
  70. gicbusdev = SYS_BUS_DEVICE(&s->fpd.apu.gic);
  71. gicdev = DEVICE(&s->fpd.apu.gic);
  72. qdev_prop_set_uint32(gicdev, "revision", 3);
  73. qdev_prop_set_uint32(gicdev, "num-cpu", nr_apu_cpus);
  74. qdev_prop_set_uint32(gicdev, "num-irq", XLNX_VERSAL_NR_IRQS + 32);
  75. redist_region_count = qlist_new();
  76. qlist_append_int(redist_region_count, nr_apu_cpus);
  77. qdev_prop_set_array(gicdev, "redist-region-count", redist_region_count);
  78. qdev_prop_set_bit(gicdev, "has-security-extensions", true);
  79. sysbus_realize(SYS_BUS_DEVICE(&s->fpd.apu.gic), &error_fatal);
  80. for (i = 0; i < ARRAY_SIZE(addrs); i++) {
  81. MemoryRegion *mr;
  82. mr = sysbus_mmio_get_region(gicbusdev, i);
  83. memory_region_add_subregion(&s->fpd.apu.mr, addrs[i], mr);
  84. }
  85. for (i = 0; i < nr_apu_cpus; i++) {
  86. DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]);
  87. int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
  88. qemu_irq maint_irq;
  89. int ti;
  90. /* Mapping from the output timer irq lines from the CPU to the
  91. * GIC PPI inputs.
  92. */
  93. const int timer_irq[] = {
  94. [GTIMER_PHYS] = VERSAL_TIMER_NS_EL1_IRQ,
  95. [GTIMER_VIRT] = VERSAL_TIMER_VIRT_IRQ,
  96. [GTIMER_HYP] = VERSAL_TIMER_NS_EL2_IRQ,
  97. [GTIMER_SEC] = VERSAL_TIMER_S_EL1_IRQ,
  98. };
  99. for (ti = 0; ti < ARRAY_SIZE(timer_irq); ti++) {
  100. qdev_connect_gpio_out(cpudev, ti,
  101. qdev_get_gpio_in(gicdev,
  102. ppibase + timer_irq[ti]));
  103. }
  104. maint_irq = qdev_get_gpio_in(gicdev,
  105. ppibase + VERSAL_GIC_MAINT_IRQ);
  106. qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
  107. 0, maint_irq);
  108. sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
  109. sysbus_connect_irq(gicbusdev, i + nr_apu_cpus,
  110. qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
  111. sysbus_connect_irq(gicbusdev, i + 2 * nr_apu_cpus,
  112. qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
  113. sysbus_connect_irq(gicbusdev, i + 3 * nr_apu_cpus,
  114. qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
  115. }
  116. for (i = 0; i < XLNX_VERSAL_NR_IRQS; i++) {
  117. pic[i] = qdev_get_gpio_in(gicdev, i);
  118. }
  119. }
  120. static void versal_create_rpu_cpus(Versal *s)
  121. {
  122. int i;
  123. object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster,
  124. TYPE_CPU_CLUSTER);
  125. qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1);
  126. for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
  127. Object *obj;
  128. object_initialize_child(OBJECT(&s->lpd.rpu.cluster),
  129. "rpu-cpu[*]", &s->lpd.rpu.cpu[i],
  130. XLNX_VERSAL_RCPU_TYPE);
  131. obj = OBJECT(&s->lpd.rpu.cpu[i]);
  132. object_property_set_bool(obj, "start-powered-off", true,
  133. &error_abort);
  134. object_property_set_int(obj, "mp-affinity", 0x100 | i, &error_abort);
  135. object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu),
  136. &error_abort);
  137. object_property_set_link(obj, "memory", OBJECT(&s->lpd.rpu.mr),
  138. &error_abort);
  139. qdev_realize(DEVICE(obj), NULL, &error_fatal);
  140. }
  141. qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal);
  142. }
  143. static void versal_create_uarts(Versal *s, qemu_irq *pic)
  144. {
  145. int i;
  146. for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
  147. static const int irqs[] = { VERSAL_UART0_IRQ_0, VERSAL_UART1_IRQ_0};
  148. static const uint64_t addrs[] = { MM_UART0, MM_UART1 };
  149. char *name = g_strdup_printf("uart%d", i);
  150. DeviceState *dev;
  151. MemoryRegion *mr;
  152. object_initialize_child(OBJECT(s), name, &s->lpd.iou.uart[i],
  153. TYPE_PL011);
  154. dev = DEVICE(&s->lpd.iou.uart[i]);
  155. qdev_prop_set_chr(dev, "chardev", serial_hd(i));
  156. sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
  157. mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
  158. memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
  159. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
  160. g_free(name);
  161. }
  162. }
  163. static void versal_create_canfds(Versal *s, qemu_irq *pic)
  164. {
  165. int i;
  166. uint32_t irqs[] = { VERSAL_CANFD0_IRQ_0, VERSAL_CANFD1_IRQ_0};
  167. uint64_t addrs[] = { MM_CANFD0, MM_CANFD1 };
  168. for (i = 0; i < ARRAY_SIZE(s->lpd.iou.canfd); i++) {
  169. char *name = g_strdup_printf("canfd%d", i);
  170. SysBusDevice *sbd;
  171. MemoryRegion *mr;
  172. object_initialize_child(OBJECT(s), name, &s->lpd.iou.canfd[i],
  173. TYPE_XILINX_CANFD);
  174. sbd = SYS_BUS_DEVICE(&s->lpd.iou.canfd[i]);
  175. object_property_set_int(OBJECT(&s->lpd.iou.canfd[i]), "ext_clk_freq",
  176. XLNX_VERSAL_CANFD_REF_CLK , &error_abort);
  177. object_property_set_link(OBJECT(&s->lpd.iou.canfd[i]), "canfdbus",
  178. OBJECT(s->lpd.iou.canbus[i]),
  179. &error_abort);
  180. sysbus_realize(sbd, &error_fatal);
  181. mr = sysbus_mmio_get_region(sbd, 0);
  182. memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
  183. sysbus_connect_irq(sbd, 0, pic[irqs[i]]);
  184. g_free(name);
  185. }
  186. }
  187. static void versal_create_usbs(Versal *s, qemu_irq *pic)
  188. {
  189. DeviceState *dev;
  190. MemoryRegion *mr;
  191. object_initialize_child(OBJECT(s), "usb2", &s->lpd.iou.usb,
  192. TYPE_XILINX_VERSAL_USB2);
  193. dev = DEVICE(&s->lpd.iou.usb);
  194. object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps),
  195. &error_abort);
  196. qdev_prop_set_uint32(dev, "intrs", 1);
  197. qdev_prop_set_uint32(dev, "slots", 2);
  198. sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
  199. mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
  200. memory_region_add_subregion(&s->mr_ps, MM_USB_0, mr);
  201. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_USB0_IRQ_0]);
  202. mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
  203. memory_region_add_subregion(&s->mr_ps, MM_USB2_CTRL_REGS, mr);
  204. }
  205. static void versal_create_gems(Versal *s, qemu_irq *pic)
  206. {
  207. int i;
  208. for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
  209. static const int irqs[] = { VERSAL_GEM0_IRQ_0, VERSAL_GEM1_IRQ_0};
  210. static const uint64_t addrs[] = { MM_GEM0, MM_GEM1 };
  211. char *name = g_strdup_printf("gem%d", i);
  212. DeviceState *dev;
  213. MemoryRegion *mr;
  214. OrIRQState *or_irq;
  215. object_initialize_child(OBJECT(s), name, &s->lpd.iou.gem[i],
  216. TYPE_CADENCE_GEM);
  217. or_irq = &s->lpd.iou.gem_irq_orgate[i];
  218. object_initialize_child(OBJECT(s), "gem-irq-orgate[*]",
  219. or_irq, TYPE_OR_IRQ);
  220. dev = DEVICE(&s->lpd.iou.gem[i]);
  221. qemu_configure_nic_device(dev, true, NULL);
  222. object_property_set_int(OBJECT(dev), "phy-addr", 23, &error_abort);
  223. object_property_set_int(OBJECT(dev), "num-priority-queues", 2,
  224. &error_abort);
  225. object_property_set_int(OBJECT(or_irq),
  226. "num-lines", 2, &error_fatal);
  227. qdev_realize(DEVICE(or_irq), NULL, &error_fatal);
  228. qdev_connect_gpio_out(DEVICE(or_irq), 0, pic[irqs[i]]);
  229. object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps),
  230. &error_abort);
  231. sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
  232. mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
  233. memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
  234. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(DEVICE(or_irq), 0));
  235. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, qdev_get_gpio_in(DEVICE(or_irq), 1));
  236. g_free(name);
  237. }
  238. }
  239. static void versal_create_admas(Versal *s, qemu_irq *pic)
  240. {
  241. int i;
  242. for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
  243. char *name = g_strdup_printf("adma%d", i);
  244. DeviceState *dev;
  245. MemoryRegion *mr;
  246. object_initialize_child(OBJECT(s), name, &s->lpd.iou.adma[i],
  247. TYPE_XLNX_ZDMA);
  248. dev = DEVICE(&s->lpd.iou.adma[i]);
  249. object_property_set_int(OBJECT(dev), "bus-width", 128, &error_abort);
  250. object_property_set_link(OBJECT(dev), "dma",
  251. OBJECT(get_system_memory()), &error_fatal);
  252. sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
  253. mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
  254. memory_region_add_subregion(&s->mr_ps,
  255. MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);
  256. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]);
  257. g_free(name);
  258. }
  259. }
  260. #define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */
  261. static void versal_create_sds(Versal *s, qemu_irq *pic)
  262. {
  263. int i;
  264. for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) {
  265. DeviceState *dev;
  266. MemoryRegion *mr;
  267. object_initialize_child(OBJECT(s), "sd[*]", &s->pmc.iou.sd[i],
  268. TYPE_SYSBUS_SDHCI);
  269. dev = DEVICE(&s->pmc.iou.sd[i]);
  270. object_property_set_uint(OBJECT(dev), "sd-spec-version", 3,
  271. &error_fatal);
  272. object_property_set_uint(OBJECT(dev), "capareg", SDHCI_CAPABILITIES,
  273. &error_fatal);
  274. object_property_set_uint(OBJECT(dev), "uhs", UHS_I, &error_fatal);
  275. sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
  276. mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
  277. memory_region_add_subregion(&s->mr_ps,
  278. MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr);
  279. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
  280. pic[VERSAL_SD0_IRQ_0 + i * 2]);
  281. }
  282. }
  283. static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic)
  284. {
  285. DeviceState *orgate;
  286. /*
  287. * The VERSAL_PMC_APB_IRQ is an 'or' of the interrupts from the following
  288. * models:
  289. * - RTC
  290. * - BBRAM
  291. * - PMC SLCR
  292. * - CFRAME regs (input 3 - 17 to the orgate)
  293. */
  294. object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
  295. &s->pmc.apb_irq_orgate, TYPE_OR_IRQ);
  296. orgate = DEVICE(&s->pmc.apb_irq_orgate);
  297. object_property_set_int(OBJECT(orgate),
  298. "num-lines", VERSAL_NUM_PMC_APB_IRQS, &error_fatal);
  299. qdev_realize(orgate, NULL, &error_fatal);
  300. qdev_connect_gpio_out(orgate, 0, pic[VERSAL_PMC_APB_IRQ]);
  301. }
  302. static void versal_create_rtc(Versal *s, qemu_irq *pic)
  303. {
  304. SysBusDevice *sbd;
  305. MemoryRegion *mr;
  306. object_initialize_child(OBJECT(s), "rtc", &s->pmc.rtc,
  307. TYPE_XLNX_ZYNQMP_RTC);
  308. sbd = SYS_BUS_DEVICE(&s->pmc.rtc);
  309. sysbus_realize(sbd, &error_fatal);
  310. mr = sysbus_mmio_get_region(sbd, 0);
  311. memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr);
  312. /*
  313. * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
  314. * supports them.
  315. */
  316. sysbus_connect_irq(sbd, 1,
  317. qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 0));
  318. }
  319. static void versal_create_trng(Versal *s, qemu_irq *pic)
  320. {
  321. SysBusDevice *sbd;
  322. MemoryRegion *mr;
  323. object_initialize_child(OBJECT(s), "trng", &s->pmc.trng,
  324. TYPE_XLNX_VERSAL_TRNG);
  325. sbd = SYS_BUS_DEVICE(&s->pmc.trng);
  326. sysbus_realize(sbd, &error_fatal);
  327. mr = sysbus_mmio_get_region(sbd, 0);
  328. memory_region_add_subregion(&s->mr_ps, MM_PMC_TRNG, mr);
  329. sysbus_connect_irq(sbd, 0, pic[VERSAL_TRNG_IRQ]);
  330. }
  331. static void versal_create_xrams(Versal *s, qemu_irq *pic)
  332. {
  333. int nr_xrams = ARRAY_SIZE(s->lpd.xram.ctrl);
  334. DeviceState *orgate;
  335. int i;
  336. /* XRAM IRQs get ORed into a single line. */
  337. object_initialize_child(OBJECT(s), "xram-irq-orgate",
  338. &s->lpd.xram.irq_orgate, TYPE_OR_IRQ);
  339. orgate = DEVICE(&s->lpd.xram.irq_orgate);
  340. object_property_set_int(OBJECT(orgate),
  341. "num-lines", nr_xrams, &error_fatal);
  342. qdev_realize(orgate, NULL, &error_fatal);
  343. qdev_connect_gpio_out(orgate, 0, pic[VERSAL_XRAM_IRQ_0]);
  344. for (i = 0; i < ARRAY_SIZE(s->lpd.xram.ctrl); i++) {
  345. SysBusDevice *sbd;
  346. MemoryRegion *mr;
  347. object_initialize_child(OBJECT(s), "xram[*]", &s->lpd.xram.ctrl[i],
  348. TYPE_XLNX_XRAM_CTRL);
  349. sbd = SYS_BUS_DEVICE(&s->lpd.xram.ctrl[i]);
  350. sysbus_realize(sbd, &error_fatal);
  351. mr = sysbus_mmio_get_region(sbd, 0);
  352. memory_region_add_subregion(&s->mr_ps,
  353. MM_XRAMC + i * MM_XRAMC_SIZE, mr);
  354. mr = sysbus_mmio_get_region(sbd, 1);
  355. memory_region_add_subregion(&s->mr_ps, MM_XRAM + i * MiB, mr);
  356. sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(orgate, i));
  357. }
  358. }
  359. static void versal_create_bbram(Versal *s, qemu_irq *pic)
  360. {
  361. SysBusDevice *sbd;
  362. object_initialize_child_with_props(OBJECT(s), "bbram", &s->pmc.bbram,
  363. sizeof(s->pmc.bbram), TYPE_XLNX_BBRAM,
  364. &error_fatal,
  365. "crc-zpads", "0",
  366. NULL);
  367. sbd = SYS_BUS_DEVICE(&s->pmc.bbram);
  368. sysbus_realize(sbd, &error_fatal);
  369. memory_region_add_subregion(&s->mr_ps, MM_PMC_BBRAM_CTRL,
  370. sysbus_mmio_get_region(sbd, 0));
  371. sysbus_connect_irq(sbd, 0,
  372. qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 1));
  373. }
  374. static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base)
  375. {
  376. SysBusDevice *part = SYS_BUS_DEVICE(dev);
  377. object_property_set_link(OBJECT(part), "efuse",
  378. OBJECT(&s->pmc.efuse), &error_abort);
  379. sysbus_realize(part, &error_abort);
  380. memory_region_add_subregion(&s->mr_ps, base,
  381. sysbus_mmio_get_region(part, 0));
  382. }
  383. static void versal_create_efuse(Versal *s, qemu_irq *pic)
  384. {
  385. Object *bits = OBJECT(&s->pmc.efuse);
  386. Object *ctrl = OBJECT(&s->pmc.efuse_ctrl);
  387. Object *cache = OBJECT(&s->pmc.efuse_cache);
  388. object_initialize_child(OBJECT(s), "efuse-ctrl", &s->pmc.efuse_ctrl,
  389. TYPE_XLNX_VERSAL_EFUSE_CTRL);
  390. object_initialize_child(OBJECT(s), "efuse-cache", &s->pmc.efuse_cache,
  391. TYPE_XLNX_VERSAL_EFUSE_CACHE);
  392. object_initialize_child_with_props(ctrl, "xlnx-efuse@0", bits,
  393. sizeof(s->pmc.efuse),
  394. TYPE_XLNX_EFUSE, &error_abort,
  395. "efuse-nr", "3",
  396. "efuse-size", "8192",
  397. NULL);
  398. qdev_realize(DEVICE(bits), NULL, &error_abort);
  399. versal_realize_efuse_part(s, ctrl, MM_PMC_EFUSE_CTRL);
  400. versal_realize_efuse_part(s, cache, MM_PMC_EFUSE_CACHE);
  401. sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]);
  402. }
  403. static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic)
  404. {
  405. SysBusDevice *sbd;
  406. object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", &s->pmc.iou.slcr,
  407. TYPE_XILINX_VERSAL_PMC_IOU_SLCR);
  408. sbd = SYS_BUS_DEVICE(&s->pmc.iou.slcr);
  409. sysbus_realize(sbd, &error_fatal);
  410. memory_region_add_subregion(&s->mr_ps, MM_PMC_PMC_IOU_SLCR,
  411. sysbus_mmio_get_region(sbd, 0));
  412. sysbus_connect_irq(sbd, 0,
  413. qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2));
  414. }
  415. static void versal_create_ospi(Versal *s, qemu_irq *pic)
  416. {
  417. SysBusDevice *sbd;
  418. MemoryRegion *mr_dac;
  419. qemu_irq ospi_mux_sel;
  420. DeviceState *orgate;
  421. memory_region_init(&s->pmc.iou.ospi.linear_mr, OBJECT(s),
  422. "versal-ospi-linear-mr" , MM_PMC_OSPI_DAC_SIZE);
  423. object_initialize_child(OBJECT(s), "versal-ospi", &s->pmc.iou.ospi.ospi,
  424. TYPE_XILINX_VERSAL_OSPI);
  425. mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 1);
  426. memory_region_add_subregion(&s->pmc.iou.ospi.linear_mr, 0x0, mr_dac);
  427. /* Create the OSPI destination DMA */
  428. object_initialize_child(OBJECT(s), "versal-ospi-dma-dst",
  429. &s->pmc.iou.ospi.dma_dst,
  430. TYPE_XLNX_CSU_DMA);
  431. object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_dst),
  432. "dma", OBJECT(get_system_memory()),
  433. &error_abort);
  434. sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst);
  435. sysbus_realize(sbd, &error_fatal);
  436. memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_DST,
  437. sysbus_mmio_get_region(sbd, 0));
  438. /* Create the OSPI source DMA */
  439. object_initialize_child(OBJECT(s), "versal-ospi-dma-src",
  440. &s->pmc.iou.ospi.dma_src,
  441. TYPE_XLNX_CSU_DMA);
  442. object_property_set_bool(OBJECT(&s->pmc.iou.ospi.dma_src), "is-dst",
  443. false, &error_abort);
  444. object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
  445. "dma", OBJECT(mr_dac), &error_abort);
  446. object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
  447. "stream-connected-dma",
  448. OBJECT(&s->pmc.iou.ospi.dma_dst),
  449. &error_abort);
  450. sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src);
  451. sysbus_realize(sbd, &error_fatal);
  452. memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_SRC,
  453. sysbus_mmio_get_region(sbd, 0));
  454. /* Realize the OSPI */
  455. object_property_set_link(OBJECT(&s->pmc.iou.ospi.ospi), "dma-src",
  456. OBJECT(&s->pmc.iou.ospi.dma_src), &error_abort);
  457. sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi);
  458. sysbus_realize(sbd, &error_fatal);
  459. memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI,
  460. sysbus_mmio_get_region(sbd, 0));
  461. memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DAC,
  462. &s->pmc.iou.ospi.linear_mr);
  463. /* ospi_mux_sel */
  464. ospi_mux_sel = qdev_get_gpio_in_named(DEVICE(&s->pmc.iou.ospi.ospi),
  465. "ospi-mux-sel", 0);
  466. qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "ospi-mux-sel", 0,
  467. ospi_mux_sel);
  468. /* OSPI irq */
  469. object_initialize_child(OBJECT(s), "ospi-irq-orgate",
  470. &s->pmc.iou.ospi.irq_orgate, TYPE_OR_IRQ);
  471. object_property_set_int(OBJECT(&s->pmc.iou.ospi.irq_orgate),
  472. "num-lines", NUM_OSPI_IRQ_LINES, &error_fatal);
  473. orgate = DEVICE(&s->pmc.iou.ospi.irq_orgate);
  474. qdev_realize(orgate, NULL, &error_fatal);
  475. sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 0,
  476. qdev_get_gpio_in(orgate, 0));
  477. sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src), 0,
  478. qdev_get_gpio_in(orgate, 1));
  479. sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst), 0,
  480. qdev_get_gpio_in(orgate, 2));
  481. qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
  482. }
  483. static void versal_create_cfu(Versal *s, qemu_irq *pic)
  484. {
  485. SysBusDevice *sbd;
  486. DeviceState *dev;
  487. int i;
  488. const struct {
  489. uint64_t reg_base;
  490. uint64_t fdri_base;
  491. } cframe_addr[] = {
  492. { MM_PMC_CFRAME0_REG, MM_PMC_CFRAME0_FDRI },
  493. { MM_PMC_CFRAME1_REG, MM_PMC_CFRAME1_FDRI },
  494. { MM_PMC_CFRAME2_REG, MM_PMC_CFRAME2_FDRI },
  495. { MM_PMC_CFRAME3_REG, MM_PMC_CFRAME3_FDRI },
  496. { MM_PMC_CFRAME4_REG, MM_PMC_CFRAME4_FDRI },
  497. { MM_PMC_CFRAME5_REG, MM_PMC_CFRAME5_FDRI },
  498. { MM_PMC_CFRAME6_REG, MM_PMC_CFRAME6_FDRI },
  499. { MM_PMC_CFRAME7_REG, MM_PMC_CFRAME7_FDRI },
  500. { MM_PMC_CFRAME8_REG, MM_PMC_CFRAME8_FDRI },
  501. { MM_PMC_CFRAME9_REG, MM_PMC_CFRAME9_FDRI },
  502. { MM_PMC_CFRAME10_REG, MM_PMC_CFRAME10_FDRI },
  503. { MM_PMC_CFRAME11_REG, MM_PMC_CFRAME11_FDRI },
  504. { MM_PMC_CFRAME12_REG, MM_PMC_CFRAME12_FDRI },
  505. { MM_PMC_CFRAME13_REG, MM_PMC_CFRAME13_FDRI },
  506. { MM_PMC_CFRAME14_REG, MM_PMC_CFRAME14_FDRI },
  507. };
  508. const struct {
  509. uint32_t blktype0_frames;
  510. uint32_t blktype1_frames;
  511. uint32_t blktype2_frames;
  512. uint32_t blktype3_frames;
  513. uint32_t blktype4_frames;
  514. uint32_t blktype5_frames;
  515. uint32_t blktype6_frames;
  516. } cframe_cfg[] = {
  517. [0] = { 34111, 3528, 12800, 11, 5, 1, 1 },
  518. [1] = { 38498, 3841, 15361, 13, 7, 3, 1 },
  519. [2] = { 38498, 3841, 15361, 13, 7, 3, 1 },
  520. [3] = { 38498, 3841, 15361, 13, 7, 3, 1 },
  521. };
  522. /* CFU FDRO */
  523. object_initialize_child(OBJECT(s), "cfu-fdro", &s->pmc.cfu_fdro,
  524. TYPE_XLNX_VERSAL_CFU_FDRO);
  525. sbd = SYS_BUS_DEVICE(&s->pmc.cfu_fdro);
  526. sysbus_realize(sbd, &error_fatal);
  527. memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_FDRO,
  528. sysbus_mmio_get_region(sbd, 0));
  529. /* CFRAME REG */
  530. for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
  531. g_autofree char *name = g_strdup_printf("cframe%d", i);
  532. object_initialize_child(OBJECT(s), name, &s->pmc.cframe[i],
  533. TYPE_XLNX_VERSAL_CFRAME_REG);
  534. sbd = SYS_BUS_DEVICE(&s->pmc.cframe[i]);
  535. dev = DEVICE(&s->pmc.cframe[i]);
  536. if (i < ARRAY_SIZE(cframe_cfg)) {
  537. object_property_set_int(OBJECT(dev), "blktype0-frames",
  538. cframe_cfg[i].blktype0_frames,
  539. &error_abort);
  540. object_property_set_int(OBJECT(dev), "blktype1-frames",
  541. cframe_cfg[i].blktype1_frames,
  542. &error_abort);
  543. object_property_set_int(OBJECT(dev), "blktype2-frames",
  544. cframe_cfg[i].blktype2_frames,
  545. &error_abort);
  546. object_property_set_int(OBJECT(dev), "blktype3-frames",
  547. cframe_cfg[i].blktype3_frames,
  548. &error_abort);
  549. object_property_set_int(OBJECT(dev), "blktype4-frames",
  550. cframe_cfg[i].blktype4_frames,
  551. &error_abort);
  552. object_property_set_int(OBJECT(dev), "blktype5-frames",
  553. cframe_cfg[i].blktype5_frames,
  554. &error_abort);
  555. object_property_set_int(OBJECT(dev), "blktype6-frames",
  556. cframe_cfg[i].blktype6_frames,
  557. &error_abort);
  558. }
  559. object_property_set_link(OBJECT(dev), "cfu-fdro",
  560. OBJECT(&s->pmc.cfu_fdro), &error_fatal);
  561. sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
  562. memory_region_add_subregion(&s->mr_ps, cframe_addr[i].reg_base,
  563. sysbus_mmio_get_region(sbd, 0));
  564. memory_region_add_subregion(&s->mr_ps, cframe_addr[i].fdri_base,
  565. sysbus_mmio_get_region(sbd, 1));
  566. sysbus_connect_irq(sbd, 0,
  567. qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate),
  568. 3 + i));
  569. }
  570. /* CFRAME BCAST */
  571. object_initialize_child(OBJECT(s), "cframe_bcast", &s->pmc.cframe_bcast,
  572. TYPE_XLNX_VERSAL_CFRAME_BCAST_REG);
  573. sbd = SYS_BUS_DEVICE(&s->pmc.cframe_bcast);
  574. dev = DEVICE(&s->pmc.cframe_bcast);
  575. for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
  576. g_autofree char *propname = g_strdup_printf("cframe%d", i);
  577. object_property_set_link(OBJECT(dev), propname,
  578. OBJECT(&s->pmc.cframe[i]), &error_fatal);
  579. }
  580. sysbus_realize(sbd, &error_fatal);
  581. memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_REG,
  582. sysbus_mmio_get_region(sbd, 0));
  583. memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_FDRI,
  584. sysbus_mmio_get_region(sbd, 1));
  585. /* CFU APB */
  586. object_initialize_child(OBJECT(s), "cfu-apb", &s->pmc.cfu_apb,
  587. TYPE_XLNX_VERSAL_CFU_APB);
  588. sbd = SYS_BUS_DEVICE(&s->pmc.cfu_apb);
  589. dev = DEVICE(&s->pmc.cfu_apb);
  590. for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
  591. g_autofree char *propname = g_strdup_printf("cframe%d", i);
  592. object_property_set_link(OBJECT(dev), propname,
  593. OBJECT(&s->pmc.cframe[i]), &error_fatal);
  594. }
  595. sysbus_realize(sbd, &error_fatal);
  596. memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_APB,
  597. sysbus_mmio_get_region(sbd, 0));
  598. memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM,
  599. sysbus_mmio_get_region(sbd, 1));
  600. memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM_2,
  601. sysbus_mmio_get_region(sbd, 2));
  602. sysbus_connect_irq(sbd, 0, pic[VERSAL_CFU_IRQ_0]);
  603. /* CFU SFR */
  604. object_initialize_child(OBJECT(s), "cfu-sfr", &s->pmc.cfu_sfr,
  605. TYPE_XLNX_VERSAL_CFU_SFR);
  606. sbd = SYS_BUS_DEVICE(&s->pmc.cfu_sfr);
  607. object_property_set_link(OBJECT(&s->pmc.cfu_sfr),
  608. "cfu", OBJECT(&s->pmc.cfu_apb), &error_abort);
  609. sysbus_realize(sbd, &error_fatal);
  610. memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_SFR,
  611. sysbus_mmio_get_region(sbd, 0));
  612. }
  613. static void versal_create_crl(Versal *s, qemu_irq *pic)
  614. {
  615. SysBusDevice *sbd;
  616. int i;
  617. object_initialize_child(OBJECT(s), "crl", &s->lpd.crl,
  618. TYPE_XLNX_VERSAL_CRL);
  619. sbd = SYS_BUS_DEVICE(&s->lpd.crl);
  620. for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
  621. g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i);
  622. object_property_set_link(OBJECT(&s->lpd.crl),
  623. name, OBJECT(&s->lpd.rpu.cpu[i]),
  624. &error_abort);
  625. }
  626. for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
  627. g_autofree gchar *name = g_strdup_printf("gem[%d]", i);
  628. object_property_set_link(OBJECT(&s->lpd.crl),
  629. name, OBJECT(&s->lpd.iou.gem[i]),
  630. &error_abort);
  631. }
  632. for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
  633. g_autofree gchar *name = g_strdup_printf("adma[%d]", i);
  634. object_property_set_link(OBJECT(&s->lpd.crl),
  635. name, OBJECT(&s->lpd.iou.adma[i]),
  636. &error_abort);
  637. }
  638. for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
  639. g_autofree gchar *name = g_strdup_printf("uart[%d]", i);
  640. object_property_set_link(OBJECT(&s->lpd.crl),
  641. name, OBJECT(&s->lpd.iou.uart[i]),
  642. &error_abort);
  643. }
  644. object_property_set_link(OBJECT(&s->lpd.crl),
  645. "usb", OBJECT(&s->lpd.iou.usb),
  646. &error_abort);
  647. sysbus_realize(sbd, &error_fatal);
  648. memory_region_add_subregion(&s->mr_ps, MM_CRL,
  649. sysbus_mmio_get_region(sbd, 0));
  650. sysbus_connect_irq(sbd, 0, pic[VERSAL_CRL_IRQ]);
  651. }
  652. /* This takes the board allocated linear DDR memory and creates aliases
  653. * for each split DDR range/aperture on the Versal address map.
  654. */
  655. static void versal_map_ddr(Versal *s)
  656. {
  657. uint64_t size = memory_region_size(s->cfg.mr_ddr);
  658. /* Describes the various split DDR access regions. */
  659. static const struct {
  660. uint64_t base;
  661. uint64_t size;
  662. } addr_ranges[] = {
  663. { MM_TOP_DDR, MM_TOP_DDR_SIZE },
  664. { MM_TOP_DDR_2, MM_TOP_DDR_2_SIZE },
  665. { MM_TOP_DDR_3, MM_TOP_DDR_3_SIZE },
  666. { MM_TOP_DDR_4, MM_TOP_DDR_4_SIZE }
  667. };
  668. uint64_t offset = 0;
  669. int i;
  670. assert(ARRAY_SIZE(addr_ranges) == ARRAY_SIZE(s->noc.mr_ddr_ranges));
  671. for (i = 0; i < ARRAY_SIZE(addr_ranges) && size; i++) {
  672. char *name;
  673. uint64_t mapsize;
  674. mapsize = size < addr_ranges[i].size ? size : addr_ranges[i].size;
  675. name = g_strdup_printf("noc-ddr-range%d", i);
  676. /* Create the MR alias. */
  677. memory_region_init_alias(&s->noc.mr_ddr_ranges[i], OBJECT(s),
  678. name, s->cfg.mr_ddr,
  679. offset, mapsize);
  680. /* Map it onto the NoC MR. */
  681. memory_region_add_subregion(&s->mr_ps, addr_ranges[i].base,
  682. &s->noc.mr_ddr_ranges[i]);
  683. offset += mapsize;
  684. size -= mapsize;
  685. g_free(name);
  686. }
  687. }
  688. static void versal_unimp_area(Versal *s, const char *name,
  689. MemoryRegion *mr,
  690. hwaddr base, hwaddr size)
  691. {
  692. DeviceState *dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE);
  693. MemoryRegion *mr_dev;
  694. qdev_prop_set_string(dev, "name", name);
  695. qdev_prop_set_uint64(dev, "size", size);
  696. object_property_add_child(OBJECT(s), name, OBJECT(dev));
  697. sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
  698. mr_dev = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
  699. memory_region_add_subregion(mr, base, mr_dev);
  700. }
  701. static void versal_unimp_sd_emmc_sel(void *opaque, int n, int level)
  702. {
  703. qemu_log_mask(LOG_UNIMP,
  704. "Selecting between enabling SD mode or eMMC mode on "
  705. "controller %d is not yet implemented\n", n);
  706. }
  707. static void versal_unimp_qspi_ospi_mux_sel(void *opaque, int n, int level)
  708. {
  709. qemu_log_mask(LOG_UNIMP,
  710. "Selecting between enabling the QSPI or OSPI linear address "
  711. "region is not yet implemented\n");
  712. }
  713. static void versal_unimp_irq_parity_imr(void *opaque, int n, int level)
  714. {
  715. qemu_log_mask(LOG_UNIMP,
  716. "PMC SLCR parity interrupt behaviour "
  717. "is not yet implemented\n");
  718. }
  719. static void versal_unimp(Versal *s)
  720. {
  721. qemu_irq gpio_in;
  722. versal_unimp_area(s, "psm", &s->mr_ps,
  723. MM_PSM_START, MM_PSM_END - MM_PSM_START);
  724. versal_unimp_area(s, "crf", &s->mr_ps,
  725. MM_FPD_CRF, MM_FPD_CRF_SIZE);
  726. versal_unimp_area(s, "apu", &s->mr_ps,
  727. MM_FPD_FPD_APU, MM_FPD_FPD_APU_SIZE);
  728. versal_unimp_area(s, "crp", &s->mr_ps,
  729. MM_PMC_CRP, MM_PMC_CRP_SIZE);
  730. versal_unimp_area(s, "iou-scntr", &s->mr_ps,
  731. MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE);
  732. versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps,
  733. MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE);
  734. qdev_init_gpio_in_named(DEVICE(s), versal_unimp_sd_emmc_sel,
  735. "sd-emmc-sel-dummy", 2);
  736. qdev_init_gpio_in_named(DEVICE(s), versal_unimp_qspi_ospi_mux_sel,
  737. "qspi-ospi-mux-sel-dummy", 1);
  738. qdev_init_gpio_in_named(DEVICE(s), versal_unimp_irq_parity_imr,
  739. "irq-parity-imr-dummy", 1);
  740. gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 0);
  741. qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 0,
  742. gpio_in);
  743. gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 1);
  744. qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 1,
  745. gpio_in);
  746. gpio_in = qdev_get_gpio_in_named(DEVICE(s), "qspi-ospi-mux-sel-dummy", 0);
  747. qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr),
  748. "qspi-ospi-mux-sel", 0,
  749. gpio_in);
  750. gpio_in = qdev_get_gpio_in_named(DEVICE(s), "irq-parity-imr-dummy", 0);
  751. qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr),
  752. SYSBUS_DEVICE_GPIO_IRQ, 0,
  753. gpio_in);
  754. }
  755. static void versal_realize(DeviceState *dev, Error **errp)
  756. {
  757. Versal *s = XLNX_VERSAL(dev);
  758. qemu_irq pic[XLNX_VERSAL_NR_IRQS];
  759. versal_create_apu_cpus(s);
  760. versal_create_apu_gic(s, pic);
  761. versal_create_rpu_cpus(s);
  762. versal_create_uarts(s, pic);
  763. versal_create_canfds(s, pic);
  764. versal_create_usbs(s, pic);
  765. versal_create_gems(s, pic);
  766. versal_create_admas(s, pic);
  767. versal_create_sds(s, pic);
  768. versal_create_pmc_apb_irq_orgate(s, pic);
  769. versal_create_rtc(s, pic);
  770. versal_create_trng(s, pic);
  771. versal_create_xrams(s, pic);
  772. versal_create_bbram(s, pic);
  773. versal_create_efuse(s, pic);
  774. versal_create_pmc_iou_slcr(s, pic);
  775. versal_create_ospi(s, pic);
  776. versal_create_crl(s, pic);
  777. versal_create_cfu(s, pic);
  778. versal_map_ddr(s);
  779. versal_unimp(s);
  780. /* Create the On Chip Memory (OCM). */
  781. memory_region_init_ram(&s->lpd.mr_ocm, OBJECT(s), "ocm",
  782. MM_OCM_SIZE, &error_fatal);
  783. memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0);
  784. memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0);
  785. memory_region_add_subregion_overlap(&s->lpd.rpu.mr, 0,
  786. &s->lpd.rpu.mr_ps_alias, 0);
  787. }
  788. static void versal_init(Object *obj)
  789. {
  790. Versal *s = XLNX_VERSAL(obj);
  791. memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
  792. memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
  793. memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
  794. memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s),
  795. "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX);
  796. }
  797. static const Property versal_properties[] = {
  798. DEFINE_PROP_LINK("ddr", Versal, cfg.mr_ddr, TYPE_MEMORY_REGION,
  799. MemoryRegion *),
  800. DEFINE_PROP_LINK("canbus0", Versal, lpd.iou.canbus[0],
  801. TYPE_CAN_BUS, CanBusState *),
  802. DEFINE_PROP_LINK("canbus1", Versal, lpd.iou.canbus[1],
  803. TYPE_CAN_BUS, CanBusState *),
  804. };
  805. static void versal_class_init(ObjectClass *klass, void *data)
  806. {
  807. DeviceClass *dc = DEVICE_CLASS(klass);
  808. dc->realize = versal_realize;
  809. device_class_set_props(dc, versal_properties);
  810. /* No VMSD since we haven't got any top-level SoC state to save. */
  811. }
  812. static const TypeInfo versal_info = {
  813. .name = TYPE_XLNX_VERSAL,
  814. .parent = TYPE_SYS_BUS_DEVICE,
  815. .instance_size = sizeof(Versal),
  816. .instance_init = versal_init,
  817. .class_init = versal_class_init,
  818. };
  819. static void versal_register_types(void)
  820. {
  821. type_register_static(&versal_info);
  822. }
  823. type_init(versal_register_types);