openrisc_sim.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. * OpenRISC simulator for use as an IIS.
  3. *
  4. * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
  5. * Feng Gao <gf91597@gmail.com>
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include "qemu/osdep.h"
  21. #include "qemu/error-report.h"
  22. #include "qapi/error.h"
  23. #include "cpu.h"
  24. #include "hw/irq.h"
  25. #include "hw/boards.h"
  26. #include "hw/char/serial-mm.h"
  27. #include "net/net.h"
  28. #include "hw/openrisc/boot.h"
  29. #include "hw/qdev-properties.h"
  30. #include "exec/address-spaces.h"
  31. #include "system/device_tree.h"
  32. #include "system/system.h"
  33. #include "hw/sysbus.h"
  34. #include "system/qtest.h"
  35. #include "system/reset.h"
  36. #include "hw/core/split-irq.h"
  37. #include <libfdt.h>
  38. #define KERNEL_LOAD_ADDR 0x100
  39. #define OR1KSIM_CPUS_MAX 4
  40. #define OR1KSIM_CLK_MHZ 20000000
  41. #define TYPE_OR1KSIM_MACHINE MACHINE_TYPE_NAME("or1k-sim")
  42. #define OR1KSIM_MACHINE(obj) \
  43. OBJECT_CHECK(Or1ksimState, (obj), TYPE_OR1KSIM_MACHINE)
  44. typedef struct Or1ksimState {
  45. /*< private >*/
  46. MachineState parent_obj;
  47. /*< public >*/
  48. void *fdt;
  49. int fdt_size;
  50. } Or1ksimState;
  51. enum {
  52. OR1KSIM_DRAM,
  53. OR1KSIM_UART,
  54. OR1KSIM_ETHOC,
  55. OR1KSIM_OMPIC,
  56. };
  57. enum {
  58. OR1KSIM_OMPIC_IRQ = 1,
  59. OR1KSIM_UART_IRQ = 2,
  60. OR1KSIM_ETHOC_IRQ = 4,
  61. };
  62. enum {
  63. OR1KSIM_UART_COUNT = 4
  64. };
  65. static const struct MemmapEntry {
  66. hwaddr base;
  67. hwaddr size;
  68. } or1ksim_memmap[] = {
  69. [OR1KSIM_DRAM] = { 0x00000000, 0 },
  70. [OR1KSIM_UART] = { 0x90000000, 0x100 },
  71. [OR1KSIM_ETHOC] = { 0x92000000, 0x800 },
  72. [OR1KSIM_OMPIC] = { 0x98000000, OR1KSIM_CPUS_MAX * 8 },
  73. };
  74. static struct openrisc_boot_info {
  75. uint32_t bootstrap_pc;
  76. uint32_t fdt_addr;
  77. } boot_info;
  78. static void main_cpu_reset(void *opaque)
  79. {
  80. OpenRISCCPU *cpu = opaque;
  81. CPUState *cs = CPU(cpu);
  82. cpu_reset(CPU(cpu));
  83. cpu_set_pc(cs, boot_info.bootstrap_pc);
  84. cpu_set_gpr(&cpu->env, 3, boot_info.fdt_addr);
  85. }
  86. static qemu_irq get_cpu_irq(OpenRISCCPU *cpus[], int cpunum, int irq_pin)
  87. {
  88. return qdev_get_gpio_in_named(DEVICE(cpus[cpunum]), "IRQ", irq_pin);
  89. }
  90. static void openrisc_create_fdt(Or1ksimState *state,
  91. const struct MemmapEntry *memmap,
  92. int num_cpus, uint64_t mem_size,
  93. const char *cmdline)
  94. {
  95. void *fdt;
  96. int cpu;
  97. char *nodename;
  98. int pic_ph;
  99. fdt = state->fdt = create_device_tree(&state->fdt_size);
  100. if (!fdt) {
  101. error_report("create_device_tree() failed");
  102. exit(1);
  103. }
  104. qemu_fdt_setprop_string(fdt, "/", "compatible", "opencores,or1ksim");
  105. qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x1);
  106. qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x1);
  107. nodename = g_strdup_printf("/memory@%" HWADDR_PRIx,
  108. memmap[OR1KSIM_DRAM].base);
  109. qemu_fdt_add_subnode(fdt, nodename);
  110. qemu_fdt_setprop_cells(fdt, nodename, "reg",
  111. memmap[OR1KSIM_DRAM].base, mem_size);
  112. qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
  113. g_free(nodename);
  114. qemu_fdt_add_subnode(fdt, "/cpus");
  115. qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
  116. qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
  117. for (cpu = 0; cpu < num_cpus; cpu++) {
  118. nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
  119. qemu_fdt_add_subnode(fdt, nodename);
  120. qemu_fdt_setprop_string(fdt, nodename, "compatible",
  121. "opencores,or1200-rtlsvn481");
  122. qemu_fdt_setprop_cell(fdt, nodename, "reg", cpu);
  123. qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
  124. OR1KSIM_CLK_MHZ);
  125. g_free(nodename);
  126. }
  127. nodename = (char *)"/pic";
  128. qemu_fdt_add_subnode(fdt, nodename);
  129. pic_ph = qemu_fdt_alloc_phandle(fdt);
  130. qemu_fdt_setprop_string(fdt, nodename, "compatible",
  131. "opencores,or1k-pic-level");
  132. qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 1);
  133. qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
  134. qemu_fdt_setprop_cell(fdt, nodename, "phandle", pic_ph);
  135. qemu_fdt_setprop_cell(fdt, "/", "interrupt-parent", pic_ph);
  136. qemu_fdt_add_subnode(fdt, "/chosen");
  137. if (cmdline) {
  138. qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
  139. }
  140. /* Create aliases node for use by devices. */
  141. qemu_fdt_add_subnode(fdt, "/aliases");
  142. }
  143. static void openrisc_sim_net_init(Or1ksimState *state, hwaddr base, hwaddr size,
  144. int num_cpus, OpenRISCCPU *cpus[],
  145. int irq_pin)
  146. {
  147. void *fdt = state->fdt;
  148. DeviceState *dev;
  149. SysBusDevice *s;
  150. char *nodename;
  151. int i;
  152. dev = qemu_create_nic_device("open_eth", true, NULL);
  153. if (!dev) {
  154. return;
  155. }
  156. s = SYS_BUS_DEVICE(dev);
  157. sysbus_realize_and_unref(s, &error_fatal);
  158. if (num_cpus > 1) {
  159. DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
  160. qdev_prop_set_uint32(splitter, "num-lines", num_cpus);
  161. qdev_realize_and_unref(splitter, NULL, &error_fatal);
  162. for (i = 0; i < num_cpus; i++) {
  163. qdev_connect_gpio_out(splitter, i, get_cpu_irq(cpus, i, irq_pin));
  164. }
  165. sysbus_connect_irq(s, 0, qdev_get_gpio_in(splitter, 0));
  166. } else {
  167. sysbus_connect_irq(s, 0, get_cpu_irq(cpus, 0, irq_pin));
  168. }
  169. sysbus_mmio_map(s, 0, base);
  170. sysbus_mmio_map(s, 1, base + 0x400);
  171. /* Init device tree node for ethoc. */
  172. nodename = g_strdup_printf("/ethoc@%" HWADDR_PRIx, base);
  173. qemu_fdt_add_subnode(fdt, nodename);
  174. qemu_fdt_setprop_string(fdt, nodename, "compatible", "opencores,ethoc");
  175. qemu_fdt_setprop_cells(fdt, nodename, "reg", base, size);
  176. qemu_fdt_setprop_cell(fdt, nodename, "interrupts", irq_pin);
  177. qemu_fdt_setprop(fdt, nodename, "big-endian", NULL, 0);
  178. qemu_fdt_setprop_string(fdt, "/aliases", "enet0", nodename);
  179. g_free(nodename);
  180. }
  181. static void openrisc_sim_ompic_init(Or1ksimState *state, hwaddr base,
  182. hwaddr size, int num_cpus,
  183. OpenRISCCPU *cpus[], int irq_pin)
  184. {
  185. void *fdt = state->fdt;
  186. DeviceState *dev;
  187. SysBusDevice *s;
  188. char *nodename;
  189. int i;
  190. dev = qdev_new("or1k-ompic");
  191. qdev_prop_set_uint32(dev, "num-cpus", num_cpus);
  192. s = SYS_BUS_DEVICE(dev);
  193. sysbus_realize_and_unref(s, &error_fatal);
  194. for (i = 0; i < num_cpus; i++) {
  195. sysbus_connect_irq(s, i, get_cpu_irq(cpus, i, irq_pin));
  196. }
  197. sysbus_mmio_map(s, 0, base);
  198. /* Add device tree node for ompic. */
  199. nodename = g_strdup_printf("/ompic@%" HWADDR_PRIx, base);
  200. qemu_fdt_add_subnode(fdt, nodename);
  201. qemu_fdt_setprop_string(fdt, nodename, "compatible", "openrisc,ompic");
  202. qemu_fdt_setprop_cells(fdt, nodename, "reg", base, size);
  203. qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
  204. qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 0);
  205. qemu_fdt_setprop_cell(fdt, nodename, "interrupts", irq_pin);
  206. g_free(nodename);
  207. }
  208. static void openrisc_sim_serial_init(Or1ksimState *state, hwaddr base,
  209. hwaddr size, int num_cpus,
  210. OpenRISCCPU *cpus[], int irq_pin,
  211. int uart_idx)
  212. {
  213. void *fdt = state->fdt;
  214. char *nodename;
  215. qemu_irq serial_irq;
  216. char alias[sizeof("serial0")];
  217. int i;
  218. if (num_cpus > 1) {
  219. DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
  220. qdev_prop_set_uint32(splitter, "num-lines", num_cpus);
  221. qdev_realize_and_unref(splitter, NULL, &error_fatal);
  222. for (i = 0; i < num_cpus; i++) {
  223. qdev_connect_gpio_out(splitter, i, get_cpu_irq(cpus, i, irq_pin));
  224. }
  225. serial_irq = qdev_get_gpio_in(splitter, 0);
  226. } else {
  227. serial_irq = get_cpu_irq(cpus, 0, irq_pin);
  228. }
  229. serial_mm_init(get_system_memory(), base, 0, serial_irq, 115200,
  230. serial_hd(uart_idx),
  231. DEVICE_BIG_ENDIAN);
  232. /* Add device tree node for serial. */
  233. nodename = g_strdup_printf("/serial@%" HWADDR_PRIx, base);
  234. qemu_fdt_add_subnode(fdt, nodename);
  235. qemu_fdt_setprop_string(fdt, nodename, "compatible", "ns16550a");
  236. qemu_fdt_setprop_cells(fdt, nodename, "reg", base, size);
  237. qemu_fdt_setprop_cell(fdt, nodename, "interrupts", irq_pin);
  238. qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", OR1KSIM_CLK_MHZ);
  239. qemu_fdt_setprop(fdt, nodename, "big-endian", NULL, 0);
  240. if (uart_idx == 0) {
  241. /* The /chosen node is created during fdt creation. */
  242. qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
  243. }
  244. snprintf(alias, sizeof(alias), "serial%d", uart_idx);
  245. qemu_fdt_setprop_string(fdt, "/aliases", alias, nodename);
  246. g_free(nodename);
  247. }
  248. static void openrisc_sim_init(MachineState *machine)
  249. {
  250. ram_addr_t ram_size = machine->ram_size;
  251. const char *kernel_filename = machine->kernel_filename;
  252. OpenRISCCPU *cpus[OR1KSIM_CPUS_MAX] = {};
  253. Or1ksimState *state = OR1KSIM_MACHINE(machine);
  254. MemoryRegion *ram;
  255. hwaddr load_addr;
  256. int n;
  257. unsigned int smp_cpus = machine->smp.cpus;
  258. assert(smp_cpus >= 1 && smp_cpus <= OR1KSIM_CPUS_MAX);
  259. for (n = 0; n < smp_cpus; n++) {
  260. cpus[n] = OPENRISC_CPU(cpu_create(machine->cpu_type));
  261. if (cpus[n] == NULL) {
  262. fprintf(stderr, "Unable to find CPU definition!\n");
  263. exit(1);
  264. }
  265. cpu_openrisc_clock_init(cpus[n]);
  266. qemu_register_reset(main_cpu_reset, cpus[n]);
  267. }
  268. ram = g_malloc(sizeof(*ram));
  269. memory_region_init_ram(ram, NULL, "openrisc.ram", ram_size, &error_fatal);
  270. memory_region_add_subregion(get_system_memory(), 0, ram);
  271. openrisc_create_fdt(state, or1ksim_memmap, smp_cpus, machine->ram_size,
  272. machine->kernel_cmdline);
  273. openrisc_sim_net_init(state, or1ksim_memmap[OR1KSIM_ETHOC].base,
  274. or1ksim_memmap[OR1KSIM_ETHOC].size,
  275. smp_cpus, cpus,
  276. OR1KSIM_ETHOC_IRQ);
  277. if (smp_cpus > 1) {
  278. openrisc_sim_ompic_init(state, or1ksim_memmap[OR1KSIM_OMPIC].base,
  279. or1ksim_memmap[OR1KSIM_OMPIC].size,
  280. smp_cpus, cpus, OR1KSIM_OMPIC_IRQ);
  281. }
  282. /*
  283. * We create the UART nodes starting with the highest address and
  284. * working downwards, because in QEMU the DTB nodes end up in the
  285. * DTB in reverse order of creation. Correctly-written guest software
  286. * will not care about the node order (it will look at stdout-path
  287. * or the alias nodes), but for the benefit of guest software which
  288. * just looks for the first UART node in the DTB, make sure the
  289. * lowest-address UART (which is QEMU's first serial port) appears
  290. * first in the DTB.
  291. */
  292. for (n = OR1KSIM_UART_COUNT - 1; n >= 0; n--) {
  293. openrisc_sim_serial_init(state, or1ksim_memmap[OR1KSIM_UART].base +
  294. or1ksim_memmap[OR1KSIM_UART].size * n,
  295. or1ksim_memmap[OR1KSIM_UART].size,
  296. smp_cpus, cpus, OR1KSIM_UART_IRQ, n);
  297. }
  298. load_addr = openrisc_load_kernel(ram_size, kernel_filename,
  299. &boot_info.bootstrap_pc);
  300. if (load_addr > 0) {
  301. if (machine->initrd_filename) {
  302. load_addr = openrisc_load_initrd(state->fdt,
  303. machine->initrd_filename,
  304. load_addr, machine->ram_size);
  305. }
  306. boot_info.fdt_addr = openrisc_load_fdt(state->fdt, load_addr,
  307. machine->ram_size);
  308. }
  309. }
  310. static void openrisc_sim_machine_init(ObjectClass *oc, void *data)
  311. {
  312. MachineClass *mc = MACHINE_CLASS(oc);
  313. mc->desc = "or1k simulation";
  314. mc->init = openrisc_sim_init;
  315. mc->max_cpus = OR1KSIM_CPUS_MAX;
  316. mc->is_default = true;
  317. mc->default_cpu_type = OPENRISC_CPU_TYPE_NAME("or1200");
  318. }
  319. static const TypeInfo or1ksim_machine_typeinfo = {
  320. .name = TYPE_OR1KSIM_MACHINE,
  321. .parent = TYPE_MACHINE,
  322. .class_init = openrisc_sim_machine_init,
  323. .instance_size = sizeof(Or1ksimState),
  324. };
  325. static void or1ksim_machine_init_register_types(void)
  326. {
  327. type_register_static(&or1ksim_machine_typeinfo);
  328. }
  329. type_init(or1ksim_machine_init_register_types)