summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-03-12 11:12:36 +0000
committerPeter Maydell <peter.maydell@linaro.org>2019-03-12 11:12:36 +0000
commiteda1df0345f5a1e337e30367124dcb0e802bdfde (patch)
treecf157ff5e5082285cbc924076b4c2837cb91001e /hw
parentbc76b7148993269608c19fd3f2fc6ed3e22bf838 (diff)
parente33763be7cd3769c9ae48e67d775348863fdabdb (diff)
downloadqemu-eda1df0345f5a1e337e30367124dcb0e802bdfde.zip
Merge remote-tracking branch 'remotes/armbru/tags/pull-pflash-2019-03-11' into staging
Pflash and firmware configuration patches for 2019-03-11 # gpg: Signature made Mon 11 Mar 2019 21:59:12 GMT # gpg: using RSA key 3870B400EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full] # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full] # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-pflash-2019-03-11: (27 commits) docs/interop/firmware.json: Prefer -machine to if=pflash pc: Support firmware configuration with -blockdev pc_sysfw: Pass PCMachineState to pc_system_firmware_init() pc_sysfw: Remove unused PcSysFwDevice pflash_cfi01: Add pflash_cfi01_get_blk() helper vl: Create block backends before setting machine properties vl: Factor configure_blockdev() out of main() vl: Improve legibility of BlockdevOptions queue sysbus: Fix latent bug with onboard devices vl: Fix latent bug with -global and onboard devices qom: Move compat_props machinery from qdev to QOM qdev: Fix latent bug with compat_props and onboard devices pflash: Clean up after commit 368a354f02b, part 2 pflash: Clean up after commit 368a354f02b, part 1 mips_malta: Clean up definition of flash memory size somewhat hw/mips/malta: Restrict 'bios_size' variable scope hw/mips/malta: Remove fl_sectors variable mips_malta: Delete disabled, broken DEBUG_BOARD_INIT code r2d: Fix flash memory size, sector size, width, device ID ppc405_boards: Don't size flash memory to match backing image ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/collie.c9
-rw-r--r--hw/arm/digic_boards.c3
-rw-r--r--hw/arm/gumstix.c10
-rw-r--r--hw/arm/mainstone.c5
-rw-r--r--hw/arm/musicpal.c8
-rw-r--r--hw/arm/omap_sx1.c10
-rw-r--r--hw/arm/versatilepb.c3
-rw-r--r--hw/arm/vexpress.c10
-rw-r--r--hw/arm/virt.c3
-rw-r--r--hw/arm/xilinx_zynq.c7
-rw-r--r--hw/arm/z2.c6
-rw-r--r--hw/block/pflash_cfi01.c128
-rw-r--r--hw/block/pflash_cfi02.c81
-rw-r--r--hw/core/qdev.c21
-rw-r--r--hw/core/sysbus.c3
-rw-r--r--hw/i386/pc.c4
-rw-r--r--hw/i386/pc_sysfw.c245
-rw-r--r--hw/lm32/lm32_boards.c8
-rw-r--r--hw/lm32/milkymist.c5
-rw-r--r--hw/microblaze/petalogix_ml605_mmu.c6
-rw-r--r--hw/microblaze/petalogix_s3adsp1800_mmu.c5
-rw-r--r--hw/mips/mips_malta.c21
-rw-r--r--hw/mips/mips_r4k.c5
-rw-r--r--hw/ppc/ppc405_boards.c102
-rw-r--r--hw/ppc/sam460ex.c42
-rw-r--r--hw/ppc/virtex_ml507.c5
-rw-r--r--hw/sh4/r2d.c17
-rw-r--r--hw/xtensa/xtfpga.c12
28 files changed, 385 insertions, 399 deletions
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
index 3ca4e078fe..d12604c573 100644
--- a/hw/arm/collie.c
+++ b/hw/arm/collie.c
@@ -9,6 +9,7 @@
* GNU GPL, version 2 or (at your option) any later version.
*/
#include "qemu/osdep.h"
+#include "qemu/units.h"
#include "hw/hw.h"
#include "hw/sysbus.h"
#include "hw/boards.h"
@@ -35,14 +36,14 @@ static void collie_init(MachineState *machine)
s = sa1110_init(sysmem, collie_binfo.ram_size, machine->cpu_type);
dinfo = drive_get(IF_PFLASH, 0, 0);
- pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x02000000,
+ pflash_cfi01_register(SA_CS0, "collie.fl1", 0x02000000,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+ 64 * KiB, 4, 0x00, 0x00, 0x00, 0x00, 0);
dinfo = drive_get(IF_PFLASH, 0, 1);
- pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x02000000,
+ pflash_cfi01_register(SA_CS1, "collie.fl2", 0x02000000,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+ 64 * KiB, 4, 0x00, 0x00, 0x00, 0x00, 0);
sysbus_create_simple("scoop", 0x40800000, NULL);
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
index 9f11dcd11f..304e4d1a29 100644
--- a/hw/arm/digic_boards.c
+++ b/hw/arm/digic_boards.c
@@ -129,9 +129,8 @@ static void digic4_add_k8p3215uqb_rom(DigicBoardState *s, hwaddr addr,
#define FLASH_K8P3215UQB_SIZE (4 * 1024 * 1024)
#define FLASH_K8P3215UQB_SECTOR_SIZE (64 * 1024)
- pflash_cfi02_register(addr, NULL, "pflash", FLASH_K8P3215UQB_SIZE,
+ pflash_cfi02_register(addr, "pflash", FLASH_K8P3215UQB_SIZE,
NULL, FLASH_K8P3215UQB_SECTOR_SIZE,
- FLASH_K8P3215UQB_SIZE / FLASH_K8P3215UQB_SECTOR_SIZE,
DIGIC4_ROM_MAX_SIZE / FLASH_K8P3215UQB_SIZE,
4,
0x00EC, 0x007E, 0x0003, 0x0001,
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
index 56cb763c4e..79886ce378 100644
--- a/hw/arm/gumstix.c
+++ b/hw/arm/gumstix.c
@@ -72,10 +72,9 @@ static void connex_init(MachineState *machine)
#else
be = 0;
#endif
- if (!pflash_cfi01_register(0x00000000, NULL, "connext.rom", connex_rom,
+ if (!pflash_cfi01_register(0x00000000, "connext.rom", connex_rom,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- sector_len, connex_rom / sector_len,
- 2, 0, 0, 0, 0, be)) {
+ sector_len, 2, 0, 0, 0, 0, be)) {
error_report("Error registering flash memory");
exit(1);
}
@@ -109,10 +108,9 @@ static void verdex_init(MachineState *machine)
#else
be = 0;
#endif
- if (!pflash_cfi01_register(0x00000000, NULL, "verdex.rom", verdex_rom,
+ if (!pflash_cfi01_register(0x00000000, "verdex.rom", verdex_rom,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- sector_len, verdex_rom / sector_len,
- 2, 0, 0, 0, 0, be)) {
+ sector_len, 2, 0, 0, 0, 0, be)) {
error_report("Error registering flash memory");
exit(1);
}
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index 0beb5c426b..e96738ad26 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -148,12 +148,11 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
exit(1);
}
- if (!pflash_cfi01_register(mainstone_flash_base[i], NULL,
+ if (!pflash_cfi01_register(mainstone_flash_base[i],
i ? "mainstone.flash1" : "mainstone.flash0",
MAINSTONE_FLASH,
blk_by_legacy_dinfo(dinfo),
- sector_len, MAINSTONE_FLASH / sector_len,
- 4, 0, 0, 0, 0, be)) {
+ sector_len, 4, 0, 0, 0, 0, be)) {
error_report("Error registering flash memory");
exit(1);
}
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index de4a12e496..93ec3c5698 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -1635,16 +1635,16 @@ static void musicpal_init(MachineState *machine)
* image is smaller than 32 MB.
*/
#ifdef TARGET_WORDS_BIGENDIAN
- pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
+ pflash_cfi02_register(0x100000000ULL - MP_FLASH_SIZE_MAX,
"musicpal.flash", flash_size,
- blk, 0x10000, (flash_size + 0xffff) >> 16,
+ blk, 0x10000,
MP_FLASH_SIZE_MAX / flash_size,
2, 0x00BF, 0x236D, 0x0000, 0x0000,
0x5555, 0x2AAA, 1);
#else
- pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
+ pflash_cfi02_register(0x100000000ULL - MP_FLASH_SIZE_MAX,
"musicpal.flash", flash_size,
- blk, 0x10000, (flash_size + 0xffff) >> 16,
+ blk, 0x10000,
MP_FLASH_SIZE_MAX / flash_size,
2, 0x00BF, 0x236D, 0x0000, 0x0000,
0x5555, 0x2AAA, 0);
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index 84550f0236..95a4fe7e7f 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -152,11 +152,10 @@ static void sx1_init(MachineState *machine, const int version)
#endif
if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
- if (!pflash_cfi01_register(OMAP_CS0_BASE, NULL,
+ if (!pflash_cfi01_register(OMAP_CS0_BASE,
"omap_sx1.flash0-1", flash_size,
blk_by_legacy_dinfo(dinfo),
- sector_size, flash_size / sector_size,
- 4, 0, 0, 0, 0, be)) {
+ sector_size, 4, 0, 0, 0, 0, be)) {
fprintf(stderr, "qemu: Error registering flash memory %d.\n",
fl_idx);
}
@@ -176,11 +175,10 @@ static void sx1_init(MachineState *machine, const int version)
memory_region_add_subregion(address_space,
OMAP_CS1_BASE + flash1_size, &cs[1]);
- if (!pflash_cfi01_register(OMAP_CS1_BASE, NULL,
+ if (!pflash_cfi01_register(OMAP_CS1_BASE,
"omap_sx1.flash1-1", flash1_size,
blk_by_legacy_dinfo(dinfo),
- sector_size, flash1_size / sector_size,
- 4, 0, 0, 0, 0, be)) {
+ sector_size, 4, 0, 0, 0, 0, be)) {
fprintf(stderr, "qemu: Error registering flash memory %d.\n",
fl_idx);
}
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index 22b09a1e61..d67181810a 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -365,11 +365,10 @@ static void versatile_init(MachineState *machine, int board_id)
/* 0x34000000 NOR Flash */
dinfo = drive_get(IF_PFLASH, 0, 0);
- if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, NULL, "versatile.flash",
+ if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, "versatile.flash",
VERSATILE_FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
VERSATILE_FLASH_SECT_SIZE,
- VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE,
4, 0x0089, 0x0018, 0x0000, 0x0, 0)) {
fprintf(stderr, "qemu: Error registering flash memory.\n");
}
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index c02d18ee61..f07134c424 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -512,10 +512,10 @@ static void vexpress_modify_dtb(const struct arm_boot_info *info, void *fdt)
/* Open code a private version of pflash registration since we
* need to set non-default device width for VExpress platform.
*/
-static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,
- DriveInfo *di)
+static PFlashCFI01 *ve_pflash_cfi01_register(hwaddr base, const char *name,
+ DriveInfo *di)
{
- DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
+ DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
if (di) {
qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(di),
@@ -536,7 +536,7 @@ static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- return OBJECT_CHECK(pflash_t, (dev), "cfi.pflash01");
+ return PFLASH_CFI01(dev);
}
static void vexpress_common_init(MachineState *machine)
@@ -548,7 +548,7 @@ static void vexpress_common_init(MachineState *machine)
qemu_irq pic[64];
uint32_t sys_id;
DriveInfo *dinfo;
- pflash_t *pflash0;
+ PFlashCFI01 *pflash0;
I2CBus *i2c;
ram_addr_t vram_size, sram_size;
MemoryRegion *sysmem = get_system_memory();
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 7f66ddad89..1e8485ff7c 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -35,6 +35,7 @@
#include "hw/arm/arm.h"
#include "hw/arm/primecell.h"
#include "hw/arm/virt.h"
+#include "hw/block/flash.h"
#include "hw/vfio/vfio-calxeda-xgmac.h"
#include "hw/vfio/vfio-amd-xgbe.h"
#include "hw/display/ramfb.h"
@@ -878,7 +879,7 @@ static void create_one_flash(const char *name, hwaddr flashbase,
* parameters as the flash devices on the Versatile Express board.
*/
DriveInfo *dinfo = drive_get_next(IF_PFLASH);
- DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
+ DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
const uint64_t sectorlength = 256 * 1024;
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 57497b0c4d..b3b8215759 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -205,12 +205,11 @@ static void zynq_init(MachineState *machine)
DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0);
/* AMD */
- pflash_cfi02_register(0xe2000000, NULL, "zynq.pflash", FLASH_SIZE,
+ pflash_cfi02_register(0xe2000000, "zynq.pflash", FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- FLASH_SECTOR_SIZE,
- FLASH_SIZE/FLASH_SECTOR_SIZE, 1,
+ FLASH_SECTOR_SIZE, 1,
1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa,
- 0);
+ 0);
dev = qdev_create(NULL, "xilinx,zynq_slcr");
qdev_init_nofail(dev);
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 3b75d4b39d..1f906ef20b 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -323,11 +323,9 @@ static void z2_init(MachineState *machine)
exit(1);
}
- if (!pflash_cfi01_register(Z2_FLASH_BASE,
- NULL, "z2.flash0", Z2_FLASH_SIZE,
+ if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- sector_len, Z2_FLASH_SIZE / sector_len,
- 4, 0, 0, 0, 0, be)) {
+ sector_len, 4, 0, 0, 0, 0, be)) {
error_report("Error registering flash memory");
exit(1);
}
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index bffb4c40e7..125f70b8e4 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -49,12 +49,6 @@
#include "sysemu/sysemu.h"
#include "trace.h"
-#define PFLASH_BUG(fmt, ...) \
-do { \
- fprintf(stderr, "PFLASH: Possible BUG - " fmt, ## __VA_ARGS__); \
- exit(1); \
-} while(0)
-
/* #define PFLASH_DEBUG */
#ifdef PFLASH_DEBUG
#define DPRINTF(fmt, ...) \
@@ -65,12 +59,10 @@ do { \
#define DPRINTF(fmt, ...) do { } while (0)
#endif
-#define CFI_PFLASH01(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH01)
-
#define PFLASH_BE 0
#define PFLASH_SECURE 1
-struct pflash_t {
+struct PFlashCFI01 {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
@@ -109,17 +101,17 @@ static const VMStateDescription vmstate_pflash = {
.minimum_version_id = 1,
.post_load = pflash_post_load,
.fields = (VMStateField[]) {
- VMSTATE_UINT8(wcycle, pflash_t),
- VMSTATE_UINT8(cmd, pflash_t),
- VMSTATE_UINT8(status, pflash_t),
- VMSTATE_UINT64(counter, pflash_t),
+ VMSTATE_UINT8(wcycle, PFlashCFI01),
+ VMSTATE_UINT8(cmd, PFlashCFI01),
+ VMSTATE_UINT8(status, PFlashCFI01),
+ VMSTATE_UINT64(counter, PFlashCFI01),
VMSTATE_END_OF_LIST()
}
};
static void pflash_timer (void *opaque)
{
- pflash_t *pfl = opaque;
+ PFlashCFI01 *pfl = opaque;
trace_pflash_timer_expired(pfl->cmd);
/* Reset flash */
@@ -133,7 +125,7 @@ static void pflash_timer (void *opaque)
* If this code is called we know we have a device_width set for
* this flash.
*/
-static uint32_t pflash_cfi_query(pflash_t *pfl, hwaddr offset)
+static uint32_t pflash_cfi_query(PFlashCFI01 *pfl, hwaddr offset)
{
int i;
uint32_t resp = 0;
@@ -193,7 +185,7 @@ static uint32_t pflash_cfi_query(pflash_t *pfl, hwaddr offset)
/* Perform a device id query based on the bank width of the flash. */
-static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset)
+static uint32_t pflash_devid_query(PFlashCFI01 *pfl, hwaddr offset)
{
int i;
uint32_t resp;
@@ -241,7 +233,7 @@ static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset)
return resp;
}
-static uint32_t pflash_data_read(pflash_t *pfl, hwaddr offset,
+static uint32_t pflash_data_read(PFlashCFI01 *pfl, hwaddr offset,
int width, int be)
{
uint8_t *p;
@@ -284,8 +276,8 @@ static uint32_t pflash_data_read(pflash_t *pfl, hwaddr offset,
return ret;
}
-static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
- int width, int be)
+static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr offset,
+ int width, int be)
{
hwaddr boff;
uint32_t ret;
@@ -398,7 +390,7 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
}
/* update flash content on disk */
-static void pflash_update(pflash_t *pfl, int offset,
+static void pflash_update(PFlashCFI01 *pfl, int offset,
int size)
{
int offset_end;
@@ -412,7 +404,7 @@ static void pflash_update(pflash_t *pfl, int offset,
}
}
-static inline void pflash_data_write(pflash_t *pfl, hwaddr offset,
+static inline void pflash_data_write(PFlashCFI01 *pfl, hwaddr offset,
uint32_t value, int width, int be)
{
uint8_t *p = pfl->storage;
@@ -448,7 +440,7 @@ static inline void pflash_data_write(pflash_t *pfl, hwaddr offset,
}
-static void pflash_write(pflash_t *pfl, hwaddr offset,
+static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
uint32_t value, int width, int be)
{
uint8_t *p;
@@ -507,6 +499,10 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
break;
case 0xe8: /* Write to buffer */
DPRINTF("%s: Write to buffer\n", __func__);
+ /* FIXME should save @offset, @width for case 1+ */
+ qemu_log_mask(LOG_UNIMP,
+ "%s: Write to buffer emulation is flawed\n",
+ __func__);
pfl->status |= 0x80; /* Ready! */
break;
case 0xf0: /* Probe for AMD flash */
@@ -550,6 +546,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
/* Mask writeblock size based on device width, or bank width if
* device width not specified.
*/
+ /* FIXME check @offset, @width */
if (pfl->device_width) {
value = extract32(value, 0, pfl->device_width * 8);
} else {
@@ -587,7 +584,13 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
case 2:
switch (pfl->cmd) {
case 0xe8: /* Block write */
+ /* FIXME check @offset, @width */
if (!pfl->ro) {
+ /*
+ * FIXME writing straight to memory is *wrong*. We
+ * should write to a buffer, and flush it to memory
+ * only on confirm command (see below).
+ */
pflash_data_write(pfl, offset, value, width, be);
} else {
pfl->status |= 0x10; /* Programming error */
@@ -603,6 +606,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
pfl->wcycle++;
if (!pfl->ro) {
/* Flush the entire write buffer onto backing storage. */
+ /* FIXME premature! */
pflash_update(pfl, offset & mask, pfl->writeblock_size);
} else {
pfl->status |= 0x10; /* Programming error */
@@ -619,11 +623,15 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
switch (pfl->cmd) {
case 0xe8: /* Block write */
if (cmd == 0xd0) {
+ /* FIXME this is where we should write out the buffer */
pfl->wcycle = 0;
pfl->status |= 0x80;
} else {
- DPRINTF("%s: unknown command for \"write block\"\n", __func__);
- PFLASH_BUG("Write block confirm");
+ qemu_log_mask(LOG_UNIMP,
+ "%s: Aborting write to buffer not implemented,"
+ " the data is already written to storage!\n"
+ "Flash device reset into READ mode.\n",
+ __func__);
goto reset_flash;
}
break;
@@ -654,7 +662,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
static MemTxResult pflash_mem_read_with_attrs(void *opaque, hwaddr addr, uint64_t *value,
unsigned len, MemTxAttrs attrs)
{
- pflash_t *pfl = opaque;
+ PFlashCFI01 *pfl = opaque;
bool be = !!(pfl->features & (1 << PFLASH_BE));
if ((pfl->features & (1 << PFLASH_SECURE)) && !attrs.secure) {
@@ -668,7 +676,7 @@ static MemTxResult pflash_mem_read_with_attrs(void *opaque, hwaddr addr, uint64_
static MemTxResult pflash_mem_write_with_attrs(void *opaque, hwaddr addr, uint64_t value,
unsigned len, MemTxAttrs attrs)
{
- pflash_t *pfl = opaque;
+ PFlashCFI01 *pfl = opaque;
bool be = !!(pfl->features & (1 << PFLASH_BE));
if ((pfl->features & (1 << PFLASH_SECURE)) && !attrs.secure) {
@@ -687,7 +695,7 @@ static const MemoryRegionOps pflash_cfi01_ops = {
static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
{
- pflash_t *pfl = CFI_PFLASH01(dev);
+ PFlashCFI01 *pfl = PFLASH_CFI01(dev);
uint64_t total_len;
int ret;
uint64_t blocks_per_device, sector_len_per_device, device_len;
@@ -864,14 +872,14 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
}
static Property pflash_cfi01_properties[] = {
- DEFINE_PROP_DRIVE("drive", struct pflash_t, blk),
+ DEFINE_PROP_DRIVE("drive", PFlashCFI01, blk),
/* num-blocks is the number of blocks actually visible to the guest,
* ie the total size of the device divided by the sector length.
* If we're emulating flash devices wired in parallel the actual
* number of blocks per indvidual device will differ.
*/
- DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0),
- DEFINE_PROP_UINT64("sector-length", struct pflash_t, sector_len, 0),
+ DEFINE_PROP_UINT32("num-blocks", PFlashCFI01, nb_blocs, 0),
+ DEFINE_PROP_UINT64("sector-length", PFlashCFI01, sector_len, 0),
/* width here is the overall width of this QEMU device in bytes.
* The QEMU device may be emulating a number of flash devices
* wired up in parallel; the width of each individual flash
@@ -888,17 +896,17 @@ static Property pflash_cfi01_properties[] = {
* 16 bit devices making up a 32 bit wide QEMU device. This
* is deprecated for new uses of this device.
*/
- DEFINE_PROP_UINT8("width", struct pflash_t, bank_width, 0),
- DEFINE_PROP_UINT8("device-width", struct pflash_t, device_width, 0),
- DEFINE_PROP_UINT8("max-device-width", struct pflash_t, max_device_width, 0),
- DEFINE_PROP_BIT("big-endian", struct pflash_t, features, PFLASH_BE, 0),
- DEFINE_PROP_BIT("secure", struct pflash_t, features, PFLASH_SECURE, 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_BOOL("old-multiple-chip-handling", struct pflash_t,
+ DEFINE_PROP_UINT8("width", PFlashCFI01, bank_width, 0),
+ DEFINE_PROP_UINT8("device-width", PFlashCFI01, device_width, 0),
+ DEFINE_PROP_UINT8("max-device-width", PFlashCFI01, max_device_width, 0),
+ DEFINE_PROP_BIT("big-endian", PFlashCFI01, features, PFLASH_BE, 0),
+ DEFINE_PROP_BIT("secure", PFlashCFI01, features, PFLASH_SECURE, 0),
+ DEFINE_PROP_UINT16("id0", PFlashCFI01, ident0, 0),
+ DEFINE_PROP_UINT16("id1", PFlashCFI01, ident1, 0),
+ DEFINE_PROP_UINT16("id2", PFlashCFI01, ident2, 0),
+ DEFINE_PROP_UINT16("id3", PFlashCFI01, ident3, 0),
+ DEFINE_PROP_STRING("name", PFlashCFI01, name),
+ DEFINE_PROP_BOOL("old-multiple-chip-handling", PFlashCFI01,
old_multiple_chip_handling, false),
DEFINE_PROP_END_OF_LIST(),
};
@@ -915,9 +923,9 @@ static void pflash_cfi01_class_init(ObjectClass *klass, void *data)
static const TypeInfo pflash_cfi01_info = {
- .name = TYPE_CFI_PFLASH01,
+ .name = TYPE_PFLASH_CFI01,
.parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(struct pflash_t),
+ .instance_size = sizeof(PFlashCFI01),
.class_init = pflash_cfi01_class_init,
};
@@ -928,20 +936,23 @@ static void pflash_cfi01_register_types(void)
type_init(pflash_cfi01_register_types)
-pflash_t *pflash_cfi01_register(hwaddr base,
- DeviceState *qdev, const char *name,
- hwaddr size,
- BlockBackend *blk,
- uint32_t sector_len, int nb_blocs,
- int bank_width, uint16_t id0, uint16_t id1,
- uint16_t id2, uint16_t id3, int be)
+PFlashCFI01 *pflash_cfi01_register(hwaddr base,
+ const char *name,
+ hwaddr size,
+ BlockBackend *blk,
+ uint32_t sector_len,
+ int bank_width,
+ uint16_t id0, uint16_t id1,
+ uint16_t id2, uint16_t id3,
+ int be)
{
- DeviceState *dev = qdev_create(NULL, TYPE_CFI_PFLASH01);
+ DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
if (blk) {
qdev_prop_set_drive(dev, "drive", blk, &error_abort);
}
- qdev_prop_set_uint32(dev, "num-blocks", nb_blocs);
+ assert(size % sector_len == 0);
+ qdev_prop_set_uint32(dev, "num-blocks", size / sector_len);
qdev_prop_set_uint64(dev, "sector-length", sector_len);
qdev_prop_set_uint8(dev, "width", bank_width);
qdev_prop_set_bit(dev, "big-endian", !!be);
@@ -953,17 +964,22 @@ pflash_t *pflash_cfi01_register(hwaddr base,
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- return CFI_PFLASH01(dev);
+ return PFLASH_CFI01(dev);
+}
+
+BlockBackend *pflash_cfi01_get_blk(PFlashCFI01 *fl)
+{
+ return fl->blk;
}
-MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl)
+MemoryRegion *pflash_cfi01_get_memory(PFlashCFI01 *fl)
{
return &fl->mem;
}
static void postload_update_cb(void *opaque, int running, RunState state)
{
- pflash_t *pfl = opaque;
+ PFlashCFI01 *pfl = opaque;
/* This is called after bdrv_invalidate_cache_all. */
qemu_del_vm_change_state_handler(pfl->vmstate);
@@ -975,7 +991,7 @@ static void postload_update_cb(void *opaque, int running, RunState state)
static int pflash_post_load(void *opaque, int version_id)
{
- pflash_t *pfl = opaque;
+ PFlashCFI01 *pfl = opaque;
if (!pfl->ro) {
pfl->vmstate = qemu_add_vm_change_state_handler(postload_update_cb,
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 1588aeff5a..c9db430611 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -57,9 +57,7 @@ do { \
#define PFLASH_LAZY_ROMD_THRESHOLD 42
-#define CFI_PFLASH02(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH02)
-
-struct pflash_t {
+struct PFlashCFI02 {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
@@ -101,7 +99,7 @@ struct pflash_t {
/*
* Set up replicated mappings of the same region.
*/
-static void pflash_setup_mappings(pflash_t *pfl)
+static void pflash_setup_mappings(PFlashCFI02 *pfl)
{
unsigned i;
hwaddr size = memory_region_size(&pfl->orig_mem);
@@ -115,7 +113,7 @@ static void pflash_setup_mappings(pflash_t *pfl)
}
}
-static void pflash_register_memory(pflash_t *pfl, int rom_mode)
+static void pflash_register_memory(PFlashCFI02 *pfl, int rom_mode)
{
memory_region_rom_device_set_romd(&pfl->orig_mem, rom_mode);
pfl->rom_mode = rom_mode;
@@ -123,7 +121,7 @@ static void pflash_register_memory(pflash_t *pfl, int rom_mode)
static void pflash_timer (void *opaque)
{
- pflash_t *pfl = opaque;
+ PFlashCFI02 *pfl = opaque;
trace_pflash_timer_expired(pfl->cmd);
/* Reset flash */
@@ -137,8 +135,8 @@ static void pflash_timer (void *opaque)
pfl->cmd = 0;
}
-static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
- int width, int be)
+static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr offset,
+ int width, int be)
{
hwaddr boff;
uint32_t ret;
@@ -246,7 +244,7 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
}
/* update flash content on disk */
-static void pflash_update(pflash_t *pfl, int offset,
+static void pflash_update(PFlashCFI02 *pfl, int offset,
int size)
{
int offset_end;
@@ -260,8 +258,8 @@ static void pflash_update(pflash_t *pfl, int offset,
}
}
-static void pflash_write (pflash_t *pfl, hwaddr offset,
- uint32_t value, int width, int be)
+static void pflash_write(PFlashCFI02 *pfl, hwaddr offset,
+ uint32_t value, int width, int be)
{
hwaddr boff;
uint8_t *p;
@@ -533,7 +531,7 @@ static const MemoryRegionOps pflash_cfi02_ops_le = {
static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
{
- pflash_t *pfl = CFI_PFLASH02(dev);
+ PFlashCFI02 *pfl = PFLASH_CFI02(dev);
uint32_t chip_len;
int ret;
Error *local_err = NULL;
@@ -679,25 +677,25 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
}
static Property pflash_cfi02_properties[] = {
- DEFINE_PROP_DRIVE("drive", struct pflash_t, blk),
- 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_DRIVE("drive", PFlashCFI02, blk),
+ DEFINE_PROP_UINT32("num-blocks", PFlashCFI02, nb_blocs, 0),
+ DEFINE_PROP_UINT32("sector-length", PFlashCFI02, sector_len, 0),
+ DEFINE_PROP_UINT8("width", PFlashCFI02, width, 0),
+ DEFINE_PROP_UINT8("mappings", PFlashCFI02, mappings, 0),
+ DEFINE_PROP_UINT8("big-endian", PFlashCFI02, be, 0),
+ DEFINE_PROP_UINT16("id0", PFlashCFI02, ident0, 0),
+ DEFINE_PROP_UINT16("id1", PFlashCFI02, ident1, 0),
+ DEFINE_PROP_UINT16("id2", PFlashCFI02, ident2, 0),
+ DEFINE_PROP_UINT16("id3", PFlashCFI02, ident3, 0),
+ DEFINE_PROP_UINT16("unlock-addr0", PFlashCFI02, unlock_addr0, 0),
+ DEFINE_PROP_UINT16("unlock-addr1", PFlashCFI02, unlock_addr1, 0),
+ DEFINE_PROP_STRING("name", PFlashCFI02, name),
DEFINE_PROP_END_OF_LIST(),
};
static void pflash_cfi02_unrealize(DeviceState *dev, Error **errp)
{
- pflash_t *pfl = CFI_PFLASH02(dev);
+ PFlashCFI02 *pfl = PFLASH_CFI02(dev);
timer_del(&pfl->timer);
}
@@ -712,9 +710,9 @@ static void pflash_cfi02_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo pflash_cfi02_info = {
- .name = TYPE_CFI_PFLASH02,
+ .name = TYPE_PFLASH_CFI02,
.parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(struct pflash_t),
+ .instance_size = sizeof(PFlashCFI02),
.class_init = pflash_cfi02_class_init,
};
@@ -725,22 +723,25 @@ static void pflash_cfi02_register_types(void)
type_init(pflash_cfi02_register_types)
-pflash_t *pflash_cfi02_register(hwaddr base,
- DeviceState *qdev, const char *name,
- hwaddr size,
- BlockBackend *blk, 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)
+PFlashCFI02 *pflash_cfi02_register(hwaddr base,
+ const char *name,
+ hwaddr size,
+ BlockBackend *blk,
+ uint32_t sector_len,
+ 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, TYPE_CFI_PFLASH02);
+ DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI02);
if (blk) {
qdev_prop_set_drive(dev, "drive", blk, &error_abort);
}
- qdev_prop_set_uint32(dev, "num-blocks", nb_blocs);
+ assert(size % sector_len == 0);
+ qdev_prop_set_uint32(dev, "num-blocks", size / sector_len);
qdev_prop_set_uint32(dev, "sector-length", sector_len);
qdev_prop_set_uint8(dev, "width", width);
qdev_prop_set_uint8(dev, "mappings", nb_mappings);
@@ -755,5 +756,5 @@ pflash_t *pflash_cfi02_register(hwaddr base,
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- return CFI_PFLASH02(dev);
+ return PFLASH_CFI02(dev);
}
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 512ce7ca7a..f9b6efe509 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -978,25 +978,12 @@ static void device_initfn(Object *obj)
QLIST_INIT(&dev->gpios);
}
-void object_apply_compat_props(Object *obj)
-{
- if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
- MachineState *m = MACHINE(qdev_get_machine());
- MachineClass *mc = MACHINE_GET_CLASS(m);
-
- if (m->accelerator) {
- AccelClass *ac = ACCEL_GET_CLASS(m->accelerator);
-
- if (ac->compat_props) {
- object_apply_global_props(obj, ac->compat_props, &error_abort);
- }
- }
- object_apply_global_props(obj, mc->compat_props, &error_abort);
- }
-}
-
static void device_post_init(Object *obj)
{
+ /*
+ * Note: ordered so that the user's global properties take
+ * precedence.
+ */
object_apply_compat_props(obj);
qdev_prop_set_globals(DEVICE(obj));
}
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 9f9edbcab9..307cf90a51 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -357,9 +357,6 @@ static void main_system_bus_create(void)
qbus_create_inplace(main_system_bus, system_bus_info.instance_size,
TYPE_SYSTEM_BUS, NULL, "main-system-bus");
OBJECT(main_system_bus)->free = g_free;
- object_property_add_child(container_get(qdev_get_machine(),
- "/unattached"),
- "sysbus", OBJECT(main_system_bus), NULL);
}
BusState *sysbus_get_default(void)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c6d047b42b..d71dc28ef6 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1809,7 +1809,7 @@ void pc_memory_init(PCMachineState *pcms,
}
/* Initialize PC system firmware */
- pc_system_firmware_init(rom_memory, !pcmc->pci_enabled);
+ pc_system_firmware_init(pcms, rom_memory);
option_rom_mr = g_malloc(sizeof(*option_rom_mr));
memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
@@ -2649,6 +2649,8 @@ static void pc_machine_initfn(Object *obj)
pcms->smbus_enabled = true;
pcms->sata_enabled = true;
pcms->pit_enabled = true;
+
+ pc_system_flash_create(pcms);
}
static void pc_machine_reset(void)
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 091e22dd60..c628540774 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -40,10 +40,16 @@
#define BIOS_FILENAME "bios.bin"
-typedef struct PcSysFwDevice {
- SysBusDevice busdev;
- uint8_t isapc_ram_fw;
-} PcSysFwDevice;
+/*
+ * We don't have a theoretically justifiable exact lower bound on the base
+ * address of any flash mapping. In practice, the IO-APIC MMIO range is
+ * [0xFEE00000..0xFEE01000] -- see IO_APIC_DEFAULT_ADDRESS --, leaving free
+ * only 18MB-4KB below 4G. For now, restrict the cumulative mapping to 8MB in
+ * size.
+ */
+#define FLASH_SIZE_LIMIT (8 * MiB)
+
+#define FLASH_SECTOR_SIZE 4096
static void pc_isa_bios_init(MemoryRegion *rom_memory,
MemoryRegion *flash_mem,
@@ -76,100 +82,118 @@ static void pc_isa_bios_init(MemoryRegion *rom_memory,
memory_region_set_readonly(isa_bios, true);
}
-#define FLASH_MAP_UNIT_MAX 2
+static PFlashCFI01 *pc_pflash_create(PCMachineState *pcms,
+ const char *name,
+ const char *alias_prop_name)
+{
+ DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
-/* We don't have a theoretically justifiable exact lower bound on the base
- * address of any flash mapping. In practice, the IO-APIC MMIO range is
- * [0xFEE00000..0xFEE01000[ -- see IO_APIC_DEFAULT_ADDRESS --, leaving free
- * only 18MB-4KB below 4G. For now, restrict the cumulative mapping to 8MB in
- * size.
- */
-#define FLASH_MAP_BASE_MIN ((hwaddr)(4 * GiB - 8 * MiB))
+ qdev_prop_set_uint64(dev, "sector-length", FLASH_SECTOR_SIZE);
+ qdev_prop_set_uint8(dev, "width", 1);
+ qdev_prop_set_string(dev, "name", name);
+ object_property_add_child(OBJECT(pcms), name, OBJECT(dev),
+ &error_abort);
+ object_property_add_alias(OBJECT(pcms), alias_prop_name,
+ OBJECT(dev), "drive", &error_abort);
+ return PFLASH_CFI01(dev);
+}
-/* This function maps flash drives from 4G downward, in order of their unit
- * numbers. The mapping starts at unit#0, with unit number increments of 1, and
- * stops before the first missing flash drive, or before
- * unit#FLASH_MAP_UNIT_MAX, whichever is reached first.
- *
- * Addressing within one flash drive is of course not reversed.
- *
- * An error message is printed and the process exits if:
- * - the size of the backing file for a flash drive is non-positive, or not a
- * multiple of the required sector size, or
- * - the current mapping's base address would fall below FLASH_MAP_BASE_MIN.
+void pc_system_flash_create(PCMachineState *pcms)
+{
+ PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
+
+ if (pcmc->pci_enabled) {
+ pcms->flash[0] = pc_pflash_create(pcms, "system.flash0",
+ "pflash0");
+ pcms->flash[1] = pc_pflash_create(pcms, "system.flash1",
+ "pflash1");
+ }
+}
+
+static void pc_system_flash_cleanup_unused(PCMachineState *pcms)
+{
+ char *prop_name;
+ int i;
+ Object *dev_obj;
+
+ assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled);
+
+ for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) {
+ dev_obj = OBJECT(pcms->flash[i]);
+ if (!object_property_get_bool(dev_obj, "realized", &error_abort)) {
+ prop_name = g_strdup_printf("pflash%d", i);
+ object_property_del(OBJECT(pcms), prop_name, &error_abort);
+ g_free(prop_name);
+ object_unparent(dev_obj);
+ pcms->flash[i] = NULL;
+ }
+ }
+}
+
+/*
+ * Map the pcms->flash[] from 4GiB downward, and realize.
+ * Map them in descending order, i.e. pcms->flash[0] at the top,
+ * without gaps.
+ * Stop at the first pcms->flash[0] lacking a block backend.
+ * Set each flash's size from its block backend. Fatal error if the
+ * size isn't a non-zero multiple of 4KiB, or the total size exceeds
+ * FLASH_SIZE_LIMIT.
*
- * The drive with unit#0 (if available) is mapped at the highest address, and
- * it is passed to pc_isa_bios_init(). Merging several drives for isa-bios is
+ * If pcms->flash[0] has a block backend, its memory is passed to
+ * pc_isa_bios_init(). Merging several flash devices for isa-bios is
* not supported.
*/
-static void pc_system_flash_init(MemoryRegion *rom_memory)
+static void pc_system_flash_map(PCMachineState *pcms,
+ MemoryRegion *rom_memory)
{
- int unit;
- DriveInfo *pflash_drv;
+ hwaddr total_size = 0;
+ int i;
BlockBackend *blk;
int64_t size;
- char *fatal_errmsg = NULL;
- hwaddr phys_addr = 0x100000000ULL;
- int sector_bits, sector_size;
- pflash_t *system_flash;
+ PFlashCFI01 *system_flash;
MemoryRegion *flash_mem;
- char name[64];
void *flash_ptr;
int ret, flash_size;
- sector_bits = 12;
- sector_size = 1 << sector_bits;
+ assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled);
- for (unit = 0;
- (unit < FLASH_MAP_UNIT_MAX &&
- (pflash_drv = drive_get(IF_PFLASH, 0, unit)) != NULL);
- ++unit) {
- blk = blk_by_legacy_dinfo(pflash_drv);
+ for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) {
+ system_flash = pcms->flash[i];
+ blk = pflash_cfi01_get_blk(system_flash);
+ if (!blk) {
+ break;
+ }
size = blk_getlength(blk);
if (size < 0) {
- fatal_errmsg = g_strdup_printf("failed to get backing file size");
- } else if (size == 0) {
- fatal_errmsg = g_strdup_printf("PC system firmware (pflash) "
- "cannot have zero size");
- } else if ((size % sector_size) != 0) {
- fatal_errmsg = g_strdup_printf("PC system firmware (pflash) "
- "must be a multiple of 0x%x", sector_size);
- } else if (phys_addr < size || phys_addr - size < FLASH_MAP_BASE_MIN) {
- fatal_errmsg = g_strdup_printf("oversized backing file, pflash "
- "segments cannot be mapped under "
- TARGET_FMT_plx, FLASH_MAP_BASE_MIN);
+ error_report("can't get size of block device %s: %s",
+ blk_name(blk), strerror(-size));
+ exit(1);
}
- if (fatal_errmsg != NULL) {
- Location loc;
-
- /* push a new, "none" location on the location stack; overwrite its
- * contents with the location saved in the option; print the error
- * (includes location); pop the top
- */
- loc_push_none(&loc);
- if (pflash_drv->opts != NULL) {
- qemu_opts_loc_restore(pflash_drv->opts);
- }
- error_report("%s", fatal_errmsg);
- loc_pop(&loc);
- g_free(fatal_errmsg);
+ if (size == 0 || size % FLASH_SECTOR_SIZE != 0) {
+ error_report("system firmware block device %s has invalid size "
+ "%" PRId64,
+ blk_name(blk), size);
+ info_report("its size must be a non-zero multiple of 0x%x",
+ FLASH_SECTOR_SIZE);
exit(1);
}
+ if ((hwaddr)size != size
+ || total_size > HWADDR_MAX - size
+ || total_size + size > FLASH_SIZE_LIMIT) {
+ error_report("combined size of system firmware exceeds "
+ "%" PRIu64 " bytes",
+ FLASH_SIZE_LIMIT);
+ exit(1);
+ }
+
+ total_size += size;
+ qdev_prop_set_uint32(DEVICE(system_flash), "num-blocks",
+ size / FLASH_SECTOR_SIZE);
+ qdev_init_nofail(DEVICE(system_flash));
+ sysbus_mmio_map(SYS_BUS_DEVICE(system_flash), 0,
+ 0x100000000ULL - total_size);
- phys_addr -= size;
-
- /* pflash_cfi01_register() creates a deep copy of the name */
- snprintf(name, sizeof name, "system.flash%d", unit);
- system_flash = pflash_cfi01_register(phys_addr, NULL /* qdev */, name,
- size, blk, sector_size,
- size >> sector_bits,
- 1 /* width */,
- 0x0000 /* id0 */,
- 0x0000 /* id1 */,
- 0x0000 /* id2 */,
- 0x0000 /* id3 */,
- 0 /* be */);
- if (unit == 0) {
+ if (i == 0) {
flash_mem = pflash_cfi01_get_memory(system_flash);
pc_isa_bios_init(rom_memory, flash_mem, size);
@@ -240,24 +264,63 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
bios);
}
-void pc_system_firmware_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
+void pc_system_firmware_init(PCMachineState *pcms,
+ MemoryRegion *rom_memory)
{
+ PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
+ int i;
DriveInfo *pflash_drv;
+ BlockBackend *pflash_blk[ARRAY_SIZE(pcms->flash)];
+ Location loc;
- pflash_drv = drive_get(IF_PFLASH, 0, 0);
-
- if (isapc_ram_fw || pflash_drv == NULL) {
- /* When a pflash drive is not found, use rom-mode */
- old_pc_system_rom_init(rom_memory, isapc_ram_fw);
+ if (!pcmc->pci_enabled) {
+ old_pc_system_rom_init(rom_memory, true);
return;
}
- if (kvm_enabled() && !kvm_readonly_mem_enabled()) {
- /* Older KVM cannot execute from device memory. So, flash memory
- * cannot be used unless the readonly memory kvm capability is present. */
- fprintf(stderr, "qemu: pflash with kvm requires KVM readonly memory support\n");
- exit(1);
+ /* Map legacy -drive if=pflash to machine properties */
+ for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) {
+ pflash_blk[i] = pflash_cfi01_get_blk(pcms->flash[i]);
+ pflash_drv = drive_get(IF_PFLASH, 0, i);
+ if (!pflash_drv) {
+ continue;
+ }
+ loc_push_none(&loc);
+ qemu_opts_loc_restore(pflash_drv->opts);
+ if (pflash_blk[i]) {
+ error_report("clashes with -machine");
+ exit(1);
+ }
+ pflash_blk[i] = blk_by_legacy_dinfo(pflash_drv);
+ qdev_prop_set_drive(DEVICE(pcms->flash[i]),
+ "drive", pflash_blk[i], &error_fatal);
+ loc_pop(&loc);
+ }
+
+ /* Reject gaps */
+ for (i = 1; i < ARRAY_SIZE(pcms->flash); i++) {
+ if (pflash_blk[i] && !pflash_blk[i - 1]) {
+ error_report("pflash%d requires pflash%d", i, i - 1);
+ exit(1);
+ }
+ }
+
+ if (!pflash_blk[0]) {
+ /* Machine property pflash0 not set, use ROM mode */
+ old_pc_system_rom_init(rom_memory, false);
+ } else {
+ if (kvm_enabled() && !kvm_readonly_mem_enabled()) {
+ /*
+ * Older KVM cannot execute from device memory. So, flash
+ * memory cannot be used unless the readonly memory kvm
+ * capability is present.
+ */
+ error_report("pflash with kvm requires KVM readonly memory support");
+ exit(1);
+ }
+
+ pc_system_flash_map(pcms, rom_memory);
}
- pc_system_flash_init(rom_memory);
+ pc_system_flash_cleanup_unused(pcms);
}
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index 599e0d4923..b820c9114b 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -113,9 +113,9 @@ static void lm32_evr_init(MachineState *machine)
dinfo = drive_get(IF_PFLASH, 0, 0);
/* Spansion S29NS128P */
- pflash_cfi02_register(flash_base, NULL, "lm32_evr.flash", flash_size,
+ pflash_cfi02_register(flash_base, "lm32_evr.flash", flash_size,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- flash_sector_size, flash_size / flash_sector_size,
+ flash_sector_size,
1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
/* create irq lines */
@@ -206,9 +206,9 @@ static void lm32_uclinux_init(MachineState *machine)
dinfo = drive_get(IF_PFLASH, 0, 0);
/* Spansion S29NS128P */
- pflash_cfi02_register(flash_base, NULL, "lm32_uclinux.flash", flash_size,
+ pflash_cfi02_register(flash_base, "lm32_uclinux.flash", flash_size,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- flash_sector_size, flash_size / flash_sector_size,
+ flash_sector_size,
1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
/* create irq lines */
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index 538f33b946..689e633199 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -120,10 +120,9 @@ milkymist_init(MachineState *machine)
dinfo = drive_get(IF_PFLASH, 0, 0);
/* Numonyx JS28F256J3F105 */
- pflash_cfi01_register(flash_base, NULL, "milkymist.flash", flash_size,
+ pflash_cfi01_register(flash_base, "milkymist.flash", flash_size,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- flash_sector_size, flash_size / flash_sector_size,
- 2, 0x00, 0x89, 0x00, 0x1d, 1);
+ flash_sector_size, 2, 0x00, 0x89, 0x00, 0x1d, 1);
/* create irq lines */
env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, cpu, 0));
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index 18048d3555..a907604116 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -106,11 +106,9 @@ petalogix_ml605_init(MachineState *machine)
dinfo = drive_get(IF_PFLASH, 0, 0);
/* 5th parameter 2 means bank-width
* 10th paremeter 0 means little-endian */
- pflash_cfi01_register(FLASH_BASEADDR,
- NULL, "petalogix_ml605.flash", FLASH_SIZE,
+ pflash_cfi01_register(FLASH_BASEADDR, "petalogix_ml605.flash", FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- 64 * KiB, FLASH_SIZE >> 16,
- 2, 0x89, 0x18, 0x0000, 0x0, 0);
+ 64 * KiB, 2, 0x89, 0x18, 0x0000, 0x0, 0);
dev = qdev_create(NULL, "xlnx.xps-intc");
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index a0edaf867c..88ce570f9a 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -87,10 +87,9 @@ petalogix_s3adsp1800_init(MachineState *machine)
dinfo = drive_get(IF_PFLASH, 0, 0);
pflash_cfi01_register(FLASH_BASEADDR,
- NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE,
+ "petalogix_s3adsp1800.flash", FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- 64 * KiB, FLASH_SIZE >> 16,
- 1, 0x89, 0x18, 0x0000, 0x0, 1);
+ 64 * KiB, 1, 0x89, 0x18, 0x0000, 0x0, 1);
dev = qdev_create(NULL, "xlnx.xps-intc");
qdev_prop_set_uint32(dev, "kind-of-intr",
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 39aef4b6db..439665ab45 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -58,8 +58,6 @@
#include "exec/semihost.h"
#include "hw/mips/cps.h"
-//#define DEBUG_BOARD_INIT
-
#define ENVP_ADDR 0x80002000l
#define ENVP_NB_ENTRIES 16
#define ENVP_ENTRY_SIZE 256
@@ -1189,13 +1187,12 @@ void mips_malta_init(MachineState *machine)
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
char *filename;
- pflash_t *fl;
+ PFlashCFI01 *fl;
MemoryRegion *system_memory = get_system_memory();
MemoryRegion *ram_high = g_new(MemoryRegion, 1);
MemoryRegion *ram_low_preio = g_new(MemoryRegion, 1);
MemoryRegion *ram_low_postio;
MemoryRegion *bios, *bios_copy = g_new(MemoryRegion, 1);
- target_long bios_size = FLASH_SIZE;
const size_t smbus_eeprom_size = 8 * 256;
uint8_t *smbus_eeprom_buf = g_malloc0(smbus_eeprom_size);
int64_t kernel_entry, bootloader_run_addr;
@@ -1208,7 +1205,6 @@ void mips_malta_init(MachineState *machine)
DriveInfo *dinfo;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
int fl_idx = 0;
- int fl_sectors = bios_size >> 16;
int be;
DeviceState *dev = qdev_create(NULL, TYPE_MIPS_MALTA);
@@ -1265,18 +1261,10 @@ void mips_malta_init(MachineState *machine)
/* Load firmware in flash / BIOS. */
dinfo = drive_get(IF_PFLASH, 0, fl_idx);
-#ifdef DEBUG_BOARD_INIT
- if (dinfo) {
- printf("Register parallel flash %d size " TARGET_FMT_lx " at "
- "addr %08llx '%s' %x\n",
- fl_idx, bios_size, FLASH_ADDRESS,
- blk_name(dinfo->bdrv), fl_sectors);
- }
-#endif
- fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios",
- BIOS_SIZE,
+ fl = pflash_cfi01_register(FLASH_ADDRESS, "mips_malta.bios",
+ FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- 65536, fl_sectors,
+ 65536,
4, 0x0000, 0x0000, 0x0000, 0x0000, be);
bios = pflash_cfi01_get_memory(fl);
fl_idx++;
@@ -1312,6 +1300,7 @@ void mips_malta_init(MachineState *machine)
bootloader_run_addr, kernel_entry);
}
} else {
+ target_long bios_size = FLASH_SIZE;
/* The flash region isn't executable from a KVM guest */
if (kvm_enabled()) {
error_report("KVM enabled but no -kernel argument was specified. "
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index a015a6d14e..93dbf76bb4 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -235,10 +235,9 @@ void mips_r4k_init(MachineState *machine)
load_image_targphys(filename, 0x1fc00000, BIOS_SIZE);
} else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
uint32_t mips_rom = 0x00400000;
- if (!pflash_cfi01_register(0x1fc00000, NULL, "mips_r4k.bios", mips_rom,
+ if (!pflash_cfi01_register(0x1fc00000, "mips_r4k.bios", mips_rom,
blk_by_legacy_dinfo(dinfo),
- sector_len, mips_rom / sector_len,
- 4, 0, 0, 0, 0, be)) {
+ sector_len, 4, 0, 0, 0, 0, be)) {
fprintf(stderr, "qemu: Error registering flash memory.\n");
}
} else if (!qtest_enabled()) {
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index f47b15f10e..13318a9faf 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -48,8 +48,6 @@
#define USE_FLASH_BIOS
-//#define DEBUG_BOARD_INIT
-
/*****************************************************************************/
/* PPC405EP reference board (IBM) */
/* Standalone board with:
@@ -158,7 +156,7 @@ static void ref405ep_init(MachineState *machine)
target_ulong kernel_base, initrd_base;
long kernel_size, initrd_size;
int linux_boot;
- int fl_idx, fl_sectors, len;
+ int len;
DriveInfo *dinfo;
MemoryRegion *sysmem = get_system_memory();
@@ -171,9 +169,6 @@ static void ref405ep_init(MachineState *machine)
ram_bases[1] = 0x00000000;
ram_sizes[1] = 0x00000000;
ram_size = 128 * MiB;
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register cpu\n", __func__);
-#endif
env = ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes,
33333333, &pic, kernel_filename == NULL ? 0 : 1);
/* allocate SRAM */
@@ -182,35 +177,19 @@ static void ref405ep_init(MachineState *machine)
&error_fatal);
memory_region_add_subregion(sysmem, 0xFFF00000, sram);
/* allocate and load BIOS */
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register BIOS\n", __func__);
-#endif
- fl_idx = 0;
#ifdef USE_FLASH_BIOS
- dinfo = drive_get(IF_PFLASH, 0, fl_idx);
+ dinfo = drive_get(IF_PFLASH, 0, 0);
if (dinfo) {
- BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
-
- bios_size = blk_getlength(blk);
- fl_sectors = (bios_size + 65535) >> 16;
-#ifdef DEBUG_BOARD_INIT
- printf("Register parallel flash %d size %lx"
- " at addr %lx '%s' %d\n",
- fl_idx, bios_size, -bios_size,
- blk_name(blk), fl_sectors);
-#endif
+ bios_size = 8 * MiB;
pflash_cfi02_register((uint32_t)(-bios_size),
- NULL, "ef405ep.bios", bios_size,
- blk, 65536, fl_sectors, 1,
+ "ef405ep.bios", bios_size,
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
+ 64 * KiB, 1,
2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
1);
- fl_idx++;
} else
#endif
{
-#ifdef DEBUG_BOARD_INIT
- printf("Load BIOS from file\n");
-#endif
bios = g_new(MemoryRegion, 1);
memory_region_init_ram(bios, NULL, "ef405ep.bios", BIOS_SIZE,
&error_fatal);
@@ -239,21 +218,12 @@ static void ref405ep_init(MachineState *machine)
memory_region_set_readonly(bios, true);
}
/* Register FPGA */
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register FPGA\n", __func__);
-#endif
ref405ep_fpga_init(sysmem, 0xF0300000);
/* Register NVRAM */
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register NVRAM\n", __func__);
-#endif
m48t59_init(NULL, 0xF0000000, 0, 8192, 1968, 8);
/* Load kernel */
linux_boot = (kernel_filename != NULL);
if (linux_boot) {
-#ifdef DEBUG_BOARD_INIT
- printf("%s: load kernel\n", __func__);
-#endif
memset(&bd, 0, sizeof(bd));
bd.bi_memstart = 0x00000000;
bd.bi_memsize = ram_size;
@@ -325,10 +295,6 @@ static void ref405ep_init(MachineState *machine)
initrd_size = 0;
bdloc = 0;
}
-#ifdef DEBUG_BOARD_INIT
- printf("bdloc " RAM_ADDR_FMT "\n", bdloc);
- printf("%s: Done\n", __func__);
-#endif
}
static void ref405ep_class_init(ObjectClass *oc, void *data)
@@ -455,7 +421,7 @@ static void taihu_405ep_init(MachineState *machine)
target_ulong kernel_base, initrd_base;
long kernel_size, initrd_size;
int linux_boot;
- int fl_idx, fl_sectors;
+ int fl_idx;
DriveInfo *dinfo;
/* RAM is soldered to the board so the size cannot be changed */
@@ -473,43 +439,24 @@ static void taihu_405ep_init(MachineState *machine)
memory_region_init_alias(&ram_memories[1], NULL,
"taihu_405ep.ram-1", ram, ram_bases[1],
ram_sizes[1]);
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register cpu\n", __func__);
-#endif
ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes,
33333333, &pic, kernel_filename == NULL ? 0 : 1);
/* allocate and load BIOS */
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register BIOS\n", __func__);
-#endif
fl_idx = 0;
#if defined(USE_FLASH_BIOS)
dinfo = drive_get(IF_PFLASH, 0, fl_idx);
if (dinfo) {
- BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
-
- bios_size = blk_getlength(blk);
- /* XXX: should check that size is 2MB */
- // bios_size = 2 * 1024 * 1024;
- fl_sectors = (bios_size + 65535) >> 16;
-#ifdef DEBUG_BOARD_INIT
- printf("Register parallel flash %d size %lx"
- " at addr %lx '%s' %d\n",
- fl_idx, bios_size, -bios_size,
- blk_name(blk), fl_sectors);
-#endif
- pflash_cfi02_register((uint32_t)(-bios_size),
- NULL, "taihu_405ep.bios", bios_size,
- blk, 65536, fl_sectors, 1,
+ bios_size = 2 * MiB;
+ pflash_cfi02_register(0xFFE00000,
+ "taihu_405ep.bios", bios_size,
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
+ 64 * KiB, 1,
4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
1);
fl_idx++;
} else
#endif
{
-#ifdef DEBUG_BOARD_INIT
- printf("Load BIOS from file\n");
-#endif
if (bios_name == NULL)
bios_name = BIOS_FILENAME;
bios = g_new(MemoryRegion, 1);
@@ -536,35 +483,19 @@ static void taihu_405ep_init(MachineState *machine)
/* Register Linux flash */
dinfo = drive_get(IF_PFLASH, 0, fl_idx);
if (dinfo) {
- BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
-
- bios_size = blk_getlength(blk);
- /* XXX: should check that size is 32MB */
bios_size = 32 * MiB;
- fl_sectors = (bios_size + 65535) >> 16;
-#ifdef DEBUG_BOARD_INIT
- printf("Register parallel flash %d size %lx"
- " at addr " TARGET_FMT_lx " '%s'\n",
- fl_idx, bios_size, (target_ulong)0xfc000000,
- blk_name(blk));
-#endif
- pflash_cfi02_register(0xfc000000, NULL, "taihu_405ep.flash", bios_size,
- blk, 65536, fl_sectors, 1,
+ pflash_cfi02_register(0xfc000000, "taihu_405ep.flash", bios_size,
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
+ 64 * KiB, 1,
4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
1);
fl_idx++;
}
/* Register CLPD & LCD display */
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register CPLD\n", __func__);
-#endif
taihu_cpld_init(sysmem, 0x50100000);
/* Load kernel */
linux_boot = (kernel_filename != NULL);
if (linux_boot) {
-#ifdef DEBUG_BOARD_INIT
- printf("%s: load kernel\n", __func__);
-#endif
kernel_base = KERNEL_LOAD_ADDR;
/* now we can load the kernel */
kernel_size = load_image_targphys(kernel_filename, kernel_base,
@@ -593,9 +524,6 @@ static void taihu_405ep_init(MachineState *machine)
initrd_base = 0;
initrd_size = 0;
}
-#ifdef DEBUG_BOARD_INIT
- printf("%s: Done\n", __func__);
-#endif
}
static void taihu_class_init(ObjectClass *oc, void *data)
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index d455c4bd07..fbcddc5b00 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -91,32 +91,42 @@ struct boot_info {
static int sam460ex_load_uboot(void)
{
+ /*
+ * This first creates 1MiB of flash memory mapped at the end of
+ * the 32-bit address space (0xFFF00000..0xFFFFFFFF).
+ *
+ * If_PFLASH unit 0 is defined, the flash memory is initialized
+ * from that block backend.
+ *
+ * Else, it's initialized to zero. And then 512KiB of ROM get
+ * mapped on top of its second half (0xFFF80000..0xFFFFFFFF),
+ * initialized from u-boot-sam460-20100605.bin.
+ *
+ * This doesn't smell right.
+ *
+ * The physical hardware appears to have 512KiB flash memory.
+ *
+ * TODO Figure out what we really need here, and clean this up.
+ */
+
DriveInfo *dinfo;
- BlockBackend *blk = NULL;
- hwaddr base = FLASH_BASE | ((hwaddr)FLASH_BASE_H << 32);
- long bios_size = FLASH_SIZE;
- int fl_sectors;
dinfo = drive_get(IF_PFLASH, 0, 0);
- if (dinfo) {
- blk = blk_by_legacy_dinfo(dinfo);
- bios_size = blk_getlength(blk);
- }
- fl_sectors = (bios_size + 65535) >> 16;
-
- if (!pflash_cfi01_register(base, NULL, "sam460ex.flash", bios_size,
- blk, 64 * KiB, fl_sectors,
- 1, 0x89, 0x18, 0x0000, 0x0, 1)) {
+ if (!pflash_cfi01_register(FLASH_BASE | ((hwaddr)FLASH_BASE_H << 32),
+ "sam460ex.flash", FLASH_SIZE,
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
+ 64 * KiB, 1, 0x89, 0x18, 0x0000, 0x0, 1)) {
error_report("Error registering flash memory");
/* XXX: return an error instead? */
exit(1);
}
- if (!blk) {
+ if (!dinfo) {
/*error_report("No flash image given with the 'pflash' parameter,"
" using default u-boot image");*/
- base = UBOOT_LOAD_BASE | ((hwaddr)FLASH_BASE_H << 32);
- rom_add_file_fixed(UBOOT_FILENAME, base, -1);
+ rom_add_file_fixed(UBOOT_FILENAME,
+ UBOOT_LOAD_BASE | ((hwaddr)FLASH_BASE_H << 32),
+ -1);
}
return 0;
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 26e2312006..0e4c7409e0 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -226,10 +226,9 @@ static void virtex_init(MachineState *machine)
memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
dinfo = drive_get(IF_PFLASH, 0, 0);
- pflash_cfi01_register(PFLASH_BASEADDR, NULL, "virtex.flash", FLASH_SIZE,
+ pflash_cfi01_register(PFLASH_BASEADDR, "virtex.flash", FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- 64 * KiB, FLASH_SIZE >> 16,
- 1, 0x89, 0x18, 0x0000, 0x0, 1);
+ 64 * KiB, 1, 0x89, 0x18, 0x0000, 0x0, 1);
cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT];
dev = qdev_create(NULL, "xlnx.xps-intc");
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index 28ed6be05b..0bcb769c85 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -43,7 +43,7 @@
#include "exec/address-spaces.h"
#define FLASH_BASE 0x00000000
-#define FLASH_SIZE 0x02000000
+#define FLASH_SIZE (16 * MiB)
#define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
#define SDRAM_SIZE 0x04000000
@@ -287,12 +287,19 @@ static void r2d_init(MachineState *machine)
sysbus_mmio_map(busdev, 1, 0x1400080c);
mmio_ide_init_drives(dev, dinfo, NULL);
- /* onboard flash memory */
+ /*
+ * Onboard flash memory
+ * According to the old board user document in Japanese (under
+ * NDA) what is referred to as FROM (Area0) is connected via a
+ * 32-bit bus and CS0 to CN8. The docs mention a Cypress
+ * S29PL127J60TFI130 chipsset. Per the 'S29PL-J 002-00615
+ * Rev. *E' datasheet, it is a 128Mbit NOR parallel flash
+ * addressable in words of 16bit.
+ */
dinfo = drive_get(IF_PFLASH, 0, 0);
- pflash_cfi02_register(0x0, NULL, "r2d.flash", FLASH_SIZE,
+ pflash_cfi02_register(0x0, "r2d.flash", FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- 16 * KiB, FLASH_SIZE >> 16,
- 1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
+ 64 * KiB, 1, 2, 0x0001, 0x227e, 0x2220, 0x2200,
0x555, 0x2aa, 0);
/* NIC: rtl8139 on-board, and 2 slots. */
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index ab3e52b415..e05ef75a75 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -162,12 +162,12 @@ static void xtfpga_net_init(MemoryRegion *address_space,
memory_region_add_subregion(address_space, buffers, ram);
}
-static pflash_t *xtfpga_flash_init(MemoryRegion *address_space,
- const XtfpgaBoardDesc *board,
- DriveInfo *dinfo, int be)
+static PFlashCFI01 *xtfpga_flash_init(MemoryRegion *address_space,
+ const XtfpgaBoardDesc *board,
+ DriveInfo *dinfo, int be)
{
SysBusDevice *s;
- DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
+ DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo),
&error_abort);
@@ -181,7 +181,7 @@ static pflash_t *xtfpga_flash_init(MemoryRegion *address_space,
s = SYS_BUS_DEVICE(dev);
memory_region_add_subregion(address_space, board->flash->base,
sysbus_mmio_get_region(s, 0));
- return OBJECT_CHECK(pflash_t, (dev), "cfi.pflash01");
+ return PFLASH_CFI01(dev);
}
static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
@@ -229,7 +229,7 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine)
XtensaMxPic *mx_pic = NULL;
qemu_irq *extints;
DriveInfo *dinfo;
- pflash_t *flash = NULL;
+ PFlashCFI01 *flash = NULL;
QemuOpts *machine_opts = qemu_get_machine_opts();
const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
const char *kernel_cmdline = qemu_opt_get(machine_opts, "append");