openrisc_sim.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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 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 "hw/hw.h"
  21. #include "hw/boards.h"
  22. #include "elf.h"
  23. #include "hw/char/serial.h"
  24. #include "net/net.h"
  25. #include "hw/loader.h"
  26. #include "exec/address-spaces.h"
  27. #include "sysemu/sysemu.h"
  28. #include "hw/sysbus.h"
  29. #include "sysemu/qtest.h"
  30. #define KERNEL_LOAD_ADDR 0x100
  31. static void main_cpu_reset(void *opaque)
  32. {
  33. OpenRISCCPU *cpu = opaque;
  34. cpu_reset(CPU(cpu));
  35. }
  36. static void openrisc_sim_net_init(MemoryRegion *address_space,
  37. hwaddr base,
  38. hwaddr descriptors,
  39. qemu_irq irq, NICInfo *nd)
  40. {
  41. DeviceState *dev;
  42. SysBusDevice *s;
  43. dev = qdev_create(NULL, "open_eth");
  44. qdev_set_nic_properties(dev, nd);
  45. qdev_init_nofail(dev);
  46. s = SYS_BUS_DEVICE(dev);
  47. sysbus_connect_irq(s, 0, irq);
  48. memory_region_add_subregion(address_space, base,
  49. sysbus_mmio_get_region(s, 0));
  50. memory_region_add_subregion(address_space, descriptors,
  51. sysbus_mmio_get_region(s, 1));
  52. }
  53. static void cpu_openrisc_load_kernel(ram_addr_t ram_size,
  54. const char *kernel_filename,
  55. OpenRISCCPU *cpu)
  56. {
  57. long kernel_size;
  58. uint64_t elf_entry;
  59. hwaddr entry;
  60. if (kernel_filename && !qtest_enabled()) {
  61. kernel_size = load_elf(kernel_filename, NULL, NULL,
  62. &elf_entry, NULL, NULL, 1, ELF_MACHINE, 1);
  63. entry = elf_entry;
  64. if (kernel_size < 0) {
  65. kernel_size = load_uimage(kernel_filename,
  66. &entry, NULL, NULL);
  67. }
  68. if (kernel_size < 0) {
  69. kernel_size = load_image_targphys(kernel_filename,
  70. KERNEL_LOAD_ADDR,
  71. ram_size - KERNEL_LOAD_ADDR);
  72. entry = KERNEL_LOAD_ADDR;
  73. }
  74. if (kernel_size < 0) {
  75. fprintf(stderr, "QEMU: couldn't load the kernel '%s'\n",
  76. kernel_filename);
  77. exit(1);
  78. }
  79. cpu->env.pc = entry;
  80. }
  81. }
  82. static void openrisc_sim_init(QEMUMachineInitArgs *args)
  83. {
  84. ram_addr_t ram_size = args->ram_size;
  85. const char *cpu_model = args->cpu_model;
  86. const char *kernel_filename = args->kernel_filename;
  87. OpenRISCCPU *cpu = NULL;
  88. MemoryRegion *ram;
  89. int n;
  90. if (!cpu_model) {
  91. cpu_model = "or1200";
  92. }
  93. for (n = 0; n < smp_cpus; n++) {
  94. cpu = cpu_openrisc_init(cpu_model);
  95. if (cpu == NULL) {
  96. fprintf(stderr, "Unable to find CPU definition!\n");
  97. exit(1);
  98. }
  99. qemu_register_reset(main_cpu_reset, cpu);
  100. main_cpu_reset(cpu);
  101. }
  102. ram = g_malloc(sizeof(*ram));
  103. memory_region_init_ram(ram, NULL, "openrisc.ram", ram_size);
  104. vmstate_register_ram_global(ram);
  105. memory_region_add_subregion(get_system_memory(), 0, ram);
  106. cpu_openrisc_pic_init(cpu);
  107. cpu_openrisc_clock_init(cpu);
  108. serial_mm_init(get_system_memory(), 0x90000000, 0, cpu->env.irq[2],
  109. 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);
  110. if (nd_table[0].used) {
  111. openrisc_sim_net_init(get_system_memory(), 0x92000000,
  112. 0x92000400, cpu->env.irq[4], nd_table);
  113. }
  114. cpu_openrisc_load_kernel(ram_size, kernel_filename, cpu);
  115. }
  116. static QEMUMachine openrisc_sim_machine = {
  117. .name = "or32-sim",
  118. .desc = "or32 simulation",
  119. .init = openrisc_sim_init,
  120. .max_cpus = 1,
  121. .is_default = 1,
  122. };
  123. static void openrisc_sim_machine_init(void)
  124. {
  125. qemu_register_machine(&openrisc_sim_machine);
  126. }
  127. machine_init(openrisc_sim_machine_init);