153018216SPaolo Bonzini /*
253018216SPaolo Bonzini * Arnewsh 5206 ColdFire system emulation.
353018216SPaolo Bonzini *
453018216SPaolo Bonzini * Copyright (c) 2007 CodeSourcery.
553018216SPaolo Bonzini *
653018216SPaolo Bonzini * This code is licensed under the GPL
753018216SPaolo Bonzini */
853018216SPaolo Bonzini
9d8416665SPeter Maydell #include "qemu/osdep.h"
10da34e65cSMarkus Armbruster #include "qapi/error.h"
114771d756SPaolo Bonzini #include "cpu.h"
120d09e41aSPaolo Bonzini #include "hw/m68k/mcf.h"
1353018216SPaolo Bonzini #include "hw/boards.h"
1453018216SPaolo Bonzini #include "hw/loader.h"
1553018216SPaolo Bonzini #include "elf.h"
16c525436eSMarkus Armbruster #include "qemu/error-report.h"
1719c82aacSAndreas Färber #include "sysemu/qtest.h"
1853018216SPaolo Bonzini
1953018216SPaolo Bonzini #define KERNEL_LOAD_ADDR 0x10000
2053018216SPaolo Bonzini #define AN5206_MBAR_ADDR 0x10000000
2153018216SPaolo Bonzini #define AN5206_RAMBAR_ADDR 0x20000000
2253018216SPaolo Bonzini
mcf5206_init(M68kCPU * cpu,MemoryRegion * sysmem,uint32_t base)23*989c8a46SPhilippe Mathieu-Daudé static void mcf5206_init(M68kCPU *cpu, MemoryRegion *sysmem, uint32_t base)
240bc6746eSThomas Huth {
250bc6746eSThomas Huth DeviceState *dev;
260bc6746eSThomas Huth SysBusDevice *s;
270bc6746eSThomas Huth
280bc6746eSThomas Huth dev = qdev_new(TYPE_MCF5206_MBAR);
29*989c8a46SPhilippe Mathieu-Daudé object_property_set_link(OBJECT(dev), "m68k-cpu",
30*989c8a46SPhilippe Mathieu-Daudé OBJECT(cpu), &error_abort);
310bc6746eSThomas Huth s = SYS_BUS_DEVICE(dev);
320bc6746eSThomas Huth sysbus_realize_and_unref(s, &error_fatal);
330bc6746eSThomas Huth
340bc6746eSThomas Huth memory_region_add_subregion(sysmem, base, sysbus_mmio_get_region(s, 0));
350bc6746eSThomas Huth }
3653018216SPaolo Bonzini
an5206_init(MachineState * machine)373ef96221SMarcel Apfelbaum static void an5206_init(MachineState *machine)
3853018216SPaolo Bonzini {
393ef96221SMarcel Apfelbaum ram_addr_t ram_size = machine->ram_size;
403ef96221SMarcel Apfelbaum const char *kernel_filename = machine->kernel_filename;
4153018216SPaolo Bonzini M68kCPU *cpu;
4253018216SPaolo Bonzini CPUM68KState *env;
4353018216SPaolo Bonzini int kernel_size;
4453018216SPaolo Bonzini uint64_t elf_entry;
4553018216SPaolo Bonzini hwaddr entry;
4653018216SPaolo Bonzini MemoryRegion *address_space_mem = get_system_memory();
4753018216SPaolo Bonzini MemoryRegion *sram = g_new(MemoryRegion, 1);
4853018216SPaolo Bonzini
4925a20b36SIgor Mammedov cpu = M68K_CPU(cpu_create(machine->cpu_type));
5053018216SPaolo Bonzini env = &cpu->env;
5153018216SPaolo Bonzini
5253018216SPaolo Bonzini /* Initialize CPU registers. */
5353018216SPaolo Bonzini env->vbr = 0;
5453018216SPaolo Bonzini /* TODO: allow changing MBAR and RAMBAR. */
5553018216SPaolo Bonzini env->mbar = AN5206_MBAR_ADDR | 1;
5653018216SPaolo Bonzini env->rambar0 = AN5206_RAMBAR_ADDR | 1;
5753018216SPaolo Bonzini
5853018216SPaolo Bonzini /* DRAM at address zero */
59c55f97a0SIgor Mammedov memory_region_add_subregion(address_space_mem, 0, machine->ram);
6053018216SPaolo Bonzini
6153018216SPaolo Bonzini /* Internal SRAM. */
6298a99ce0SPeter Maydell memory_region_init_ram(sram, NULL, "an5206.sram", 512, &error_fatal);
6353018216SPaolo Bonzini memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram);
6453018216SPaolo Bonzini
65*989c8a46SPhilippe Mathieu-Daudé mcf5206_init(cpu, address_space_mem, AN5206_MBAR_ADDR);
6653018216SPaolo Bonzini
6753018216SPaolo Bonzini /* Load kernel. */
6853018216SPaolo Bonzini if (!kernel_filename) {
6919c82aacSAndreas Färber if (qtest_enabled()) {
7019c82aacSAndreas Färber return;
7119c82aacSAndreas Färber }
7245876e91SAlistair Francis error_report("Kernel image must be specified");
7353018216SPaolo Bonzini exit(1);
7453018216SPaolo Bonzini }
7553018216SPaolo Bonzini
764366e1dbSLiam Merwick kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry,
776cdda0ffSAleksandar Markovic NULL, NULL, NULL, 1, EM_68K, 0, 0);
7853018216SPaolo Bonzini entry = elf_entry;
7953018216SPaolo Bonzini if (kernel_size < 0) {
8025bda50aSMax Filippov kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL,
8125bda50aSMax Filippov NULL, NULL);
8253018216SPaolo Bonzini }
8353018216SPaolo Bonzini if (kernel_size < 0) {
8453018216SPaolo Bonzini kernel_size = load_image_targphys(kernel_filename, KERNEL_LOAD_ADDR,
8553018216SPaolo Bonzini ram_size - KERNEL_LOAD_ADDR);
8653018216SPaolo Bonzini entry = KERNEL_LOAD_ADDR;
8753018216SPaolo Bonzini }
8853018216SPaolo Bonzini if (kernel_size < 0) {
8945876e91SAlistair Francis error_report("Could not load kernel '%s'", kernel_filename);
9053018216SPaolo Bonzini exit(1);
9153018216SPaolo Bonzini }
9253018216SPaolo Bonzini
9353018216SPaolo Bonzini env->pc = entry;
9453018216SPaolo Bonzini }
9553018216SPaolo Bonzini
an5206_machine_init(MachineClass * mc)96e264d29dSEduardo Habkost static void an5206_machine_init(MachineClass *mc)
9753018216SPaolo Bonzini {
98e264d29dSEduardo Habkost mc->desc = "Arnewsh 5206";
99e264d29dSEduardo Habkost mc->init = an5206_init;
10025a20b36SIgor Mammedov mc->default_cpu_type = M68K_CPU_TYPE_NAME("m5206");
101c55f97a0SIgor Mammedov mc->default_ram_id = "an5206.ram";
10253018216SPaolo Bonzini }
10353018216SPaolo Bonzini
104e264d29dSEduardo Habkost DEFINE_MACHINE("an5206", an5206_machine_init)
105