diff options
author | Aurelien Jarno <aurelien@aurel32.net> | 2012-11-01 16:42:29 +0100 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2012-11-01 16:42:29 +0100 |
commit | 735c1eeb85450acd551c5990952f7ed8512d8547 (patch) | |
tree | e9973aefc432339548d281814a0724b512fc6788 /hw | |
parent | 286d52ebfc0d0d53c2a878e454292fea14bad41b (diff) | |
parent | 50a5be6c3d50c7684a417da4eb5f9587dace0a44 (diff) | |
download | qemu-735c1eeb85450acd551c5990952f7ed8512d8547.zip |
Merge branch 'arm-devs.for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm
* 'arm-devs.for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm: (28 commits)
hw/sd.c: add SD card save/load support
vmstate: Add support for saving/loading bitmaps
hw/sd.c: Fix erase for high capacity cards
pflash_cfi01: Fix debug mode printfery
pflash_cfi0x: QOMified
pflash_cfi01: remove unused total_len field
pflash_cfi0x: remove unused base field
hw/versatile_i2c: Use LOG_GUEST_ERROR
hw/arm_l2x0: Use LOG_GUEST_ERROR
hw/arm_sysctl: Use LOG_GUEST_ERROR
hw/armv7m_nvic: Use LOG_GUEST_ERROR and LOG_UNIMP
hw/arm_timer: Use LOG_GUEST_ERROR and LOG_UNIMP
hw/arm_gic: Use LOG_GUEST_ERROR
hw/arm11mpcore: Use LOG_GUEST_ERROR rather than hw_error()
hw/pl190: Use LOG_UNIMP rather than hw_error()
hw/pl110: Use LOG_GUEST_ERROR rather than hw_error()
hw/pl080: Use LOG_GUEST_ERROR and LOG_UNIMP
hw/pl061: Use LOG_GUEST_ERROR
hw/pl050: Use LOG_GUEST_ERROR
hw/exynos4_boards: Don't prematurely explode QEMUMachineInitArgs
...
Diffstat (limited to 'hw')
-rw-r--r-- | hw/arm11mpcore.c | 7 | ||||
-rw-r--r-- | hw/arm_gic.c | 12 | ||||
-rw-r--r-- | hw/arm_l2x0.c | 6 | ||||
-rw-r--r-- | hw/arm_sysctl.c | 8 | ||||
-rw-r--r-- | hw/arm_timer.c | 19 | ||||
-rw-r--r-- | hw/armv7m_nvic.c | 87 | ||||
-rw-r--r-- | hw/exynos4_boards.c | 32 | ||||
-rw-r--r-- | hw/mainstone.c | 21 | ||||
-rw-r--r-- | hw/nseries.c | 39 | ||||
-rw-r--r-- | hw/omap_sx1.c | 36 | ||||
-rw-r--r-- | hw/pflash_cfi01.c | 148 | ||||
-rw-r--r-- | hw/pflash_cfi02.c | 162 | ||||
-rw-r--r-- | hw/pl050.c | 6 | ||||
-rw-r--r-- | hw/pl061.c | 6 | ||||
-rw-r--r-- | hw/pl080.c | 11 | ||||
-rw-r--r-- | hw/pl110.c | 6 | ||||
-rw-r--r-- | hw/pl190.c | 2 | ||||
-rw-r--r-- | hw/realview.c | 68 | ||||
-rw-r--r-- | hw/sd.c | 106 | ||||
-rw-r--r-- | hw/sd.h | 1 | ||||
-rw-r--r-- | hw/spitz.c | 45 | ||||
-rw-r--r-- | hw/versatile_i2c.c | 6 | ||||
-rw-r--r-- | hw/versatilepb.c | 44 | ||||
-rw-r--r-- | hw/vexpress.c | 38 |
24 files changed, 487 insertions, 429 deletions
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c index 105f158fd4..640ed20a61 100644 --- a/hw/arm11mpcore.c +++ b/hw/arm11mpcore.c @@ -44,7 +44,9 @@ static uint64_t mpcore_scu_read(void *opaque, hwaddr offset, case 0x0c: /* Invalidate all. */ return 0; default: - hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "mpcore_priv_read: Bad offset %x\n", (int)offset); + return 0; } } @@ -61,7 +63,8 @@ static void mpcore_scu_write(void *opaque, hwaddr offset, /* This is a no-op as cache is not emulated. */ break; default: - hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "mpcore_priv_read: Bad offset %x\n", (int)offset); } } diff --git a/hw/arm_gic.c b/hw/arm_gic.c index ce16e8367f..f9e423f152 100644 --- a/hw/arm_gic.c +++ b/hw/arm_gic.c @@ -324,7 +324,8 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset) } return res; bad_reg: - hw_error("gic_dist_readb: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "gic_dist_readb: Bad offset %x\n", (int)offset); return 0; } @@ -487,7 +488,8 @@ static void gic_dist_writeb(void *opaque, hwaddr offset, gic_update(s); return; bad_reg: - hw_error("gic_dist_writeb: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "gic_dist_writeb: Bad offset %x\n", (int)offset); } static void gic_dist_writew(void *opaque, hwaddr offset, @@ -556,7 +558,8 @@ static uint32_t gic_cpu_read(GICState *s, int cpu, int offset) case 0x18: /* Highest Pending Interrupt */ return s->current_pending[cpu]; default: - hw_error("gic_cpu_read: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "gic_cpu_read: Bad offset %x\n", (int)offset); return 0; } } @@ -577,7 +580,8 @@ static void gic_cpu_write(GICState *s, int cpu, int offset, uint32_t value) case 0x10: /* End Of Interrupt */ return gic_complete_irq(s, cpu, value & 0x3ff); default: - hw_error("gic_cpu_write: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "gic_cpu_write: Bad offset %x\n", (int)offset); return; } gic_update(s); diff --git a/hw/arm_l2x0.c b/hw/arm_l2x0.c index 8f5921c3a6..6abf0ee160 100644 --- a/hw/arm_l2x0.c +++ b/hw/arm_l2x0.c @@ -87,7 +87,8 @@ static uint64_t l2x0_priv_read(void *opaque, hwaddr offset, case 0xF80: return 0; default: - fprintf(stderr, "l2x0_priv_read: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "l2x0_priv_read: Bad offset %x\n", (int)offset); break; } return 0; @@ -128,7 +129,8 @@ static void l2x0_priv_write(void *opaque, hwaddr offset, case 0xF80: return; default: - fprintf(stderr, "l2x0_priv_write: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "l2x0_priv_write: Bad offset %x\n", (int)offset); break; } } diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c index 26318e14d5..58eb98216d 100644 --- a/hw/arm_sysctl.c +++ b/hw/arm_sysctl.c @@ -184,7 +184,9 @@ static uint64_t arm_sysctl_read(void *opaque, hwaddr offset, return s->sys_cfgstat; default: bad_reg: - printf ("arm_sysctl_read: Bad register offset 0x%x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "arm_sysctl_read: Bad register offset 0x%x\n", + (int)offset); return 0; } } @@ -339,7 +341,9 @@ static void arm_sysctl_write(void *opaque, hwaddr offset, return; default: bad_reg: - printf ("arm_sysctl_write: Bad register offset 0x%x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "arm_sysctl_write: Bad register offset 0x%x\n", + (int)offset); return; } } diff --git a/hw/arm_timer.c b/hw/arm_timer.c index 2e136216c6..af339d3d19 100644 --- a/hw/arm_timer.c +++ b/hw/arm_timer.c @@ -64,7 +64,8 @@ static uint32_t arm_timer_read(void *opaque, hwaddr offset) return 0; return s->int_level; default: - hw_error("%s: Bad offset %x\n", __func__, (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad offset %x\n", __func__, (int)offset); return 0; } } @@ -131,7 +132,8 @@ static void arm_timer_write(void *opaque, hwaddr offset, arm_timer_recalibrate(s, 0); break; default: - hw_error("%s: Bad offset %x\n", __func__, (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad offset %x\n", __func__, (int)offset); } arm_timer_update(s); } @@ -223,10 +225,14 @@ static uint64_t sp804_read(void *opaque, hwaddr offset, /* Integration Test control registers, which we won't support */ case 0xf00: /* TimerITCR */ case 0xf04: /* TimerITOP (strictly write only but..) */ + qemu_log_mask(LOG_UNIMP, + "%s: integration test registers unimplemented\n", + __func__); return 0; } - hw_error("%s: Bad offset %x\n", __func__, (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad offset %x\n", __func__, (int)offset); return 0; } @@ -246,7 +252,8 @@ static void sp804_write(void *opaque, hwaddr offset, } /* Technically we could be writing to the Test Registers, but not likely */ - hw_error("%s: Bad offset %x\n", __func__, (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %x\n", + __func__, (int)offset); } static const MemoryRegionOps sp804_ops = { @@ -300,7 +307,7 @@ static uint64_t icp_pit_read(void *opaque, hwaddr offset, /* ??? Don't know the PrimeCell ID for this device. */ n = offset >> 8; if (n > 2) { - hw_error("%s: Bad timer %d\n", __func__, n); + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad timer %d\n", __func__, n); } return arm_timer_read(s->timer[n], offset & 0xff); @@ -314,7 +321,7 @@ static void icp_pit_write(void *opaque, hwaddr offset, n = offset >> 8; if (n > 2) { - hw_error("%s: Bad timer %d\n", __func__, n); + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad timer %d\n", __func__, n); } arm_timer_write(s->timer[n], offset & 0xff, value); diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c index 35c1aa67e2..f0a2e7b5d2 100644 --- a/hw/armv7m_nvic.c +++ b/hw/armv7m_nvic.c @@ -138,9 +138,8 @@ void armv7m_nvic_complete_irq(void *opaque, int irq) gic_complete_irq(&s->gic, 0, irq); } -static uint32_t nvic_readl(void *opaque, uint32_t offset) +static uint32_t nvic_readl(nvic_state *s, uint32_t offset) { - nvic_state *s = (nvic_state *)opaque; uint32_t val; int irq; @@ -216,14 +215,6 @@ static uint32_t nvic_readl(void *opaque, uint32_t offset) case 0xd14: /* Configuration Control. */ /* TODO: Implement Configuration Control bits. */ return 0; - case 0xd18: case 0xd1c: case 0xd20: /* System Handler Priority. */ - irq = offset - 0xd14; - val = 0; - val |= s->gic.priority1[irq++][0]; - val |= s->gic.priority1[irq++][0] << 8; - val |= s->gic.priority1[irq++][0] << 16; - val |= s->gic.priority1[irq][0] << 24; - return val; case 0xd24: /* System Handler Status. */ val = 0; if (s->gic.irq_state[ARMV7M_EXCP_MEM].active) val |= (1 << 0); @@ -243,7 +234,7 @@ static uint32_t nvic_readl(void *opaque, uint32_t offset) return val; case 0xd28: /* Configurable Fault Status. */ /* TODO: Implement Fault Status. */ - hw_error("Not implemented: Configurable Fault Status."); + qemu_log_mask(LOG_UNIMP, "Configurable Fault Status unimplemented\n"); return 0; case 0xd2c: /* Hard Fault Status. */ case 0xd30: /* Debug Fault Status. */ @@ -251,7 +242,8 @@ static uint32_t nvic_readl(void *opaque, uint32_t offset) case 0xd38: /* Bus Fault Address. */ case 0xd3c: /* Aux Fault Status. */ /* TODO: Implement fault status registers. */ - goto bad_reg; + qemu_log_mask(LOG_UNIMP, "Fault status registers unimplemented\n"); + return 0; case 0xd40: /* PFR0. */ return 0x00000030; case 0xd44: /* PRF1. */ @@ -280,14 +272,13 @@ static uint32_t nvic_readl(void *opaque, uint32_t offset) return 0x01310102; /* TODO: Implement debug registers. */ default: - bad_reg: - hw_error("NVIC: Bad read offset 0x%x\n", offset); + qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset); + return 0; } } -static void nvic_writel(void *opaque, uint32_t offset, uint32_t value) +static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value) { - nvic_state *s = (nvic_state *)opaque; uint32_t oldval; switch (offset) { case 0x10: /* SysTick Control and Status. */ @@ -345,27 +336,17 @@ static void nvic_writel(void *opaque, uint32_t offset, uint32_t value) case 0xd0c: /* Application Interrupt/Reset Control. */ if ((value >> 16) == 0x05fa) { if (value & 2) { - hw_error("VECTCLRACTIVE not implemented"); + qemu_log_mask(LOG_UNIMP, "VECTCLRACTIVE unimplemented\n"); } if (value & 5) { - hw_error("System reset"); + qemu_log_mask(LOG_UNIMP, "AIRCR system reset unimplemented\n"); } } break; case 0xd10: /* System Control. */ case 0xd14: /* Configuration Control. */ /* TODO: Implement control registers. */ - goto bad_reg; - case 0xd18: case 0xd1c: case 0xd20: /* System Handler Priority. */ - { - int irq; - irq = offset - 0xd14; - s->gic.priority1[irq++][0] = value & 0xff; - s->gic.priority1[irq++][0] = (value >> 8) & 0xff; - s->gic.priority1[irq++][0] = (value >> 16) & 0xff; - s->gic.priority1[irq][0] = (value >> 24) & 0xff; - gic_update(&s->gic); - } + qemu_log_mask(LOG_UNIMP, "NVIC: SCR and CCR unimplemented\n"); break; case 0xd24: /* System Handler Control. */ /* TODO: Real hardware allows you to set/clear the active bits @@ -380,47 +361,71 @@ static void nvic_writel(void *opaque, uint32_t offset, uint32_t value) case 0xd34: /* Mem Manage Address. */ case 0xd38: /* Bus Fault Address. */ case 0xd3c: /* Aux Fault Status. */ - goto bad_reg; + qemu_log_mask(LOG_UNIMP, + "NVIC: fault status registers unimplemented\n"); + break; case 0xf00: /* Software Triggered Interrupt Register */ if ((value & 0x1ff) < s->num_irq) { gic_set_pending_private(&s->gic, 0, value & 0x1ff); } break; default: - bad_reg: - hw_error("NVIC: Bad write offset 0x%x\n", offset); + qemu_log_mask(LOG_GUEST_ERROR, + "NVIC: Bad write offset 0x%x\n", offset); } } static uint64_t nvic_sysreg_read(void *opaque, hwaddr addr, unsigned size) { - /* At the moment we only support the ID registers for byte/word access. - * This is not strictly correct as a few of the other registers also - * allow byte access. - */ + nvic_state *s = (nvic_state *)opaque; uint32_t offset = addr; - if (offset >= 0xfe0) { + int i; + uint32_t val; + + switch (offset) { + case 0xd18 ... 0xd23: /* System Handler Priority. */ + val = 0; + for (i = 0; i < size; i++) { + val |= s->gic.priority1[(offset - 0xd14) + i][0] << (i * 8); + } + return val; + case 0xfe0 ... 0xfff: /* ID. */ if (offset & 3) { return 0; } return nvic_id[(offset - 0xfe0) >> 2]; } if (size == 4) { - return nvic_readl(opaque, offset); + return nvic_readl(s, offset); } - hw_error("NVIC: Bad read of size %d at offset 0x%x\n", size, offset); + qemu_log_mask(LOG_GUEST_ERROR, + "NVIC: Bad read of size %d at offset 0x%x\n", size, offset); + return 0; } static void nvic_sysreg_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { + nvic_state *s = (nvic_state *)opaque; uint32_t offset = addr; + int i; + + switch (offset) { + case 0xd18 ... 0xd23: /* System Handler Priority. */ + for (i = 0; i < size; i++) { + s->gic.priority1[(offset - 0xd14) + i][0] = + (value >> (i * 8)) & 0xff; + } + gic_update(&s->gic); + return; + } if (size == 4) { - nvic_writel(opaque, offset, value); + nvic_writel(s, offset, value); return; } - hw_error("NVIC: Bad write of size %d at offset 0x%x\n", size, offset); + qemu_log_mask(LOG_GUEST_ERROR, + "NVIC: Bad write of size %d at offset 0x%x\n", size, offset); } static const MemoryRegionOps nvic_sysreg_ops = { diff --git a/hw/exynos4_boards.c b/hw/exynos4_boards.c index 4951064c3f..bc815bbae3 100644 --- a/hw/exynos4_boards.c +++ b/hw/exynos4_boards.c @@ -93,11 +93,8 @@ static void lan9215_init(uint32_t base, qemu_irq irq) } } -static Exynos4210State *exynos4_boards_init_common( - const char *kernel_filename, - const char *kernel_cmdline, - const char *initrd_filename, - Exynos4BoardType board_type) +static Exynos4210State *exynos4_boards_init_common(QEMUMachineInitArgs *args, + Exynos4BoardType board_type) { if (smp_cpus != EXYNOS4210_NCPUS) { fprintf(stderr, "%s board supports only %d CPU cores. Ignoring smp_cpus" @@ -110,9 +107,9 @@ static Exynos4210State *exynos4_boards_init_common( exynos4_board_binfo.board_id = exynos4_board_id[board_type]; exynos4_board_binfo.smp_bootreg_addr = exynos4_board_smp_bootreg_addr[board_type]; - exynos4_board_binfo.kernel_filename = kernel_filename; - exynos4_board_binfo.initrd_filename = initrd_filename; - exynos4_board_binfo.kernel_cmdline = kernel_cmdline; + exynos4_board_binfo.kernel_filename = args->kernel_filename; + exynos4_board_binfo.initrd_filename = args->initrd_filename; + exynos4_board_binfo.kernel_cmdline = args->kernel_cmdline; exynos4_board_binfo.gic_cpu_if_addr = EXYNOS4210_SMP_PRIVATE_BASE_ADDR + 0x100; @@ -122,9 +119,9 @@ static Exynos4210State *exynos4_boards_init_common( " initrd_filename: %s\n", exynos4_board_ram_size[board_type] / 1048576, exynos4_board_ram_size[board_type], - kernel_filename, - kernel_cmdline, - initrd_filename); + args->kernel_filename, + args->kernel_cmdline, + args->initrd_filename); return exynos4210_init(get_system_memory(), exynos4_board_ram_size[board_type]); @@ -132,22 +129,15 @@ static Exynos4210State *exynos4_boards_init_common( static void nuri_init(QEMUMachineInitArgs *args) { - const char *kernel_filename = args->kernel_filename; - const char *kernel_cmdline = args->kernel_cmdline; - const char *initrd_filename = args->initrd_filename; - exynos4_boards_init_common(kernel_filename, kernel_cmdline, - initrd_filename, EXYNOS4_BOARD_NURI); + exynos4_boards_init_common(args, EXYNOS4_BOARD_NURI); arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo); } static void smdkc210_init(QEMUMachineInitArgs *args) { - const char *kernel_filename = args->kernel_filename; - const char *kernel_cmdline = args->kernel_cmdline; - const char *initrd_filename = args->initrd_filename; - Exynos4210State *s = exynos4_boards_init_common(kernel_filename, - kernel_cmdline, initrd_filename, EXYNOS4_BOARD_SMDKC210); + Exynos4210State *s = exynos4_boards_init_common(args, + EXYNOS4_BOARD_SMDKC210); lan9215_init(SMDK_LAN9118_BASE_ADDR, qemu_irq_invert(s->irq_table[exynos4210_get_irq(37, 1)])); diff --git a/hw/mainstone.c b/hw/mainstone.c index 3266946954..5bbecb7304 100644 --- a/hw/mainstone.c +++ b/hw/mainstone.c @@ -95,10 +95,8 @@ static struct arm_boot_info mainstone_binfo = { }; static void mainstone_common_init(MemoryRegion *address_space_mem, - ram_addr_t ram_size, - const char *kernel_filename, - const char *kernel_cmdline, const char *initrd_filename, - const char *cpu_model, enum mainstone_model_e model, int arm_id) + QEMUMachineInitArgs *args, + enum mainstone_model_e model, int arm_id) { uint32_t sector_len = 256 * 1024; hwaddr mainstone_flash_base[] = { MST_FLASH_0, MST_FLASH_1 }; @@ -108,6 +106,7 @@ static void mainstone_common_init(MemoryRegion *address_space_mem, int i; int be; MemoryRegion *rom = g_new(MemoryRegion, 1); + const char *cpu_model = args->cpu_model; if (!cpu_model) cpu_model = "pxa270-c5"; @@ -164,22 +163,16 @@ static void mainstone_common_init(MemoryRegion *address_space_mem, smc91c111_init(&nd_table[0], MST_ETH_PHYS, qdev_get_gpio_in(mst_irq, ETHERNET_IRQ)); - mainstone_binfo.kernel_filename = kernel_filename; - mainstone_binfo.kernel_cmdline = kernel_cmdline; - mainstone_binfo.initrd_filename = initrd_filename; + mainstone_binfo.kernel_filename = args->kernel_filename; + mainstone_binfo.kernel_cmdline = args->kernel_cmdline; + mainstone_binfo.initrd_filename = args->initrd_filename; mainstone_binfo.board_id = arm_id; arm_load_kernel(mpu->cpu, &mainstone_binfo); } static void mainstone_init(QEMUMachineInitArgs *args) { - 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; - mainstone_common_init(get_system_memory(), ram_size, kernel_filename, - kernel_cmdline, initrd_filename, cpu_model, mainstone, 0x196); + mainstone_common_init(get_system_memory(), args, mainstone, 0x196); } static QEMUMachine mainstone2_machine = { diff --git a/hw/nseries.c b/hw/nseries.c index 9306aa15a7..652d9da333 100644 --- a/hw/nseries.c +++ b/hw/nseries.c @@ -1284,17 +1284,15 @@ static int n810_atag_setup(const struct arm_boot_info *info, void *p) return n8x0_atag_setup(p, 810); } -static void n8x0_init(ram_addr_t ram_size, const char *boot_device, - const char *kernel_filename, - const char *kernel_cmdline, const char *initrd_filename, - const char *cpu_model, struct arm_boot_info *binfo, int model) +static void n8x0_init(QEMUMachineInitArgs *args, + struct arm_boot_info *binfo, int model) { MemoryRegion *sysmem = get_system_memory(); struct n800_s *s = (struct n800_s *) g_malloc0(sizeof(*s)); int sdram_size = binfo->ram_size; DisplayState *ds; - s->mpu = omap2420_mpu_init(sysmem, sdram_size, cpu_model); + s->mpu = omap2420_mpu_init(sysmem, sdram_size, args->cpu_model); /* Setup peripherals * @@ -1338,17 +1336,18 @@ static void n8x0_init(ram_addr_t ram_size, const char *boot_device, n8x0_usb_setup(s); } - if (kernel_filename) { + if (args->kernel_filename) { /* Or at the linux loader. */ - binfo->kernel_filename = kernel_filename; - binfo->kernel_cmdline = kernel_cmdline; - binfo->initrd_filename = initrd_filename; + binfo->kernel_filename = args->kernel_filename; + binfo->kernel_cmdline = args->kernel_cmdline; + binfo->initrd_filename = args->initrd_filename; arm_load_kernel(s->mpu->cpu, binfo); qemu_register_reset(n8x0_boot_init, s); } - if (option_rom[0].name && (boot_device[0] == 'n' || !kernel_filename)) { + if (option_rom[0].name && + (args->boot_device[0] == 'n' || !args->kernel_filename)) { int rom_size; uint8_t nolo_tags[0x10000]; /* No, wait, better start at the ROM. */ @@ -1400,28 +1399,12 @@ static struct arm_boot_info n810_binfo = { static void n800_init(QEMUMachineInitArgs *args) { - 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; - const char *boot_device = args->boot_device; - return n8x0_init(ram_size, boot_device, - kernel_filename, kernel_cmdline, initrd_filename, - cpu_model, &n800_binfo, 800); + return n8x0_init(args, &n800_binfo, 800); } static void n810_init(QEMUMachineInitArgs *args) { - 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; - const char *boot_device = args->boot_device; - return n8x0_init(ram_size, boot_device, - kernel_filename, kernel_cmdline, initrd_filename, - cpu_model, &n810_binfo, 810); + return n8x0_init(args, &n810_binfo, 810); } static QEMUMachine n800_machine = { diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c index eb2bf0569c..21a5bbb006 100644 --- a/hw/omap_sx1.c +++ b/hw/omap_sx1.c @@ -97,11 +97,7 @@ static struct arm_boot_info sx1_binfo = { .board_id = 0x265, }; -static void sx1_init(ram_addr_t ram_size, - const char *boot_device, - const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename, const char *cpu_model, - const int version) +static void sx1_init(QEMUMachineInitArgs *args, const int version) { struct omap_mpu_state_s *mpu; MemoryRegion *address_space = get_system_memory(); @@ -121,7 +117,7 @@ static void sx1_init(ram_addr_t ram_size, flash_size = flash2_size; } - mpu = omap310_mpu_init(address_space, sx1_binfo.ram_size, cpu_model); + mpu = omap310_mpu_init(address_space, sx1_binfo.ram_size, args->cpu_model); /* External Flash (EMIFS) */ memory_region_init_ram(flash, "omap_sx1.flash0-0", flash_size); @@ -192,16 +188,16 @@ static void sx1_init(ram_addr_t ram_size, OMAP_CS1_BASE, &cs[1]); } - if (!kernel_filename && !fl_idx) { + if (!args->kernel_filename && !fl_idx) { fprintf(stderr, "Kernel or Flash image must be specified\n"); exit(1); } /* Load the kernel. */ - if (kernel_filename) { - sx1_binfo.kernel_filename = kernel_filename; - sx1_binfo.kernel_cmdline = kernel_cmdline; - sx1_binfo.initrd_filename = initrd_filename; + if (args->kernel_filename) { + sx1_binfo.kernel_filename = args->kernel_filename; + sx1_binfo.kernel_cmdline = args->kernel_cmdline; + sx1_binfo.initrd_filename = args->initrd_filename; arm_load_kernel(mpu->cpu, &sx1_binfo); } @@ -211,26 +207,12 @@ static void sx1_init(ram_addr_t ram_size, static void sx1_init_v1(QEMUMachineInitArgs *args) { - 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; - const char *boot_device = args->boot_device; - sx1_init(ram_size, boot_device, kernel_filename, - kernel_cmdline, initrd_filename, cpu_model, 1); + sx1_init(args, 1); } static void sx1_init_v2(QEMUMachineInitArgs *args) { - 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; - const char *boot_device = args->boot_device; - sx1_init(ram_size, boot_device, kernel_filename, - kernel_cmdline, initrd_filename, cpu_model, 2); + sx1_init(args, 2); } static QEMUMachine sx1_machine_v2 = { diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c index 5e3a409c2b..7d040b508a 100644 --- a/hw/pflash_cfi01.c +++ b/hw/pflash_cfi01.c @@ -42,6 +42,7 @@ #include "qemu-timer.h" #include "exec-memory.h" #include "host-utils.h" +#include "sysbus.h" #define PFLASH_BUG(fmt, ...) \ do { \ @@ -60,23 +61,28 @@ do { \ #endif struct pflash_t { + SysBusDevice busdev; BlockDriverState *bs; - hwaddr base; - hwaddr sector_len; - hwaddr total_len; - int width; + uint32_t nb_blocs; + uint64_t sector_len; + uint8_t width; + uint8_t be; int wcycle; /* if 0, the flash is read normally */ int bypass; int ro; uint8_t cmd; uint8_t status; - uint16_t ident[4]; + uint16_t ident0; + uint16_t ident1; + uint16_t ident2; + uint16_t ident3; uint8_t cfi_len; uint8_t cfi_table[0x52]; hwaddr counter; unsigned int writeblock_size; QEMUTimer *timer; MemoryRegion mem; + char *name; void *storage; }; @@ -168,15 +174,16 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, case 0x90: switch (boff) { case 0: - ret = pfl->ident[0] << 8 | pfl->ident[1]; + ret = pfl->ident0 << 8 | pfl->ident1; DPRINTF("%s: Manufacturer Code %04x\n", __func__, ret); break; case 1: - ret = pfl->ident[2] << 8 | pfl->ident[3]; + ret = pfl->ident2 << 8 | pfl->ident3; DPRINTF("%s: Device ID Code %04x\n", __func__, ret); break; default: - DPRINTF("%s: Read Device Information boff=%x\n", __func__, boff); + DPRINTF("%s: Read Device Information boff=%x\n", __func__, + (unsigned)boff); ret = 0; break; } @@ -279,9 +286,8 @@ static void pflash_write(pflash_t *pfl, hwaddr offset, p = pfl->storage; offset &= ~(pfl->sector_len - 1); - DPRINTF("%s: block erase at " TARGET_FMT_plx " bytes " - TARGET_FMT_plx "\n", - __func__, offset, pfl->sector_len); + DPRINTF("%s: block erase at " TARGET_FMT_plx " bytes %x\n", + __func__, offset, (unsigned)pfl->sector_len); if (!pfl->ro) { memset(p + offset, 0xff, pfl->sector_len); @@ -543,19 +549,13 @@ static const MemoryRegionOps pflash_cfi01_ops_le = { .endianness = DEVICE_NATIVE_ENDIAN, }; -pflash_t *pflash_cfi01_register(hwaddr base, - DeviceState *qdev, const char *name, - hwaddr size, - BlockDriverState *bs, uint32_t sector_len, - int nb_blocs, int width, - uint16_t id0, uint16_t id1, - uint16_t id2, uint16_t id3, int be) +static int pflash_cfi01_init(SysBusDevice *dev) { - pflash_t *pfl; - hwaddr total_len; + pflash_t *pfl = FROM_SYSBUS(typeof(*pfl), dev); + uint64_t total_len; int ret; - total_len = sector_len * nb_blocs; + total_len = pfl->sector_len * pfl->nb_blocs; /* XXX: to be fixed */ #if 0 @@ -564,27 +564,22 @@ pflash_t *pflash_cfi01_register(hwaddr base, return NULL; #endif - pfl = g_malloc0(sizeof(pflash_t)); - memory_region_init_rom_device( - &pfl->mem, be ? &pflash_cfi01_ops_be : &pflash_cfi01_ops_le, pfl, - name, size); - vmstate_register_ram(&pfl->mem, qdev); + &pfl->mem, pfl->be ? &pflash_cfi01_ops_be : &pflash_cfi01_ops_le, pfl, + pfl->name, total_len); + vmstate_register_ram(&pfl->mem, DEVICE(pfl)); pfl->storage = memory_region_get_ram_ptr(&pfl->mem); - memory_region_add_subregion(get_system_memory(), base, &pfl->mem); + sysbus_init_mmio(dev, &pfl->mem); - pfl->bs = bs; if (pfl->bs) { /* read the initial flash content */ ret = bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9); + if (ret < 0) { - memory_region_del_subregion(get_system_memory(), &pfl->mem); - vmstate_unregister_ram(&pfl->mem, qdev); + vmstate_unregister_ram(&pfl->mem, DEVICE(pfl)); memory_region_destroy(&pfl->mem); - g_free(pfl); - return NULL; + return 1; } - bdrv_attach_dev_nofail(pfl->bs, pfl); } if (pfl->bs) { @@ -594,17 +589,9 @@ pflash_t *pflash_cfi01_register(hwaddr base, } pfl->timer = qemu_new_timer_ns(vm_clock, pflash_timer, pfl); - pfl->base = base; - pfl->sector_len = sector_len; - pfl->total_len = total_len; - pfl->width = width; pfl->wcycle = 0; pfl->cmd = 0; pfl->status = 0; - pfl->ident[0] = id0; - pfl->ident[1] = id1; - pfl->ident[2] = id2; - pfl->ident[3] = id3; /* Hardcoded CFI table */ pfl->cfi_len = 0x52; /* Standard "QRY" string */ @@ -653,7 +640,7 @@ pflash_t *pflash_cfi01_register(hwaddr base, pfl->cfi_table[0x28] = 0x02; pfl->cfi_table[0x29] = 0x00; /* Max number of bytes in multi-bytes write */ - if (width == 1) { + if (pfl->width == 1) { pfl->cfi_table[0x2A] = 0x08; } else { pfl->cfi_table[0x2A] = 0x0B; @@ -664,10 +651,10 @@ pflash_t *pflash_cfi01_register(hwaddr base, /* Number of erase block regions (uniform) */ pfl->cfi_table[0x2C] = 0x01; /* Erase block region 1 */ - pfl->cfi_table[0x2D] = nb_blocs - 1; - pfl->cfi_table[0x2E] = (nb_blocs - 1) >> 8; - pfl->cfi_table[0x2F] = sector_len >> 8; - pfl->cfi_table[0x30] = sector_len >> 16; + pfl->cfi_table[0x2D] = pfl->nb_blocs - 1; + pfl->cfi_table[0x2E] = (pfl->nb_blocs - 1) >> 8; + pfl->cfi_table[0x2F] = pfl->sector_len >> 8; + pfl->cfi_table[0x30] = pfl->sector_len >> 16; /* Extended */ pfl->cfi_table[0x31] = 'P'; @@ -689,6 +676,75 @@ pflash_t *pflash_cfi01_register(hwaddr base, pfl->cfi_table[0x3f] = 0x01; /* Number of protection fields */ + return 0; +} + +static Property pflash_cfi01_properties[] = { + DEFINE_PROP_DRIVE("drive", struct pflash_t, bs), + DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0), + DEFINE_PROP_UINT64("sector-length", struct pflash_t, sector_len, 0), + DEFINE_PROP_UINT8("width", struct pflash_t, width, 0), + DEFINE_PROP_UINT8("big-endian", struct pflash_t, be, 0), + DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0), + DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0), + DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0), + DEFINE_PROP_UINT16("id3", struct pflash_t, ident3, 0), + DEFINE_PROP_STRING("name", struct pflash_t, name), + DEFINE_PROP_END_OF_LIST(), +}; + +static void pflash_cfi01_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = pflash_cfi01_init; + dc->props = pflash_cfi01_properties; +} + + +static const TypeInfo pflash_cfi01_info = { + .name = "cfi.pflash01", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(struct pflash_t), + .class_init = pflash_cfi01_class_init, +}; + +static void pflash_cfi01_register_types(void) +{ + type_register_static(&pflash_cfi01_info); +} + +type_init(pflash_cfi01_register_types) + +pflash_t *pflash_cfi01_register(hwaddr base, + DeviceState *qdev, const char *name, + hwaddr size, + BlockDriverState *bs, + uint32_t sector_len, int nb_blocs, int width, + uint16_t id0, uint16_t id1, + uint16_t id2, uint16_t id3, int be) +{ + DeviceState *dev = qdev_create(NULL, "cfi.pflash01"); + SysBusDevice *busdev = sysbus_from_qdev(dev); + pflash_t *pfl = (pflash_t *)object_dynamic_cast(OBJECT(dev), + "cfi.pflash01"); + + if (bs && qdev_prop_set_drive(dev, "drive", bs)) { + abort(); + } + qdev_prop_set_uint32(dev, "num-blocks", nb_blocs); + qdev_prop_set_uint64(dev, "sector-length", sector_len); + qdev_prop_set_uint8(dev, "width", width); + qdev_prop_set_uint8(dev, "big-endian", !!be); + qdev_prop_set_uint16(dev, "id0", id0); + qdev_prop_set_uint16(dev, "id1", id1); + qdev_prop_set_uint16(dev, "id2", id2); + qdev_prop_set_uint16(dev, "id3", id3); + qdev_prop_set_string(dev, "name", name); + qdev_init_nofail(dev); + + sysbus_mmio_map(busdev, 0, base); return pfl; } diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c index 9f94c0623d..f918e36580 100644 --- a/hw/pflash_cfi02.c +++ b/hw/pflash_cfi02.c @@ -41,6 +41,7 @@ #include "block.h" #include "exec-memory.h" #include "host-utils.h" +#include "sysbus.h" //#define PFLASH_DEBUG #ifdef PFLASH_DEBUG @@ -55,19 +56,26 @@ do { \ #define PFLASH_LAZY_ROMD_THRESHOLD 42 struct pflash_t { + SysBusDevice busdev; BlockDriverState *bs; - hwaddr base; uint32_t sector_len; + uint32_t nb_blocs; uint32_t chip_len; - int mappings; - int width; + uint8_t mappings; + uint8_t width; + uint8_t be; int wcycle; /* if 0, the flash is read normally */ int bypass; int ro; uint8_t cmd; uint8_t status; - uint16_t ident[4]; - uint16_t unlock_addr[2]; + /* FIXME: implement array device properties */ + uint16_t ident0; + uint16_t ident1; + uint16_t ident2; + uint16_t ident3; + uint16_t unlock_addr0; + uint16_t unlock_addr1; uint8_t cfi_len; uint8_t cfi_table[0x52]; QEMUTimer *timer; @@ -80,6 +88,7 @@ struct pflash_t { MemoryRegion orig_mem; int rom_mode; int read_counter; /* used for lazy switch-back to rom mode */ + char *name; void *storage; }; @@ -190,16 +199,17 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, switch (boff) { case 0x00: case 0x01: - ret = pfl->ident[boff & 0x01]; + ret = boff & 0x01 ? pfl->ident1 : pfl->ident0; break; case 0x02: ret = 0x00; /* Pretend all sectors are unprotected */ break; case 0x0E: case 0x0F: - if (pfl->ident[2 + (boff & 0x01)] == (uint8_t)-1) + ret = boff & 0x01 ? pfl->ident3 : pfl->ident2; + if (ret == (uint8_t)-1) { goto flash_read; - ret = pfl->ident[2 + (boff & 0x01)]; + } break; default: goto flash_read; @@ -283,9 +293,9 @@ static void pflash_write (pflash_t *pfl, hwaddr offset, pfl->cmd = 0x98; return; } - if (boff != pfl->unlock_addr[0] || cmd != 0xAA) { + if (boff != pfl->unlock_addr0 || cmd != 0xAA) { DPRINTF("%s: unlock0 failed " TARGET_FMT_plx " %02x %04x\n", - __func__, boff, cmd, pfl->unlock_addr[0]); + __func__, boff, cmd, pfl->unlock_addr0); goto reset_flash; } DPRINTF("%s: unlock sequence started\n", __func__); @@ -293,7 +303,7 @@ static void pflash_write (pflash_t *pfl, hwaddr offset, case 1: /* We started an unlock sequence */ check_unlock1: - if (boff != pfl->unlock_addr[1] || cmd != 0x55) { + if (boff != pfl->unlock_addr1 || cmd != 0x55) { DPRINTF("%s: unlock1 failed " TARGET_FMT_plx " %02x\n", __func__, boff, cmd); goto reset_flash; @@ -302,7 +312,7 @@ static void pflash_write (pflash_t *pfl, hwaddr offset, break; case 2: /* We finished an unlock sequence */ - if (!pfl->bypass && boff != pfl->unlock_addr[0]) { + if (!pfl->bypass && boff != pfl->unlock_addr0) { DPRINTF("%s: command failed " TARGET_FMT_plx " %02x\n", __func__, boff, cmd); goto reset_flash; @@ -400,7 +410,7 @@ static void pflash_write (pflash_t *pfl, hwaddr offset, case 5: switch (cmd) { case 0x10: - if (boff != pfl->unlock_addr[0]) { + if (boff != pfl->unlock_addr0) { DPRINTF("%s: chip erase: invalid address " TARGET_FMT_plx "\n", __func__, offset); goto reset_flash; @@ -575,50 +585,38 @@ static const MemoryRegionOps pflash_cfi02_ops_le = { .endianness = DEVICE_NATIVE_ENDIAN, }; -pflash_t *pflash_cfi02_register(hwaddr base, - DeviceState *qdev, const char *name, - hwaddr size, - BlockDriverState *bs, uint32_t sector_len, - int nb_blocs, int nb_mappings, int width, - uint16_t id0, uint16_t id1, - uint16_t id2, uint16_t id3, - uint16_t unlock_addr0, uint16_t unlock_addr1, - int be) +static int pflash_cfi02_init(SysBusDevice *dev) { - pflash_t *pfl; - int32_t chip_len; + pflash_t *pfl = FROM_SYSBUS(typeof(*pfl), dev); + uint32_t chip_len; int ret; - chip_len = sector_len * nb_blocs; + chip_len = pfl->sector_len * pfl->nb_blocs; /* XXX: to be fixed */ #if 0 if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) && total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024)) return NULL; #endif - pfl = g_malloc0(sizeof(pflash_t)); - memory_region_init_rom_device( - &pfl->orig_mem, be ? &pflash_cfi02_ops_be : &pflash_cfi02_ops_le, pfl, - name, size); - vmstate_register_ram(&pfl->orig_mem, qdev); + + memory_region_init_rom_device(&pfl->orig_mem, pfl->be ? + &pflash_cfi02_ops_be : &pflash_cfi02_ops_le, + pfl, pfl->name, chip_len); + vmstate_register_ram(&pfl->orig_mem, DEVICE(pfl)); pfl->storage = memory_region_get_ram_ptr(&pfl->orig_mem); - pfl->base = base; pfl->chip_len = chip_len; - pfl->mappings = nb_mappings; - pfl->bs = bs; if (pfl->bs) { /* read the initial flash content */ ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9); if (ret < 0) { g_free(pfl); - return NULL; + return 1; } - bdrv_attach_dev_nofail(pfl->bs, pfl); } pflash_setup_mappings(pfl); pfl->rom_mode = 1; - memory_region_add_subregion(get_system_memory(), pfl->base, &pfl->mem); + sysbus_init_mmio(dev, &pfl->mem); if (pfl->bs) { pfl->ro = bdrv_is_read_only(pfl->bs); @@ -627,17 +625,9 @@ pflash_t *pflash_cfi02_register(hwaddr base, } pfl->timer = qemu_new_timer_ns(vm_clock, pflash_timer, pfl); - pfl->sector_len = sector_len; - pfl->width = width; pfl->wcycle = 0; pfl->cmd = 0; pfl->status = 0; - pfl->ident[0] = id0; - pfl->ident[1] = id1; - pfl->ident[2] = id2; - pfl->ident[3] = id3; - pfl->unlock_addr[0] = unlock_addr0; - pfl->unlock_addr[1] = unlock_addr1; /* Hardcoded CFI table (mostly from SG29 Spansion flash) */ pfl->cfi_len = 0x52; /* Standard "QRY" string */ @@ -693,10 +683,10 @@ pflash_t *pflash_cfi02_register(hwaddr base, /* Number of erase block regions (uniform) */ pfl->cfi_table[0x2C] = 0x01; /* Erase block region 1 */ - pfl->cfi_table[0x2D] = nb_blocs - 1; - pfl->cfi_table[0x2E] = (nb_blocs - 1) >> 8; - pfl->cfi_table[0x2F] = sector_len >> 8; - pfl->cfi_table[0x30] = sector_len >> 16; + pfl->cfi_table[0x2D] = pfl->nb_blocs - 1; + pfl->cfi_table[0x2E] = (pfl->nb_blocs - 1) >> 8; + pfl->cfi_table[0x2F] = pfl->sector_len >> 8; + pfl->cfi_table[0x30] = pfl->sector_len >> 16; /* Extended */ pfl->cfi_table[0x31] = 'P'; @@ -716,5 +706,81 @@ pflash_t *pflash_cfi02_register(hwaddr base, pfl->cfi_table[0x3b] = 0x00; pfl->cfi_table[0x3c] = 0x00; + return 0; +} + +static Property pflash_cfi02_properties[] = { + DEFINE_PROP_DRIVE("drive", struct pflash_t, bs), + DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0), + DEFINE_PROP_UINT32("sector-length", struct pflash_t, sector_len, 0), + DEFINE_PROP_UINT8("width", struct pflash_t, width, 0), + DEFINE_PROP_UINT8("mappings", struct pflash_t, mappings, 0), + DEFINE_PROP_UINT8("big-endian", struct pflash_t, be, 0), + DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0), + DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0), + DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0), + DEFINE_PROP_UINT16("id3", struct pflash_t, ident3, 0), + DEFINE_PROP_UINT16("unlock-addr0", struct pflash_t, unlock_addr0, 0), + DEFINE_PROP_UINT16("unlock-addr1", struct pflash_t, unlock_addr1, 0), + DEFINE_PROP_STRING("name", struct pflash_t, name), + DEFINE_PROP_END_OF_LIST(), +}; + +static void pflash_cfi02_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = pflash_cfi02_init; + dc->props = pflash_cfi02_properties; +} + +static const TypeInfo pflash_cfi02_info = { + .name = "cfi.pflash02", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(struct pflash_t), + .class_init = pflash_cfi02_class_init, +}; + +static void pflash_cfi02_register_types(void) +{ + type_register_static(&pflash_cfi02_info); +} + +type_init(pflash_cfi02_register_types) + +pflash_t *pflash_cfi02_register(hwaddr base, + DeviceState *qdev, const char *name, + hwaddr size, + BlockDriverState *bs, uint32_t sector_len, + int nb_blocs, int nb_mappings, int width, + uint16_t id0, uint16_t id1, + uint16_t id2, uint16_t id3, + uint16_t unlock_addr0, uint16_t unlock_addr1, + int be) +{ + DeviceState *dev = qdev_create(NULL, "cfi.pflash02"); + SysBusDevice *busdev = sysbus_from_qdev(dev); + pflash_t *pfl = (pflash_t *)object_dynamic_cast(OBJECT(dev), + "cfi.pflash02"); + + if (bs && qdev_prop_set_drive(dev, "drive", bs)) { + abort(); + } + qdev_prop_set_uint32(dev, "num-blocks", nb_blocs); + qdev_prop_set_uint32(dev, "sector-length", sector_len); + qdev_prop_set_uint8(dev, "width", width); + qdev_prop_set_uint8(dev, "mappings", nb_mappings); + qdev_prop_set_uint8(dev, "big-endian", !!be); + qdev_prop_set_uint16(dev, "id0", id0); + qdev_prop_set_uint16(dev, "id1", id1); + qdev_prop_set_uint16(dev, "id2", id2); + qdev_prop_set_uint16(dev, "id3", id3); + qdev_prop_set_uint16(dev, "unlock-addr0", unlock_addr0); + qdev_prop_set_uint16(dev, "unlock-addr1", unlock_addr1); + qdev_prop_set_string(dev, "name", name); + qdev_init_nofail(dev); + + sysbus_mmio_map(busdev, 0, base); return pfl; } diff --git a/hw/pl050.c b/hw/pl050.c index 470572eabb..47032f1260 100644 --- a/hw/pl050.c +++ b/hw/pl050.c @@ -95,7 +95,8 @@ static uint64_t pl050_read(void *opaque, hwaddr offset, case 4: /* KMIIR */ return s->pending | 2; default: - hw_error("pl050_read: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "pl050_read: Bad offset %x\n", (int)offset); return 0; } } @@ -123,7 +124,8 @@ static void pl050_write(void *opaque, hwaddr offset, s->clk = value; return; default: - hw_error("pl050_write: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "pl050_write: Bad offset %x\n", (int)offset); } } static const MemoryRegionOps pl050_ops = { diff --git a/hw/pl061.c b/hw/pl061.c index 7d182e7cdf..f1ed5ced1d 100644 --- a/hw/pl061.c +++ b/hw/pl061.c @@ -164,7 +164,8 @@ static uint64_t pl061_read(void *opaque, hwaddr offset, case 0x528: /* Analog mode select */ return s->amsel; default: - hw_error("pl061_read: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "pl061_read: Bad offset %x\n", (int)offset); return 0; } } @@ -239,7 +240,8 @@ static void pl061_write(void *opaque, hwaddr offset, s->amsel = value & 0xff; break; default: - hw_error("pl061_write: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "pl061_write: Bad offset %x\n", (int)offset); } pl061_update(s); } diff --git a/hw/pl080.c b/hw/pl080.c index 6abe52857e..26150af757 100644 --- a/hw/pl080.c +++ b/hw/pl080.c @@ -281,7 +281,8 @@ static uint64_t pl080_read(void *opaque, hwaddr offset, return s->sync; default: bad_offset: - hw_error("pl080_read: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "pl080_read: Bad offset %x\n", (int)offset); return 0; } } @@ -327,12 +328,13 @@ static void pl080_write(void *opaque, hwaddr offset, case 10: /* SoftLBReq */ case 11: /* SoftLSReq */ /* ??? Implement these. */ - hw_error("pl080_write: Soft DMA not implemented\n"); + qemu_log_mask(LOG_UNIMP, "pl080_write: Soft DMA not implemented\n"); break; case 12: /* Configuration */ s->conf = value; if (s->conf & (PL080_CONF_M1 | PL080_CONF_M1)) { - hw_error("pl080_write: Big-endian DMA not implemented\n"); + qemu_log_mask(LOG_UNIMP, + "pl080_write: Big-endian DMA not implemented\n"); } pl080_run(s); break; @@ -341,7 +343,8 @@ static void pl080_write(void *opaque, hwaddr offset, break; default: bad_offset: - hw_error("pl080_write: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "pl080_write: Bad offset %x\n", (int)offset); } pl080_update(s); } diff --git a/hw/pl110.c b/hw/pl110.c index 82486b0c14..d5472f4cce 100644 --- a/hw/pl110.c +++ b/hw/pl110.c @@ -349,7 +349,8 @@ static uint64_t pl110_read(void *opaque, hwaddr offset, case 12: /* LCDLPCURR */ return s->lpbase; default: - hw_error("pl110_read: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "pl110_read: Bad offset %x\n", (int)offset); return 0; } } @@ -417,7 +418,8 @@ static void pl110_write(void *opaque, hwaddr offset, pl110_update(s); break; default: - hw_error("pl110_write: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "pl110_write: Bad offset %x\n", (int)offset); } } diff --git a/hw/pl190.c b/hw/pl190.c index 213229b566..40199302a9 100644 --- a/hw/pl190.c +++ b/hw/pl190.c @@ -199,7 +199,7 @@ static void pl190_write(void *opaque, hwaddr offset, break; case 0xc0: /* ITCR */ if (val) { - hw_error("pl190: Test mode not implemented\n"); + qemu_log_mask(LOG_UNIMP, "pl190: Test mode not implemented\n"); } break; default: diff --git a/hw/realview.c b/hw/realview.c index b5cb08cb84..e789c159a9 100644 --- a/hw/realview.c +++ b/hw/realview.c @@ -44,11 +44,8 @@ static const int realview_board_id[] = { 0x76d }; -static void realview_init(ram_addr_t ram_size, - const char *boot_device, - const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename, const char *cpu_model, - enum realview_board_type board_type) +static void realview_init(QEMUMachineInitArgs *args, + enum realview_board_type board_type) { ARMCPU *cpu = NULL; CPUARMState *env; @@ -73,6 +70,7 @@ static void realview_init(ram_addr_t ram_size, uint32_t proc_id = 0; uint32_t sys_id; ram_addr_t low_ram_size; + ram_addr_t ram_size = args->ram_size; switch (board_type) { case BOARD_EB: @@ -89,7 +87,7 @@ static void realview_init(ram_addr_t ram_size, break; } for (n = 0; n < smp_cpus; n++) { - cpu = cpu_arm_init(cpu_model); + cpu = cpu_arm_init(args->cpu_model); if (!cpu) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); @@ -321,9 +319,9 @@ static void realview_init(ram_addr_t ram_size, memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack); realview_binfo.ram_size = ram_size; - realview_binfo.kernel_filename = kernel_filename; - realview_binfo.kernel_cmdline = kernel_cmdline; - realview_binfo.initrd_filename = initrd_filename; + realview_binfo.kernel_filename = args->kernel_filename; + realview_binfo.kernel_cmdline = args->kernel_cmdline; + realview_binfo.initrd_filename = args->initrd_filename; realview_binfo.nb_cpus = smp_cpus; realview_binfo.board_id = realview_board_id[board_type]; realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0); @@ -332,62 +330,34 @@ static void realview_init(ram_addr_t ram_size, static void realview_eb_init(QEMUMachineInitArgs *args) { - 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; - const char *boot_device = args->boot_device; - if (!cpu_model) { - cpu_model = "arm926"; + if (!args->cpu_model) { + args->cpu_model = "arm926"; } - realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline, - initrd_filename, cpu_model, BOARD_EB); + realview_init(args, BOARD_EB); } static void realview_eb_mpcore_init(QEMUMachineInitArgs *args) { - 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; - const char *boot_device = args->boot_device; - if (!cpu_model) { - cpu_model = "arm11mpcore"; + if (!args->cpu_model) { + args->cpu_model = "arm11mpcore"; } - realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline, - initrd_filename, cpu_model, BOARD_EB_MPCORE); + realview_init(args, BOARD_EB_MPCORE); } static void realview_pb_a8_init(QEMUMachineInitArgs *args) { - 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; - const char *boot_device = args->boot_device; - if (!cpu_model) { - cpu_model = "cortex-a8"; + if (!args->cpu_model) { + args->cpu_model = "cortex-a8"; } - realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline, - initrd_filename, cpu_model, BOARD_PB_A8); + realview_init(args, BOARD_PB_A8); } static void realview_pbx_a9_init(QEMUMachineInitArgs *args) { - 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; - const char *boot_device = args->boot_device; - if (!cpu_model) { - cpu_model = "cortex-a9"; + if (!args->cpu_model) { + args->cpu_model = "cortex-a9"; } - realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline, - initrd_filename, cpu_model, BOARD_PBX_A9); + realview_init(args, BOARD_PBX_A9); } static QEMUMachine realview_eb_machine = { @@ -55,24 +55,28 @@ typedef enum { sd_illegal = -2, } sd_rsp_type_t; +enum SDCardModes { + sd_inactive, + sd_card_identification_mode, + sd_data_transfer_mode, +}; + +enum SDCardStates { + sd_inactive_state = -1, + sd_idle_state = 0, + sd_ready_state, + sd_identification_state, + sd_standby_state, + sd_transfer_state, + sd_sendingdata_state, + sd_receivingdata_state, + sd_programming_state, + sd_disconnect_state, +}; + struct SDState { - enum { - sd_inactive, - sd_card_identification_mode, - sd_data_transfer_mode, - } mode; - enum { - sd_inactive_state = -1, - sd_idle_state = 0, - sd_ready_state, - sd_identification_state, - sd_standby_state, - sd_transfer_state, - sd_sendingdata_state, - sd_receivingdata_state, - sd_programming_state, - sd_disconnect_state, - } state; + uint32_t mode; /* current card mode, one of SDCardModes */ + int32_t state; /* current card state, one of SDCardStates */ uint32_t ocr; uint8_t scr[8]; uint8_t cid[16]; @@ -83,21 +87,22 @@ struct SDState { uint32_t vhs; bool wp_switch; unsigned long *wp_groups; + int32_t wpgrps_size; uint64_t size; - int blk_len; + uint32_t blk_len; uint32_t erase_start; uint32_t erase_end; uint8_t pwd[16]; - int pwd_len; - int function_group[6]; + uint32_t pwd_len; + uint8_t function_group[6]; bool spi; - int current_cmd; + uint8_t current_cmd; /* True if we will handle the next command as an ACMD. Note that this does * *not* track the APP_CMD status bit! */ bool expecting_acmd; - int blk_written; + uint32_t blk_written; uint64_t data_start; uint32_t data_offset; uint8_t data[512]; @@ -421,8 +426,9 @@ static void sd_reset(SDState *sd, BlockDriverState *bdrv) if (sd->wp_groups) g_free(sd->wp_groups); sd->wp_switch = bdrv ? bdrv_is_read_only(bdrv) : false; - sd->wp_groups = bitmap_new(sect); - memset(sd->function_group, 0, sizeof(int) * 6); + sd->wpgrps_size = sect; + sd->wp_groups = bitmap_new(sd->wpgrps_size); + memset(sd->function_group, 0, sizeof(sd->function_group)); sd->erase_start = 0; sd->erase_end = 0; sd->size = size; @@ -446,6 +452,38 @@ static const BlockDevOps sd_block_ops = { .change_media_cb = sd_cardchange, }; +static const VMStateDescription sd_vmstate = { + .name = "sd-card", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(mode, SDState), + VMSTATE_INT32(state, SDState), + VMSTATE_UINT8_ARRAY(cid, SDState, 16), + VMSTATE_UINT8_ARRAY(csd, SDState, 16), + VMSTATE_UINT16(rca, SDState), + VMSTATE_UINT32(card_status, SDState), + VMSTATE_PARTIAL_BUFFER(sd_status, SDState, 1), + VMSTATE_UINT32(vhs, SDState), + VMSTATE_BITMAP(wp_groups, SDState, 0, wpgrps_size), + VMSTATE_UINT32(blk_len, SDState), + VMSTATE_UINT32(erase_start, SDState), + VMSTATE_UINT32(erase_end, SDState), + VMSTATE_UINT8_ARRAY(pwd, SDState, 16), + VMSTATE_UINT32(pwd_len, SDState), + VMSTATE_UINT8_ARRAY(function_group, SDState, 6), + VMSTATE_UINT8(current_cmd, SDState), + VMSTATE_BOOL(expecting_acmd, SDState), + VMSTATE_UINT32(blk_written, SDState), + VMSTATE_UINT64(data_start, SDState), + VMSTATE_UINT32(data_offset, SDState), + VMSTATE_UINT8_ARRAY(data, SDState, 512), + VMSTATE_BUFFER_UNSAFE(buf, SDState, 1, 512), + VMSTATE_BOOL(enable, SDState), + VMSTATE_END_OF_LIST() + } +}; + /* We do not model the chip select pin, so allow the board to select whether card should be in SSI or MMC/SD mode. It is also up to the board to ensure that ssi transfers only occur when the chip select @@ -463,6 +501,7 @@ SDState *sd_init(BlockDriverState *bs, bool is_spi) bdrv_attach_dev_nofail(sd->bdrv, sd); bdrv_set_dev_ops(sd->bdrv, &sd_block_ops, sd); } + vmstate_register(NULL, -1, &sd_vmstate, sd); return sd; } @@ -476,19 +515,28 @@ void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert) static void sd_erase(SDState *sd) { - int i, start, end; + int i; + uint64_t erase_start = sd->erase_start; + uint64_t erase_end = sd->erase_end; + if (!sd->erase_start || !sd->erase_end) { sd->card_status |= ERASE_SEQ_ERROR; return; } - start = sd_addr_to_wpnum(sd->erase_start); - end = sd_addr_to_wpnum(sd->erase_end); + if (extract32(sd->ocr, OCR_CCS_BITN, 1)) { + /* High capacity memory card: erase units are 512 byte blocks */ + erase_start *= 512; + erase_end *= 512; + } + + erase_start = sd_addr_to_wpnum(erase_start); + erase_end = sd_addr_to_wpnum(erase_end); sd->erase_start = 0; sd->erase_end = 0; sd->csd[14] |= 0x40; - for (i = start; i <= end; i++) { + for (i = erase_start; i <= erase_end; i++) { if (test_bit(i, sd->wp_groups)) { sd->card_status |= WP_ERASE_SKIP; } @@ -567,7 +615,7 @@ static void sd_lock_command(SDState *sd) sd->card_status |= LOCK_UNLOCK_FAILED; return; } - bitmap_zero(sd->wp_groups, sd_addr_to_wpnum(sd->size) + 1); + bitmap_zero(sd->wp_groups, sd->wpgrps_size); sd->csd[14] &= ~0x10; sd->card_status &= ~CARD_IS_LOCKED; sd->pwd_len = 0; @@ -50,6 +50,7 @@ #define READY_FOR_DATA (1 << 8) #define APP_CMD (1 << 5) #define AKE_SEQ_ERROR (1 << 3) +#define OCR_CCS_BITN 30 typedef enum { sd_none = -1, diff --git a/hw/spitz.c b/hw/spitz.c index 944c274a82..12e2815221 100644 --- a/hw/spitz.c +++ b/hw/spitz.c @@ -879,15 +879,14 @@ static struct arm_boot_info spitz_binfo = { .ram_size = 0x04000000, }; -static void spitz_common_init(ram_addr_t ram_size, - const char *kernel_filename, - const char *kernel_cmdline, const char *initrd_filename, - const char *cpu_model, enum spitz_model_e model, int arm_id) +static void spitz_common_init(QEMUMachineInitArgs *args, + enum spitz_model_e model, int arm_id) { PXA2xxState *mpu; DeviceState *scp0, *scp1 = NULL; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *rom = g_new(MemoryRegion, 1); + const char *cpu_model = args->cpu_model; if (!cpu_model) cpu_model = (model == terrier) ? "pxa270-c5" : "pxa270-c0"; @@ -928,9 +927,9 @@ static void spitz_common_init(ram_addr_t ram_size, /* A 4.0 GB microdrive is permanently sitting in CF slot 0. */ spitz_microdrive_attach(mpu, 0); - spitz_binfo.kernel_filename = kernel_filename; - spitz_binfo.kernel_cmdline = kernel_cmdline; - spitz_binfo.initrd_filename = initrd_filename; + spitz_binfo.kernel_filename = args->kernel_filename; + spitz_binfo.kernel_cmdline = args->kernel_cmdline; + spitz_binfo.initrd_filename = args->initrd_filename; spitz_binfo.board_id = arm_id; arm_load_kernel(mpu->cpu, &spitz_binfo); sl_bootparam_write(SL_PXA_PARAM_BASE); @@ -938,46 +937,22 @@ static void spitz_common_init(ram_addr_t ram_size, static void spitz_init(QEMUMachineInitArgs *args) { - 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; - spitz_common_init(ram_size, kernel_filename, - kernel_cmdline, initrd_filename, cpu_model, spitz, 0x2c9); + spitz_common_init(args, spitz, 0x2c9); } static void borzoi_init(QEMUMachineInitArgs *args) { - 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; - spitz_common_init(ram_size, kernel_filename, - kernel_cmdline, initrd_filename, cpu_model, borzoi, 0x33f); + spitz_common_init(args, borzoi, 0x33f); } static void akita_init(QEMUMachineInitArgs *args) { - 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; - spitz_common_init(ram_size, kernel_filename, - kernel_cmdline, initrd_filename, cpu_model, akita, 0x2e8); + spitz_common_init(args, akita, 0x2e8); } static void terrier_init(QEMUMachineInitArgs *args) { - 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; - spitz_common_init(ram_size, kernel_filename, - kernel_cmdline, initrd_filename, cpu_model, terrier, 0x33f); + spitz_common_init(args, terrier, 0x33f); } static QEMUMachine akitapda_machine = { diff --git a/hw/versatile_i2c.c b/hw/versatile_i2c.c index 44e7e40f2f..ad71e9d92d 100644 --- a/hw/versatile_i2c.c +++ b/hw/versatile_i2c.c @@ -40,7 +40,8 @@ static uint64_t versatile_i2c_read(void *opaque, hwaddr offset, if (offset == 0) { return (s->out & 1) | (s->in << 1); } else { - hw_error("%s: Bad offset 0x%x\n", __func__, (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad offset 0x%x\n", __func__, (int)offset); return -1; } } @@ -58,7 +59,8 @@ static void versatile_i2c_write(void *opaque, hwaddr offset, s->out &= ~value; break; default: - hw_error("%s: Bad offset 0x%x\n", __func__, (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad offset 0x%x\n", __func__, (int)offset); } bitbang_i2c_set(s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0); s->in = bitbang_i2c_set(s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0); diff --git a/hw/versatilepb.c b/hw/versatilepb.c index e85f982897..25e652b1aa 100644 --- a/hw/versatilepb.c +++ b/hw/versatilepb.c @@ -167,11 +167,7 @@ static int vpb_sic_init(SysBusDevice *dev) static struct arm_boot_info versatile_binfo; -static void versatile_init(ram_addr_t ram_size, - const char *boot_device, - const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename, const char *cpu_model, - int board_id) +static void versatile_init(QEMUMachineInitArgs *args, int board_id) { ARMCPU *cpu; MemoryRegion *sysmem = get_system_memory(); @@ -189,15 +185,15 @@ static void versatile_init(ram_addr_t ram_size, int done_smc = 0; DriveInfo *dinfo; - if (!cpu_model) { - cpu_model = "arm926"; + if (!args->cpu_model) { + args->cpu_model = "arm926"; } - cpu = cpu_arm_init(cpu_model); + cpu = cpu_arm_init(args->cpu_model); if (!cpu) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } - memory_region_init_ram(ram, "versatile.ram", ram_size); + memory_region_init_ram(ram, "versatile.ram", args->ram_size); vmstate_register_ram_global(ram); /* ??? RAM should repeat to fill physical memory space. */ /* SDRAM at address zero. */ @@ -340,40 +336,22 @@ static void versatile_init(ram_addr_t ram_size, fprintf(stderr, "qemu: Error registering flash memory.\n"); } - 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.ram_size = args->ram_size; + versatile_binfo.kernel_filename = args->kernel_filename; + versatile_binfo.kernel_cmdline = args->kernel_cmdline; + versatile_binfo.initrd_filename = args->initrd_filename; versatile_binfo.board_id = board_id; arm_load_kernel(cpu, &versatile_binfo); } static void vpb_init(QEMUMachineInitArgs *args) { - 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; - const char *boot_device = args->boot_device; - versatile_init(ram_size, - boot_device, - kernel_filename, kernel_cmdline, - initrd_filename, cpu_model, 0x183); + versatile_init(args, 0x183); } static void vab_init(QEMUMachineInitArgs *args) { - 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; - const char *boot_device = args->boot_device; - versatile_init(ram_size, - boot_device, - kernel_filename, kernel_cmdline, - initrd_filename, cpu_model, 0x25e); + versatile_init(args, 0x25e); } static QEMUMachine versatilepb_machine = { diff --git a/hw/vexpress.c b/hw/vexpress.c index 3f7cb66a6b..d93f057bff 100644 --- a/hw/vexpress.c +++ b/hw/vexpress.c @@ -348,12 +348,7 @@ static const VEDBoardInfo a15_daughterboard = { }; static void vexpress_common_init(const VEDBoardInfo *daughterboard, - ram_addr_t ram_size, - const char *boot_device, - const char *kernel_filename, - const char *kernel_cmdline, - const char *initrd_filename, - const char *cpu_model) + QEMUMachineInitArgs *args) { DeviceState *dev, *sysctl, *pl041; qemu_irq pic[64]; @@ -366,7 +361,8 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard, MemoryRegion *sram = g_new(MemoryRegion, 1); const hwaddr *map = daughterboard->motherboard_map; - daughterboard->init(daughterboard, ram_size, cpu_model, pic, &proc_id); + daughterboard->init(daughterboard, args->ram_size, args->cpu_model, + pic, &proc_id); /* Motherboard peripherals: the wiring is the same but the * addresses vary between the legacy and A-Series memory maps. @@ -454,10 +450,10 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard, /* VE_DAPROM: not modelled */ - vexpress_binfo.ram_size = ram_size; - vexpress_binfo.kernel_filename = kernel_filename; - vexpress_binfo.kernel_cmdline = kernel_cmdline; - vexpress_binfo.initrd_filename = initrd_filename; + vexpress_binfo.ram_size = args->ram_size; + vexpress_binfo.kernel_filename = args->kernel_filename; + vexpress_binfo.kernel_cmdline = args->kernel_cmdline; + vexpress_binfo.initrd_filename = args->initrd_filename; vexpress_binfo.nb_cpus = smp_cpus; vexpress_binfo.board_id = VEXPRESS_BOARD_ID; vexpress_binfo.loader_start = daughterboard->loader_start; @@ -469,28 +465,12 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard, static void vexpress_a9_init(QEMUMachineInitArgs *args) { - 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; - const char *boot_device = args->boot_device; - vexpress_common_init(&a9_daughterboard, - ram_size, boot_device, kernel_filename, - kernel_cmdline, initrd_filename, cpu_model); + vexpress_common_init(&a9_daughterboard, args); } static void vexpress_a15_init(QEMUMachineInitArgs *args) { - 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; - const char *boot_device = args->boot_device; - vexpress_common_init(&a15_daughterboard, - ram_size, boot_device, kernel_filename, - kernel_cmdline, initrd_filename, cpu_model); + vexpress_common_init(&a15_daughterboard, args); } static QEMUMachine vexpress_a9_machine = { |