Message ID | 1366984929-18693-1-git-send-email-jcd@tribudubois.net |
---|---|
State | New |
Headers | show |
Peter, I have submitted a few patch to add support to the i.MX25 processor and the 3DS Freescale evaluation platform. Most of the i.MX devices present on i.MX25 can be reused on other Freescale processors including the i.MX6. So far I did not get that much feedback on this. Is this of any interest to somebody? If so, what it the process to get it adopted in an official tree. Thanks JC On 04/26/2013 04:02 PM, Jean-Christophe DUBOIS wrote: > This is an initial port of the Freescale i.MX25 processor. > > This allow a minimally configured linux kernel to boot on Qemu. > > It also handle the newly added FEC ethernet device. > > Signed-off-by: Jean-Christophe DUBOIS <jcd@tribudubois.net> > --- > hw/arm/Makefile.objs | 1 + > hw/arm/imx25_3ds.c | 218 +++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 219 insertions(+) > create mode 100644 hw/arm/imx25_3ds.c > > diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs > index 9e3a06f..2f4280d 100644 > --- a/hw/arm/Makefile.objs > +++ b/hw/arm/Makefile.objs > @@ -2,6 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o > obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o > obj-y += omap_sx1.o palm.o pic_cpu.o realview.o spitz.o stellaris.o > obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o > +obj-y += imx25_3ds.o > > obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o > obj-y += omap1.o omap2.o strongarm.o > diff --git a/hw/arm/imx25_3ds.c b/hw/arm/imx25_3ds.c > new file mode 100644 > index 0000000..9de4941 > --- /dev/null > +++ b/hw/arm/imx25_3ds.c > @@ -0,0 +1,218 @@ > +/* > + * Copyright (c) 2013 Jean-Christophe Dubois > + * > + * 3Dstack Board System emulation. > + * > + * Based on hw/arm/kzm.c > + * > + * Copyright (c) 2008 OKL and 2011 NICTA > + * Written by Hans at OK-Labs > + * Updated by Peter Chubb. > + * > + * This code is licensed under the GPL, version 2 or later. > + * See the file `COPYING' in the top level directory. > + * > + * It (partially) emulates a i.MX25 3D-Stack PDK board > + */ > + > +#include "hw/sysbus.h" > +#include "exec/address-spaces.h" > +#include "hw/hw.h" > +#include "hw/arm/arm.h" > +#include "hw/devices.h" > +#include "net/net.h" > +#include "sysemu/sysemu.h" > +#include "hw/boards.h" > +#include "hw/char/serial.h" > +#include "hw/arm/imx.h" > + > +/* Memory map for 3D-Stack Emulation Baseboard: > + * 0x00000000-0x00003fff 16k ROM IGNORED > + * 0x00004000-0x00403fff Reserved IGNORED > + * 0x00404000-0x00408fff 20k ROM IGNORED > + * 0x00409000-0x0fffffff Reserved IGNORED > + * 0x10000000-0x1fffffff Reserved IGNORED > + * 0x20000000-0x2fffffff Reserved IGNORED > + * 0x30000000-0x3fffffff Reserved IGNORED > + * 0x40000000-0x43efffff Reserved IGNORED > + * 0x43f00000-0x6fffffff I.MX25 Internal Register Space > + * 0x43f00000 IO_AREA0 > + * 0x43f90000 UART1 EMULATED > + * 0x43f94000 UART2 EMULATED > + * 0x43fb0000 UART4 IGNORED > + * 0x43fb4000 UART5 IGNORED > + * 0x5000c000 UART3 IGNORED > + * 0x53f80000 CCM EMULATED > + * 0x53f84000 GPT 4 EMULATED > + * 0x53f88000 GPT 3 EMULATED > + * 0x53f8c000 GPT 2 EMULATED > + * 0x53f90000 GPT 1 EMULATED > + * 0x53f94000 PIT 1 EMULATED > + * 0x53f98000 PIT 2 EMULATED > + * 0x68000000 ASIC EMULATED > + * 0x78000000-0x7801ffff SRAM EMULATED > + * 0x78020000-0x7fffffff SRAM Aliasing EMULATED > + * 0x80000000-0x87ffffff RAM + Alias EMULATED > + * 0x90000000-0x9fffffff RAM + Alias EMULATED > + * 0xa0000000-0xa7ffffff Flash IGNORED > + * 0xa8000000-0xafffffff Flash IGNORED > + * 0xb0000000-0xb1ffffff SRAM IGNORED > + * 0xb2000000-0xb3ffffff SRAM IGNORED > + * 0xb4000000-0xb5ffffff CS4 IGNORED > + * 0xb6000000-0xb8000fff Reserved IGNORED > + * 0xb8001000-0xb8001fff SDRAM CTRL reg IGNORED > + * 0xb8002000-0xb8002fff WEIM CTRL reg IGNORED > + * 0xb8003000-0xb8003fff M3IF CTRL reg IGNORED > + * 0xb8004000-0xb8004fff EMI CTRL reg IGNORED > + * 0xb8005000-0xbaffffff Reserved IGNORED > + * 0xbb000000-0xbb000fff NAND flash area buf IGNORED > + * 0xbb001000-0xbb0011ff NAND flash reserved IGNORED > + * 0xbb001200-0xbb001dff Reserved IGNORED > + * 0xbb001e00-0xbb001fff NAN flash CTRL reg IGNORED > + * 0xbb012000-0xbfffffff Reserved IGNORED > + * 0xc0000000-0xffffffff Reserved IGNORED > + */ > + > +#define IMX25_SRAM_ADDRESS (0x78000000) > +#define IMX25_SRAMSIZE (128*1024) > +#define IMX25_CS_SRAMSIZE (128*1024*1024) > +#define IMX25_3DS_ADDRESS (0x80000000) > +#define IMX25_CS_RAMSIZE (256*1024*1024) > + > +static struct arm_boot_info imx25_3ds_binfo = { > + .loader_start = IMX25_3DS_ADDRESS, > + .board_id = 1771, > +}; > + > +static void imx25_3ds_init(QEMUMachineInitArgs *args) > +{ > + int i; > + ram_addr_t ram_size = args->ram_size; > + const char *cpu_model = args->cpu_model; > + const char *kernel_filename = args->kernel_filename; > + const char *kernel_cmdline = args->kernel_cmdline; > + const char *initrd_filename = args->initrd_filename; > + ARMCPU *cpu; > + MemoryRegion *address_space_mem = get_system_memory(); > + qemu_irq *cpu_pic; > + DeviceState *dev; > + DeviceState *ccm; > + MemoryRegion *sram = g_new(MemoryRegion, 1); > + MemoryRegion *sram_alias = g_new(MemoryRegion, 1); > + > + > + if (!cpu_model) { > + cpu_model = "arm926"; > + } > + > + cpu = cpu_arm_init(cpu_model); > + if (!cpu) { > + fprintf(stderr, "Unable to find CPU definition\n"); > + exit(1); > + } > + > + if (ram_size > (2 * IMX25_CS_RAMSIZE)) { > + fprintf(stderr, "i.MX25 can support only up to %d MB\n", > + 2 * IMX25_CS_RAMSIZE / (1024 * 1024)); > + exit(1); > + } > + > + /* create our main memory */ > + for (i = 0; i <= (ram_size / IMX25_CS_RAMSIZE); i++) { > + ram_addr_t blk_size = ram_size - (IMX25_CS_RAMSIZE * i); > + MemoryRegion *ram; > + char ram_name[20]; > + > + if (blk_size > IMX25_CS_RAMSIZE) { > + blk_size = IMX25_CS_RAMSIZE; > + } > + > + if (blk_size == 0) { > + break; > + } > + > + sprintf(ram_name, "imx25.ram%d", i); > + > + ram = g_new(MemoryRegion, 1); > + memory_region_init_ram(ram, ram_name, blk_size); > + vmstate_register_ram_global(ram); > + memory_region_add_subregion(address_space_mem, IMX25_3DS_ADDRESS > + + (IMX25_CS_RAMSIZE * i), ram); > + > + /* Add ram alias */ > + if (blk_size < IMX25_CS_RAMSIZE) { > + MemoryRegion *ram_alias = g_new(MemoryRegion, 1); > + char alias_name[20]; > + > + sprintf(alias_name, "ram.alias%d", i); > + > + memory_region_init_alias(ram_alias, alias_name, ram, 0, > + IMX25_CS_RAMSIZE - blk_size); > + memory_region_add_subregion(address_space_mem, IMX25_3DS_ADDRESS > + + (IMX25_CS_RAMSIZE * i) + blk_size, > + ram_alias); > + } > + } > + > + /* create the sram area */ > + memory_region_init_ram(sram, "imx25.sram", IMX25_SRAMSIZE); > + vmstate_register_ram_global(sram); > + memory_region_add_subregion(address_space_mem, IMX25_SRAM_ADDRESS, > + sram); > + > + /* add sram alias */ > + memory_region_init_alias(sram_alias, "sram.alias", sram, 0, > + IMX25_CS_SRAMSIZE - IMX25_SRAMSIZE); > + memory_region_add_subregion(address_space_mem, > + IMX25_SRAM_ADDRESS + IMX25_SRAMSIZE, > + sram_alias); > + > + /* add the PIC */ > + cpu_pic = arm_pic_init_cpu(cpu); > + dev = sysbus_create_varargs("imx_avic", 0x68000000, > + cpu_pic[ARM_PIC_CPU_IRQ], > + cpu_pic[ARM_PIC_CPU_FIQ], NULL); > + > + /* add some serial lines */ > + imx_serial_create(0, 0x43f90000, qdev_get_gpio_in(dev, 45)); > + imx_serial_create(1, 0x43f94000, qdev_get_gpio_in(dev, 32)); > + // Qemu does not support more than 4 serial ports. Too bad. > + //imx_serial_create(3, 0x5000c000, qdev_get_gpio_in(dev, 18)); > + //imx_serial_create(4, 0x43fb0000, qdev_get_gpio_in(dev, 46)); > + //imx_serial_create(5, 0x43fb4000, qdev_get_gpio_in(dev, 47)); > + > + ccm = sysbus_create_simple("imx_ccm", 0x53f80000, NULL); > + > + /* add gpt timers */ > + imx_timerg_create(0x53f84000, qdev_get_gpio_in(dev, 1), ccm); > + imx_timerg_create(0x53f88000, qdev_get_gpio_in(dev, 29), ccm); > + imx_timerg_create(0x53f8c000, qdev_get_gpio_in(dev, 53), ccm); > + imx_timerg_create(0x53f90000, qdev_get_gpio_in(dev, 54), ccm); > + > + /* add epit timers */ > + imx_timerp_create(0x53f94000, qdev_get_gpio_in(dev, 28), ccm); > + imx_timerp_create(0x53f98000, qdev_get_gpio_in(dev, 27), ccm); > + > + imx_fec_create(0, 0x50038000, qdev_get_gpio_in(dev, 57)); > + > + imx25_3ds_binfo.ram_size = ram_size; > + imx25_3ds_binfo.kernel_filename = kernel_filename; > + imx25_3ds_binfo.kernel_cmdline = kernel_cmdline; > + imx25_3ds_binfo.initrd_filename = initrd_filename; > + imx25_3ds_binfo.nb_cpus = 1; > + arm_load_kernel(cpu, &imx25_3ds_binfo); > +} > + > +static QEMUMachine imx25_3ds_machine = { > + .name = "imx25_3ds", > + .desc = "ARM i.MX25 PDK board (ARM926)", > + .init = imx25_3ds_init, > + DEFAULT_MACHINE_OPTIONS, > +}; > + > +static void imx25_3ds_machine_init(void) > +{ > + qemu_register_machine(&imx25_3ds_machine); > +} > + > +machine_init(imx25_3ds_machine_init)
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 9e3a06f..2f4280d 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -2,6 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o obj-y += omap_sx1.o palm.o pic_cpu.o realview.o spitz.o stellaris.o obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o +obj-y += imx25_3ds.o obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o obj-y += omap1.o omap2.o strongarm.o diff --git a/hw/arm/imx25_3ds.c b/hw/arm/imx25_3ds.c new file mode 100644 index 0000000..9de4941 --- /dev/null +++ b/hw/arm/imx25_3ds.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2013 Jean-Christophe Dubois + * + * 3Dstack Board System emulation. + * + * Based on hw/arm/kzm.c + * + * Copyright (c) 2008 OKL and 2011 NICTA + * Written by Hans at OK-Labs + * Updated by Peter Chubb. + * + * This code is licensed under the GPL, version 2 or later. + * See the file `COPYING' in the top level directory. + * + * It (partially) emulates a i.MX25 3D-Stack PDK board + */ + +#include "hw/sysbus.h" +#include "exec/address-spaces.h" +#include "hw/hw.h" +#include "hw/arm/arm.h" +#include "hw/devices.h" +#include "net/net.h" +#include "sysemu/sysemu.h" +#include "hw/boards.h" +#include "hw/char/serial.h" +#include "hw/arm/imx.h" + +/* Memory map for 3D-Stack Emulation Baseboard: + * 0x00000000-0x00003fff 16k ROM IGNORED + * 0x00004000-0x00403fff Reserved IGNORED + * 0x00404000-0x00408fff 20k ROM IGNORED + * 0x00409000-0x0fffffff Reserved IGNORED + * 0x10000000-0x1fffffff Reserved IGNORED + * 0x20000000-0x2fffffff Reserved IGNORED + * 0x30000000-0x3fffffff Reserved IGNORED + * 0x40000000-0x43efffff Reserved IGNORED + * 0x43f00000-0x6fffffff I.MX25 Internal Register Space + * 0x43f00000 IO_AREA0 + * 0x43f90000 UART1 EMULATED + * 0x43f94000 UART2 EMULATED + * 0x43fb0000 UART4 IGNORED + * 0x43fb4000 UART5 IGNORED + * 0x5000c000 UART3 IGNORED + * 0x53f80000 CCM EMULATED + * 0x53f84000 GPT 4 EMULATED + * 0x53f88000 GPT 3 EMULATED + * 0x53f8c000 GPT 2 EMULATED + * 0x53f90000 GPT 1 EMULATED + * 0x53f94000 PIT 1 EMULATED + * 0x53f98000 PIT 2 EMULATED + * 0x68000000 ASIC EMULATED + * 0x78000000-0x7801ffff SRAM EMULATED + * 0x78020000-0x7fffffff SRAM Aliasing EMULATED + * 0x80000000-0x87ffffff RAM + Alias EMULATED + * 0x90000000-0x9fffffff RAM + Alias EMULATED + * 0xa0000000-0xa7ffffff Flash IGNORED + * 0xa8000000-0xafffffff Flash IGNORED + * 0xb0000000-0xb1ffffff SRAM IGNORED + * 0xb2000000-0xb3ffffff SRAM IGNORED + * 0xb4000000-0xb5ffffff CS4 IGNORED + * 0xb6000000-0xb8000fff Reserved IGNORED + * 0xb8001000-0xb8001fff SDRAM CTRL reg IGNORED + * 0xb8002000-0xb8002fff WEIM CTRL reg IGNORED + * 0xb8003000-0xb8003fff M3IF CTRL reg IGNORED + * 0xb8004000-0xb8004fff EMI CTRL reg IGNORED + * 0xb8005000-0xbaffffff Reserved IGNORED + * 0xbb000000-0xbb000fff NAND flash area buf IGNORED + * 0xbb001000-0xbb0011ff NAND flash reserved IGNORED + * 0xbb001200-0xbb001dff Reserved IGNORED + * 0xbb001e00-0xbb001fff NAN flash CTRL reg IGNORED + * 0xbb012000-0xbfffffff Reserved IGNORED + * 0xc0000000-0xffffffff Reserved IGNORED + */ + +#define IMX25_SRAM_ADDRESS (0x78000000) +#define IMX25_SRAMSIZE (128*1024) +#define IMX25_CS_SRAMSIZE (128*1024*1024) +#define IMX25_3DS_ADDRESS (0x80000000) +#define IMX25_CS_RAMSIZE (256*1024*1024) + +static struct arm_boot_info imx25_3ds_binfo = { + .loader_start = IMX25_3DS_ADDRESS, + .board_id = 1771, +}; + +static void imx25_3ds_init(QEMUMachineInitArgs *args) +{ + int i; + ram_addr_t ram_size = args->ram_size; + const char *cpu_model = args->cpu_model; + const char *kernel_filename = args->kernel_filename; + const char *kernel_cmdline = args->kernel_cmdline; + const char *initrd_filename = args->initrd_filename; + ARMCPU *cpu; + MemoryRegion *address_space_mem = get_system_memory(); + qemu_irq *cpu_pic; + DeviceState *dev; + DeviceState *ccm; + MemoryRegion *sram = g_new(MemoryRegion, 1); + MemoryRegion *sram_alias = g_new(MemoryRegion, 1); + + + if (!cpu_model) { + cpu_model = "arm926"; + } + + cpu = cpu_arm_init(cpu_model); + if (!cpu) { + fprintf(stderr, "Unable to find CPU definition\n"); + exit(1); + } + + if (ram_size > (2 * IMX25_CS_RAMSIZE)) { + fprintf(stderr, "i.MX25 can support only up to %d MB\n", + 2 * IMX25_CS_RAMSIZE / (1024 * 1024)); + exit(1); + } + + /* create our main memory */ + for (i = 0; i <= (ram_size / IMX25_CS_RAMSIZE); i++) { + ram_addr_t blk_size = ram_size - (IMX25_CS_RAMSIZE * i); + MemoryRegion *ram; + char ram_name[20]; + + if (blk_size > IMX25_CS_RAMSIZE) { + blk_size = IMX25_CS_RAMSIZE; + } + + if (blk_size == 0) { + break; + } + + sprintf(ram_name, "imx25.ram%d", i); + + ram = g_new(MemoryRegion, 1); + memory_region_init_ram(ram, ram_name, blk_size); + vmstate_register_ram_global(ram); + memory_region_add_subregion(address_space_mem, IMX25_3DS_ADDRESS + + (IMX25_CS_RAMSIZE * i), ram); + + /* Add ram alias */ + if (blk_size < IMX25_CS_RAMSIZE) { + MemoryRegion *ram_alias = g_new(MemoryRegion, 1); + char alias_name[20]; + + sprintf(alias_name, "ram.alias%d", i); + + memory_region_init_alias(ram_alias, alias_name, ram, 0, + IMX25_CS_RAMSIZE - blk_size); + memory_region_add_subregion(address_space_mem, IMX25_3DS_ADDRESS + + (IMX25_CS_RAMSIZE * i) + blk_size, + ram_alias); + } + } + + /* create the sram area */ + memory_region_init_ram(sram, "imx25.sram", IMX25_SRAMSIZE); + vmstate_register_ram_global(sram); + memory_region_add_subregion(address_space_mem, IMX25_SRAM_ADDRESS, + sram); + + /* add sram alias */ + memory_region_init_alias(sram_alias, "sram.alias", sram, 0, + IMX25_CS_SRAMSIZE - IMX25_SRAMSIZE); + memory_region_add_subregion(address_space_mem, + IMX25_SRAM_ADDRESS + IMX25_SRAMSIZE, + sram_alias); + + /* add the PIC */ + cpu_pic = arm_pic_init_cpu(cpu); + dev = sysbus_create_varargs("imx_avic", 0x68000000, + cpu_pic[ARM_PIC_CPU_IRQ], + cpu_pic[ARM_PIC_CPU_FIQ], NULL); + + /* add some serial lines */ + imx_serial_create(0, 0x43f90000, qdev_get_gpio_in(dev, 45)); + imx_serial_create(1, 0x43f94000, qdev_get_gpio_in(dev, 32)); + // Qemu does not support more than 4 serial ports. Too bad. + //imx_serial_create(3, 0x5000c000, qdev_get_gpio_in(dev, 18)); + //imx_serial_create(4, 0x43fb0000, qdev_get_gpio_in(dev, 46)); + //imx_serial_create(5, 0x43fb4000, qdev_get_gpio_in(dev, 47)); + + ccm = sysbus_create_simple("imx_ccm", 0x53f80000, NULL); + + /* add gpt timers */ + imx_timerg_create(0x53f84000, qdev_get_gpio_in(dev, 1), ccm); + imx_timerg_create(0x53f88000, qdev_get_gpio_in(dev, 29), ccm); + imx_timerg_create(0x53f8c000, qdev_get_gpio_in(dev, 53), ccm); + imx_timerg_create(0x53f90000, qdev_get_gpio_in(dev, 54), ccm); + + /* add epit timers */ + imx_timerp_create(0x53f94000, qdev_get_gpio_in(dev, 28), ccm); + imx_timerp_create(0x53f98000, qdev_get_gpio_in(dev, 27), ccm); + + imx_fec_create(0, 0x50038000, qdev_get_gpio_in(dev, 57)); + + imx25_3ds_binfo.ram_size = ram_size; + imx25_3ds_binfo.kernel_filename = kernel_filename; + imx25_3ds_binfo.kernel_cmdline = kernel_cmdline; + imx25_3ds_binfo.initrd_filename = initrd_filename; + imx25_3ds_binfo.nb_cpus = 1; + arm_load_kernel(cpu, &imx25_3ds_binfo); +} + +static QEMUMachine imx25_3ds_machine = { + .name = "imx25_3ds", + .desc = "ARM i.MX25 PDK board (ARM926)", + .init = imx25_3ds_init, + DEFAULT_MACHINE_OPTIONS, +}; + +static void imx25_3ds_machine_init(void) +{ + qemu_register_machine(&imx25_3ds_machine); +} + +machine_init(imx25_3ds_machine_init)
This is an initial port of the Freescale i.MX25 processor. This allow a minimally configured linux kernel to boot on Qemu. It also handle the newly added FEC ethernet device. Signed-off-by: Jean-Christophe DUBOIS <jcd@tribudubois.net> --- hw/arm/Makefile.objs | 1 + hw/arm/imx25_3ds.c | 218 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 hw/arm/imx25_3ds.c