This patch adds the emulation of the 64 MB Intel Flash present at address 0x34000000 on the ARM Versatile PB platform, with a 256 KB sector size. This flash emulation is enabled using the -pflash option. If not enabled, Qemu falls back to the traditionnal way of loading the kernel. Signed-off-by: Thomas Petazzoni --- hw/versatilepb.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) Index: qemu/hw/versatilepb.c =================================================================== --- qemu.orig/hw/versatilepb.c +++ qemu/hw/versatilepb.c @@ -15,6 +15,7 @@ #include "sysemu.h" #include "pci.h" #include "boards.h" +#include "flash.h" /* Primary interrupt controller. */ @@ -159,6 +160,10 @@ static struct arm_boot_info versatile_binfo; +#define VERSATILE_FLASH_ADDR 0x34000000 +#define VERSATILE_FLASH_SIZE (64 * 1024 * 1024) +#define VERSATILE_FLASH_SECT_SIZE (256 * 1024) + static void versatile_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, @@ -174,6 +179,7 @@ int n; int done_smc = 0; int index; + int hasflash = 0; if (!cpu_model) cpu_model = "arm926"; @@ -184,7 +190,8 @@ } /* ??? RAM should repeat to fill physical memory space. */ /* SDRAM at address zero. */ - cpu_register_physical_memory(0, ram_size, IO_MEM_RAM); + cpu_register_physical_memory(0, ram_size, + qemu_ram_alloc(ram_size) | IO_MEM_RAM); arm_sysctl_init(0x10000000, 0x41007004); pic = arm_pic_init_cpu(env); @@ -249,6 +256,21 @@ /* Add PL031 Real Time Clock. */ pl031_init(0x101e8000,pic[10]); + index = drive_get_index(IF_PFLASH, 0, 0); + if (index != -1) { + if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, + qemu_ram_alloc(VERSATILE_FLASH_SIZE), + drives_table[index].bdrv, + VERSATILE_FLASH_SECT_SIZE, + VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE, + 4, 0, 0, 0, 0)) { + fprintf(stderr, "qemu: error registering flash memory.\n"); + exit(1); + } + + hasflash = 1; + } + /* Memory map for Versatile/PB: */ /* 0x10000000 System registers. */ /* 0x10001000 PCI controller config registers. */ @@ -285,12 +307,17 @@ /* 0x101f3000 UART2. */ /* 0x101f4000 SSPI. */ - versatile_binfo.ram_size = ram_size; - versatile_binfo.kernel_filename = kernel_filename; - versatile_binfo.kernel_cmdline = kernel_cmdline; - versatile_binfo.initrd_filename = initrd_filename; - versatile_binfo.board_id = board_id; - arm_load_kernel(env, &versatile_binfo); + if (! hasflash) { + versatile_binfo.ram_size = ram_size; + versatile_binfo.kernel_filename = kernel_filename; + versatile_binfo.kernel_cmdline = kernel_cmdline; + versatile_binfo.initrd_filename = initrd_filename; + versatile_binfo.board_id = board_id; + arm_load_kernel(env, &versatile_binfo); + } + else { + env->regs[15] = 0x34000000; + } } static void vpb_init(ram_addr_t ram_size, int vga_ram_size, @@ -321,6 +348,7 @@ .init = vpb_init, .use_scsi = 1, .max_cpus = 1, + .ram_require = VERSATILE_FLASH_SIZE, }; QEMUMachine versatileab_machine = { @@ -329,4 +357,5 @@ .init = vab_init, .use_scsi = 1, .max_cpus = 1, + .ram_require = VERSATILE_FLASH_SIZE, }; -- Thomas Petazzoni, Free Electrons Kernel, drivers and embedded Linux development, consulting, training and support. http://free-electrons.com