153018216SPaolo Bonzini /*
253018216SPaolo Bonzini * Calxeda Highbank SoC emulation
353018216SPaolo Bonzini *
453018216SPaolo Bonzini * Copyright (c) 2010-2012 Calxeda
553018216SPaolo Bonzini *
653018216SPaolo Bonzini * This program is free software; you can redistribute it and/or modify it
753018216SPaolo Bonzini * under the terms and conditions of the GNU General Public License,
853018216SPaolo Bonzini * version 2 or later, as published by the Free Software Foundation.
953018216SPaolo Bonzini *
1053018216SPaolo Bonzini * This program is distributed in the hope it will be useful, but WITHOUT
1153018216SPaolo Bonzini * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1253018216SPaolo Bonzini * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
1353018216SPaolo Bonzini * more details.
1453018216SPaolo Bonzini *
1553018216SPaolo Bonzini * You should have received a copy of the GNU General Public License along with
1653018216SPaolo Bonzini * this program. If not, see <http://www.gnu.org/licenses/>.
1753018216SPaolo Bonzini *
1853018216SPaolo Bonzini */
1953018216SPaolo Bonzini
2012b16722SPeter Maydell #include "qemu/osdep.h"
212c65db5eSPaolo Bonzini #include "qemu/datadir.h"
22da34e65cSMarkus Armbruster #include "qapi/error.h"
2353018216SPaolo Bonzini #include "hw/sysbus.h"
24d6454270SMarkus Armbruster #include "migration/vmstate.h"
2512ec8bd5SPeter Maydell #include "hw/arm/boot.h"
2653018216SPaolo Bonzini #include "hw/loader.h"
2753018216SPaolo Bonzini #include "net/net.h"
2854d31236SMarkus Armbruster #include "sysemu/runstate.h"
2953018216SPaolo Bonzini #include "sysemu/sysemu.h"
3053018216SPaolo Bonzini #include "hw/boards.h"
31f282f296SPeter Crosthwaite #include "qemu/error-report.h"
32f0d1d2c1Sxiaoqiang zhao #include "hw/char/pl011.h"
33fbb5945eSPhilippe Mathieu-Daudé #include "hw/ide/ahci-sysbus.h"
34c2de81e2SPhilippe Mathieu-Daudé #include "hw/cpu/a9mpcore.h"
35c2de81e2SPhilippe Mathieu-Daudé #include "hw/cpu/a15mpcore.h"
36c5c752afSPrasad J Pandit #include "qemu/log.h"
37db1015e9SEduardo Habkost #include "qom/object.h"
38416dd952SPeter Maydell #include "cpu.h"
39d780d056SPhilippe Mathieu-Daudé #include "target/arm/cpu-qom.h"
4053018216SPaolo Bonzini
4153018216SPaolo Bonzini #define SMP_BOOT_ADDR 0x100
4253018216SPaolo Bonzini #define SMP_BOOT_REG 0x40
43e2cddeebSPeter Crosthwaite #define MPCORE_PERIPHBASE 0xfff10000
4453018216SPaolo Bonzini
4540340e5fSPeter Crosthwaite #define MVBAR_ADDR 0x200
46716536a9SAndrew Baumann #define BOARD_SETUP_ADDR (MVBAR_ADDR + 8 * sizeof(uint32_t))
4740340e5fSPeter Crosthwaite
4853018216SPaolo Bonzini #define NIRQ_GIC 160
4953018216SPaolo Bonzini
5053018216SPaolo Bonzini /* Board init. */
5153018216SPaolo Bonzini
5253018216SPaolo Bonzini #define NUM_REGS 0x200
hb_regs_write(void * opaque,hwaddr offset,uint64_t value,unsigned size)5353018216SPaolo Bonzini static void hb_regs_write(void *opaque, hwaddr offset,
5453018216SPaolo Bonzini uint64_t value, unsigned size)
5553018216SPaolo Bonzini {
5653018216SPaolo Bonzini uint32_t *regs = opaque;
5753018216SPaolo Bonzini
5853018216SPaolo Bonzini if (offset == 0xf00) {
5953018216SPaolo Bonzini if (value == 1 || value == 2) {
60cf83f140SEric Blake qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
6153018216SPaolo Bonzini } else if (value == 3) {
62cf83f140SEric Blake qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
6353018216SPaolo Bonzini }
6453018216SPaolo Bonzini }
6553018216SPaolo Bonzini
66c5c752afSPrasad J Pandit if (offset / 4 >= NUM_REGS) {
67c5c752afSPrasad J Pandit qemu_log_mask(LOG_GUEST_ERROR,
68c5c752afSPrasad J Pandit "highbank: bad write offset 0x%" HWADDR_PRIx "\n", offset);
69c5c752afSPrasad J Pandit return;
70c5c752afSPrasad J Pandit }
7153018216SPaolo Bonzini regs[offset / 4] = value;
7253018216SPaolo Bonzini }
7353018216SPaolo Bonzini
hb_regs_read(void * opaque,hwaddr offset,unsigned size)7453018216SPaolo Bonzini static uint64_t hb_regs_read(void *opaque, hwaddr offset,
7553018216SPaolo Bonzini unsigned size)
7653018216SPaolo Bonzini {
77c5c752afSPrasad J Pandit uint32_t value;
7853018216SPaolo Bonzini uint32_t *regs = opaque;
79c5c752afSPrasad J Pandit
80c5c752afSPrasad J Pandit if (offset / 4 >= NUM_REGS) {
81c5c752afSPrasad J Pandit qemu_log_mask(LOG_GUEST_ERROR,
82c5c752afSPrasad J Pandit "highbank: bad read offset 0x%" HWADDR_PRIx "\n", offset);
83c5c752afSPrasad J Pandit return 0;
84c5c752afSPrasad J Pandit }
85c5c752afSPrasad J Pandit value = regs[offset / 4];
8653018216SPaolo Bonzini
8753018216SPaolo Bonzini if ((offset == 0x100) || (offset == 0x108) || (offset == 0x10C)) {
8853018216SPaolo Bonzini value |= 0x30000000;
8953018216SPaolo Bonzini }
9053018216SPaolo Bonzini
9153018216SPaolo Bonzini return value;
9253018216SPaolo Bonzini }
9353018216SPaolo Bonzini
9453018216SPaolo Bonzini static const MemoryRegionOps hb_mem_ops = {
9553018216SPaolo Bonzini .read = hb_regs_read,
9653018216SPaolo Bonzini .write = hb_regs_write,
9753018216SPaolo Bonzini .endianness = DEVICE_NATIVE_ENDIAN,
9853018216SPaolo Bonzini };
9953018216SPaolo Bonzini
100426533faSAndreas Färber #define TYPE_HIGHBANK_REGISTERS "highbank-regs"
1018063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(HighbankRegsState, HIGHBANK_REGISTERS)
102426533faSAndreas Färber
103db1015e9SEduardo Habkost struct HighbankRegsState {
104426533faSAndreas Färber /*< private >*/
105426533faSAndreas Färber SysBusDevice parent_obj;
106426533faSAndreas Färber /*< public >*/
107426533faSAndreas Färber
108112f2ac9SStefan Weil MemoryRegion iomem;
10953018216SPaolo Bonzini uint32_t regs[NUM_REGS];
110db1015e9SEduardo Habkost };
11153018216SPaolo Bonzini
112cfa52e09SPhilippe Mathieu-Daudé static const VMStateDescription vmstate_highbank_regs = {
11353018216SPaolo Bonzini .name = "highbank-regs",
11453018216SPaolo Bonzini .version_id = 0,
11553018216SPaolo Bonzini .minimum_version_id = 0,
116607ef570SRichard Henderson .fields = (const VMStateField[]) {
11753018216SPaolo Bonzini VMSTATE_UINT32_ARRAY(regs, HighbankRegsState, NUM_REGS),
11853018216SPaolo Bonzini VMSTATE_END_OF_LIST(),
11953018216SPaolo Bonzini },
12053018216SPaolo Bonzini };
12153018216SPaolo Bonzini
highbank_regs_reset(DeviceState * dev)12253018216SPaolo Bonzini static void highbank_regs_reset(DeviceState *dev)
12353018216SPaolo Bonzini {
124426533faSAndreas Färber HighbankRegsState *s = HIGHBANK_REGISTERS(dev);
12553018216SPaolo Bonzini
12653018216SPaolo Bonzini s->regs[0x40] = 0x05F20121;
12753018216SPaolo Bonzini s->regs[0x41] = 0x2;
12853018216SPaolo Bonzini s->regs[0x42] = 0x05F30121;
12953018216SPaolo Bonzini s->regs[0x43] = 0x05F40121;
13053018216SPaolo Bonzini }
13153018216SPaolo Bonzini
highbank_regs_init(Object * obj)132ff7a27c1Sxiaoqiang.zhao static void highbank_regs_init(Object *obj)
13353018216SPaolo Bonzini {
134ff7a27c1Sxiaoqiang.zhao HighbankRegsState *s = HIGHBANK_REGISTERS(obj);
135ff7a27c1Sxiaoqiang.zhao SysBusDevice *dev = SYS_BUS_DEVICE(obj);
13653018216SPaolo Bonzini
137ff7a27c1Sxiaoqiang.zhao memory_region_init_io(&s->iomem, obj, &hb_mem_ops, s->regs,
13864bde0f3SPaolo Bonzini "highbank_regs", 0x1000);
139112f2ac9SStefan Weil sysbus_init_mmio(dev, &s->iomem);
14053018216SPaolo Bonzini }
14153018216SPaolo Bonzini
highbank_regs_class_init(ObjectClass * klass,void * data)14253018216SPaolo Bonzini static void highbank_regs_class_init(ObjectClass *klass, void *data)
14353018216SPaolo Bonzini {
14453018216SPaolo Bonzini DeviceClass *dc = DEVICE_CLASS(klass);
14553018216SPaolo Bonzini
14653018216SPaolo Bonzini dc->desc = "Calxeda Highbank registers";
14753018216SPaolo Bonzini dc->vmsd = &vmstate_highbank_regs;
148e3d08143SPeter Maydell device_class_set_legacy_reset(dc, highbank_regs_reset);
14953018216SPaolo Bonzini }
15053018216SPaolo Bonzini
15153018216SPaolo Bonzini static const TypeInfo highbank_regs_info = {
152426533faSAndreas Färber .name = TYPE_HIGHBANK_REGISTERS,
15353018216SPaolo Bonzini .parent = TYPE_SYS_BUS_DEVICE,
15453018216SPaolo Bonzini .instance_size = sizeof(HighbankRegsState),
155ff7a27c1Sxiaoqiang.zhao .instance_init = highbank_regs_init,
15653018216SPaolo Bonzini .class_init = highbank_regs_class_init,
15753018216SPaolo Bonzini };
15853018216SPaolo Bonzini
highbank_regs_register_types(void)15953018216SPaolo Bonzini static void highbank_regs_register_types(void)
16053018216SPaolo Bonzini {
16153018216SPaolo Bonzini type_register_static(&highbank_regs_info);
16253018216SPaolo Bonzini }
16353018216SPaolo Bonzini
16453018216SPaolo Bonzini type_init(highbank_regs_register_types)
16553018216SPaolo Bonzini
16653018216SPaolo Bonzini static struct arm_boot_info highbank_binfo;
16753018216SPaolo Bonzini
168574f66bcSAndre Przywara enum cxmachines {
169574f66bcSAndre Przywara CALXEDA_HIGHBANK,
170b25a83f0SAndre Przywara CALXEDA_MIDWAY,
171574f66bcSAndre Przywara };
172574f66bcSAndre Przywara
17353018216SPaolo Bonzini /* ram_size must be set to match the upper bound of memory in the
17453018216SPaolo Bonzini * device tree (linux/arch/arm/boot/dts/highbank.dts), which is
17553018216SPaolo Bonzini * normally 0xff900000 or -m 4089. When running this board on a
17653018216SPaolo Bonzini * 32-bit host, set the reg value of memory to 0xf7ff00000 in the
17753018216SPaolo Bonzini * device tree and pass -m 2047 to QEMU.
17853018216SPaolo Bonzini */
calxeda_init(MachineState * machine,enum cxmachines machine_id)1793ef96221SMarcel Apfelbaum static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
18053018216SPaolo Bonzini {
181574f66bcSAndre Przywara DeviceState *dev = NULL;
18253018216SPaolo Bonzini SysBusDevice *busdev;
18353018216SPaolo Bonzini qemu_irq pic[128];
18453018216SPaolo Bonzini int n;
185cc7d44c2SLike Xu unsigned int smp_cpus = machine->smp.cpus;
18653018216SPaolo Bonzini qemu_irq cpu_irq[4];
1875ae79fe8SPeter Maydell qemu_irq cpu_fiq[4];
188582c8f75SPeter Maydell qemu_irq cpu_virq[4];
189582c8f75SPeter Maydell qemu_irq cpu_vfiq[4];
19053018216SPaolo Bonzini MemoryRegion *sysram;
19153018216SPaolo Bonzini MemoryRegion *sysmem;
19253018216SPaolo Bonzini char *sysboot_filename;
19353018216SPaolo Bonzini
1943ef96221SMarcel Apfelbaum switch (machine_id) {
195574f66bcSAndre Przywara case CALXEDA_HIGHBANK:
196ba1ba5ccSIgor Mammedov machine->cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
197574f66bcSAndre Przywara break;
198b25a83f0SAndre Przywara case CALXEDA_MIDWAY:
199ba1ba5ccSIgor Mammedov machine->cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
200b25a83f0SAndre Przywara break;
201ba1ba5ccSIgor Mammedov default:
202*42bf363cSPierrick Bouvier g_assert_not_reached();
203574f66bcSAndre Przywara }
20453018216SPaolo Bonzini
20553018216SPaolo Bonzini for (n = 0; n < smp_cpus; n++) {
206d097696eSPeter Maydell Object *cpuobj;
20753018216SPaolo Bonzini ARMCPU *cpu;
208f282f296SPeter Crosthwaite
209ba1ba5ccSIgor Mammedov cpuobj = object_new(machine->cpu_type);
210d097696eSPeter Maydell cpu = ARM_CPU(cpuobj);
211f282f296SPeter Crosthwaite
2126a4e6117SPhilippe Mathieu-Daudé object_property_add_child(OBJECT(machine), "cpu[*]", cpuobj);
2135325cc34SMarkus Armbruster object_property_set_int(cpuobj, "psci-conduit", QEMU_PSCI_CONDUIT_SMC,
2145325cc34SMarkus Armbruster &error_abort);
21540340e5fSPeter Crosthwaite
216efba1595SDaniel P. Berrangé if (object_property_find(cpuobj, "reset-cbar")) {
2175325cc34SMarkus Armbruster object_property_set_int(cpuobj, "reset-cbar", MPCORE_PERIPHBASE,
2185325cc34SMarkus Armbruster &error_abort);
219c0f1ead9SPeter Crosthwaite }
220ce189ab2SMarkus Armbruster qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
2219188dbf7SPeter Maydell cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
2225ae79fe8SPeter Maydell cpu_fiq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ);
223582c8f75SPeter Maydell cpu_virq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_VIRQ);
224582c8f75SPeter Maydell cpu_vfiq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_VFIQ);
22553018216SPaolo Bonzini }
22653018216SPaolo Bonzini
22753018216SPaolo Bonzini sysmem = get_system_memory();
22853018216SPaolo Bonzini /* SDRAM at address zero. */
22989c43bdfSIgor Mammedov memory_region_add_subregion(sysmem, 0, machine->ram);
23053018216SPaolo Bonzini
23153018216SPaolo Bonzini sysram = g_new(MemoryRegion, 1);
232eb7d1f17SPeter Maydell memory_region_init_ram(sysram, NULL, "highbank.sysram", 0x8000,
233f8ed85acSMarkus Armbruster &error_fatal);
23453018216SPaolo Bonzini memory_region_add_subregion(sysmem, 0xfff88000, sysram);
2350ad3b5d3SPaolo Bonzini if (machine->firmware != NULL) {
2360ad3b5d3SPaolo Bonzini sysboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, machine->firmware);
23753018216SPaolo Bonzini if (sysboot_filename != NULL) {
23860ff4e63SStefan Weil if (load_image_targphys(sysboot_filename, 0xfff88000, 0x8000) < 0) {
2390ad3b5d3SPaolo Bonzini error_report("Unable to load %s", machine->firmware);
240c525436eSMarkus Armbruster exit(1);
24153018216SPaolo Bonzini }
2426e05a12fSGonglei g_free(sysboot_filename);
24353018216SPaolo Bonzini } else {
2440ad3b5d3SPaolo Bonzini error_report("Unable to find %s", machine->firmware);
245c525436eSMarkus Armbruster exit(1);
24653018216SPaolo Bonzini }
24753018216SPaolo Bonzini }
24853018216SPaolo Bonzini
2493ef96221SMarcel Apfelbaum switch (machine_id) {
250574f66bcSAndre Przywara case CALXEDA_HIGHBANK:
251df707969SMarkus Armbruster dev = qdev_new("l2x0");
252b25a83f0SAndre Przywara busdev = SYS_BUS_DEVICE(dev);
2533c6ef471SMarkus Armbruster sysbus_realize_and_unref(busdev, &error_fatal);
254b25a83f0SAndre Przywara sysbus_mmio_map(busdev, 0, 0xfff12000);
255b25a83f0SAndre Przywara
256df707969SMarkus Armbruster dev = qdev_new(TYPE_A9MPCORE_PRIV);
257574f66bcSAndre Przywara break;
258b25a83f0SAndre Przywara case CALXEDA_MIDWAY:
259df707969SMarkus Armbruster dev = qdev_new(TYPE_A15MPCORE_PRIV);
260b25a83f0SAndre Przywara break;
261574f66bcSAndre Przywara }
26253018216SPaolo Bonzini qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
26353018216SPaolo Bonzini qdev_prop_set_uint32(dev, "num-irq", NIRQ_GIC);
26453018216SPaolo Bonzini busdev = SYS_BUS_DEVICE(dev);
2653c6ef471SMarkus Armbruster sysbus_realize_and_unref(busdev, &error_fatal);
266e2cddeebSPeter Crosthwaite sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
26753018216SPaolo Bonzini for (n = 0; n < smp_cpus; n++) {
26853018216SPaolo Bonzini sysbus_connect_irq(busdev, n, cpu_irq[n]);
2695ae79fe8SPeter Maydell sysbus_connect_irq(busdev, n + smp_cpus, cpu_fiq[n]);
270582c8f75SPeter Maydell sysbus_connect_irq(busdev, n + 2 * smp_cpus, cpu_virq[n]);
271582c8f75SPeter Maydell sysbus_connect_irq(busdev, n + 3 * smp_cpus, cpu_vfiq[n]);
27253018216SPaolo Bonzini }
27353018216SPaolo Bonzini
27453018216SPaolo Bonzini for (n = 0; n < 128; n++) {
27553018216SPaolo Bonzini pic[n] = qdev_get_gpio_in(dev, n);
27653018216SPaolo Bonzini }
27753018216SPaolo Bonzini
278df707969SMarkus Armbruster dev = qdev_new("sp804");
27953018216SPaolo Bonzini qdev_prop_set_uint32(dev, "freq0", 150000000);
28053018216SPaolo Bonzini qdev_prop_set_uint32(dev, "freq1", 150000000);
28153018216SPaolo Bonzini busdev = SYS_BUS_DEVICE(dev);
2823c6ef471SMarkus Armbruster sysbus_realize_and_unref(busdev, &error_fatal);
28353018216SPaolo Bonzini sysbus_mmio_map(busdev, 0, 0xfff34000);
28453018216SPaolo Bonzini sysbus_connect_irq(busdev, 0, pic[18]);
2859bca0edbSPeter Maydell pl011_create(0xfff36000, pic[20], serial_hd(0));
28653018216SPaolo Bonzini
287df707969SMarkus Armbruster dev = qdev_new(TYPE_HIGHBANK_REGISTERS);
28853018216SPaolo Bonzini busdev = SYS_BUS_DEVICE(dev);
2893c6ef471SMarkus Armbruster sysbus_realize_and_unref(busdev, &error_fatal);
29053018216SPaolo Bonzini sysbus_mmio_map(busdev, 0, 0xfff3c000);
29153018216SPaolo Bonzini
29253018216SPaolo Bonzini sysbus_create_simple("pl061", 0xfff30000, pic[14]);
29353018216SPaolo Bonzini sysbus_create_simple("pl061", 0xfff31000, pic[15]);
29453018216SPaolo Bonzini sysbus_create_simple("pl061", 0xfff32000, pic[16]);
29553018216SPaolo Bonzini sysbus_create_simple("pl061", 0xfff33000, pic[17]);
29653018216SPaolo Bonzini sysbus_create_simple("pl031", 0xfff35000, pic[19]);
29753018216SPaolo Bonzini sysbus_create_simple("pl022", 0xfff39000, pic[23]);
29853018216SPaolo Bonzini
299c2de81e2SPhilippe Mathieu-Daudé sysbus_create_simple(TYPE_SYSBUS_AHCI, 0xffe08000, pic[83]);
30053018216SPaolo Bonzini
30127c0235fSDavid Woodhouse dev = qemu_create_nic_device("xgmac", true, NULL);
30227c0235fSDavid Woodhouse if (dev) {
3033c6ef471SMarkus Armbruster sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
30453018216SPaolo Bonzini sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xfff50000);
30553018216SPaolo Bonzini sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[77]);
30653018216SPaolo Bonzini sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, pic[78]);
30753018216SPaolo Bonzini sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, pic[79]);
30827c0235fSDavid Woodhouse }
30953018216SPaolo Bonzini
31027c0235fSDavid Woodhouse dev = qemu_create_nic_device("xgmac", true, NULL);
31127c0235fSDavid Woodhouse if (dev) {
3123c6ef471SMarkus Armbruster sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
31353018216SPaolo Bonzini sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xfff51000);
31453018216SPaolo Bonzini sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[80]);
31553018216SPaolo Bonzini sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, pic[81]);
31653018216SPaolo Bonzini sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, pic[82]);
31753018216SPaolo Bonzini }
31853018216SPaolo Bonzini
3192a7ae4eeSMarkus Armbruster /* TODO create and connect IDE devices for ide_drive_get() */
3202a7ae4eeSMarkus Armbruster
32189c43bdfSIgor Mammedov highbank_binfo.ram_size = machine->ram_size;
32253018216SPaolo Bonzini /* highbank requires a dtb in order to boot, and the dtb will override
32353018216SPaolo Bonzini * the board ID. The following value is ignored, so set it to -1 to be
32453018216SPaolo Bonzini * clear that the value is meaningless.
32553018216SPaolo Bonzini */
32653018216SPaolo Bonzini highbank_binfo.board_id = -1;
32753018216SPaolo Bonzini highbank_binfo.loader_start = 0;
32840340e5fSPeter Crosthwaite highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR;
32933284d48SPeter Maydell highbank_binfo.psci_conduit = QEMU_PSCI_CONDUIT_SMC;
33040340e5fSPeter Crosthwaite
3312744ece8STao Xu arm_load_kernel(ARM_CPU(first_cpu), machine, &highbank_binfo);
33253018216SPaolo Bonzini }
33353018216SPaolo Bonzini
highbank_init(MachineState * machine)3343ef96221SMarcel Apfelbaum static void highbank_init(MachineState *machine)
335574f66bcSAndre Przywara {
3363ef96221SMarcel Apfelbaum calxeda_init(machine, CALXEDA_HIGHBANK);
337574f66bcSAndre Przywara }
338574f66bcSAndre Przywara
midway_init(MachineState * machine)3393ef96221SMarcel Apfelbaum static void midway_init(MachineState *machine)
340b25a83f0SAndre Przywara {
3413ef96221SMarcel Apfelbaum calxeda_init(machine, CALXEDA_MIDWAY);
342b25a83f0SAndre Przywara }
343b25a83f0SAndre Przywara
highbank_class_init(ObjectClass * oc,void * data)3448a661aeaSAndreas Färber static void highbank_class_init(ObjectClass *oc, void *data)
34553018216SPaolo Bonzini {
346104395bcSPhilippe Mathieu-Daudé static const char * const valid_cpu_types[] = {
347104395bcSPhilippe Mathieu-Daudé ARM_CPU_TYPE_NAME("cortex-a9"),
348104395bcSPhilippe Mathieu-Daudé NULL
349104395bcSPhilippe Mathieu-Daudé };
3508a661aeaSAndreas Färber MachineClass *mc = MACHINE_CLASS(oc);
3518a661aeaSAndreas Färber
352e264d29dSEduardo Habkost mc->desc = "Calxeda Highbank (ECX-1000)";
353e264d29dSEduardo Habkost mc->init = highbank_init;
354104395bcSPhilippe Mathieu-Daudé mc->valid_cpu_types = valid_cpu_types;
3552a7ae4eeSMarkus Armbruster mc->block_default_type = IF_IDE;
3562a7ae4eeSMarkus Armbruster mc->units_per_default_bus = 1;
357e264d29dSEduardo Habkost mc->max_cpus = 4;
3584672cbd7SPeter Maydell mc->ignore_memory_transaction_failures = true;
35989c43bdfSIgor Mammedov mc->default_ram_id = "highbank.dram";
36053018216SPaolo Bonzini }
36153018216SPaolo Bonzini
3628a661aeaSAndreas Färber static const TypeInfo highbank_type = {
3638a661aeaSAndreas Färber .name = MACHINE_TYPE_NAME("highbank"),
3648a661aeaSAndreas Färber .parent = TYPE_MACHINE,
3658a661aeaSAndreas Färber .class_init = highbank_class_init,
3668a661aeaSAndreas Färber };
367e264d29dSEduardo Habkost
midway_class_init(ObjectClass * oc,void * data)3688a661aeaSAndreas Färber static void midway_class_init(ObjectClass *oc, void *data)
369e264d29dSEduardo Habkost {
370104395bcSPhilippe Mathieu-Daudé static const char * const valid_cpu_types[] = {
371104395bcSPhilippe Mathieu-Daudé ARM_CPU_TYPE_NAME("cortex-a15"),
372104395bcSPhilippe Mathieu-Daudé NULL
373104395bcSPhilippe Mathieu-Daudé };
3748a661aeaSAndreas Färber MachineClass *mc = MACHINE_CLASS(oc);
3758a661aeaSAndreas Färber
376e264d29dSEduardo Habkost mc->desc = "Calxeda Midway (ECX-2000)";
377e264d29dSEduardo Habkost mc->init = midway_init;
378104395bcSPhilippe Mathieu-Daudé mc->valid_cpu_types = valid_cpu_types;
3792a7ae4eeSMarkus Armbruster mc->block_default_type = IF_IDE;
3802a7ae4eeSMarkus Armbruster mc->units_per_default_bus = 1;
381e264d29dSEduardo Habkost mc->max_cpus = 4;
3824672cbd7SPeter Maydell mc->ignore_memory_transaction_failures = true;
38389c43bdfSIgor Mammedov mc->default_ram_id = "highbank.dram";
384e264d29dSEduardo Habkost }
385e264d29dSEduardo Habkost
3868a661aeaSAndreas Färber static const TypeInfo midway_type = {
3878a661aeaSAndreas Färber .name = MACHINE_TYPE_NAME("midway"),
3888a661aeaSAndreas Färber .parent = TYPE_MACHINE,
3898a661aeaSAndreas Färber .class_init = midway_class_init,
3908a661aeaSAndreas Färber };
3918a661aeaSAndreas Färber
calxeda_machines_init(void)3928a661aeaSAndreas Färber static void calxeda_machines_init(void)
3938a661aeaSAndreas Färber {
3948a661aeaSAndreas Färber type_register_static(&highbank_type);
3958a661aeaSAndreas Färber type_register_static(&midway_type);
3968a661aeaSAndreas Färber }
3978a661aeaSAndreas Färber
3980e6aac87SEduardo Habkost type_init(calxeda_machines_init)
399