microblaze-v-generic.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * QEMU model of Microblaze V generic board.
  3. *
  4. * based on hw/microblaze/petalogix_ml605_mmu.c
  5. *
  6. * Copyright (c) 2011 Michal Simek <monstr@monstr.eu>
  7. * Copyright (c) 2011 PetaLogix
  8. * Copyright (c) 2009 Edgar E. Iglesias.
  9. * Copyright (C) 2024, Advanced Micro Devices, Inc.
  10. * SPDX-License-Identifier: GPL-2.0-or-later
  11. *
  12. * Written by Sai Pavan Boddu <sai.pavan.boddu@amd.com
  13. * and by Michal Simek <michal.simek@amd.com>.
  14. */
  15. #include "qemu/osdep.h"
  16. #include "qemu/units.h"
  17. #include "qapi/error.h"
  18. #include "cpu.h"
  19. #include "hw/sysbus.h"
  20. #include "system/system.h"
  21. #include "net/net.h"
  22. #include "hw/boards.h"
  23. #include "hw/char/serial-mm.h"
  24. #include "exec/address-spaces.h"
  25. #include "hw/char/xilinx_uartlite.h"
  26. #include "hw/misc/unimp.h"
  27. #define LMB_BRAM_SIZE (128 * KiB)
  28. #define MEMORY_BASEADDR 0x80000000
  29. #define INTC_BASEADDR 0x41200000
  30. #define TIMER_BASEADDR 0x41c00000
  31. #define TIMER_BASEADDR2 0x41c10000
  32. #define UARTLITE_BASEADDR 0x40600000
  33. #define ETHLITE_BASEADDR 0x40e00000
  34. #define UART16550_BASEADDR 0x44a10000
  35. #define AXIENET_BASEADDR 0x40c00000
  36. #define AXIDMA_BASEADDR 0x41e00000
  37. #define GPIO_BASEADDR 0x40000000
  38. #define GPIO_BASEADDR2 0x40010000
  39. #define GPIO_BASEADDR3 0x40020000
  40. #define I2C_BASEADDR 0x40800000
  41. #define QSPI_BASEADDR 0x44a00000
  42. #define TIMER_IRQ 0
  43. #define UARTLITE_IRQ 1
  44. #define UART16550_IRQ 4
  45. #define ETHLITE_IRQ 5
  46. #define TIMER_IRQ2 6
  47. #define AXIENET_IRQ 7
  48. #define AXIDMA_IRQ1 8
  49. #define AXIDMA_IRQ0 9
  50. static void mb_v_generic_init(MachineState *machine)
  51. {
  52. ram_addr_t ram_size = machine->ram_size;
  53. DeviceState *dev, *dma, *eth0;
  54. Object *ds, *cs;
  55. int i;
  56. RISCVCPU *cpu;
  57. hwaddr ddr_base = MEMORY_BASEADDR;
  58. MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1);
  59. MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
  60. qemu_irq irq[32];
  61. MemoryRegion *sysmem = get_system_memory();
  62. cpu = RISCV_CPU(object_new(machine->cpu_type));
  63. object_property_set_bool(OBJECT(cpu), "h", false, NULL);
  64. object_property_set_bool(OBJECT(cpu), "d", false, NULL);
  65. qdev_realize(DEVICE(cpu), NULL, &error_abort);
  66. /* Attach emulated BRAM through the LMB. */
  67. memory_region_init_ram(phys_lmb_bram, NULL,
  68. "mb_v.lmb_bram", LMB_BRAM_SIZE,
  69. &error_fatal);
  70. memory_region_add_subregion(sysmem, 0x00000000, phys_lmb_bram);
  71. memory_region_init_ram(phys_ram, NULL, "mb_v.ram",
  72. ram_size, &error_fatal);
  73. memory_region_add_subregion(sysmem, ddr_base, phys_ram);
  74. dev = qdev_new("xlnx.xps-intc");
  75. qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE);
  76. qdev_prop_set_uint32(dev, "kind-of-intr",
  77. 1 << UARTLITE_IRQ);
  78. sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
  79. sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR);
  80. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
  81. qdev_get_gpio_in(DEVICE(cpu), 11));
  82. for (i = 0; i < 32; i++) {
  83. irq[i] = qdev_get_gpio_in(dev, i);
  84. }
  85. /* Uartlite */
  86. dev = qdev_new(TYPE_XILINX_UARTLITE);
  87. qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE);
  88. qdev_prop_set_chr(dev, "chardev", serial_hd(0));
  89. sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
  90. sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, UARTLITE_BASEADDR);
  91. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[UARTLITE_IRQ]);
  92. /* Full uart */
  93. serial_mm_init(sysmem, UART16550_BASEADDR + 0x1000, 2,
  94. irq[UART16550_IRQ], 115200, serial_hd(1),
  95. DEVICE_LITTLE_ENDIAN);
  96. /* 2 timers at irq 0 @ 100 Mhz. */
  97. dev = qdev_new("xlnx.xps-timer");
  98. qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE);
  99. qdev_prop_set_uint32(dev, "one-timer-only", 0);
  100. qdev_prop_set_uint32(dev, "clock-frequency", 100000000);
  101. sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
  102. sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR);
  103. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]);
  104. /* 2 timers at irq 3 @ 100 Mhz. */
  105. dev = qdev_new("xlnx.xps-timer");
  106. qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE);
  107. qdev_prop_set_uint32(dev, "one-timer-only", 0);
  108. qdev_prop_set_uint32(dev, "clock-frequency", 100000000);
  109. sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
  110. sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR2);
  111. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ2]);
  112. /* Emaclite */
  113. dev = qdev_new("xlnx.xps-ethernetlite");
  114. qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE);
  115. qemu_configure_nic_device(dev, true, NULL);
  116. qdev_prop_set_uint32(dev, "tx-ping-pong", 0);
  117. qdev_prop_set_uint32(dev, "rx-ping-pong", 0);
  118. sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
  119. sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, ETHLITE_BASEADDR);
  120. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[ETHLITE_IRQ]);
  121. /* axi ethernet and dma initialization. */
  122. eth0 = qdev_new("xlnx.axi-ethernet");
  123. dma = qdev_new("xlnx.axi-dma");
  124. /* FIXME: attach to the sysbus instead */
  125. object_property_add_child(qdev_get_machine(), "xilinx-eth", OBJECT(eth0));
  126. object_property_add_child(qdev_get_machine(), "xilinx-dma", OBJECT(dma));
  127. ds = object_property_get_link(OBJECT(dma),
  128. "axistream-connected-target", NULL);
  129. cs = object_property_get_link(OBJECT(dma),
  130. "axistream-control-connected-target", NULL);
  131. qemu_configure_nic_device(eth0, true, NULL);
  132. qdev_prop_set_uint32(eth0, "rxmem", 0x1000);
  133. qdev_prop_set_uint32(eth0, "txmem", 0x1000);
  134. object_property_set_link(OBJECT(eth0), "axistream-connected", ds,
  135. &error_abort);
  136. object_property_set_link(OBJECT(eth0), "axistream-control-connected", cs,
  137. &error_abort);
  138. sysbus_realize_and_unref(SYS_BUS_DEVICE(eth0), &error_fatal);
  139. sysbus_mmio_map(SYS_BUS_DEVICE(eth0), 0, AXIENET_BASEADDR);
  140. sysbus_connect_irq(SYS_BUS_DEVICE(eth0), 0, irq[AXIENET_IRQ]);
  141. ds = object_property_get_link(OBJECT(eth0),
  142. "axistream-connected-target", NULL);
  143. cs = object_property_get_link(OBJECT(eth0),
  144. "axistream-control-connected-target", NULL);
  145. qdev_prop_set_uint32(dma, "freqhz", 100000000);
  146. object_property_set_link(OBJECT(dma), "axistream-connected", ds,
  147. &error_abort);
  148. object_property_set_link(OBJECT(dma), "axistream-control-connected", cs,
  149. &error_abort);
  150. sysbus_realize_and_unref(SYS_BUS_DEVICE(dma), &error_fatal);
  151. sysbus_mmio_map(SYS_BUS_DEVICE(dma), 0, AXIDMA_BASEADDR);
  152. sysbus_connect_irq(SYS_BUS_DEVICE(dma), 0, irq[AXIDMA_IRQ0]);
  153. sysbus_connect_irq(SYS_BUS_DEVICE(dma), 1, irq[AXIDMA_IRQ1]);
  154. /* unimplemented devices */
  155. create_unimplemented_device("gpio", GPIO_BASEADDR, 0x10000);
  156. create_unimplemented_device("gpio2", GPIO_BASEADDR2, 0x10000);
  157. create_unimplemented_device("gpio3", GPIO_BASEADDR3, 0x10000);
  158. create_unimplemented_device("i2c", I2C_BASEADDR, 0x10000);
  159. create_unimplemented_device("qspi", QSPI_BASEADDR, 0x10000);
  160. }
  161. static void mb_v_generic_machine_init(MachineClass *mc)
  162. {
  163. mc->desc = "AMD Microblaze-V generic platform";
  164. mc->init = mb_v_generic_init;
  165. mc->min_cpus = 1;
  166. mc->max_cpus = 1;
  167. mc->default_cpu_type = TYPE_RISCV_CPU_BASE;
  168. mc->default_cpus = 1;
  169. }
  170. DEFINE_MACHINE("amd-microblaze-v-generic", mb_v_generic_machine_init)