Hi Valentin, On Sun, Oct 5, 2014 at 7:03 PM, Valentin Manea <valentin.ma...@gmail.com> wrote: > Create new OpenRISC machine(asim) with default IDE support. It will > incude more peripherals in order to run a fully fledged Linux computer. > > Signed-off-by: Valentin Manea <valentin.ma...@gmail.com> > --- > default-configs/or32-softmmu.mak | 3 + > hw/openrisc/Makefile.objs | 1 + > hw/openrisc/openrisc_asim.c | 202 > +++++++++++++++++++++++++++++++++++++++ > 3 files changed, 206 insertions(+) > create mode 100644 hw/openrisc/openrisc_asim.c > > diff --git a/default-configs/or32-softmmu.mak > b/default-configs/or32-softmmu.mak > index cce4746..c3ff078 100644 > --- a/default-configs/or32-softmmu.mak > +++ b/default-configs/or32-softmmu.mak > @@ -2,3 +2,6 @@ > > CONFIG_SERIAL=y > CONFIG_OPENCORES_ETH=y > +CONFIG_IDE_CORE=y > +CONFIG_IDE_QDEV=y > +CONFIG_IDE_MMIO=y > diff --git a/hw/openrisc/Makefile.objs b/hw/openrisc/Makefile.objs > index 61246b1..f266f5d 100644 > --- a/hw/openrisc/Makefile.objs > +++ b/hw/openrisc/Makefile.objs > @@ -1,2 +1,3 @@ > obj-y = pic_cpu.o cputimer.o > obj-y += openrisc_sim.o > +obj-y += openrisc_asim.o > diff --git a/hw/openrisc/openrisc_asim.c b/hw/openrisc/openrisc_asim.c > new file mode 100644 > index 0000000..80aa5ed > --- /dev/null > +++ b/hw/openrisc/openrisc_asim.c > @@ -0,0 +1,202 @@ > +/* > + * OpenRISC simulator with more peripherals > + * > + * Copyright (c) 2011-2014 Jia Liu <pro...@gmail.com> > + * Feng Gao <gf91...@gmail.com> > + * Valentin Manea <valentin.ma...@gmail.com> > + * > + * This OpenRISC machine supports more hardware - same configuration as the > + * jor1k(http://s-macke.github.io/jor1k). Currently the default Linux branch > + * does not have all the support for this machine so the jor1k Linux kernel > is > + * needed for more advanced usecases: X support, compiling etc. You can > download > + * a precompiled image here http://mrs.ro/dl/or1k/vmlinux or compile it using > + * the instructions at https://github.com/s-macke/jor1k/wiki > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, see > <http://www.gnu.org/licenses/>. > + */ > + > +#include "hw/hw.h" > +#include "hw/boards.h" > +#include "elf.h" > +#include "hw/char/serial.h" > +#include "net/net.h" > +#include "hw/loader.h" > +#include "hw/ide.h" > +#include "exec/address-spaces.h" > +#include "sysemu/sysemu.h" > +#include "hw/sysbus.h" > +#include "sysemu/blockdev.h" > +#include "sysemu/qtest.h" > + > +#define KERNEL_LOAD_ADDR 0x100 > + > +enum { > + OR_UART0, > + OR_IDE, > + OR_OPENETH > +}; > + > +static hwaddr mem_map[] = { > + [OR_UART0] = 0x90000000, > + [OR_IDE] = 0x9e000000, > + [OR_OPENETH] = 0x92000000, > +}; > + > + > +static void main_cpu_reset(void *opaque) > +{ > + OpenRISCCPU *cpu = opaque; > + > + cpu_reset(CPU(cpu)); > +} > + > +static void openrisc_sim_ide_init(MemoryRegion *address_space, > + hwaddr base, > + hwaddr descriptors, > + qemu_irq irq) > +{ > + DeviceState *dev; > + SysBusDevice *busdev; > + DriveInfo *dinfo; > + > + > + dinfo = drive_get(IF_IDE, 0, 0); > + if (!dinfo) { > + return; > + } > + dev = qdev_create(NULL, "mmio-ide"); > + busdev = SYS_BUS_DEVICE(dev); > + sysbus_connect_irq(busdev, 0, irq); > + qdev_prop_set_uint32(dev, "shift", 2); > + qdev_init_nofail(dev); > + memory_region_add_subregion(address_space, base, > + sysbus_mmio_get_region(busdev, 0)); > + memory_region_add_subregion(address_space, descriptors, > + sysbus_mmio_get_region(busdev, 1)); > + mmio_ide_init_drives(dev, dinfo, NULL); > +} > + > +static void openrisc_sim_net_init(MemoryRegion *address_space, > + hwaddr base, > + hwaddr descriptors, > + qemu_irq irq, NICInfo *nd) > +{ > + DeviceState *dev; > + SysBusDevice *s; > + > + dev = qdev_create(NULL, "open_eth"); > + qdev_set_nic_properties(dev, nd); > + qdev_init_nofail(dev); > + > + s = SYS_BUS_DEVICE(dev); > + sysbus_connect_irq(s, 0, irq); > + memory_region_add_subregion(address_space, base, > + sysbus_mmio_get_region(s, 0)); > + memory_region_add_subregion(address_space, descriptors, > + sysbus_mmio_get_region(s, 1)); > +} > + > +static void cpu_openrisc_load_kernel(ram_addr_t ram_size, > + const char *kernel_filename, > + OpenRISCCPU *cpu) > +{ > + long kernel_size; > + uint64_t elf_entry; > + hwaddr entry; > + > + if (kernel_filename && !qtest_enabled()) { > + kernel_size = load_elf(kernel_filename, NULL, NULL, > + &elf_entry, NULL, NULL, 1, ELF_MACHINE, 1); > + entry = elf_entry; > + if (kernel_size < 0) { > + kernel_size = load_uimage(kernel_filename, > + &entry, NULL, NULL); > + } > + if (kernel_size < 0) { > + kernel_size = load_image_targphys(kernel_filename, > + KERNEL_LOAD_ADDR, > + ram_size - KERNEL_LOAD_ADDR); > + entry = KERNEL_LOAD_ADDR; > + } > + > + if (kernel_size < 0) { > + fprintf(stderr, "QEMU: couldn't load the kernel '%s'\n", > + kernel_filename); > + exit(1); > + } > + cpu->env.pc = entry; > + } > +} > + > +static void openrisc_sim_init(MachineState *machine) > +{ > + ram_addr_t ram_size = machine->ram_size; > + const char *cpu_model = machine->cpu_model; > + const char *kernel_filename = machine->kernel_filename; > + OpenRISCCPU *cpu = NULL; > + MemoryRegion *ram; > + int n; > + > + if (!cpu_model) { > + cpu_model = "or1200"; > + } > + > + for (n = 0; n < smp_cpus; n++) { > + cpu = cpu_openrisc_init(cpu_model); > + if (cpu == NULL) { > + fprintf(stderr, "Unable to find CPU definition!\n"); > + exit(1); > + } > + qemu_register_reset(main_cpu_reset, cpu); > + main_cpu_reset(cpu); > + } > + > + ram = g_malloc(sizeof(*ram)); > + memory_region_init_ram(ram, NULL, "openrisc.ram", ram_size, > &error_abort); > + vmstate_register_ram_global(ram); > + memory_region_add_subregion(get_system_memory(), 0, ram); > + > + cpu_openrisc_pic_init(cpu); > + cpu_openrisc_clock_init(cpu); > + > + serial_mm_init(get_system_memory(), mem_map[OR_UART0], 0, > cpu->env.irq[2], > + 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN); > + > + if (nd_table[0].used) { > + openrisc_sim_net_init(get_system_memory(), mem_map[OR_OPENETH], > + mem_map[OR_OPENETH] + 0x400, cpu->env.irq[4], > + nd_table); > + } > + > + /* Platform ATA device */ > + openrisc_sim_ide_init(get_system_memory(), mem_map[OR_IDE], > + mem_map[OR_IDE] + 0x100, cpu->env.irq[15]); > + > + > + cpu_openrisc_load_kernel(ram_size, kernel_filename, cpu); > +} > + > +static QEMUMachine openrisc_sim_machine = { > + .name = "asim", > + .desc = "or32 simulation", > + .init = openrisc_sim_init, > + .max_cpus = 1, > +}; > + > +static void openrisc_sim_machine_init(void) > +{ > + qemu_register_machine(&openrisc_sim_machine); > +} > + > +machine_init(openrisc_sim_machine_init); > -- > 1.9.1 > >
Thank you for this new machine. Reviewed-by: Jia Liu <pro...@gmail.com> Regards, Jia