ths | 5fafdf2 | 2007-09-16 21:08:06 +0000 | [diff] [blame] | 1 | /* |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 2 | * ARM RealView Baseboard System emulation. |
| 3 | * |
pbrook | a1bb27b | 2007-04-06 16:49:48 +0000 | [diff] [blame] | 4 | * Copyright (c) 2006-2007 CodeSourcery. |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 5 | * Written by Paul Brook |
| 6 | * |
Matthew Fernandez | 8e31bf3 | 2011-06-26 12:21:35 +1000 | [diff] [blame] | 7 | * This code is licensed under the GPL. |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 8 | */ |
| 9 | |
Paul Brook | 2e9bdce | 2009-05-14 22:35:07 +0100 | [diff] [blame] | 10 | #include "sysbus.h" |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 11 | #include "arm-misc.h" |
| 12 | #include "primecell.h" |
| 13 | #include "devices.h" |
| 14 | #include "pci.h" |
| 15 | #include "net.h" |
| 16 | #include "sysemu.h" |
| 17 | #include "boards.h" |
Oskar Andero | d1157ca | 2012-04-20 15:38:52 +0000 | [diff] [blame] | 18 | #include "i2c.h" |
Blue Swirl | 2446333 | 2010-08-24 15:22:24 +0000 | [diff] [blame] | 19 | #include "blockdev.h" |
Avi Kivity | 35e8782 | 2011-10-02 17:04:26 +0200 | [diff] [blame] | 20 | #include "exec-memory.h" |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 21 | |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 22 | #define SMP_BOOT_ADDR 0xe0000000 |
Evgeny Voevodin | 078758d | 2012-01-13 20:52:40 +0000 | [diff] [blame] | 23 | #define SMP_BOOTREG_ADDR 0x10000030 |
Paul Brook | eee4850 | 2009-11-20 00:45:54 +0000 | [diff] [blame] | 24 | |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 25 | /* Board init. */ |
| 26 | |
balrog | f93eb9f | 2008-04-14 20:27:51 +0000 | [diff] [blame] | 27 | static struct arm_boot_info realview_binfo = { |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 28 | .smp_loader_start = SMP_BOOT_ADDR, |
Evgeny Voevodin | 078758d | 2012-01-13 20:52:40 +0000 | [diff] [blame] | 29 | .smp_bootreg_addr = SMP_BOOTREG_ADDR, |
balrog | f93eb9f | 2008-04-14 20:27:51 +0000 | [diff] [blame] | 30 | }; |
| 31 | |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 32 | /* The following two lists must be consistent. */ |
Paul Brook | c988bfa | 2009-11-13 04:31:22 +0000 | [diff] [blame] | 33 | enum realview_board_type { |
| 34 | BOARD_EB, |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 35 | BOARD_EB_MPCORE, |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 36 | BOARD_PB_A8, |
| 37 | BOARD_PBX_A9, |
| 38 | }; |
| 39 | |
Blue Swirl | d05ac8f | 2009-12-04 20:44:44 +0000 | [diff] [blame] | 40 | static const int realview_board_id[] = { |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 41 | 0x33b, |
| 42 | 0x33b, |
| 43 | 0x769, |
| 44 | 0x76d |
Paul Brook | c988bfa | 2009-11-13 04:31:22 +0000 | [diff] [blame] | 45 | }; |
| 46 | |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 47 | static void realview_init(ram_addr_t ram_size, |
aliguori | 3023f33 | 2009-01-16 19:04:14 +0000 | [diff] [blame] | 48 | const char *boot_device, |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 49 | const char *kernel_filename, const char *kernel_cmdline, |
Paul Brook | c988bfa | 2009-11-13 04:31:22 +0000 | [diff] [blame] | 50 | const char *initrd_filename, const char *cpu_model, |
| 51 | enum realview_board_type board_type) |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 52 | { |
Andreas Färber | 5ae9330 | 2012-03-14 01:38:23 +0100 | [diff] [blame] | 53 | CPUARMState *env = NULL; |
Avi Kivity | 35e8782 | 2011-10-02 17:04:26 +0200 | [diff] [blame] | 54 | MemoryRegion *sysmem = get_system_memory(); |
| 55 | MemoryRegion *ram_lo = g_new(MemoryRegion, 1); |
| 56 | MemoryRegion *ram_hi = g_new(MemoryRegion, 1); |
| 57 | MemoryRegion *ram_alias = g_new(MemoryRegion, 1); |
| 58 | MemoryRegion *ram_hack = g_new(MemoryRegion, 1); |
Peter Maydell | 03a0e94 | 2011-10-28 10:55:38 +0100 | [diff] [blame] | 59 | DeviceState *dev, *sysctl, *gpio2, *pl041; |
Paul Brook | c988bfa | 2009-11-13 04:31:22 +0000 | [diff] [blame] | 60 | SysBusDevice *busdev; |
Paul Brook | fe7e875 | 2009-05-14 22:35:08 +0100 | [diff] [blame] | 61 | qemu_irq *irqp; |
| 62 | qemu_irq pic[64]; |
Peter Maydell | 26883c6 | 2011-02-21 20:57:53 +0000 | [diff] [blame] | 63 | qemu_irq mmc_irq[2]; |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 64 | PCIBus *pci_bus; |
| 65 | NICInfo *nd; |
Paul Brook | eee4850 | 2009-11-20 00:45:54 +0000 | [diff] [blame] | 66 | i2c_bus *i2c; |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 67 | int n; |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 68 | int done_nic = 0; |
pbrook | 9ee6e8b | 2007-11-11 00:04:49 +0000 | [diff] [blame] | 69 | qemu_irq cpu_irq[4]; |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 70 | int is_mpcore = 0; |
| 71 | int is_pb = 0; |
Paul Brook | 26e92f6 | 2009-11-13 03:30:33 +0000 | [diff] [blame] | 72 | uint32_t proc_id = 0; |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 73 | uint32_t sys_id; |
| 74 | ram_addr_t low_ram_size; |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 75 | |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 76 | switch (board_type) { |
| 77 | case BOARD_EB: |
| 78 | break; |
| 79 | case BOARD_EB_MPCORE: |
| 80 | is_mpcore = 1; |
| 81 | break; |
| 82 | case BOARD_PB_A8: |
| 83 | is_pb = 1; |
| 84 | break; |
| 85 | case BOARD_PBX_A9: |
| 86 | is_mpcore = 1; |
| 87 | is_pb = 1; |
| 88 | break; |
| 89 | } |
Paul Brook | c988bfa | 2009-11-13 04:31:22 +0000 | [diff] [blame] | 90 | for (n = 0; n < smp_cpus; n++) { |
pbrook | 9ee6e8b | 2007-11-11 00:04:49 +0000 | [diff] [blame] | 91 | env = cpu_init(cpu_model); |
| 92 | if (!env) { |
| 93 | fprintf(stderr, "Unable to find CPU definition\n"); |
| 94 | exit(1); |
| 95 | } |
Paul Brook | fe7e875 | 2009-05-14 22:35:08 +0100 | [diff] [blame] | 96 | irqp = arm_pic_init_cpu(env); |
| 97 | cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ]; |
bellard | aaed909 | 2007-11-10 15:15:54 +0000 | [diff] [blame] | 98 | } |
Paul Brook | 26e92f6 | 2009-11-13 03:30:33 +0000 | [diff] [blame] | 99 | if (arm_feature(env, ARM_FEATURE_V7)) { |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 100 | if (is_mpcore) { |
| 101 | proc_id = 0x0c000000; |
| 102 | } else { |
| 103 | proc_id = 0x0e000000; |
| 104 | } |
Paul Brook | 26e92f6 | 2009-11-13 03:30:33 +0000 | [diff] [blame] | 105 | } else if (arm_feature(env, ARM_FEATURE_V6K)) { |
| 106 | proc_id = 0x06000000; |
| 107 | } else if (arm_feature(env, ARM_FEATURE_V6)) { |
| 108 | proc_id = 0x04000000; |
| 109 | } else { |
| 110 | proc_id = 0x02000000; |
| 111 | } |
bellard | aaed909 | 2007-11-10 15:15:54 +0000 | [diff] [blame] | 112 | |
Paul Brook | 21a8894 | 2009-12-21 20:19:12 +0000 | [diff] [blame] | 113 | if (is_pb && ram_size > 0x20000000) { |
| 114 | /* Core tile RAM. */ |
| 115 | low_ram_size = ram_size - 0x20000000; |
| 116 | ram_size = 0x20000000; |
Avi Kivity | c5705a7 | 2011-12-20 15:59:12 +0200 | [diff] [blame] | 117 | memory_region_init_ram(ram_lo, "realview.lowmem", low_ram_size); |
| 118 | vmstate_register_ram_global(ram_lo); |
Avi Kivity | 35e8782 | 2011-10-02 17:04:26 +0200 | [diff] [blame] | 119 | memory_region_add_subregion(sysmem, 0x20000000, ram_lo); |
Paul Brook | 21a8894 | 2009-12-21 20:19:12 +0000 | [diff] [blame] | 120 | } |
| 121 | |
Avi Kivity | c5705a7 | 2011-12-20 15:59:12 +0200 | [diff] [blame] | 122 | memory_region_init_ram(ram_hi, "realview.highmem", ram_size); |
| 123 | vmstate_register_ram_global(ram_hi); |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 124 | low_ram_size = ram_size; |
| 125 | if (low_ram_size > 0x10000000) |
| 126 | low_ram_size = 0x10000000; |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 127 | /* SDRAM at address zero. */ |
Avi Kivity | 35e8782 | 2011-10-02 17:04:26 +0200 | [diff] [blame] | 128 | memory_region_init_alias(ram_alias, "realview.alias", |
| 129 | ram_hi, 0, low_ram_size); |
| 130 | memory_region_add_subregion(sysmem, 0, ram_alias); |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 131 | if (is_pb) { |
| 132 | /* And again at a high address. */ |
Avi Kivity | 35e8782 | 2011-10-02 17:04:26 +0200 | [diff] [blame] | 133 | memory_region_add_subregion(sysmem, 0x70000000, ram_hi); |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 134 | } else { |
| 135 | ram_size = low_ram_size; |
| 136 | } |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 137 | |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 138 | sys_id = is_pb ? 0x01780500 : 0xc1400400; |
Peter Maydell | 26883c6 | 2011-02-21 20:57:53 +0000 | [diff] [blame] | 139 | sysctl = qdev_create(NULL, "realview_sysctl"); |
| 140 | qdev_prop_set_uint32(sysctl, "sys_id", sys_id); |
Peter Maydell | 26883c6 | 2011-02-21 20:57:53 +0000 | [diff] [blame] | 141 | qdev_prop_set_uint32(sysctl, "proc_id", proc_id); |
Peter Maydell | 7a65c8c | 2012-02-09 06:11:16 +0000 | [diff] [blame] | 142 | qdev_init_nofail(sysctl); |
Peter Maydell | 26883c6 | 2011-02-21 20:57:53 +0000 | [diff] [blame] | 143 | sysbus_mmio_map(sysbus_from_qdev(sysctl), 0, 0x10000000); |
pbrook | 9ee6e8b | 2007-11-11 00:04:49 +0000 | [diff] [blame] | 144 | |
Paul Brook | c988bfa | 2009-11-13 04:31:22 +0000 | [diff] [blame] | 145 | if (is_mpcore) { |
Peter Maydell | 96eacf6 | 2012-02-16 09:56:09 +0000 | [diff] [blame] | 146 | target_phys_addr_t periphbase; |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 147 | dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore"); |
Paul Brook | c988bfa | 2009-11-13 04:31:22 +0000 | [diff] [blame] | 148 | qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); |
| 149 | qdev_init_nofail(dev); |
| 150 | busdev = sysbus_from_qdev(dev); |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 151 | if (is_pb) { |
Peter Maydell | 96eacf6 | 2012-02-16 09:56:09 +0000 | [diff] [blame] | 152 | periphbase = 0x1f000000; |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 153 | } else { |
Peter Maydell | 96eacf6 | 2012-02-16 09:56:09 +0000 | [diff] [blame] | 154 | periphbase = 0x10100000; |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 155 | } |
Peter Maydell | 96eacf6 | 2012-02-16 09:56:09 +0000 | [diff] [blame] | 156 | sysbus_mmio_map(busdev, 0, periphbase); |
Paul Brook | c988bfa | 2009-11-13 04:31:22 +0000 | [diff] [blame] | 157 | for (n = 0; n < smp_cpus; n++) { |
| 158 | sysbus_connect_irq(busdev, n, cpu_irq[n]); |
| 159 | } |
Peter Maydell | 96eacf6 | 2012-02-16 09:56:09 +0000 | [diff] [blame] | 160 | sysbus_create_varargs("l2x0", periphbase + 0x2000, NULL); |
| 161 | /* Both A9 and 11MPCore put the GIC CPU i/f at base + 0x100 */ |
| 162 | realview_binfo.gic_cpu_if_addr = periphbase + 0x100; |
pbrook | 9ee6e8b | 2007-11-11 00:04:49 +0000 | [diff] [blame] | 163 | } else { |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 164 | uint32_t gic_addr = is_pb ? 0x1e000000 : 0x10040000; |
| 165 | /* For now just create the nIRQ GIC, and ignore the others. */ |
| 166 | dev = sysbus_create_simple("realview_gic", gic_addr, cpu_irq[0]); |
Paul Brook | fe7e875 | 2009-05-14 22:35:08 +0100 | [diff] [blame] | 167 | } |
| 168 | for (n = 0; n < 64; n++) { |
Paul Brook | 067a3dd | 2009-05-26 14:56:11 +0100 | [diff] [blame] | 169 | pic[n] = qdev_get_gpio_in(dev, n); |
pbrook | 9ee6e8b | 2007-11-11 00:04:49 +0000 | [diff] [blame] | 170 | } |
| 171 | |
Peter Maydell | 03a0e94 | 2011-10-28 10:55:38 +0100 | [diff] [blame] | 172 | pl041 = qdev_create(NULL, "pl041"); |
| 173 | qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512); |
| 174 | qdev_init_nofail(pl041); |
| 175 | sysbus_mmio_map(sysbus_from_qdev(pl041), 0, 0x10004000); |
| 176 | sysbus_connect_irq(sysbus_from_qdev(pl041), 0, pic[19]); |
| 177 | |
Paul Brook | 86394e9 | 2009-05-14 22:35:07 +0100 | [diff] [blame] | 178 | sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]); |
| 179 | sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]); |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 180 | |
Paul Brook | a7d518a | 2009-05-14 22:35:07 +0100 | [diff] [blame] | 181 | sysbus_create_simple("pl011", 0x10009000, pic[12]); |
| 182 | sysbus_create_simple("pl011", 0x1000a000, pic[13]); |
| 183 | sysbus_create_simple("pl011", 0x1000b000, pic[14]); |
| 184 | sysbus_create_simple("pl011", 0x1000c000, pic[15]); |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 185 | |
| 186 | /* DMA controller is optional, apparently. */ |
Paul Brook | b4496b1 | 2009-05-14 22:35:08 +0100 | [diff] [blame] | 187 | sysbus_create_simple("pl081", 0x10030000, pic[24]); |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 188 | |
Paul Brook | 6a824ec | 2009-05-14 22:35:07 +0100 | [diff] [blame] | 189 | sysbus_create_simple("sp804", 0x10011000, pic[4]); |
| 190 | sysbus_create_simple("sp804", 0x10012000, pic[5]); |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 191 | |
Peter Maydell | 26883c6 | 2011-02-21 20:57:53 +0000 | [diff] [blame] | 192 | sysbus_create_simple("pl061", 0x10013000, pic[6]); |
| 193 | sysbus_create_simple("pl061", 0x10014000, pic[7]); |
| 194 | gpio2 = sysbus_create_simple("pl061", 0x10015000, pic[8]); |
| 195 | |
Peter Maydell | acb9b72 | 2011-07-22 15:36:54 +0000 | [diff] [blame] | 196 | sysbus_create_simple("pl111", 0x10020000, pic[23]); |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 197 | |
Peter Maydell | 26883c6 | 2011-02-21 20:57:53 +0000 | [diff] [blame] | 198 | dev = sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL); |
| 199 | /* Wire up MMC card detect and read-only signals. These have |
| 200 | * to go to both the PL061 GPIO and the sysctl register. |
| 201 | * Note that the PL181 orders these lines (readonly,inserted) |
| 202 | * and the PL061 has them the other way about. Also the card |
| 203 | * detect line is inverted. |
| 204 | */ |
| 205 | mmc_irq[0] = qemu_irq_split( |
| 206 | qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT), |
| 207 | qdev_get_gpio_in(gpio2, 1)); |
| 208 | mmc_irq[1] = qemu_irq_split( |
| 209 | qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN), |
| 210 | qemu_irq_invert(qdev_get_gpio_in(gpio2, 0))); |
| 211 | qdev_connect_gpio_out(dev, 0, mmc_irq[0]); |
| 212 | qdev_connect_gpio_out(dev, 1, mmc_irq[1]); |
pbrook | a1bb27b | 2007-04-06 16:49:48 +0000 | [diff] [blame] | 213 | |
Paul Brook | a63bdb3 | 2009-05-14 22:35:07 +0100 | [diff] [blame] | 214 | sysbus_create_simple("pl031", 0x10017000, pic[10]); |
pbrook | 7e1543c | 2007-06-30 17:32:17 +0000 | [diff] [blame] | 215 | |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 216 | if (!is_pb) { |
Peter Maydell | 7d6e771 | 2011-09-01 18:36:53 +0100 | [diff] [blame] | 217 | dev = qdev_create(NULL, "realview_pci"); |
| 218 | busdev = sysbus_from_qdev(dev); |
| 219 | qdev_init_nofail(dev); |
| 220 | sysbus_mmio_map(busdev, 0, 0x61000000); /* PCI self-config */ |
| 221 | sysbus_mmio_map(busdev, 1, 0x62000000); /* PCI config */ |
| 222 | sysbus_mmio_map(busdev, 2, 0x63000000); /* PCI I/O */ |
| 223 | sysbus_connect_irq(busdev, 0, pic[48]); |
| 224 | sysbus_connect_irq(busdev, 1, pic[49]); |
| 225 | sysbus_connect_irq(busdev, 2, pic[50]); |
| 226 | sysbus_connect_irq(busdev, 3, pic[51]); |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 227 | pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci"); |
| 228 | if (usb_enabled) { |
Gerd Hoffmann | afb9a60 | 2012-03-07 15:06:32 +0100 | [diff] [blame] | 229 | pci_create_simple(pci_bus, -1, "pci-ohci"); |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 230 | } |
| 231 | n = drive_get_max_bus(IF_SCSI); |
| 232 | while (n >= 0) { |
| 233 | pci_create_simple(pci_bus, -1, "lsi53c895a"); |
| 234 | n--; |
| 235 | } |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 236 | } |
| 237 | for(n = 0; n < nb_nics; n++) { |
| 238 | nd = &nd_table[n]; |
aliguori | 0ae18ce | 2009-01-13 19:39:36 +0000 | [diff] [blame] | 239 | |
Peter Maydell | e6b3c8c | 2011-03-22 18:21:58 +0000 | [diff] [blame] | 240 | if (!done_nic && (!nd->model || |
| 241 | strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0)) { |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 242 | if (is_pb) { |
| 243 | lan9118_init(nd, 0x4e000000, pic[28]); |
| 244 | } else { |
| 245 | smc91c111_init(nd, 0x4e000000, pic[28]); |
| 246 | } |
| 247 | done_nic = 1; |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 248 | } else { |
Markus Armbruster | 07caea3 | 2009-09-25 03:53:51 +0200 | [diff] [blame] | 249 | pci_nic_init_nofail(nd, "rtl8139", NULL); |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 250 | } |
| 251 | } |
| 252 | |
Oskar Andero | d1157ca | 2012-04-20 15:38:52 +0000 | [diff] [blame] | 253 | dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL); |
Paul Brook | eee4850 | 2009-11-20 00:45:54 +0000 | [diff] [blame] | 254 | i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); |
| 255 | i2c_create_slave(i2c, "ds1338", 0x68); |
| 256 | |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 257 | /* Memory map for RealView Emulation Baseboard: */ |
| 258 | /* 0x10000000 System registers. */ |
| 259 | /* 0x10001000 System controller. */ |
Paul Brook | eee4850 | 2009-11-20 00:45:54 +0000 | [diff] [blame] | 260 | /* 0x10002000 Two-Wire Serial Bus. */ |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 261 | /* 0x10003000 Reserved. */ |
| 262 | /* 0x10004000 AACI. */ |
| 263 | /* 0x10005000 MCI. */ |
| 264 | /* 0x10006000 KMI0. */ |
| 265 | /* 0x10007000 KMI1. */ |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 266 | /* 0x10008000 Character LCD. (EB) */ |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 267 | /* 0x10009000 UART0. */ |
| 268 | /* 0x1000a000 UART1. */ |
| 269 | /* 0x1000b000 UART2. */ |
| 270 | /* 0x1000c000 UART3. */ |
| 271 | /* 0x1000d000 SSPI. */ |
| 272 | /* 0x1000e000 SCI. */ |
| 273 | /* 0x1000f000 Reserved. */ |
| 274 | /* 0x10010000 Watchdog. */ |
| 275 | /* 0x10011000 Timer 0+1. */ |
| 276 | /* 0x10012000 Timer 2+3. */ |
| 277 | /* 0x10013000 GPIO 0. */ |
| 278 | /* 0x10014000 GPIO 1. */ |
| 279 | /* 0x10015000 GPIO 2. */ |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 280 | /* 0x10002000 Two-Wire Serial Bus - DVI. (PB) */ |
pbrook | 7e1543c | 2007-06-30 17:32:17 +0000 | [diff] [blame] | 281 | /* 0x10017000 RTC. */ |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 282 | /* 0x10018000 DMC. */ |
| 283 | /* 0x10019000 PCI controller config. */ |
| 284 | /* 0x10020000 CLCD. */ |
| 285 | /* 0x10030000 DMA Controller. */ |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 286 | /* 0x10040000 GIC1. (EB) */ |
| 287 | /* 0x10050000 GIC2. (EB) */ |
| 288 | /* 0x10060000 GIC3. (EB) */ |
| 289 | /* 0x10070000 GIC4. (EB) */ |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 290 | /* 0x10080000 SMC. */ |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 291 | /* 0x1e000000 GIC1. (PB) */ |
| 292 | /* 0x1e001000 GIC2. (PB) */ |
| 293 | /* 0x1e002000 GIC3. (PB) */ |
| 294 | /* 0x1e003000 GIC4. (PB) */ |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 295 | /* 0x40000000 NOR flash. */ |
| 296 | /* 0x44000000 DoC flash. */ |
| 297 | /* 0x48000000 SRAM. */ |
| 298 | /* 0x4c000000 Configuration flash. */ |
| 299 | /* 0x4e000000 Ethernet. */ |
| 300 | /* 0x4f000000 USB. */ |
| 301 | /* 0x50000000 PISMO. */ |
| 302 | /* 0x54000000 PISMO. */ |
| 303 | /* 0x58000000 PISMO. */ |
| 304 | /* 0x5c000000 PISMO. */ |
| 305 | /* 0x60000000 PCI. */ |
| 306 | /* 0x61000000 PCI Self Config. */ |
| 307 | /* 0x62000000 PCI Config. */ |
| 308 | /* 0x63000000 PCI IO. */ |
| 309 | /* 0x64000000 PCI mem 0. */ |
| 310 | /* 0x68000000 PCI mem 1. */ |
| 311 | /* 0x6c000000 PCI mem 2. */ |
| 312 | |
pbrook | 7ffab4d | 2009-04-09 17:15:18 +0000 | [diff] [blame] | 313 | /* ??? Hack to map an additional page of ram for the secondary CPU |
| 314 | startup code. I guess this works on real hardware because the |
| 315 | BootROM happens to be in ROM/flash or in memory that isn't clobbered |
| 316 | until after Linux boots the secondary CPUs. */ |
Avi Kivity | c5705a7 | 2011-12-20 15:59:12 +0200 | [diff] [blame] | 317 | memory_region_init_ram(ram_hack, "realview.hack", 0x1000); |
| 318 | vmstate_register_ram_global(ram_hack); |
Avi Kivity | 35e8782 | 2011-10-02 17:04:26 +0200 | [diff] [blame] | 319 | memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack); |
pbrook | 7ffab4d | 2009-04-09 17:15:18 +0000 | [diff] [blame] | 320 | |
balrog | f93eb9f | 2008-04-14 20:27:51 +0000 | [diff] [blame] | 321 | realview_binfo.ram_size = ram_size; |
| 322 | realview_binfo.kernel_filename = kernel_filename; |
| 323 | realview_binfo.kernel_cmdline = kernel_cmdline; |
| 324 | realview_binfo.initrd_filename = initrd_filename; |
Paul Brook | c988bfa | 2009-11-13 04:31:22 +0000 | [diff] [blame] | 325 | realview_binfo.nb_cpus = smp_cpus; |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 326 | realview_binfo.board_id = realview_board_id[board_type]; |
Paul Brook | 21a8894 | 2009-12-21 20:19:12 +0000 | [diff] [blame] | 327 | realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0); |
balrog | f93eb9f | 2008-04-14 20:27:51 +0000 | [diff] [blame] | 328 | arm_load_kernel(first_cpu, &realview_binfo); |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 329 | } |
| 330 | |
Paul Brook | c988bfa | 2009-11-13 04:31:22 +0000 | [diff] [blame] | 331 | static void realview_eb_init(ram_addr_t ram_size, |
| 332 | const char *boot_device, |
| 333 | const char *kernel_filename, const char *kernel_cmdline, |
| 334 | const char *initrd_filename, const char *cpu_model) |
| 335 | { |
| 336 | if (!cpu_model) { |
| 337 | cpu_model = "arm926"; |
| 338 | } |
| 339 | realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline, |
| 340 | initrd_filename, cpu_model, BOARD_EB); |
| 341 | } |
| 342 | |
| 343 | static void realview_eb_mpcore_init(ram_addr_t ram_size, |
| 344 | const char *boot_device, |
| 345 | const char *kernel_filename, const char *kernel_cmdline, |
| 346 | const char *initrd_filename, const char *cpu_model) |
| 347 | { |
| 348 | if (!cpu_model) { |
| 349 | cpu_model = "arm11mpcore"; |
| 350 | } |
| 351 | realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline, |
| 352 | initrd_filename, cpu_model, BOARD_EB_MPCORE); |
| 353 | } |
| 354 | |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 355 | static void realview_pb_a8_init(ram_addr_t ram_size, |
| 356 | const char *boot_device, |
| 357 | const char *kernel_filename, const char *kernel_cmdline, |
| 358 | const char *initrd_filename, const char *cpu_model) |
| 359 | { |
| 360 | if (!cpu_model) { |
| 361 | cpu_model = "cortex-a8"; |
| 362 | } |
| 363 | realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline, |
| 364 | initrd_filename, cpu_model, BOARD_PB_A8); |
| 365 | } |
| 366 | |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 367 | static void realview_pbx_a9_init(ram_addr_t ram_size, |
| 368 | const char *boot_device, |
| 369 | const char *kernel_filename, const char *kernel_cmdline, |
| 370 | const char *initrd_filename, const char *cpu_model) |
| 371 | { |
| 372 | if (!cpu_model) { |
| 373 | cpu_model = "cortex-a9"; |
| 374 | } |
| 375 | realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline, |
| 376 | initrd_filename, cpu_model, BOARD_PBX_A9); |
| 377 | } |
| 378 | |
Paul Brook | c988bfa | 2009-11-13 04:31:22 +0000 | [diff] [blame] | 379 | static QEMUMachine realview_eb_machine = { |
| 380 | .name = "realview-eb", |
blueswir1 | c9b1ae2 | 2008-09-28 18:55:17 +0000 | [diff] [blame] | 381 | .desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)", |
Paul Brook | c988bfa | 2009-11-13 04:31:22 +0000 | [diff] [blame] | 382 | .init = realview_eb_init, |
blueswir1 | c9b1ae2 | 2008-09-28 18:55:17 +0000 | [diff] [blame] | 383 | .use_scsi = 1, |
pbrook | e69954b | 2006-09-23 17:40:58 +0000 | [diff] [blame] | 384 | }; |
Anthony Liguori | f80f9ec | 2009-05-20 18:38:09 -0500 | [diff] [blame] | 385 | |
Paul Brook | c988bfa | 2009-11-13 04:31:22 +0000 | [diff] [blame] | 386 | static QEMUMachine realview_eb_mpcore_machine = { |
| 387 | .name = "realview-eb-mpcore", |
| 388 | .desc = "ARM RealView Emulation Baseboard (ARM11MPCore)", |
| 389 | .init = realview_eb_mpcore_init, |
| 390 | .use_scsi = 1, |
| 391 | .max_cpus = 4, |
| 392 | }; |
| 393 | |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 394 | static QEMUMachine realview_pb_a8_machine = { |
| 395 | .name = "realview-pb-a8", |
| 396 | .desc = "ARM RealView Platform Baseboard for Cortex-A8", |
| 397 | .init = realview_pb_a8_init, |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 398 | }; |
| 399 | |
| 400 | static QEMUMachine realview_pbx_a9_machine = { |
| 401 | .name = "realview-pbx-a9", |
| 402 | .desc = "ARM RealView Platform Baseboard Explore for Cortex-A9", |
| 403 | .init = realview_pbx_a9_init, |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 404 | .use_scsi = 1, |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 405 | .max_cpus = 4, |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 406 | }; |
| 407 | |
Anthony Liguori | f80f9ec | 2009-05-20 18:38:09 -0500 | [diff] [blame] | 408 | static void realview_machine_init(void) |
| 409 | { |
Paul Brook | c988bfa | 2009-11-13 04:31:22 +0000 | [diff] [blame] | 410 | qemu_register_machine(&realview_eb_machine); |
| 411 | qemu_register_machine(&realview_eb_mpcore_machine); |
Paul Brook | 0ef849d | 2009-11-16 17:06:43 +0000 | [diff] [blame] | 412 | qemu_register_machine(&realview_pb_a8_machine); |
Paul Brook | f7c7032 | 2009-11-19 16:45:21 +0000 | [diff] [blame] | 413 | qemu_register_machine(&realview_pbx_a9_machine); |
Anthony Liguori | f80f9ec | 2009-05-20 18:38:09 -0500 | [diff] [blame] | 414 | } |
| 415 | |
| 416 | machine_init(realview_machine_init); |