highbank.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. /*
  2. * Calxeda Highbank SoC emulation
  3. *
  4. * Copyright (c) 2010-2012 Calxeda
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms and conditions of the GNU General Public License,
  8. * version 2 or later, as published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope it will be useful, but WITHOUT
  11. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13. * more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along with
  16. * this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. #include "qemu/osdep.h"
  20. #include "qemu-common.h"
  21. #include "qapi/error.h"
  22. #include "hw/sysbus.h"
  23. #include "migration/vmstate.h"
  24. #include "hw/arm/boot.h"
  25. #include "hw/loader.h"
  26. #include "net/net.h"
  27. #include "sysemu/kvm.h"
  28. #include "sysemu/runstate.h"
  29. #include "sysemu/sysemu.h"
  30. #include "hw/boards.h"
  31. #include "exec/address-spaces.h"
  32. #include "qemu/error-report.h"
  33. #include "hw/char/pl011.h"
  34. #include "hw/ide/ahci.h"
  35. #include "hw/cpu/a9mpcore.h"
  36. #include "hw/cpu/a15mpcore.h"
  37. #include "qemu/log.h"
  38. #define SMP_BOOT_ADDR 0x100
  39. #define SMP_BOOT_REG 0x40
  40. #define MPCORE_PERIPHBASE 0xfff10000
  41. #define MVBAR_ADDR 0x200
  42. #define BOARD_SETUP_ADDR (MVBAR_ADDR + 8 * sizeof(uint32_t))
  43. #define NIRQ_GIC 160
  44. /* Board init. */
  45. static void hb_write_board_setup(ARMCPU *cpu,
  46. const struct arm_boot_info *info)
  47. {
  48. arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR);
  49. }
  50. static void hb_write_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
  51. {
  52. int n;
  53. uint32_t smpboot[] = {
  54. 0xee100fb0, /* mrc p15, 0, r0, c0, c0, 5 - read current core id */
  55. 0xe210000f, /* ands r0, r0, #0x0f */
  56. 0xe3a03040, /* mov r3, #0x40 - jump address is 0x40 + 0x10 * core id */
  57. 0xe0830200, /* add r0, r3, r0, lsl #4 */
  58. 0xe59f2024, /* ldr r2, privbase */
  59. 0xe3a01001, /* mov r1, #1 */
  60. 0xe5821100, /* str r1, [r2, #256] - set GICC_CTLR.Enable */
  61. 0xe3a010ff, /* mov r1, #0xff */
  62. 0xe5821104, /* str r1, [r2, #260] - set GICC_PMR.Priority to 0xff */
  63. 0xf57ff04f, /* dsb */
  64. 0xe320f003, /* wfi */
  65. 0xe5901000, /* ldr r1, [r0] */
  66. 0xe1110001, /* tst r1, r1 */
  67. 0x0afffffb, /* beq <wfi> */
  68. 0xe12fff11, /* bx r1 */
  69. MPCORE_PERIPHBASE /* privbase: MPCore peripheral base address. */
  70. };
  71. for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
  72. smpboot[n] = tswap32(smpboot[n]);
  73. }
  74. rom_add_blob_fixed_as("smpboot", smpboot, sizeof(smpboot), SMP_BOOT_ADDR,
  75. arm_boot_address_space(cpu, info));
  76. }
  77. static void hb_reset_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
  78. {
  79. CPUARMState *env = &cpu->env;
  80. switch (info->nb_cpus) {
  81. case 4:
  82. address_space_stl_notdirty(&address_space_memory,
  83. SMP_BOOT_REG + 0x30, 0,
  84. MEMTXATTRS_UNSPECIFIED, NULL);
  85. case 3:
  86. address_space_stl_notdirty(&address_space_memory,
  87. SMP_BOOT_REG + 0x20, 0,
  88. MEMTXATTRS_UNSPECIFIED, NULL);
  89. case 2:
  90. address_space_stl_notdirty(&address_space_memory,
  91. SMP_BOOT_REG + 0x10, 0,
  92. MEMTXATTRS_UNSPECIFIED, NULL);
  93. env->regs[15] = SMP_BOOT_ADDR;
  94. break;
  95. default:
  96. break;
  97. }
  98. }
  99. #define NUM_REGS 0x200
  100. static void hb_regs_write(void *opaque, hwaddr offset,
  101. uint64_t value, unsigned size)
  102. {
  103. uint32_t *regs = opaque;
  104. if (offset == 0xf00) {
  105. if (value == 1 || value == 2) {
  106. qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
  107. } else if (value == 3) {
  108. qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
  109. }
  110. }
  111. if (offset / 4 >= NUM_REGS) {
  112. qemu_log_mask(LOG_GUEST_ERROR,
  113. "highbank: bad write offset 0x%" HWADDR_PRIx "\n", offset);
  114. return;
  115. }
  116. regs[offset / 4] = value;
  117. }
  118. static uint64_t hb_regs_read(void *opaque, hwaddr offset,
  119. unsigned size)
  120. {
  121. uint32_t value;
  122. uint32_t *regs = opaque;
  123. if (offset / 4 >= NUM_REGS) {
  124. qemu_log_mask(LOG_GUEST_ERROR,
  125. "highbank: bad read offset 0x%" HWADDR_PRIx "\n", offset);
  126. return 0;
  127. }
  128. value = regs[offset / 4];
  129. if ((offset == 0x100) || (offset == 0x108) || (offset == 0x10C)) {
  130. value |= 0x30000000;
  131. }
  132. return value;
  133. }
  134. static const MemoryRegionOps hb_mem_ops = {
  135. .read = hb_regs_read,
  136. .write = hb_regs_write,
  137. .endianness = DEVICE_NATIVE_ENDIAN,
  138. };
  139. #define TYPE_HIGHBANK_REGISTERS "highbank-regs"
  140. #define HIGHBANK_REGISTERS(obj) \
  141. OBJECT_CHECK(HighbankRegsState, (obj), TYPE_HIGHBANK_REGISTERS)
  142. typedef struct {
  143. /*< private >*/
  144. SysBusDevice parent_obj;
  145. /*< public >*/
  146. MemoryRegion iomem;
  147. uint32_t regs[NUM_REGS];
  148. } HighbankRegsState;
  149. static VMStateDescription vmstate_highbank_regs = {
  150. .name = "highbank-regs",
  151. .version_id = 0,
  152. .minimum_version_id = 0,
  153. .fields = (VMStateField[]) {
  154. VMSTATE_UINT32_ARRAY(regs, HighbankRegsState, NUM_REGS),
  155. VMSTATE_END_OF_LIST(),
  156. },
  157. };
  158. static void highbank_regs_reset(DeviceState *dev)
  159. {
  160. HighbankRegsState *s = HIGHBANK_REGISTERS(dev);
  161. s->regs[0x40] = 0x05F20121;
  162. s->regs[0x41] = 0x2;
  163. s->regs[0x42] = 0x05F30121;
  164. s->regs[0x43] = 0x05F40121;
  165. }
  166. static void highbank_regs_init(Object *obj)
  167. {
  168. HighbankRegsState *s = HIGHBANK_REGISTERS(obj);
  169. SysBusDevice *dev = SYS_BUS_DEVICE(obj);
  170. memory_region_init_io(&s->iomem, obj, &hb_mem_ops, s->regs,
  171. "highbank_regs", 0x1000);
  172. sysbus_init_mmio(dev, &s->iomem);
  173. }
  174. static void highbank_regs_class_init(ObjectClass *klass, void *data)
  175. {
  176. DeviceClass *dc = DEVICE_CLASS(klass);
  177. dc->desc = "Calxeda Highbank registers";
  178. dc->vmsd = &vmstate_highbank_regs;
  179. dc->reset = highbank_regs_reset;
  180. }
  181. static const TypeInfo highbank_regs_info = {
  182. .name = TYPE_HIGHBANK_REGISTERS,
  183. .parent = TYPE_SYS_BUS_DEVICE,
  184. .instance_size = sizeof(HighbankRegsState),
  185. .instance_init = highbank_regs_init,
  186. .class_init = highbank_regs_class_init,
  187. };
  188. static void highbank_regs_register_types(void)
  189. {
  190. type_register_static(&highbank_regs_info);
  191. }
  192. type_init(highbank_regs_register_types)
  193. static struct arm_boot_info highbank_binfo;
  194. enum cxmachines {
  195. CALXEDA_HIGHBANK,
  196. CALXEDA_MIDWAY,
  197. };
  198. /* ram_size must be set to match the upper bound of memory in the
  199. * device tree (linux/arch/arm/boot/dts/highbank.dts), which is
  200. * normally 0xff900000 or -m 4089. When running this board on a
  201. * 32-bit host, set the reg value of memory to 0xf7ff00000 in the
  202. * device tree and pass -m 2047 to QEMU.
  203. */
  204. static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
  205. {
  206. ram_addr_t ram_size = machine->ram_size;
  207. DeviceState *dev = NULL;
  208. SysBusDevice *busdev;
  209. qemu_irq pic[128];
  210. int n;
  211. unsigned int smp_cpus = machine->smp.cpus;
  212. qemu_irq cpu_irq[4];
  213. qemu_irq cpu_fiq[4];
  214. qemu_irq cpu_virq[4];
  215. qemu_irq cpu_vfiq[4];
  216. MemoryRegion *sysram;
  217. MemoryRegion *dram;
  218. MemoryRegion *sysmem;
  219. char *sysboot_filename;
  220. switch (machine_id) {
  221. case CALXEDA_HIGHBANK:
  222. machine->cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
  223. break;
  224. case CALXEDA_MIDWAY:
  225. machine->cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
  226. break;
  227. default:
  228. assert(0);
  229. }
  230. for (n = 0; n < smp_cpus; n++) {
  231. Object *cpuobj;
  232. ARMCPU *cpu;
  233. cpuobj = object_new(machine->cpu_type);
  234. cpu = ARM_CPU(cpuobj);
  235. object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_SMC,
  236. "psci-conduit", &error_abort);
  237. if (n) {
  238. /* Secondary CPUs start in PSCI powered-down state */
  239. object_property_set_bool(cpuobj, true,
  240. "start-powered-off", &error_abort);
  241. }
  242. if (object_property_find(cpuobj, "reset-cbar", NULL)) {
  243. object_property_set_int(cpuobj, MPCORE_PERIPHBASE,
  244. "reset-cbar", &error_abort);
  245. }
  246. object_property_set_bool(cpuobj, true, "realized", &error_fatal);
  247. cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
  248. cpu_fiq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ);
  249. cpu_virq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_VIRQ);
  250. cpu_vfiq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_VFIQ);
  251. }
  252. sysmem = get_system_memory();
  253. dram = g_new(MemoryRegion, 1);
  254. memory_region_allocate_system_memory(dram, NULL, "highbank.dram", ram_size);
  255. /* SDRAM at address zero. */
  256. memory_region_add_subregion(sysmem, 0, dram);
  257. sysram = g_new(MemoryRegion, 1);
  258. memory_region_init_ram(sysram, NULL, "highbank.sysram", 0x8000,
  259. &error_fatal);
  260. memory_region_add_subregion(sysmem, 0xfff88000, sysram);
  261. if (bios_name != NULL) {
  262. sysboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
  263. if (sysboot_filename != NULL) {
  264. if (load_image_targphys(sysboot_filename, 0xfff88000, 0x8000) < 0) {
  265. error_report("Unable to load %s", bios_name);
  266. exit(1);
  267. }
  268. g_free(sysboot_filename);
  269. } else {
  270. error_report("Unable to find %s", bios_name);
  271. exit(1);
  272. }
  273. }
  274. switch (machine_id) {
  275. case CALXEDA_HIGHBANK:
  276. dev = qdev_create(NULL, "l2x0");
  277. qdev_init_nofail(dev);
  278. busdev = SYS_BUS_DEVICE(dev);
  279. sysbus_mmio_map(busdev, 0, 0xfff12000);
  280. dev = qdev_create(NULL, TYPE_A9MPCORE_PRIV);
  281. break;
  282. case CALXEDA_MIDWAY:
  283. dev = qdev_create(NULL, TYPE_A15MPCORE_PRIV);
  284. break;
  285. }
  286. qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
  287. qdev_prop_set_uint32(dev, "num-irq", NIRQ_GIC);
  288. qdev_init_nofail(dev);
  289. busdev = SYS_BUS_DEVICE(dev);
  290. sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
  291. for (n = 0; n < smp_cpus; n++) {
  292. sysbus_connect_irq(busdev, n, cpu_irq[n]);
  293. sysbus_connect_irq(busdev, n + smp_cpus, cpu_fiq[n]);
  294. sysbus_connect_irq(busdev, n + 2 * smp_cpus, cpu_virq[n]);
  295. sysbus_connect_irq(busdev, n + 3 * smp_cpus, cpu_vfiq[n]);
  296. }
  297. for (n = 0; n < 128; n++) {
  298. pic[n] = qdev_get_gpio_in(dev, n);
  299. }
  300. dev = qdev_create(NULL, "sp804");
  301. qdev_prop_set_uint32(dev, "freq0", 150000000);
  302. qdev_prop_set_uint32(dev, "freq1", 150000000);
  303. qdev_init_nofail(dev);
  304. busdev = SYS_BUS_DEVICE(dev);
  305. sysbus_mmio_map(busdev, 0, 0xfff34000);
  306. sysbus_connect_irq(busdev, 0, pic[18]);
  307. pl011_create(0xfff36000, pic[20], serial_hd(0));
  308. dev = qdev_create(NULL, TYPE_HIGHBANK_REGISTERS);
  309. qdev_init_nofail(dev);
  310. busdev = SYS_BUS_DEVICE(dev);
  311. sysbus_mmio_map(busdev, 0, 0xfff3c000);
  312. sysbus_create_simple("pl061", 0xfff30000, pic[14]);
  313. sysbus_create_simple("pl061", 0xfff31000, pic[15]);
  314. sysbus_create_simple("pl061", 0xfff32000, pic[16]);
  315. sysbus_create_simple("pl061", 0xfff33000, pic[17]);
  316. sysbus_create_simple("pl031", 0xfff35000, pic[19]);
  317. sysbus_create_simple("pl022", 0xfff39000, pic[23]);
  318. sysbus_create_simple(TYPE_SYSBUS_AHCI, 0xffe08000, pic[83]);
  319. if (nd_table[0].used) {
  320. qemu_check_nic_model(&nd_table[0], "xgmac");
  321. dev = qdev_create(NULL, "xgmac");
  322. qdev_set_nic_properties(dev, &nd_table[0]);
  323. qdev_init_nofail(dev);
  324. sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xfff50000);
  325. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[77]);
  326. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, pic[78]);
  327. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, pic[79]);
  328. qemu_check_nic_model(&nd_table[1], "xgmac");
  329. dev = qdev_create(NULL, "xgmac");
  330. qdev_set_nic_properties(dev, &nd_table[1]);
  331. qdev_init_nofail(dev);
  332. sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xfff51000);
  333. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[80]);
  334. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, pic[81]);
  335. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, pic[82]);
  336. }
  337. /* TODO create and connect IDE devices for ide_drive_get() */
  338. highbank_binfo.ram_size = ram_size;
  339. /* highbank requires a dtb in order to boot, and the dtb will override
  340. * the board ID. The following value is ignored, so set it to -1 to be
  341. * clear that the value is meaningless.
  342. */
  343. highbank_binfo.board_id = -1;
  344. highbank_binfo.nb_cpus = smp_cpus;
  345. highbank_binfo.loader_start = 0;
  346. highbank_binfo.write_secondary_boot = hb_write_secondary;
  347. highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary;
  348. if (!kvm_enabled()) {
  349. highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR;
  350. highbank_binfo.write_board_setup = hb_write_board_setup;
  351. highbank_binfo.secure_board_setup = true;
  352. } else {
  353. warn_report("cannot load built-in Monitor support "
  354. "if KVM is enabled. Some guests (such as Linux) "
  355. "may not boot.");
  356. }
  357. arm_load_kernel(ARM_CPU(first_cpu), machine, &highbank_binfo);
  358. }
  359. static void highbank_init(MachineState *machine)
  360. {
  361. calxeda_init(machine, CALXEDA_HIGHBANK);
  362. }
  363. static void midway_init(MachineState *machine)
  364. {
  365. calxeda_init(machine, CALXEDA_MIDWAY);
  366. }
  367. static void highbank_class_init(ObjectClass *oc, void *data)
  368. {
  369. MachineClass *mc = MACHINE_CLASS(oc);
  370. mc->desc = "Calxeda Highbank (ECX-1000)";
  371. mc->init = highbank_init;
  372. mc->block_default_type = IF_IDE;
  373. mc->units_per_default_bus = 1;
  374. mc->max_cpus = 4;
  375. mc->ignore_memory_transaction_failures = true;
  376. }
  377. static const TypeInfo highbank_type = {
  378. .name = MACHINE_TYPE_NAME("highbank"),
  379. .parent = TYPE_MACHINE,
  380. .class_init = highbank_class_init,
  381. };
  382. static void midway_class_init(ObjectClass *oc, void *data)
  383. {
  384. MachineClass *mc = MACHINE_CLASS(oc);
  385. mc->desc = "Calxeda Midway (ECX-2000)";
  386. mc->init = midway_init;
  387. mc->block_default_type = IF_IDE;
  388. mc->units_per_default_bus = 1;
  389. mc->max_cpus = 4;
  390. mc->ignore_memory_transaction_failures = true;
  391. }
  392. static const TypeInfo midway_type = {
  393. .name = MACHINE_TYPE_NAME("midway"),
  394. .parent = TYPE_MACHINE,
  395. .class_init = midway_class_init,
  396. };
  397. static void calxeda_machines_init(void)
  398. {
  399. type_register_static(&highbank_type);
  400. type_register_static(&midway_type);
  401. }
  402. type_init(calxeda_machines_init)