openrisc_sim.c 4.5 KB

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