diff mbox

[1/6] hw/arm/virt: Provide flash devices for boot ROMs

Message ID 1409930126-28449-2-git-send-email-ard.biesheuvel@linaro.org
State Superseded
Headers show

Commit Message

Ard Biesheuvel Sept. 5, 2014, 3:15 p.m. UTC
From: Peter Maydell <peter.maydell@linaro.org>

Add two flash devices to the virt board, so that it can be used for
running guests which want a bootrom image such as UEFI. We provide
two flash devices to make it more convenient to provide both a
read-only UEFI image and a read-write place to store guest-set
UEFI config variables. The '-bios' command line option is set up
to provide an image for the first of the two flash devices.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/arm/virt.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

Comments

Peter Maydell Sept. 9, 2014, 6:20 p.m. UTC | #1
On 5 September 2014 16:15, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> From: Peter Maydell <peter.maydell@linaro.org>
>
> Add two flash devices to the virt board, so that it can be used for
> running guests which want a bootrom image such as UEFI. We provide
> two flash devices to make it more convenient to provide both a
> read-only UEFI image and a read-write place to store guest-set
> UEFI config variables. The '-bios' command line option is set up
> to provide an image for the first of the two flash devices.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/arm/virt.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 70 insertions(+)

This one's been around long enough that I'm going to add
it to target-arm.next now.

There were previously questions about whether we should
have flash or RAM at the bottom, but I think it makes
sense just to have a "like vexpress" config with two
flash devices. This does make telling QEMU about backing
storage for the 2nd flash a little complicated, but I
think anybody seriously running a config like that will
be using the management tools layer anyhow.

thanks
-- PMM
Ard Biesheuvel Sept. 10, 2014, 9:09 a.m. UTC | #2
On 9 September 2014 20:20, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 5 September 2014 16:15, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>> From: Peter Maydell <peter.maydell@linaro.org>
>>
>> Add two flash devices to the virt board, so that it can be used for
>> running guests which want a bootrom image such as UEFI. We provide
>> two flash devices to make it more convenient to provide both a
>> read-only UEFI image and a read-write place to store guest-set
>> UEFI config variables. The '-bios' command line option is set up
>> to provide an image for the first of the two flash devices.
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>  hw/arm/virt.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 70 insertions(+)
>
> This one's been around long enough that I'm going to add
> it to target-arm.next now.
>
> There were previously questions about whether we should
> have flash or RAM at the bottom, but I think it makes
> sense just to have a "like vexpress" config with two
> flash devices. This does make telling QEMU about backing
> storage for the 2nd flash a little complicated, but I
> think anybody seriously running a config like that will
> be using the management tools layer anyhow.
>

You mean having to use -pflash and pad the images out to 64 MB? I
wouldn't worry about that.
Peter Maydell Sept. 10, 2014, 9:12 a.m. UTC | #3
On 10 September 2014 10:09, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> On 9 September 2014 20:20, Peter Maydell <peter.maydell@linaro.org> wrote:
>> There were previously questions about whether we should
>> have flash or RAM at the bottom, but I think it makes
>> sense just to have a "like vexpress" config with two
>> flash devices. This does make telling QEMU about backing
>> storage for the 2nd flash a little complicated, but I
>> think anybody seriously running a config like that will
>> be using the management tools layer anyhow.

> You mean having to use -pflash and pad the images out to 64 MB? I
> wouldn't worry about that.

More particularly that if you don't want to provide backing
storage for the first flash but only the second, you can't just
use pflash but have to use the longer -drive options.

-- PMM
Ard Biesheuvel Sept. 10, 2014, 10:27 a.m. UTC | #4
On 10 September 2014 11:12, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 10 September 2014 10:09, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>> On 9 September 2014 20:20, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> There were previously questions about whether we should
>>> have flash or RAM at the bottom, but I think it makes
>>> sense just to have a "like vexpress" config with two
>>> flash devices. This does make telling QEMU about backing
>>> storage for the 2nd flash a little complicated, but I
>>> think anybody seriously running a config like that will
>>> be using the management tools layer anyhow.
>
>> You mean having to use -pflash and pad the images out to 64 MB? I
>> wouldn't worry about that.
>
> More particularly that if you don't want to provide backing
> storage for the first flash but only the second, you can't just
> use pflash but have to use the longer -drive options.
>

OK, I will drop this one from my series then.
diff mbox

Patch

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 5853bb3ee4d5..c7f3680d6460 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -37,6 +37,7 @@ 
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
 #include "hw/boards.h"
+#include "hw/loader.h"
 #include "exec/address-spaces.h"
 #include "qemu/bitops.h"
 #include "qemu/error-report.h"
@@ -435,6 +436,73 @@  static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic)
     }
 }
 
+static void create_one_flash(const char *name, hwaddr flashbase,
+                             hwaddr flashsize)
+{
+    /* Create and map a single flash device. We use the same
+     * parameters as the flash devices on the Versatile Express board.
+     */
+    DriveInfo *dinfo = drive_get_next(IF_PFLASH);
+    DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
+    const uint64_t sectorlength = 256 * 1024;
+
+    if (dinfo && qdev_prop_set_drive(dev, "drive", dinfo->bdrv)) {
+        abort();
+    }
+
+    qdev_prop_set_uint32(dev, "num-blocks", flashsize / sectorlength);
+    qdev_prop_set_uint64(dev, "sector-length", sectorlength);
+    qdev_prop_set_uint8(dev, "width", 4);
+    qdev_prop_set_uint8(dev, "device-width", 2);
+    qdev_prop_set_uint8(dev, "big-endian", 0);
+    qdev_prop_set_uint16(dev, "id0", 0x89);
+    qdev_prop_set_uint16(dev, "id1", 0x18);
+    qdev_prop_set_uint16(dev, "id2", 0x00);
+    qdev_prop_set_uint16(dev, "id3", 0x00);
+    qdev_prop_set_string(dev, "name", name);
+    qdev_init_nofail(dev);
+
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, flashbase);
+}
+
+static void create_flash(const VirtBoardInfo *vbi)
+{
+    /* Create two flash devices to fill the VIRT_FLASH space in the memmap.
+     * Any file passed via -bios goes in the first of these.
+     */
+    hwaddr flashsize = vbi->memmap[VIRT_FLASH].size / 2;
+    hwaddr flashbase = vbi->memmap[VIRT_FLASH].base;
+    char *nodename;
+
+    if (bios_name) {
+        const char *fn;
+
+        if (drive_get(IF_PFLASH, 0, 0)) {
+            error_report("The contents of the first flash device may be "
+                         "specified with -bios or with -drive if=pflash... "
+                         "but you cannot use both options at once");
+            exit(1);
+        }
+        fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+        if (!fn || load_image_targphys(fn, flashbase, flashsize) < 0) {
+            error_report("Could not load ROM image '%s'", bios_name);
+            exit(1);
+        }
+    }
+
+    create_one_flash("virt.flash0", flashbase, flashsize);
+    create_one_flash("virt.flash1", flashbase + flashsize, flashsize);
+
+    nodename = g_strdup_printf("/flash@%" PRIx64, flashbase);
+    qemu_fdt_add_subnode(vbi->fdt, nodename);
+    qemu_fdt_setprop_string(vbi->fdt, nodename, "compatible", "cfi-flash");
+    qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
+                                 2, flashbase, 2, flashsize,
+                                 2, flashbase + flashsize, 2, flashsize);
+    qemu_fdt_setprop_cell(vbi->fdt, nodename, "bank-width", 4);
+    g_free(nodename);
+}
+
 static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
 {
     const VirtBoardInfo *board = (const VirtBoardInfo *)binfo;
@@ -514,6 +582,8 @@  static void machvirt_init(MachineState *machine)
     vmstate_register_ram_global(ram);
     memory_region_add_subregion(sysmem, vbi->memmap[VIRT_MEM].base, ram);
 
+    create_flash(vbi);
+
     create_gic(vbi, pic);
 
     create_uart(vbi, pic);