exynos4_boards.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Samsung exynos4 SoC based boards emulation
  3. *
  4. * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
  5. * Maksim Kozlov <m.kozlov@samsung.com>
  6. * Evgeny Voevodin <e.voevodin@samsung.com>
  7. * Igor Mitsyanko <i.mitsyanko@samsung.com>
  8. *
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public License as published by the
  11. * Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful, but WITHOUT
  15. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  16. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  17. * for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License along
  20. * with this program; if not, see <http://www.gnu.org/licenses/>.
  21. *
  22. */
  23. #include "sysemu/sysemu.h"
  24. #include "sysbus.h"
  25. #include "net/net.h"
  26. #include "arm-misc.h"
  27. #include "exec/address-spaces.h"
  28. #include "exynos4210.h"
  29. #include "boards.h"
  30. #undef DEBUG
  31. //#define DEBUG
  32. #ifdef DEBUG
  33. #undef PRINT_DEBUG
  34. #define PRINT_DEBUG(fmt, args...) \
  35. do { \
  36. fprintf(stderr, " [%s:%d] "fmt, __func__, __LINE__, ##args); \
  37. } while (0)
  38. #else
  39. #define PRINT_DEBUG(fmt, args...) do {} while (0)
  40. #endif
  41. #define SMDK_LAN9118_BASE_ADDR 0x05000000
  42. typedef enum Exynos4BoardType {
  43. EXYNOS4_BOARD_NURI,
  44. EXYNOS4_BOARD_SMDKC210,
  45. EXYNOS4_NUM_OF_BOARDS
  46. } Exynos4BoardType;
  47. static int exynos4_board_id[EXYNOS4_NUM_OF_BOARDS] = {
  48. [EXYNOS4_BOARD_NURI] = 0xD33,
  49. [EXYNOS4_BOARD_SMDKC210] = 0xB16,
  50. };
  51. static int exynos4_board_smp_bootreg_addr[EXYNOS4_NUM_OF_BOARDS] = {
  52. [EXYNOS4_BOARD_NURI] = EXYNOS4210_SECOND_CPU_BOOTREG,
  53. [EXYNOS4_BOARD_SMDKC210] = EXYNOS4210_SECOND_CPU_BOOTREG,
  54. };
  55. static unsigned long exynos4_board_ram_size[EXYNOS4_NUM_OF_BOARDS] = {
  56. [EXYNOS4_BOARD_NURI] = 0x40000000,
  57. [EXYNOS4_BOARD_SMDKC210] = 0x40000000,
  58. };
  59. static struct arm_boot_info exynos4_board_binfo = {
  60. .loader_start = EXYNOS4210_BASE_BOOT_ADDR,
  61. .smp_loader_start = EXYNOS4210_SMP_BOOT_ADDR,
  62. .nb_cpus = EXYNOS4210_NCPUS,
  63. .write_secondary_boot = exynos4210_write_secondary,
  64. };
  65. static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS];
  66. static void lan9215_init(uint32_t base, qemu_irq irq)
  67. {
  68. DeviceState *dev;
  69. SysBusDevice *s;
  70. /* This should be a 9215 but the 9118 is close enough */
  71. if (nd_table[0].used) {
  72. qemu_check_nic_model(&nd_table[0], "lan9118");
  73. dev = qdev_create(NULL, "lan9118");
  74. qdev_set_nic_properties(dev, &nd_table[0]);
  75. qdev_prop_set_uint32(dev, "mode_16bit", 1);
  76. qdev_init_nofail(dev);
  77. s = SYS_BUS_DEVICE(dev);
  78. sysbus_mmio_map(s, 0, base);
  79. sysbus_connect_irq(s, 0, irq);
  80. }
  81. }
  82. static Exynos4210State *exynos4_boards_init_common(QEMUMachineInitArgs *args,
  83. Exynos4BoardType board_type)
  84. {
  85. if (smp_cpus != EXYNOS4210_NCPUS) {
  86. fprintf(stderr, "%s board supports only %d CPU cores. Ignoring smp_cpus"
  87. " value.\n",
  88. exynos4_machines[board_type].name,
  89. exynos4_machines[board_type].max_cpus);
  90. }
  91. exynos4_board_binfo.ram_size = exynos4_board_ram_size[board_type];
  92. exynos4_board_binfo.board_id = exynos4_board_id[board_type];
  93. exynos4_board_binfo.smp_bootreg_addr =
  94. exynos4_board_smp_bootreg_addr[board_type];
  95. exynos4_board_binfo.kernel_filename = args->kernel_filename;
  96. exynos4_board_binfo.initrd_filename = args->initrd_filename;
  97. exynos4_board_binfo.kernel_cmdline = args->kernel_cmdline;
  98. exynos4_board_binfo.gic_cpu_if_addr =
  99. EXYNOS4210_SMP_PRIVATE_BASE_ADDR + 0x100;
  100. PRINT_DEBUG("\n ram_size: %luMiB [0x%08lx]\n"
  101. " kernel_filename: %s\n"
  102. " kernel_cmdline: %s\n"
  103. " initrd_filename: %s\n",
  104. exynos4_board_ram_size[board_type] / 1048576,
  105. exynos4_board_ram_size[board_type],
  106. args->kernel_filename,
  107. args->kernel_cmdline,
  108. args->initrd_filename);
  109. return exynos4210_init(get_system_memory(),
  110. exynos4_board_ram_size[board_type]);
  111. }
  112. static void nuri_init(QEMUMachineInitArgs *args)
  113. {
  114. exynos4_boards_init_common(args, EXYNOS4_BOARD_NURI);
  115. arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
  116. }
  117. static void smdkc210_init(QEMUMachineInitArgs *args)
  118. {
  119. Exynos4210State *s = exynos4_boards_init_common(args,
  120. EXYNOS4_BOARD_SMDKC210);
  121. lan9215_init(SMDK_LAN9118_BASE_ADDR,
  122. qemu_irq_invert(s->irq_table[exynos4210_get_irq(37, 1)]));
  123. arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
  124. }
  125. static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS] = {
  126. [EXYNOS4_BOARD_NURI] = {
  127. .name = "nuri",
  128. .desc = "Samsung NURI board (Exynos4210)",
  129. .init = nuri_init,
  130. .max_cpus = EXYNOS4210_NCPUS,
  131. DEFAULT_MACHINE_OPTIONS,
  132. },
  133. [EXYNOS4_BOARD_SMDKC210] = {
  134. .name = "smdkc210",
  135. .desc = "Samsung SMDKC210 board (Exynos4210)",
  136. .init = smdkc210_init,
  137. .max_cpus = EXYNOS4210_NCPUS,
  138. DEFAULT_MACHINE_OPTIONS,
  139. },
  140. };
  141. static void exynos4_machine_init(void)
  142. {
  143. qemu_register_machine(&exynos4_machines[EXYNOS4_BOARD_NURI]);
  144. qemu_register_machine(&exynos4_machines[EXYNOS4_BOARD_SMDKC210]);
  145. }
  146. machine_init(exynos4_machine_init);