* [Qemu-devel] [PATCH v4] hw/pc: Support system flash memory with -pflash parameter
@ 2011-07-08 19:37 Jordan Justen
2011-07-16 0:16 ` Jordan Justen
2011-07-23 15:51 ` Anthony Liguori
0 siblings, 2 replies; 9+ messages in thread
From: Jordan Justen @ 2011-07-08 19:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Jordan Justen
If -pflash is specified and -bios is specified then pflash will
be mapped just below the system rom using hw/pflash_cfi01.c.
If -pflash is specified on the command line, but -bios is
not specified, then 'bios.bin' will NOT be loaded, and
instead the -pflash flash image will be mapped just below
4GB in place of the normal rom image.
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
---
default-configs/i386-softmmu.mak | 1 +
default-configs/x86_64-softmmu.mak | 1 +
hw/pc.c | 161 +++++++++++++++++++++++++++---------
3 files changed, 125 insertions(+), 38 deletions(-)
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 55589fa..8697cd4 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
CONFIG_SOUND=y
CONFIG_HPET=y
CONFIG_APPLESMC=y
+CONFIG_PFLASH_CFI01=y
diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
index 8895028..eca9284 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
CONFIG_SOUND=y
CONFIG_HPET=y
CONFIG_APPLESMC=y
+CONFIG_PFLASH_CFI01=y
diff --git a/hw/pc.c b/hw/pc.c
index a3e8539..e25354f 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -41,6 +41,7 @@
#include "sysemu.h"
#include "blockdev.h"
#include "ui/qemu-spice.h"
+#include "flash.h"
/* output Bochs bios info messages */
//#define DEBUG_BIOS
@@ -957,70 +958,154 @@ void pc_cpus_init(const char *cpu_model)
}
}
-void pc_memory_init(const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename,
- ram_addr_t below_4g_mem_size,
- ram_addr_t above_4g_mem_size)
+static void pc_isa_bios_init(ram_addr_t ram_offset, int ram_size)
{
- char *filename;
- int ret, linux_boot, i;
- ram_addr_t ram_addr, bios_offset, option_rom_offset;
- int bios_size, isa_bios_size;
- void *fw_cfg;
-
- linux_boot = (kernel_filename != NULL);
+ int isa_bios_size;
- /* allocate RAM */
- ram_addr = qemu_ram_alloc(NULL, "pc.ram",
- below_4g_mem_size + above_4g_mem_size);
- cpu_register_physical_memory(0, 0xa0000, ram_addr);
- cpu_register_physical_memory(0x100000,
- below_4g_mem_size - 0x100000,
- ram_addr + 0x100000);
- if (above_4g_mem_size > 0) {
- cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
- ram_addr + below_4g_mem_size);
+ /* map the last 128KB of the BIOS in ISA space */
+ isa_bios_size = ram_size;
+ if (isa_bios_size > (128 * 1024)) {
+ isa_bios_size = 128 * 1024;
}
+ ram_offset = ram_offset + ram_size - isa_bios_size;
+ cpu_register_physical_memory(0x100000 - isa_bios_size,
+ isa_bios_size,
+ ram_offset | IO_MEM_ROM);
+}
+
+static int pc_system_rom_init(void)
+{
+ int ret;
+ int bios_size;
+ ram_addr_t bios_offset;
+ char *filename;
/* BIOS load */
- if (bios_name == NULL)
+ if (bios_name == NULL) {
bios_name = BIOS_FILENAME;
+ }
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) {
bios_size = get_image_size(filename);
} else {
bios_size = -1;
}
- if (bios_size <= 0 ||
- (bios_size % 65536) != 0) {
- goto bios_error;
+
+ if (bios_size <= 0 || (bios_size % 65536) != 0) {
+ ret = -1;
+ } else {
+ bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
+ ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
}
- bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
- ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
+
if (ret != 0) {
- bios_error:
fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);
exit(1);
}
+
if (filename) {
qemu_free(filename);
}
- /* map the last 128KB of the BIOS in ISA space */
- isa_bios_size = bios_size;
- if (isa_bios_size > (128 * 1024))
- isa_bios_size = 128 * 1024;
- cpu_register_physical_memory(0x100000 - isa_bios_size,
- isa_bios_size,
- (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
- option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
- cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE, option_rom_offset);
+ pc_isa_bios_init(bios_offset, bios_size);
/* map all the bios at the top of memory */
cpu_register_physical_memory((uint32_t)(-bios_size),
bios_size, bios_offset | IO_MEM_ROM);
+ return bios_size;
+}
+
+static void pc_system_flash_init(DriveInfo *pflash_drv, int rom_size)
+{
+ BlockDriverState *bdrv;
+ int64_t size;
+ target_phys_addr_t phys_addr;
+ ram_addr_t addr;
+ int sector_bits, sector_size;
+
+ bdrv = NULL;
+
+ bdrv = pflash_drv->bdrv;
+ size = bdrv_getlength(pflash_drv->bdrv);
+ sector_bits = 12;
+ sector_size = 1 << sector_bits;
+
+ if ((size % sector_size) != 0) {
+ fprintf(stderr,
+ "qemu: -pflash size must be a multiple of 0x%x\n",
+ sector_size);
+ exit(1);
+ }
+
+ phys_addr = 0x100000000ULL - rom_size - size;
+ addr = qemu_ram_alloc(NULL, "system.flash", size);
+ DPRINTF("flash addr: 0x%lx\n", (int64_t)phys_addr);
+ pflash_cfi01_register(phys_addr, addr, bdrv,
+ sector_size, size >> sector_bits,
+ 4, 0x0000, 0x0000, 0x0000, 0x0000, 0);
+
+ if (rom_size == 0) {
+ pc_isa_bios_init(addr, size);
+ }
+}
+
+static void pc_system_firmware_init(void)
+{
+ int flash_present, rom_present;
+ int rom_size;
+ DriveInfo *pflash_drv;
+
+ pflash_drv = drive_get(IF_PFLASH, 0, 0);
+ flash_present = (pflash_drv != NULL);
+
+ /* Load rom if -bios is used or if -pflash is not used */
+ rom_present = ((bios_name != NULL) || !flash_present);
+
+ /* If rom is present, then it is mapped just below 4GB */
+ if (rom_present) {
+ rom_size = pc_system_rom_init();
+ } else {
+ rom_size = 0;
+ }
+
+ /* If flash is present, then it is mapped just below the rom, or
+ * just below 4GB when rom is not present. */
+ if (flash_present) {
+ pc_system_flash_init(pflash_drv, rom_size);
+ }
+}
+
+void pc_memory_init(const char *kernel_filename,
+ const char *kernel_cmdline,
+ const char *initrd_filename,
+ ram_addr_t below_4g_mem_size,
+ ram_addr_t above_4g_mem_size)
+{
+ int linux_boot, i;
+ ram_addr_t ram_addr, option_rom_offset;
+ void *fw_cfg;
+
+ linux_boot = (kernel_filename != NULL);
+
+ /* allocate RAM */
+ ram_addr = qemu_ram_alloc(NULL, "pc.ram",
+ below_4g_mem_size + above_4g_mem_size);
+ cpu_register_physical_memory(0, 0xa0000, ram_addr);
+ cpu_register_physical_memory(0x100000,
+ below_4g_mem_size - 0x100000,
+ ram_addr + 0x100000);
+ if (above_4g_mem_size > 0) {
+ cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
+ ram_addr + below_4g_mem_size);
+ }
+
+ /* Initialize ROM or flash ranges for PC firmware */
+ pc_system_firmware_init();
+
+ option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
+ cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE, option_rom_offset);
+
fw_cfg = bochs_bios_init();
rom_set_fw(fw_cfg);
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH v4] hw/pc: Support system flash memory with -pflash parameter
2011-07-08 19:37 [Qemu-devel] [PATCH v4] hw/pc: Support system flash memory with -pflash parameter Jordan Justen
@ 2011-07-16 0:16 ` Jordan Justen
2011-07-23 15:51 ` Anthony Liguori
1 sibling, 0 replies; 9+ messages in thread
From: Jordan Justen @ 2011-07-16 0:16 UTC (permalink / raw)
To: qemu-devel
Hi all,
Are there any concerns with this patch?
I haven't heard much feedback, except:
* Jes Sorensen - March 28 - code style
* Aurelien Jarno - April 18 - Reviewed-by
Thanks,
-Jordan
On Fri, Jul 8, 2011 at 12:37, Jordan Justen <jordan.l.justen@intel.com> wrote:
> If -pflash is specified and -bios is specified then pflash will
> be mapped just below the system rom using hw/pflash_cfi01.c.
>
> If -pflash is specified on the command line, but -bios is
> not specified, then 'bios.bin' will NOT be loaded, and
> instead the -pflash flash image will be mapped just below
> 4GB in place of the normal rom image.
>
> Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
> Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
> default-configs/i386-softmmu.mak | 1 +
> default-configs/x86_64-softmmu.mak | 1 +
> hw/pc.c | 161 +++++++++++++++++++++++++++---------
> 3 files changed, 125 insertions(+), 38 deletions(-)
>
> diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
> index 55589fa..8697cd4 100644
> --- a/default-configs/i386-softmmu.mak
> +++ b/default-configs/i386-softmmu.mak
> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
> CONFIG_SOUND=y
> CONFIG_HPET=y
> CONFIG_APPLESMC=y
> +CONFIG_PFLASH_CFI01=y
> diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
> index 8895028..eca9284 100644
> --- a/default-configs/x86_64-softmmu.mak
> +++ b/default-configs/x86_64-softmmu.mak
> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
> CONFIG_SOUND=y
> CONFIG_HPET=y
> CONFIG_APPLESMC=y
> +CONFIG_PFLASH_CFI01=y
> diff --git a/hw/pc.c b/hw/pc.c
> index a3e8539..e25354f 100644
> --- a/hw/pc.c
> +++ b/hw/pc.c
> @@ -41,6 +41,7 @@
> #include "sysemu.h"
> #include "blockdev.h"
> #include "ui/qemu-spice.h"
> +#include "flash.h"
>
> /* output Bochs bios info messages */
> //#define DEBUG_BIOS
> @@ -957,70 +958,154 @@ void pc_cpus_init(const char *cpu_model)
> }
> }
>
> -void pc_memory_init(const char *kernel_filename,
> - const char *kernel_cmdline,
> - const char *initrd_filename,
> - ram_addr_t below_4g_mem_size,
> - ram_addr_t above_4g_mem_size)
> +static void pc_isa_bios_init(ram_addr_t ram_offset, int ram_size)
> {
> - char *filename;
> - int ret, linux_boot, i;
> - ram_addr_t ram_addr, bios_offset, option_rom_offset;
> - int bios_size, isa_bios_size;
> - void *fw_cfg;
> -
> - linux_boot = (kernel_filename != NULL);
> + int isa_bios_size;
>
> - /* allocate RAM */
> - ram_addr = qemu_ram_alloc(NULL, "pc.ram",
> - below_4g_mem_size + above_4g_mem_size);
> - cpu_register_physical_memory(0, 0xa0000, ram_addr);
> - cpu_register_physical_memory(0x100000,
> - below_4g_mem_size - 0x100000,
> - ram_addr + 0x100000);
> - if (above_4g_mem_size > 0) {
> - cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
> - ram_addr + below_4g_mem_size);
> + /* map the last 128KB of the BIOS in ISA space */
> + isa_bios_size = ram_size;
> + if (isa_bios_size > (128 * 1024)) {
> + isa_bios_size = 128 * 1024;
> }
> + ram_offset = ram_offset + ram_size - isa_bios_size;
> + cpu_register_physical_memory(0x100000 - isa_bios_size,
> + isa_bios_size,
> + ram_offset | IO_MEM_ROM);
> +}
> +
> +static int pc_system_rom_init(void)
> +{
> + int ret;
> + int bios_size;
> + ram_addr_t bios_offset;
> + char *filename;
>
> /* BIOS load */
> - if (bios_name == NULL)
> + if (bios_name == NULL) {
> bios_name = BIOS_FILENAME;
> + }
> filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> if (filename) {
> bios_size = get_image_size(filename);
> } else {
> bios_size = -1;
> }
> - if (bios_size <= 0 ||
> - (bios_size % 65536) != 0) {
> - goto bios_error;
> +
> + if (bios_size <= 0 || (bios_size % 65536) != 0) {
> + ret = -1;
> + } else {
> + bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
> + ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
> }
> - bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
> - ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
> +
> if (ret != 0) {
> - bios_error:
> fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);
> exit(1);
> }
> +
> if (filename) {
> qemu_free(filename);
> }
> - /* map the last 128KB of the BIOS in ISA space */
> - isa_bios_size = bios_size;
> - if (isa_bios_size > (128 * 1024))
> - isa_bios_size = 128 * 1024;
> - cpu_register_physical_memory(0x100000 - isa_bios_size,
> - isa_bios_size,
> - (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
>
> - option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
> - cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE, option_rom_offset);
> + pc_isa_bios_init(bios_offset, bios_size);
>
> /* map all the bios at the top of memory */
> cpu_register_physical_memory((uint32_t)(-bios_size),
> bios_size, bios_offset | IO_MEM_ROM);
>
> + return bios_size;
> +}
> +
> +static void pc_system_flash_init(DriveInfo *pflash_drv, int rom_size)
> +{
> + BlockDriverState *bdrv;
> + int64_t size;
> + target_phys_addr_t phys_addr;
> + ram_addr_t addr;
> + int sector_bits, sector_size;
> +
> + bdrv = NULL;
> +
> + bdrv = pflash_drv->bdrv;
> + size = bdrv_getlength(pflash_drv->bdrv);
> + sector_bits = 12;
> + sector_size = 1 << sector_bits;
> +
> + if ((size % sector_size) != 0) {
> + fprintf(stderr,
> + "qemu: -pflash size must be a multiple of 0x%x\n",
> + sector_size);
> + exit(1);
> + }
> +
> + phys_addr = 0x100000000ULL - rom_size - size;
> + addr = qemu_ram_alloc(NULL, "system.flash", size);
> + DPRINTF("flash addr: 0x%lx\n", (int64_t)phys_addr);
> + pflash_cfi01_register(phys_addr, addr, bdrv,
> + sector_size, size >> sector_bits,
> + 4, 0x0000, 0x0000, 0x0000, 0x0000, 0);
> +
> + if (rom_size == 0) {
> + pc_isa_bios_init(addr, size);
> + }
> +}
> +
> +static void pc_system_firmware_init(void)
> +{
> + int flash_present, rom_present;
> + int rom_size;
> + DriveInfo *pflash_drv;
> +
> + pflash_drv = drive_get(IF_PFLASH, 0, 0);
> + flash_present = (pflash_drv != NULL);
> +
> + /* Load rom if -bios is used or if -pflash is not used */
> + rom_present = ((bios_name != NULL) || !flash_present);
> +
> + /* If rom is present, then it is mapped just below 4GB */
> + if (rom_present) {
> + rom_size = pc_system_rom_init();
> + } else {
> + rom_size = 0;
> + }
> +
> + /* If flash is present, then it is mapped just below the rom, or
> + * just below 4GB when rom is not present. */
> + if (flash_present) {
> + pc_system_flash_init(pflash_drv, rom_size);
> + }
> +}
> +
> +void pc_memory_init(const char *kernel_filename,
> + const char *kernel_cmdline,
> + const char *initrd_filename,
> + ram_addr_t below_4g_mem_size,
> + ram_addr_t above_4g_mem_size)
> +{
> + int linux_boot, i;
> + ram_addr_t ram_addr, option_rom_offset;
> + void *fw_cfg;
> +
> + linux_boot = (kernel_filename != NULL);
> +
> + /* allocate RAM */
> + ram_addr = qemu_ram_alloc(NULL, "pc.ram",
> + below_4g_mem_size + above_4g_mem_size);
> + cpu_register_physical_memory(0, 0xa0000, ram_addr);
> + cpu_register_physical_memory(0x100000,
> + below_4g_mem_size - 0x100000,
> + ram_addr + 0x100000);
> + if (above_4g_mem_size > 0) {
> + cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
> + ram_addr + below_4g_mem_size);
> + }
> +
> + /* Initialize ROM or flash ranges for PC firmware */
> + pc_system_firmware_init();
> +
> + option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
> + cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE, option_rom_offset);
> +
> fw_cfg = bochs_bios_init();
> rom_set_fw(fw_cfg);
>
> --
> 1.7.1
>
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH v4] hw/pc: Support system flash memory with -pflash parameter
2011-07-08 19:37 [Qemu-devel] [PATCH v4] hw/pc: Support system flash memory with -pflash parameter Jordan Justen
2011-07-16 0:16 ` Jordan Justen
@ 2011-07-23 15:51 ` Anthony Liguori
2011-07-23 20:19 ` Jordan Justen
1 sibling, 1 reply; 9+ messages in thread
From: Anthony Liguori @ 2011-07-23 15:51 UTC (permalink / raw)
To: Jordan Justen; +Cc: Kevin Wolf, qemu-devel
On 07/08/2011 02:37 PM, Jordan Justen wrote:
> If -pflash is specified and -bios is specified then pflash will
> be mapped just below the system rom using hw/pflash_cfi01.c.
>
> If -pflash is specified on the command line, but -bios is
> not specified, then 'bios.bin' will NOT be loaded, and
> instead the -pflash flash image will be mapped just below
> 4GB in place of the normal rom image.
This is way too tied to the pc platform to be this generic.
I think a better approach would be to default to having unit=0 of
IF_PFLASH default to a read-only BDS that points to bios.bin. -bios
would just be a short cut to use a different file name but you should be
able to override with -drive too.
And to really simplify things, you could add a readonly flag to -bios
such that you could do:
-bios foo.img,readonly=off
Which is what I think you're looking for semantically.
Regards,
Anthony Liguori
>
> Signed-off-by: Jordan Justen<jordan.l.justen@intel.com>
> Reviewed-by: Aurelien Jarno<aurelien@aurel32.net>
> ---
> default-configs/i386-softmmu.mak | 1 +
> default-configs/x86_64-softmmu.mak | 1 +
> hw/pc.c | 161 +++++++++++++++++++++++++++---------
> 3 files changed, 125 insertions(+), 38 deletions(-)
>
> diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
> index 55589fa..8697cd4 100644
> --- a/default-configs/i386-softmmu.mak
> +++ b/default-configs/i386-softmmu.mak
> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
> CONFIG_SOUND=y
> CONFIG_HPET=y
> CONFIG_APPLESMC=y
> +CONFIG_PFLASH_CFI01=y
> diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
> index 8895028..eca9284 100644
> --- a/default-configs/x86_64-softmmu.mak
> +++ b/default-configs/x86_64-softmmu.mak
> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
> CONFIG_SOUND=y
> CONFIG_HPET=y
> CONFIG_APPLESMC=y
> +CONFIG_PFLASH_CFI01=y
> diff --git a/hw/pc.c b/hw/pc.c
> index a3e8539..e25354f 100644
> --- a/hw/pc.c
> +++ b/hw/pc.c
> @@ -41,6 +41,7 @@
> #include "sysemu.h"
> #include "blockdev.h"
> #include "ui/qemu-spice.h"
> +#include "flash.h"
>
> /* output Bochs bios info messages */
> //#define DEBUG_BIOS
> @@ -957,70 +958,154 @@ void pc_cpus_init(const char *cpu_model)
> }
> }
>
> -void pc_memory_init(const char *kernel_filename,
> - const char *kernel_cmdline,
> - const char *initrd_filename,
> - ram_addr_t below_4g_mem_size,
> - ram_addr_t above_4g_mem_size)
> +static void pc_isa_bios_init(ram_addr_t ram_offset, int ram_size)
> {
> - char *filename;
> - int ret, linux_boot, i;
> - ram_addr_t ram_addr, bios_offset, option_rom_offset;
> - int bios_size, isa_bios_size;
> - void *fw_cfg;
> -
> - linux_boot = (kernel_filename != NULL);
> + int isa_bios_size;
>
> - /* allocate RAM */
> - ram_addr = qemu_ram_alloc(NULL, "pc.ram",
> - below_4g_mem_size + above_4g_mem_size);
> - cpu_register_physical_memory(0, 0xa0000, ram_addr);
> - cpu_register_physical_memory(0x100000,
> - below_4g_mem_size - 0x100000,
> - ram_addr + 0x100000);
> - if (above_4g_mem_size> 0) {
> - cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
> - ram_addr + below_4g_mem_size);
> + /* map the last 128KB of the BIOS in ISA space */
> + isa_bios_size = ram_size;
> + if (isa_bios_size> (128 * 1024)) {
> + isa_bios_size = 128 * 1024;
> }
> + ram_offset = ram_offset + ram_size - isa_bios_size;
> + cpu_register_physical_memory(0x100000 - isa_bios_size,
> + isa_bios_size,
> + ram_offset | IO_MEM_ROM);
> +}
> +
> +static int pc_system_rom_init(void)
> +{
> + int ret;
> + int bios_size;
> + ram_addr_t bios_offset;
> + char *filename;
>
> /* BIOS load */
> - if (bios_name == NULL)
> + if (bios_name == NULL) {
> bios_name = BIOS_FILENAME;
> + }
> filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> if (filename) {
> bios_size = get_image_size(filename);
> } else {
> bios_size = -1;
> }
> - if (bios_size<= 0 ||
> - (bios_size % 65536) != 0) {
> - goto bios_error;
> +
> + if (bios_size<= 0 || (bios_size % 65536) != 0) {
> + ret = -1;
> + } else {
> + bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
> + ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
> }
> - bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
> - ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
> +
> if (ret != 0) {
> - bios_error:
> fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);
> exit(1);
> }
> +
> if (filename) {
> qemu_free(filename);
> }
> - /* map the last 128KB of the BIOS in ISA space */
> - isa_bios_size = bios_size;
> - if (isa_bios_size> (128 * 1024))
> - isa_bios_size = 128 * 1024;
> - cpu_register_physical_memory(0x100000 - isa_bios_size,
> - isa_bios_size,
> - (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
>
> - option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
> - cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE, option_rom_offset);
> + pc_isa_bios_init(bios_offset, bios_size);
>
> /* map all the bios at the top of memory */
> cpu_register_physical_memory((uint32_t)(-bios_size),
> bios_size, bios_offset | IO_MEM_ROM);
>
> + return bios_size;
> +}
> +
> +static void pc_system_flash_init(DriveInfo *pflash_drv, int rom_size)
> +{
> + BlockDriverState *bdrv;
> + int64_t size;
> + target_phys_addr_t phys_addr;
> + ram_addr_t addr;
> + int sector_bits, sector_size;
> +
> + bdrv = NULL;
> +
> + bdrv = pflash_drv->bdrv;
> + size = bdrv_getlength(pflash_drv->bdrv);
> + sector_bits = 12;
> + sector_size = 1<< sector_bits;
> +
> + if ((size % sector_size) != 0) {
> + fprintf(stderr,
> + "qemu: -pflash size must be a multiple of 0x%x\n",
> + sector_size);
> + exit(1);
> + }
> +
> + phys_addr = 0x100000000ULL - rom_size - size;
> + addr = qemu_ram_alloc(NULL, "system.flash", size);
> + DPRINTF("flash addr: 0x%lx\n", (int64_t)phys_addr);
> + pflash_cfi01_register(phys_addr, addr, bdrv,
> + sector_size, size>> sector_bits,
> + 4, 0x0000, 0x0000, 0x0000, 0x0000, 0);
> +
> + if (rom_size == 0) {
> + pc_isa_bios_init(addr, size);
> + }
> +}
> +
> +static void pc_system_firmware_init(void)
> +{
> + int flash_present, rom_present;
> + int rom_size;
> + DriveInfo *pflash_drv;
> +
> + pflash_drv = drive_get(IF_PFLASH, 0, 0);
> + flash_present = (pflash_drv != NULL);
> +
> + /* Load rom if -bios is used or if -pflash is not used */
> + rom_present = ((bios_name != NULL) || !flash_present);
> +
> + /* If rom is present, then it is mapped just below 4GB */
> + if (rom_present) {
> + rom_size = pc_system_rom_init();
> + } else {
> + rom_size = 0;
> + }
> +
> + /* If flash is present, then it is mapped just below the rom, or
> + * just below 4GB when rom is not present. */
> + if (flash_present) {
> + pc_system_flash_init(pflash_drv, rom_size);
> + }
> +}
> +
> +void pc_memory_init(const char *kernel_filename,
> + const char *kernel_cmdline,
> + const char *initrd_filename,
> + ram_addr_t below_4g_mem_size,
> + ram_addr_t above_4g_mem_size)
> +{
> + int linux_boot, i;
> + ram_addr_t ram_addr, option_rom_offset;
> + void *fw_cfg;
> +
> + linux_boot = (kernel_filename != NULL);
> +
> + /* allocate RAM */
> + ram_addr = qemu_ram_alloc(NULL, "pc.ram",
> + below_4g_mem_size + above_4g_mem_size);
> + cpu_register_physical_memory(0, 0xa0000, ram_addr);
> + cpu_register_physical_memory(0x100000,
> + below_4g_mem_size - 0x100000,
> + ram_addr + 0x100000);
> + if (above_4g_mem_size> 0) {
> + cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
> + ram_addr + below_4g_mem_size);
> + }
> +
> + /* Initialize ROM or flash ranges for PC firmware */
> + pc_system_firmware_init();
> +
> + option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
> + cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE, option_rom_offset);
> +
> fw_cfg = bochs_bios_init();
> rom_set_fw(fw_cfg);
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH v4] hw/pc: Support system flash memory with -pflash parameter
2011-07-23 15:51 ` Anthony Liguori
@ 2011-07-23 20:19 ` Jordan Justen
2011-07-23 21:25 ` Anthony Liguori
0 siblings, 1 reply; 9+ messages in thread
From: Jordan Justen @ 2011-07-23 20:19 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Kevin Wolf, Jordan Justen, qemu-devel
On Sat, Jul 23, 2011 at 08:51, Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 07/08/2011 02:37 PM, Jordan Justen wrote:
>>
>> If -pflash is specified and -bios is specified then pflash will
>> be mapped just below the system rom using hw/pflash_cfi01.c.
>>
>> If -pflash is specified on the command line, but -bios is
>> not specified, then 'bios.bin' will NOT be loaded, and
>> instead the -pflash flash image will be mapped just below
>> 4GB in place of the normal rom image.
>
> This is way too tied to the pc platform to be this generic.
>
> I think a better approach would be to default to having unit=0 of IF_PFLASH
> default to a read-only BDS that points to bios.bin. -bios would just be a
> short cut to use a different file name but you should be able to override
> with -drive too.
>
> And to really simplify things, you could add a readonly flag to -bios such
> that you could do:
>
> -bios foo.img,readonly=off
>
> Which is what I think you're looking for semantically.
There seemed to be some feedback on the list interested in preserving
a read-only firmware, and just adding a flash region.
So, for example, the firmware could be read from a common system
location like is generally done with bios.bin today, and VM instance
specific flash region could still be added.
If the entire firmware is moved to a separate VM instance specific
flash, then firmware update also gets complicated. It is no longer
just a matter of updating the qemu firmware package in your distro's
package management system.
What about taking your idea, but adding a second drive that would be
mapped just below the 1st if it is specified with -drive?
Thanks,
-Jordan
>
> Regards,
>
> Anthony Liguori
>
>>
>> Signed-off-by: Jordan Justen<jordan.l.justen@intel.com>
>> Reviewed-by: Aurelien Jarno<aurelien@aurel32.net>
>
>
>
>> ---
>> default-configs/i386-softmmu.mak | 1 +
>> default-configs/x86_64-softmmu.mak | 1 +
>> hw/pc.c | 161
>> +++++++++++++++++++++++++++---------
>> 3 files changed, 125 insertions(+), 38 deletions(-)
>>
>> diff --git a/default-configs/i386-softmmu.mak
>> b/default-configs/i386-softmmu.mak
>> index 55589fa..8697cd4 100644
>> --- a/default-configs/i386-softmmu.mak
>> +++ b/default-configs/i386-softmmu.mak
>> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
>> CONFIG_SOUND=y
>> CONFIG_HPET=y
>> CONFIG_APPLESMC=y
>> +CONFIG_PFLASH_CFI01=y
>> diff --git a/default-configs/x86_64-softmmu.mak
>> b/default-configs/x86_64-softmmu.mak
>> index 8895028..eca9284 100644
>> --- a/default-configs/x86_64-softmmu.mak
>> +++ b/default-configs/x86_64-softmmu.mak
>> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
>> CONFIG_SOUND=y
>> CONFIG_HPET=y
>> CONFIG_APPLESMC=y
>> +CONFIG_PFLASH_CFI01=y
>> diff --git a/hw/pc.c b/hw/pc.c
>> index a3e8539..e25354f 100644
>> --- a/hw/pc.c
>> +++ b/hw/pc.c
>> @@ -41,6 +41,7 @@
>> #include "sysemu.h"
>> #include "blockdev.h"
>> #include "ui/qemu-spice.h"
>> +#include "flash.h"
>>
>> /* output Bochs bios info messages */
>> //#define DEBUG_BIOS
>> @@ -957,70 +958,154 @@ void pc_cpus_init(const char *cpu_model)
>> }
>> }
>>
>> -void pc_memory_init(const char *kernel_filename,
>> - const char *kernel_cmdline,
>> - const char *initrd_filename,
>> - ram_addr_t below_4g_mem_size,
>> - ram_addr_t above_4g_mem_size)
>> +static void pc_isa_bios_init(ram_addr_t ram_offset, int ram_size)
>> {
>> - char *filename;
>> - int ret, linux_boot, i;
>> - ram_addr_t ram_addr, bios_offset, option_rom_offset;
>> - int bios_size, isa_bios_size;
>> - void *fw_cfg;
>> -
>> - linux_boot = (kernel_filename != NULL);
>> + int isa_bios_size;
>>
>> - /* allocate RAM */
>> - ram_addr = qemu_ram_alloc(NULL, "pc.ram",
>> - below_4g_mem_size + above_4g_mem_size);
>> - cpu_register_physical_memory(0, 0xa0000, ram_addr);
>> - cpu_register_physical_memory(0x100000,
>> - below_4g_mem_size - 0x100000,
>> - ram_addr + 0x100000);
>> - if (above_4g_mem_size> 0) {
>> - cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
>> - ram_addr + below_4g_mem_size);
>> + /* map the last 128KB of the BIOS in ISA space */
>> + isa_bios_size = ram_size;
>> + if (isa_bios_size> (128 * 1024)) {
>> + isa_bios_size = 128 * 1024;
>> }
>> + ram_offset = ram_offset + ram_size - isa_bios_size;
>> + cpu_register_physical_memory(0x100000 - isa_bios_size,
>> + isa_bios_size,
>> + ram_offset | IO_MEM_ROM);
>> +}
>> +
>> +static int pc_system_rom_init(void)
>> +{
>> + int ret;
>> + int bios_size;
>> + ram_addr_t bios_offset;
>> + char *filename;
>>
>> /* BIOS load */
>> - if (bios_name == NULL)
>> + if (bios_name == NULL) {
>> bios_name = BIOS_FILENAME;
>> + }
>> filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
>> if (filename) {
>> bios_size = get_image_size(filename);
>> } else {
>> bios_size = -1;
>> }
>> - if (bios_size<= 0 ||
>> - (bios_size % 65536) != 0) {
>> - goto bios_error;
>> +
>> + if (bios_size<= 0 || (bios_size % 65536) != 0) {
>> + ret = -1;
>> + } else {
>> + bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
>> + ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
>> }
>> - bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
>> - ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
>> +
>> if (ret != 0) {
>> - bios_error:
>> fprintf(stderr, "qemu: could not load PC BIOS '%s'\n",
>> bios_name);
>> exit(1);
>> }
>> +
>> if (filename) {
>> qemu_free(filename);
>> }
>> - /* map the last 128KB of the BIOS in ISA space */
>> - isa_bios_size = bios_size;
>> - if (isa_bios_size> (128 * 1024))
>> - isa_bios_size = 128 * 1024;
>> - cpu_register_physical_memory(0x100000 - isa_bios_size,
>> - isa_bios_size,
>> - (bios_offset + bios_size -
>> isa_bios_size) | IO_MEM_ROM);
>>
>> - option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
>> - cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE,
>> option_rom_offset);
>> + pc_isa_bios_init(bios_offset, bios_size);
>>
>> /* map all the bios at the top of memory */
>> cpu_register_physical_memory((uint32_t)(-bios_size),
>> bios_size, bios_offset | IO_MEM_ROM);
>>
>> + return bios_size;
>> +}
>> +
>> +static void pc_system_flash_init(DriveInfo *pflash_drv, int rom_size)
>> +{
>> + BlockDriverState *bdrv;
>> + int64_t size;
>> + target_phys_addr_t phys_addr;
>> + ram_addr_t addr;
>> + int sector_bits, sector_size;
>> +
>> + bdrv = NULL;
>> +
>> + bdrv = pflash_drv->bdrv;
>> + size = bdrv_getlength(pflash_drv->bdrv);
>> + sector_bits = 12;
>> + sector_size = 1<< sector_bits;
>> +
>> + if ((size % sector_size) != 0) {
>> + fprintf(stderr,
>> + "qemu: -pflash size must be a multiple of 0x%x\n",
>> + sector_size);
>> + exit(1);
>> + }
>> +
>> + phys_addr = 0x100000000ULL - rom_size - size;
>> + addr = qemu_ram_alloc(NULL, "system.flash", size);
>> + DPRINTF("flash addr: 0x%lx\n", (int64_t)phys_addr);
>> + pflash_cfi01_register(phys_addr, addr, bdrv,
>> + sector_size, size>> sector_bits,
>> + 4, 0x0000, 0x0000, 0x0000, 0x0000, 0);
>> +
>> + if (rom_size == 0) {
>> + pc_isa_bios_init(addr, size);
>> + }
>> +}
>> +
>> +static void pc_system_firmware_init(void)
>> +{
>> + int flash_present, rom_present;
>> + int rom_size;
>> + DriveInfo *pflash_drv;
>> +
>> + pflash_drv = drive_get(IF_PFLASH, 0, 0);
>> + flash_present = (pflash_drv != NULL);
>> +
>> + /* Load rom if -bios is used or if -pflash is not used */
>> + rom_present = ((bios_name != NULL) || !flash_present);
>> +
>> + /* If rom is present, then it is mapped just below 4GB */
>> + if (rom_present) {
>> + rom_size = pc_system_rom_init();
>> + } else {
>> + rom_size = 0;
>> + }
>> +
>> + /* If flash is present, then it is mapped just below the rom, or
>> + * just below 4GB when rom is not present. */
>> + if (flash_present) {
>> + pc_system_flash_init(pflash_drv, rom_size);
>> + }
>> +}
>> +
>> +void pc_memory_init(const char *kernel_filename,
>> + const char *kernel_cmdline,
>> + const char *initrd_filename,
>> + ram_addr_t below_4g_mem_size,
>> + ram_addr_t above_4g_mem_size)
>> +{
>> + int linux_boot, i;
>> + ram_addr_t ram_addr, option_rom_offset;
>> + void *fw_cfg;
>> +
>> + linux_boot = (kernel_filename != NULL);
>> +
>> + /* allocate RAM */
>> + ram_addr = qemu_ram_alloc(NULL, "pc.ram",
>> + below_4g_mem_size + above_4g_mem_size);
>> + cpu_register_physical_memory(0, 0xa0000, ram_addr);
>> + cpu_register_physical_memory(0x100000,
>> + below_4g_mem_size - 0x100000,
>> + ram_addr + 0x100000);
>> + if (above_4g_mem_size> 0) {
>> + cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
>> + ram_addr + below_4g_mem_size);
>> + }
>> +
>> + /* Initialize ROM or flash ranges for PC firmware */
>> + pc_system_firmware_init();
>> +
>> + option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
>> + cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE,
>> option_rom_offset);
>> +
>> fw_cfg = bochs_bios_init();
>> rom_set_fw(fw_cfg);
>>
>
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH v4] hw/pc: Support system flash memory with -pflash parameter
2011-07-23 20:19 ` Jordan Justen
@ 2011-07-23 21:25 ` Anthony Liguori
2011-07-23 22:06 ` Jordan Justen
0 siblings, 1 reply; 9+ messages in thread
From: Anthony Liguori @ 2011-07-23 21:25 UTC (permalink / raw)
To: Jordan Justen; +Cc: Kevin Wolf, Jordan Justen, qemu-devel
On 07/23/2011 03:19 PM, Jordan Justen wrote:
> On Sat, Jul 23, 2011 at 08:51, Anthony Liguori<anthony@codemonkey.ws> wrote:
>> On 07/08/2011 02:37 PM, Jordan Justen wrote:
>>>
>>> If -pflash is specified and -bios is specified then pflash will
>>> be mapped just below the system rom using hw/pflash_cfi01.c.
>>>
>>> If -pflash is specified on the command line, but -bios is
>>> not specified, then 'bios.bin' will NOT be loaded, and
>>> instead the -pflash flash image will be mapped just below
>>> 4GB in place of the normal rom image.
>>
>> This is way too tied to the pc platform to be this generic.
>>
>> I think a better approach would be to default to having unit=0 of IF_PFLASH
>> default to a read-only BDS that points to bios.bin. -bios would just be a
>> short cut to use a different file name but you should be able to override
>> with -drive too.
>>
>> And to really simplify things, you could add a readonly flag to -bios such
>> that you could do:
>>
>> -bios foo.img,readonly=off
>>
>> Which is what I think you're looking for semantically.
>
> There seemed to be some feedback on the list interested in preserving
> a read-only firmware, and just adding a flash region.
>
> So, for example, the firmware could be read from a common system
> location like is generally done with bios.bin today, and VM instance
> specific flash region could still be added.
You can have multiple flash regions.
You're introducing two modes. In one mode, we emulate a flash device
and expose it for the BIOS ROM. In the second mode, we don't emulate a
device but we expose the BIOS ROM based on a file in a shared read-only
location.
I'm suggesting always emulating a flash device, but by default make the
device read-only and have it be loaded from a file in a shared read-only
location.
That means we have a single code path and a consistent view from a
management tooling perspective. IOW, management tools will always see
that there is a BIOS block device, and they need to worry about making
sure that BIOS block device is there.
>
> If the entire firmware is moved to a separate VM instance specific
> flash, then firmware update also gets complicated. It is no longer
> just a matter of updating the qemu firmware package in your distro's
> package management system.
I think the bit your misunderstanding is that you should default the
firmware to be created from a common file as a read-only device.
Regards,
Anthony Liguori
>
> What about taking your idea, but adding a second drive that would be
> mapped just below the 1st if it is specified with -drive?
>
> Thanks,
>
> -Jordan
>
>>
>> Regards,
>>
>> Anthony Liguori
>>
>>>
>>> Signed-off-by: Jordan Justen<jordan.l.justen@intel.com>
>>> Reviewed-by: Aurelien Jarno<aurelien@aurel32.net>
>>
>>
>>
>>> ---
>>> default-configs/i386-softmmu.mak | 1 +
>>> default-configs/x86_64-softmmu.mak | 1 +
>>> hw/pc.c | 161
>>> +++++++++++++++++++++++++++---------
>>> 3 files changed, 125 insertions(+), 38 deletions(-)
>>>
>>> diff --git a/default-configs/i386-softmmu.mak
>>> b/default-configs/i386-softmmu.mak
>>> index 55589fa..8697cd4 100644
>>> --- a/default-configs/i386-softmmu.mak
>>> +++ b/default-configs/i386-softmmu.mak
>>> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
>>> CONFIG_SOUND=y
>>> CONFIG_HPET=y
>>> CONFIG_APPLESMC=y
>>> +CONFIG_PFLASH_CFI01=y
>>> diff --git a/default-configs/x86_64-softmmu.mak
>>> b/default-configs/x86_64-softmmu.mak
>>> index 8895028..eca9284 100644
>>> --- a/default-configs/x86_64-softmmu.mak
>>> +++ b/default-configs/x86_64-softmmu.mak
>>> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
>>> CONFIG_SOUND=y
>>> CONFIG_HPET=y
>>> CONFIG_APPLESMC=y
>>> +CONFIG_PFLASH_CFI01=y
>>> diff --git a/hw/pc.c b/hw/pc.c
>>> index a3e8539..e25354f 100644
>>> --- a/hw/pc.c
>>> +++ b/hw/pc.c
>>> @@ -41,6 +41,7 @@
>>> #include "sysemu.h"
>>> #include "blockdev.h"
>>> #include "ui/qemu-spice.h"
>>> +#include "flash.h"
>>>
>>> /* output Bochs bios info messages */
>>> //#define DEBUG_BIOS
>>> @@ -957,70 +958,154 @@ void pc_cpus_init(const char *cpu_model)
>>> }
>>> }
>>>
>>> -void pc_memory_init(const char *kernel_filename,
>>> - const char *kernel_cmdline,
>>> - const char *initrd_filename,
>>> - ram_addr_t below_4g_mem_size,
>>> - ram_addr_t above_4g_mem_size)
>>> +static void pc_isa_bios_init(ram_addr_t ram_offset, int ram_size)
>>> {
>>> - char *filename;
>>> - int ret, linux_boot, i;
>>> - ram_addr_t ram_addr, bios_offset, option_rom_offset;
>>> - int bios_size, isa_bios_size;
>>> - void *fw_cfg;
>>> -
>>> - linux_boot = (kernel_filename != NULL);
>>> + int isa_bios_size;
>>>
>>> - /* allocate RAM */
>>> - ram_addr = qemu_ram_alloc(NULL, "pc.ram",
>>> - below_4g_mem_size + above_4g_mem_size);
>>> - cpu_register_physical_memory(0, 0xa0000, ram_addr);
>>> - cpu_register_physical_memory(0x100000,
>>> - below_4g_mem_size - 0x100000,
>>> - ram_addr + 0x100000);
>>> - if (above_4g_mem_size> 0) {
>>> - cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
>>> - ram_addr + below_4g_mem_size);
>>> + /* map the last 128KB of the BIOS in ISA space */
>>> + isa_bios_size = ram_size;
>>> + if (isa_bios_size> (128 * 1024)) {
>>> + isa_bios_size = 128 * 1024;
>>> }
>>> + ram_offset = ram_offset + ram_size - isa_bios_size;
>>> + cpu_register_physical_memory(0x100000 - isa_bios_size,
>>> + isa_bios_size,
>>> + ram_offset | IO_MEM_ROM);
>>> +}
>>> +
>>> +static int pc_system_rom_init(void)
>>> +{
>>> + int ret;
>>> + int bios_size;
>>> + ram_addr_t bios_offset;
>>> + char *filename;
>>>
>>> /* BIOS load */
>>> - if (bios_name == NULL)
>>> + if (bios_name == NULL) {
>>> bios_name = BIOS_FILENAME;
>>> + }
>>> filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
>>> if (filename) {
>>> bios_size = get_image_size(filename);
>>> } else {
>>> bios_size = -1;
>>> }
>>> - if (bios_size<= 0 ||
>>> - (bios_size % 65536) != 0) {
>>> - goto bios_error;
>>> +
>>> + if (bios_size<= 0 || (bios_size % 65536) != 0) {
>>> + ret = -1;
>>> + } else {
>>> + bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
>>> + ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
>>> }
>>> - bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
>>> - ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
>>> +
>>> if (ret != 0) {
>>> - bios_error:
>>> fprintf(stderr, "qemu: could not load PC BIOS '%s'\n",
>>> bios_name);
>>> exit(1);
>>> }
>>> +
>>> if (filename) {
>>> qemu_free(filename);
>>> }
>>> - /* map the last 128KB of the BIOS in ISA space */
>>> - isa_bios_size = bios_size;
>>> - if (isa_bios_size> (128 * 1024))
>>> - isa_bios_size = 128 * 1024;
>>> - cpu_register_physical_memory(0x100000 - isa_bios_size,
>>> - isa_bios_size,
>>> - (bios_offset + bios_size -
>>> isa_bios_size) | IO_MEM_ROM);
>>>
>>> - option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
>>> - cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE,
>>> option_rom_offset);
>>> + pc_isa_bios_init(bios_offset, bios_size);
>>>
>>> /* map all the bios at the top of memory */
>>> cpu_register_physical_memory((uint32_t)(-bios_size),
>>> bios_size, bios_offset | IO_MEM_ROM);
>>>
>>> + return bios_size;
>>> +}
>>> +
>>> +static void pc_system_flash_init(DriveInfo *pflash_drv, int rom_size)
>>> +{
>>> + BlockDriverState *bdrv;
>>> + int64_t size;
>>> + target_phys_addr_t phys_addr;
>>> + ram_addr_t addr;
>>> + int sector_bits, sector_size;
>>> +
>>> + bdrv = NULL;
>>> +
>>> + bdrv = pflash_drv->bdrv;
>>> + size = bdrv_getlength(pflash_drv->bdrv);
>>> + sector_bits = 12;
>>> + sector_size = 1<< sector_bits;
>>> +
>>> + if ((size % sector_size) != 0) {
>>> + fprintf(stderr,
>>> + "qemu: -pflash size must be a multiple of 0x%x\n",
>>> + sector_size);
>>> + exit(1);
>>> + }
>>> +
>>> + phys_addr = 0x100000000ULL - rom_size - size;
>>> + addr = qemu_ram_alloc(NULL, "system.flash", size);
>>> + DPRINTF("flash addr: 0x%lx\n", (int64_t)phys_addr);
>>> + pflash_cfi01_register(phys_addr, addr, bdrv,
>>> + sector_size, size>> sector_bits,
>>> + 4, 0x0000, 0x0000, 0x0000, 0x0000, 0);
>>> +
>>> + if (rom_size == 0) {
>>> + pc_isa_bios_init(addr, size);
>>> + }
>>> +}
>>> +
>>> +static void pc_system_firmware_init(void)
>>> +{
>>> + int flash_present, rom_present;
>>> + int rom_size;
>>> + DriveInfo *pflash_drv;
>>> +
>>> + pflash_drv = drive_get(IF_PFLASH, 0, 0);
>>> + flash_present = (pflash_drv != NULL);
>>> +
>>> + /* Load rom if -bios is used or if -pflash is not used */
>>> + rom_present = ((bios_name != NULL) || !flash_present);
>>> +
>>> + /* If rom is present, then it is mapped just below 4GB */
>>> + if (rom_present) {
>>> + rom_size = pc_system_rom_init();
>>> + } else {
>>> + rom_size = 0;
>>> + }
>>> +
>>> + /* If flash is present, then it is mapped just below the rom, or
>>> + * just below 4GB when rom is not present. */
>>> + if (flash_present) {
>>> + pc_system_flash_init(pflash_drv, rom_size);
>>> + }
>>> +}
>>> +
>>> +void pc_memory_init(const char *kernel_filename,
>>> + const char *kernel_cmdline,
>>> + const char *initrd_filename,
>>> + ram_addr_t below_4g_mem_size,
>>> + ram_addr_t above_4g_mem_size)
>>> +{
>>> + int linux_boot, i;
>>> + ram_addr_t ram_addr, option_rom_offset;
>>> + void *fw_cfg;
>>> +
>>> + linux_boot = (kernel_filename != NULL);
>>> +
>>> + /* allocate RAM */
>>> + ram_addr = qemu_ram_alloc(NULL, "pc.ram",
>>> + below_4g_mem_size + above_4g_mem_size);
>>> + cpu_register_physical_memory(0, 0xa0000, ram_addr);
>>> + cpu_register_physical_memory(0x100000,
>>> + below_4g_mem_size - 0x100000,
>>> + ram_addr + 0x100000);
>>> + if (above_4g_mem_size> 0) {
>>> + cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
>>> + ram_addr + below_4g_mem_size);
>>> + }
>>> +
>>> + /* Initialize ROM or flash ranges for PC firmware */
>>> + pc_system_firmware_init();
>>> +
>>> + option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
>>> + cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE,
>>> option_rom_offset);
>>> +
>>> fw_cfg = bochs_bios_init();
>>> rom_set_fw(fw_cfg);
>>>
>>
>>
>>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH v4] hw/pc: Support system flash memory with -pflash parameter
2011-07-23 21:25 ` Anthony Liguori
@ 2011-07-23 22:06 ` Jordan Justen
2011-07-23 22:26 ` Anthony Liguori
0 siblings, 1 reply; 9+ messages in thread
From: Jordan Justen @ 2011-07-23 22:06 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Kevin Wolf, Jordan Justen, qemu-devel
On Sat, Jul 23, 2011 at 14:25, Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 07/23/2011 03:19 PM, Jordan Justen wrote:
>>
>> On Sat, Jul 23, 2011 at 08:51, Anthony Liguori<anthony@codemonkey.ws>
>> wrote:
>>>
>>> On 07/08/2011 02:37 PM, Jordan Justen wrote:
>>>>
>>>> If -pflash is specified and -bios is specified then pflash will
>>>> be mapped just below the system rom using hw/pflash_cfi01.c.
>>>>
>>>> If -pflash is specified on the command line, but -bios is
>>>> not specified, then 'bios.bin' will NOT be loaded, and
>>>> instead the -pflash flash image will be mapped just below
>>>> 4GB in place of the normal rom image.
>>>
>>> This is way too tied to the pc platform to be this generic.
>>>
>>> I think a better approach would be to default to having unit=0 of
>>> IF_PFLASH
>>> default to a read-only BDS that points to bios.bin. -bios would just be
>>> a
>>> short cut to use a different file name but you should be able to override
>>> with -drive too.
>>>
>>> And to really simplify things, you could add a readonly flag to -bios
>>> such
>>> that you could do:
>>>
>>> -bios foo.img,readonly=off
>>>
>>> Which is what I think you're looking for semantically.
>>
>> There seemed to be some feedback on the list interested in preserving
>> a read-only firmware, and just adding a flash region.
>>
>> So, for example, the firmware could be read from a common system
>> location like is generally done with bios.bin today, and VM instance
>> specific flash region could still be added.
>
> You can have multiple flash regions.
So, is your recommendation that we support N pflash images in
x86/x86-64? Instance/index 0 is mapped just under 4GB, and the rest
follow below this?
This seems like a good plan, although I can't see a usage for more
than 2 instances.
-Jordan
> You're introducing two modes. In one mode, we emulate a flash device and
> expose it for the BIOS ROM. In the second mode, we don't emulate a device
> but we expose the BIOS ROM based on a file in a shared read-only location.
>
> I'm suggesting always emulating a flash device, but by default make the
> device read-only and have it be loaded from a file in a shared read-only
> location.
>
> That means we have a single code path and a consistent view from a
> management tooling perspective. IOW, management tools will always see that
> there is a BIOS block device, and they need to worry about making sure that
> BIOS block device is there.
>
>>
>> If the entire firmware is moved to a separate VM instance specific
>> flash, then firmware update also gets complicated. It is no longer
>> just a matter of updating the qemu firmware package in your distro's
>> package management system.
>
> I think the bit your misunderstanding is that you should default the
> firmware to be created from a common file as a read-only device.
>
> Regards,
>
> Anthony Liguori
>
>>
>> What about taking your idea, but adding a second drive that would be
>> mapped just below the 1st if it is specified with -drive?
>>
>> Thanks,
>>
>> -Jordan
>>
>>>
>>> Regards,
>>>
>>> Anthony Liguori
>>>
>>>>
>>>> Signed-off-by: Jordan Justen<jordan.l.justen@intel.com>
>>>> Reviewed-by: Aurelien Jarno<aurelien@aurel32.net>
>>>
>>>
>>>
>>>> ---
>>>> default-configs/i386-softmmu.mak | 1 +
>>>> default-configs/x86_64-softmmu.mak | 1 +
>>>> hw/pc.c | 161
>>>> +++++++++++++++++++++++++++---------
>>>> 3 files changed, 125 insertions(+), 38 deletions(-)
>>>>
>>>> diff --git a/default-configs/i386-softmmu.mak
>>>> b/default-configs/i386-softmmu.mak
>>>> index 55589fa..8697cd4 100644
>>>> --- a/default-configs/i386-softmmu.mak
>>>> +++ b/default-configs/i386-softmmu.mak
>>>> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
>>>> CONFIG_SOUND=y
>>>> CONFIG_HPET=y
>>>> CONFIG_APPLESMC=y
>>>> +CONFIG_PFLASH_CFI01=y
>>>> diff --git a/default-configs/x86_64-softmmu.mak
>>>> b/default-configs/x86_64-softmmu.mak
>>>> index 8895028..eca9284 100644
>>>> --- a/default-configs/x86_64-softmmu.mak
>>>> +++ b/default-configs/x86_64-softmmu.mak
>>>> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
>>>> CONFIG_SOUND=y
>>>> CONFIG_HPET=y
>>>> CONFIG_APPLESMC=y
>>>> +CONFIG_PFLASH_CFI01=y
>>>> diff --git a/hw/pc.c b/hw/pc.c
>>>> index a3e8539..e25354f 100644
>>>> --- a/hw/pc.c
>>>> +++ b/hw/pc.c
>>>> @@ -41,6 +41,7 @@
>>>> #include "sysemu.h"
>>>> #include "blockdev.h"
>>>> #include "ui/qemu-spice.h"
>>>> +#include "flash.h"
>>>>
>>>> /* output Bochs bios info messages */
>>>> //#define DEBUG_BIOS
>>>> @@ -957,70 +958,154 @@ void pc_cpus_init(const char *cpu_model)
>>>> }
>>>> }
>>>>
>>>> -void pc_memory_init(const char *kernel_filename,
>>>> - const char *kernel_cmdline,
>>>> - const char *initrd_filename,
>>>> - ram_addr_t below_4g_mem_size,
>>>> - ram_addr_t above_4g_mem_size)
>>>> +static void pc_isa_bios_init(ram_addr_t ram_offset, int ram_size)
>>>> {
>>>> - char *filename;
>>>> - int ret, linux_boot, i;
>>>> - ram_addr_t ram_addr, bios_offset, option_rom_offset;
>>>> - int bios_size, isa_bios_size;
>>>> - void *fw_cfg;
>>>> -
>>>> - linux_boot = (kernel_filename != NULL);
>>>> + int isa_bios_size;
>>>>
>>>> - /* allocate RAM */
>>>> - ram_addr = qemu_ram_alloc(NULL, "pc.ram",
>>>> - below_4g_mem_size + above_4g_mem_size);
>>>> - cpu_register_physical_memory(0, 0xa0000, ram_addr);
>>>> - cpu_register_physical_memory(0x100000,
>>>> - below_4g_mem_size - 0x100000,
>>>> - ram_addr + 0x100000);
>>>> - if (above_4g_mem_size> 0) {
>>>> - cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
>>>> - ram_addr + below_4g_mem_size);
>>>> + /* map the last 128KB of the BIOS in ISA space */
>>>> + isa_bios_size = ram_size;
>>>> + if (isa_bios_size> (128 * 1024)) {
>>>> + isa_bios_size = 128 * 1024;
>>>> }
>>>> + ram_offset = ram_offset + ram_size - isa_bios_size;
>>>> + cpu_register_physical_memory(0x100000 - isa_bios_size,
>>>> + isa_bios_size,
>>>> + ram_offset | IO_MEM_ROM);
>>>> +}
>>>> +
>>>> +static int pc_system_rom_init(void)
>>>> +{
>>>> + int ret;
>>>> + int bios_size;
>>>> + ram_addr_t bios_offset;
>>>> + char *filename;
>>>>
>>>> /* BIOS load */
>>>> - if (bios_name == NULL)
>>>> + if (bios_name == NULL) {
>>>> bios_name = BIOS_FILENAME;
>>>> + }
>>>> filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
>>>> if (filename) {
>>>> bios_size = get_image_size(filename);
>>>> } else {
>>>> bios_size = -1;
>>>> }
>>>> - if (bios_size<= 0 ||
>>>> - (bios_size % 65536) != 0) {
>>>> - goto bios_error;
>>>> +
>>>> + if (bios_size<= 0 || (bios_size % 65536) != 0) {
>>>> + ret = -1;
>>>> + } else {
>>>> + bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
>>>> + ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size),
>>>> -1);
>>>> }
>>>> - bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
>>>> - ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
>>>> +
>>>> if (ret != 0) {
>>>> - bios_error:
>>>> fprintf(stderr, "qemu: could not load PC BIOS '%s'\n",
>>>> bios_name);
>>>> exit(1);
>>>> }
>>>> +
>>>> if (filename) {
>>>> qemu_free(filename);
>>>> }
>>>> - /* map the last 128KB of the BIOS in ISA space */
>>>> - isa_bios_size = bios_size;
>>>> - if (isa_bios_size> (128 * 1024))
>>>> - isa_bios_size = 128 * 1024;
>>>> - cpu_register_physical_memory(0x100000 - isa_bios_size,
>>>> - isa_bios_size,
>>>> - (bios_offset + bios_size -
>>>> isa_bios_size) | IO_MEM_ROM);
>>>>
>>>> - option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
>>>> - cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE,
>>>> option_rom_offset);
>>>> + pc_isa_bios_init(bios_offset, bios_size);
>>>>
>>>> /* map all the bios at the top of memory */
>>>> cpu_register_physical_memory((uint32_t)(-bios_size),
>>>> bios_size, bios_offset | IO_MEM_ROM);
>>>>
>>>> + return bios_size;
>>>> +}
>>>> +
>>>> +static void pc_system_flash_init(DriveInfo *pflash_drv, int rom_size)
>>>> +{
>>>> + BlockDriverState *bdrv;
>>>> + int64_t size;
>>>> + target_phys_addr_t phys_addr;
>>>> + ram_addr_t addr;
>>>> + int sector_bits, sector_size;
>>>> +
>>>> + bdrv = NULL;
>>>> +
>>>> + bdrv = pflash_drv->bdrv;
>>>> + size = bdrv_getlength(pflash_drv->bdrv);
>>>> + sector_bits = 12;
>>>> + sector_size = 1<< sector_bits;
>>>> +
>>>> + if ((size % sector_size) != 0) {
>>>> + fprintf(stderr,
>>>> + "qemu: -pflash size must be a multiple of 0x%x\n",
>>>> + sector_size);
>>>> + exit(1);
>>>> + }
>>>> +
>>>> + phys_addr = 0x100000000ULL - rom_size - size;
>>>> + addr = qemu_ram_alloc(NULL, "system.flash", size);
>>>> + DPRINTF("flash addr: 0x%lx\n", (int64_t)phys_addr);
>>>> + pflash_cfi01_register(phys_addr, addr, bdrv,
>>>> + sector_size, size>> sector_bits,
>>>> + 4, 0x0000, 0x0000, 0x0000, 0x0000, 0);
>>>> +
>>>> + if (rom_size == 0) {
>>>> + pc_isa_bios_init(addr, size);
>>>> + }
>>>> +}
>>>> +
>>>> +static void pc_system_firmware_init(void)
>>>> +{
>>>> + int flash_present, rom_present;
>>>> + int rom_size;
>>>> + DriveInfo *pflash_drv;
>>>> +
>>>> + pflash_drv = drive_get(IF_PFLASH, 0, 0);
>>>> + flash_present = (pflash_drv != NULL);
>>>> +
>>>> + /* Load rom if -bios is used or if -pflash is not used */
>>>> + rom_present = ((bios_name != NULL) || !flash_present);
>>>> +
>>>> + /* If rom is present, then it is mapped just below 4GB */
>>>> + if (rom_present) {
>>>> + rom_size = pc_system_rom_init();
>>>> + } else {
>>>> + rom_size = 0;
>>>> + }
>>>> +
>>>> + /* If flash is present, then it is mapped just below the rom, or
>>>> + * just below 4GB when rom is not present. */
>>>> + if (flash_present) {
>>>> + pc_system_flash_init(pflash_drv, rom_size);
>>>> + }
>>>> +}
>>>> +
>>>> +void pc_memory_init(const char *kernel_filename,
>>>> + const char *kernel_cmdline,
>>>> + const char *initrd_filename,
>>>> + ram_addr_t below_4g_mem_size,
>>>> + ram_addr_t above_4g_mem_size)
>>>> +{
>>>> + int linux_boot, i;
>>>> + ram_addr_t ram_addr, option_rom_offset;
>>>> + void *fw_cfg;
>>>> +
>>>> + linux_boot = (kernel_filename != NULL);
>>>> +
>>>> + /* allocate RAM */
>>>> + ram_addr = qemu_ram_alloc(NULL, "pc.ram",
>>>> + below_4g_mem_size + above_4g_mem_size);
>>>> + cpu_register_physical_memory(0, 0xa0000, ram_addr);
>>>> + cpu_register_physical_memory(0x100000,
>>>> + below_4g_mem_size - 0x100000,
>>>> + ram_addr + 0x100000);
>>>> + if (above_4g_mem_size> 0) {
>>>> + cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
>>>> + ram_addr + below_4g_mem_size);
>>>> + }
>>>> +
>>>> + /* Initialize ROM or flash ranges for PC firmware */
>>>> + pc_system_firmware_init();
>>>> +
>>>> + option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
>>>> + cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE,
>>>> option_rom_offset);
>>>> +
>>>> fw_cfg = bochs_bios_init();
>>>> rom_set_fw(fw_cfg);
>>>>
>>>
>>>
>>>
>>
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH v4] hw/pc: Support system flash memory with -pflash parameter
2011-07-23 22:06 ` Jordan Justen
@ 2011-07-23 22:26 ` Anthony Liguori
2011-07-24 0:18 ` Jordan Justen
0 siblings, 1 reply; 9+ messages in thread
From: Anthony Liguori @ 2011-07-23 22:26 UTC (permalink / raw)
To: Jordan Justen; +Cc: Kevin Wolf, Jordan Justen, qemu-devel
On 07/23/2011 05:06 PM, Jordan Justen wrote:
> On Sat, Jul 23, 2011 at 14:25, Anthony Liguori<anthony@codemonkey.ws> wrote:
>> On 07/23/2011 03:19 PM, Jordan Justen wrote:
>>>
>>> On Sat, Jul 23, 2011 at 08:51, Anthony Liguori<anthony@codemonkey.ws>
>>> wrote:
>>>>
>>>> On 07/08/2011 02:37 PM, Jordan Justen wrote:
>>>>>
>>>>> If -pflash is specified and -bios is specified then pflash will
>>>>> be mapped just below the system rom using hw/pflash_cfi01.c.
>>>>>
>>>>> If -pflash is specified on the command line, but -bios is
>>>>> not specified, then 'bios.bin' will NOT be loaded, and
>>>>> instead the -pflash flash image will be mapped just below
>>>>> 4GB in place of the normal rom image.
>>>>
>>>> This is way too tied to the pc platform to be this generic.
>>>>
>>>> I think a better approach would be to default to having unit=0 of
>>>> IF_PFLASH
>>>> default to a read-only BDS that points to bios.bin. -bios would just be
>>>> a
>>>> short cut to use a different file name but you should be able to override
>>>> with -drive too.
>>>>
>>>> And to really simplify things, you could add a readonly flag to -bios
>>>> such
>>>> that you could do:
>>>>
>>>> -bios foo.img,readonly=off
>>>>
>>>> Which is what I think you're looking for semantically.
>>>
>>> There seemed to be some feedback on the list interested in preserving
>>> a read-only firmware, and just adding a flash region.
>>>
>>> So, for example, the firmware could be read from a common system
>>> location like is generally done with bios.bin today, and VM instance
>>> specific flash region could still be added.
>>
>> You can have multiple flash regions.
>
> So, is your recommendation that we support N pflash images in
> x86/x86-64? Instance/index 0 is mapped just under 4GB, and the rest
> follow below this?
No. There should be a flash device, pflash index 0 is fine, but it
should be mapped under 4GB and also in the legacy BIOS space.
This is the PC firmware flash. By default it should be read-only and it
should be created by using ${prefix}/share/bios.bin. But it should be
possible to override both the filename and the read-only flag.
In terms of other flash devices, I don't think it's that simple. Flash
is tied to the mobo layout so I don't think index > 0 really makes sense
unless you allow a specific mapping address. I doubt that's terribly
useful.
Regards,
Anthony Liguori
>
> This seems like a good plan, although I can't see a usage for more
> than 2 instances.
>
> -Jordan
>
>> You're introducing two modes. In one mode, we emulate a flash device and
>> expose it for the BIOS ROM. In the second mode, we don't emulate a device
>> but we expose the BIOS ROM based on a file in a shared read-only location.
>>
>> I'm suggesting always emulating a flash device, but by default make the
>> device read-only and have it be loaded from a file in a shared read-only
>> location.
>>
>> That means we have a single code path and a consistent view from a
>> management tooling perspective. IOW, management tools will always see that
>> there is a BIOS block device, and they need to worry about making sure that
>> BIOS block device is there.
>>
>>>
>>> If the entire firmware is moved to a separate VM instance specific
>>> flash, then firmware update also gets complicated. It is no longer
>>> just a matter of updating the qemu firmware package in your distro's
>>> package management system.
>>
>> I think the bit your misunderstanding is that you should default the
>> firmware to be created from a common file as a read-only device.
>>
>> Regards,
>>
>> Anthony Liguori
>>
>>>
>>> What about taking your idea, but adding a second drive that would be
>>> mapped just below the 1st if it is specified with -drive?
>>>
>>> Thanks,
>>>
>>> -Jordan
>>>
>>>>
>>>> Regards,
>>>>
>>>> Anthony Liguori
>>>>
>>>>>
>>>>> Signed-off-by: Jordan Justen<jordan.l.justen@intel.com>
>>>>> Reviewed-by: Aurelien Jarno<aurelien@aurel32.net>
>>>>
>>>>
>>>>
>>>>> ---
>>>>> default-configs/i386-softmmu.mak | 1 +
>>>>> default-configs/x86_64-softmmu.mak | 1 +
>>>>> hw/pc.c | 161
>>>>> +++++++++++++++++++++++++++---------
>>>>> 3 files changed, 125 insertions(+), 38 deletions(-)
>>>>>
>>>>> diff --git a/default-configs/i386-softmmu.mak
>>>>> b/default-configs/i386-softmmu.mak
>>>>> index 55589fa..8697cd4 100644
>>>>> --- a/default-configs/i386-softmmu.mak
>>>>> +++ b/default-configs/i386-softmmu.mak
>>>>> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
>>>>> CONFIG_SOUND=y
>>>>> CONFIG_HPET=y
>>>>> CONFIG_APPLESMC=y
>>>>> +CONFIG_PFLASH_CFI01=y
>>>>> diff --git a/default-configs/x86_64-softmmu.mak
>>>>> b/default-configs/x86_64-softmmu.mak
>>>>> index 8895028..eca9284 100644
>>>>> --- a/default-configs/x86_64-softmmu.mak
>>>>> +++ b/default-configs/x86_64-softmmu.mak
>>>>> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
>>>>> CONFIG_SOUND=y
>>>>> CONFIG_HPET=y
>>>>> CONFIG_APPLESMC=y
>>>>> +CONFIG_PFLASH_CFI01=y
>>>>> diff --git a/hw/pc.c b/hw/pc.c
>>>>> index a3e8539..e25354f 100644
>>>>> --- a/hw/pc.c
>>>>> +++ b/hw/pc.c
>>>>> @@ -41,6 +41,7 @@
>>>>> #include "sysemu.h"
>>>>> #include "blockdev.h"
>>>>> #include "ui/qemu-spice.h"
>>>>> +#include "flash.h"
>>>>>
>>>>> /* output Bochs bios info messages */
>>>>> //#define DEBUG_BIOS
>>>>> @@ -957,70 +958,154 @@ void pc_cpus_init(const char *cpu_model)
>>>>> }
>>>>> }
>>>>>
>>>>> -void pc_memory_init(const char *kernel_filename,
>>>>> - const char *kernel_cmdline,
>>>>> - const char *initrd_filename,
>>>>> - ram_addr_t below_4g_mem_size,
>>>>> - ram_addr_t above_4g_mem_size)
>>>>> +static void pc_isa_bios_init(ram_addr_t ram_offset, int ram_size)
>>>>> {
>>>>> - char *filename;
>>>>> - int ret, linux_boot, i;
>>>>> - ram_addr_t ram_addr, bios_offset, option_rom_offset;
>>>>> - int bios_size, isa_bios_size;
>>>>> - void *fw_cfg;
>>>>> -
>>>>> - linux_boot = (kernel_filename != NULL);
>>>>> + int isa_bios_size;
>>>>>
>>>>> - /* allocate RAM */
>>>>> - ram_addr = qemu_ram_alloc(NULL, "pc.ram",
>>>>> - below_4g_mem_size + above_4g_mem_size);
>>>>> - cpu_register_physical_memory(0, 0xa0000, ram_addr);
>>>>> - cpu_register_physical_memory(0x100000,
>>>>> - below_4g_mem_size - 0x100000,
>>>>> - ram_addr + 0x100000);
>>>>> - if (above_4g_mem_size> 0) {
>>>>> - cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
>>>>> - ram_addr + below_4g_mem_size);
>>>>> + /* map the last 128KB of the BIOS in ISA space */
>>>>> + isa_bios_size = ram_size;
>>>>> + if (isa_bios_size> (128 * 1024)) {
>>>>> + isa_bios_size = 128 * 1024;
>>>>> }
>>>>> + ram_offset = ram_offset + ram_size - isa_bios_size;
>>>>> + cpu_register_physical_memory(0x100000 - isa_bios_size,
>>>>> + isa_bios_size,
>>>>> + ram_offset | IO_MEM_ROM);
>>>>> +}
>>>>> +
>>>>> +static int pc_system_rom_init(void)
>>>>> +{
>>>>> + int ret;
>>>>> + int bios_size;
>>>>> + ram_addr_t bios_offset;
>>>>> + char *filename;
>>>>>
>>>>> /* BIOS load */
>>>>> - if (bios_name == NULL)
>>>>> + if (bios_name == NULL) {
>>>>> bios_name = BIOS_FILENAME;
>>>>> + }
>>>>> filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
>>>>> if (filename) {
>>>>> bios_size = get_image_size(filename);
>>>>> } else {
>>>>> bios_size = -1;
>>>>> }
>>>>> - if (bios_size<= 0 ||
>>>>> - (bios_size % 65536) != 0) {
>>>>> - goto bios_error;
>>>>> +
>>>>> + if (bios_size<= 0 || (bios_size % 65536) != 0) {
>>>>> + ret = -1;
>>>>> + } else {
>>>>> + bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
>>>>> + ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size),
>>>>> -1);
>>>>> }
>>>>> - bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
>>>>> - ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
>>>>> +
>>>>> if (ret != 0) {
>>>>> - bios_error:
>>>>> fprintf(stderr, "qemu: could not load PC BIOS '%s'\n",
>>>>> bios_name);
>>>>> exit(1);
>>>>> }
>>>>> +
>>>>> if (filename) {
>>>>> qemu_free(filename);
>>>>> }
>>>>> - /* map the last 128KB of the BIOS in ISA space */
>>>>> - isa_bios_size = bios_size;
>>>>> - if (isa_bios_size> (128 * 1024))
>>>>> - isa_bios_size = 128 * 1024;
>>>>> - cpu_register_physical_memory(0x100000 - isa_bios_size,
>>>>> - isa_bios_size,
>>>>> - (bios_offset + bios_size -
>>>>> isa_bios_size) | IO_MEM_ROM);
>>>>>
>>>>> - option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
>>>>> - cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE,
>>>>> option_rom_offset);
>>>>> + pc_isa_bios_init(bios_offset, bios_size);
>>>>>
>>>>> /* map all the bios at the top of memory */
>>>>> cpu_register_physical_memory((uint32_t)(-bios_size),
>>>>> bios_size, bios_offset | IO_MEM_ROM);
>>>>>
>>>>> + return bios_size;
>>>>> +}
>>>>> +
>>>>> +static void pc_system_flash_init(DriveInfo *pflash_drv, int rom_size)
>>>>> +{
>>>>> + BlockDriverState *bdrv;
>>>>> + int64_t size;
>>>>> + target_phys_addr_t phys_addr;
>>>>> + ram_addr_t addr;
>>>>> + int sector_bits, sector_size;
>>>>> +
>>>>> + bdrv = NULL;
>>>>> +
>>>>> + bdrv = pflash_drv->bdrv;
>>>>> + size = bdrv_getlength(pflash_drv->bdrv);
>>>>> + sector_bits = 12;
>>>>> + sector_size = 1<< sector_bits;
>>>>> +
>>>>> + if ((size % sector_size) != 0) {
>>>>> + fprintf(stderr,
>>>>> + "qemu: -pflash size must be a multiple of 0x%x\n",
>>>>> + sector_size);
>>>>> + exit(1);
>>>>> + }
>>>>> +
>>>>> + phys_addr = 0x100000000ULL - rom_size - size;
>>>>> + addr = qemu_ram_alloc(NULL, "system.flash", size);
>>>>> + DPRINTF("flash addr: 0x%lx\n", (int64_t)phys_addr);
>>>>> + pflash_cfi01_register(phys_addr, addr, bdrv,
>>>>> + sector_size, size>> sector_bits,
>>>>> + 4, 0x0000, 0x0000, 0x0000, 0x0000, 0);
>>>>> +
>>>>> + if (rom_size == 0) {
>>>>> + pc_isa_bios_init(addr, size);
>>>>> + }
>>>>> +}
>>>>> +
>>>>> +static void pc_system_firmware_init(void)
>>>>> +{
>>>>> + int flash_present, rom_present;
>>>>> + int rom_size;
>>>>> + DriveInfo *pflash_drv;
>>>>> +
>>>>> + pflash_drv = drive_get(IF_PFLASH, 0, 0);
>>>>> + flash_present = (pflash_drv != NULL);
>>>>> +
>>>>> + /* Load rom if -bios is used or if -pflash is not used */
>>>>> + rom_present = ((bios_name != NULL) || !flash_present);
>>>>> +
>>>>> + /* If rom is present, then it is mapped just below 4GB */
>>>>> + if (rom_present) {
>>>>> + rom_size = pc_system_rom_init();
>>>>> + } else {
>>>>> + rom_size = 0;
>>>>> + }
>>>>> +
>>>>> + /* If flash is present, then it is mapped just below the rom, or
>>>>> + * just below 4GB when rom is not present. */
>>>>> + if (flash_present) {
>>>>> + pc_system_flash_init(pflash_drv, rom_size);
>>>>> + }
>>>>> +}
>>>>> +
>>>>> +void pc_memory_init(const char *kernel_filename,
>>>>> + const char *kernel_cmdline,
>>>>> + const char *initrd_filename,
>>>>> + ram_addr_t below_4g_mem_size,
>>>>> + ram_addr_t above_4g_mem_size)
>>>>> +{
>>>>> + int linux_boot, i;
>>>>> + ram_addr_t ram_addr, option_rom_offset;
>>>>> + void *fw_cfg;
>>>>> +
>>>>> + linux_boot = (kernel_filename != NULL);
>>>>> +
>>>>> + /* allocate RAM */
>>>>> + ram_addr = qemu_ram_alloc(NULL, "pc.ram",
>>>>> + below_4g_mem_size + above_4g_mem_size);
>>>>> + cpu_register_physical_memory(0, 0xa0000, ram_addr);
>>>>> + cpu_register_physical_memory(0x100000,
>>>>> + below_4g_mem_size - 0x100000,
>>>>> + ram_addr + 0x100000);
>>>>> + if (above_4g_mem_size> 0) {
>>>>> + cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
>>>>> + ram_addr + below_4g_mem_size);
>>>>> + }
>>>>> +
>>>>> + /* Initialize ROM or flash ranges for PC firmware */
>>>>> + pc_system_firmware_init();
>>>>> +
>>>>> + option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
>>>>> + cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE,
>>>>> option_rom_offset);
>>>>> +
>>>>> fw_cfg = bochs_bios_init();
>>>>> rom_set_fw(fw_cfg);
>>>>>
>>>>
>>>>
>>>>
>>>
>>
>>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH v4] hw/pc: Support system flash memory with -pflash parameter
2011-07-23 22:26 ` Anthony Liguori
@ 2011-07-24 0:18 ` Jordan Justen
2011-07-24 0:56 ` Anthony Liguori
0 siblings, 1 reply; 9+ messages in thread
From: Jordan Justen @ 2011-07-24 0:18 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Kevin Wolf, Jordan Justen, qemu-devel
On Sat, Jul 23, 2011 at 15:26, Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 07/23/2011 05:06 PM, Jordan Justen wrote:
>>
>> On Sat, Jul 23, 2011 at 14:25, Anthony Liguori<anthony@codemonkey.ws>
>> wrote:
>>>
>>> On 07/23/2011 03:19 PM, Jordan Justen wrote:
>>>>
>>>> On Sat, Jul 23, 2011 at 08:51, Anthony Liguori<anthony@codemonkey.ws>
>>>> wrote:
>>>>>
>>>>> On 07/08/2011 02:37 PM, Jordan Justen wrote:
>>>>>>
>>>>>> If -pflash is specified and -bios is specified then pflash will
>>>>>> be mapped just below the system rom using hw/pflash_cfi01.c.
>>>>>>
>>>>>> If -pflash is specified on the command line, but -bios is
>>>>>> not specified, then 'bios.bin' will NOT be loaded, and
>>>>>> instead the -pflash flash image will be mapped just below
>>>>>> 4GB in place of the normal rom image.
>>>>>
>>>>> This is way too tied to the pc platform to be this generic.
>>>>>
>>>>> I think a better approach would be to default to having unit=0 of
>>>>> IF_PFLASH
>>>>> default to a read-only BDS that points to bios.bin. -bios would just
>>>>> be
>>>>> a
>>>>> short cut to use a different file name but you should be able to
>>>>> override
>>>>> with -drive too.
>>>>>
>>>>> And to really simplify things, you could add a readonly flag to -bios
>>>>> such
>>>>> that you could do:
>>>>>
>>>>> -bios foo.img,readonly=off
>>>>>
>>>>> Which is what I think you're looking for semantically.
>>>>
>>>> There seemed to be some feedback on the list interested in preserving
>>>> a read-only firmware, and just adding a flash region.
>>>>
>>>> So, for example, the firmware could be read from a common system
>>>> location like is generally done with bios.bin today, and VM instance
>>>> specific flash region could still be added.
>>>
>>> You can have multiple flash regions.
>>
>> So, is your recommendation that we support N pflash images in
>> x86/x86-64? Instance/index 0 is mapped just under 4GB, and the rest
>> follow below this?
>
> No. There should be a flash device, pflash index 0 is fine, but it should
> be mapped under 4GB and also in the legacy BIOS space.
>
> This is the PC firmware flash. By default it should be read-only and it
> should be created by using ${prefix}/share/bios.bin. But it should be
> possible to override both the filename and the read-only flag.
>
> In terms of other flash devices, I don't think it's that simple. Flash is
> tied to the mobo layout so I don't think index > 0 really makes sense unless
> you allow a specific mapping address. I doubt that's terribly useful.
I think VM's have a different situation than real hardware. I'm not
sure an all ROM or all flash decision will work well for qemu. In
most cases it may work better to make a ROM image available just below
4GB, and add a flash image below this ROM.
This allows the qemu's firmware to be updated as usual in
${prefix}/share/bios.bin, but still allows a flash memory to be
available below this. (The flash below the ROM could be used only for
storing UEFI variables.)
Otherwise when a new qemu is released along with a new firmware image,
the VM instance using writable flash will continue to use the old
firmware image.
-Jordan
>
> Regards,
>
> Anthony Liguori
>
>>
>> This seems like a good plan, although I can't see a usage for more
>> than 2 instances.
>>
>> -Jordan
>>
>>> You're introducing two modes. In one mode, we emulate a flash device and
>>> expose it for the BIOS ROM. In the second mode, we don't emulate a
>>> device
>>> but we expose the BIOS ROM based on a file in a shared read-only
>>> location.
>>>
>>> I'm suggesting always emulating a flash device, but by default make the
>>> device read-only and have it be loaded from a file in a shared read-only
>>> location.
>>>
>>> That means we have a single code path and a consistent view from a
>>> management tooling perspective. IOW, management tools will always see
>>> that
>>> there is a BIOS block device, and they need to worry about making sure
>>> that
>>> BIOS block device is there.
>>>
>>>>
>>>> If the entire firmware is moved to a separate VM instance specific
>>>> flash, then firmware update also gets complicated. It is no longer
>>>> just a matter of updating the qemu firmware package in your distro's
>>>> package management system.
>>>
>>> I think the bit your misunderstanding is that you should default the
>>> firmware to be created from a common file as a read-only device.
>>>
>>> Regards,
>>>
>>> Anthony Liguori
>>>
>>>>
>>>> What about taking your idea, but adding a second drive that would be
>>>> mapped just below the 1st if it is specified with -drive?
>>>>
>>>> Thanks,
>>>>
>>>> -Jordan
>>>>
>>>>>
>>>>> Regards,
>>>>>
>>>>> Anthony Liguori
>>>>>
>>>>>>
>>>>>> Signed-off-by: Jordan Justen<jordan.l.justen@intel.com>
>>>>>> Reviewed-by: Aurelien Jarno<aurelien@aurel32.net>
>>>>>
>>>>>
>>>>>
>>>>>> ---
>>>>>> default-configs/i386-softmmu.mak | 1 +
>>>>>> default-configs/x86_64-softmmu.mak | 1 +
>>>>>> hw/pc.c | 161
>>>>>> +++++++++++++++++++++++++++---------
>>>>>> 3 files changed, 125 insertions(+), 38 deletions(-)
>>>>>>
>>>>>> diff --git a/default-configs/i386-softmmu.mak
>>>>>> b/default-configs/i386-softmmu.mak
>>>>>> index 55589fa..8697cd4 100644
>>>>>> --- a/default-configs/i386-softmmu.mak
>>>>>> +++ b/default-configs/i386-softmmu.mak
>>>>>> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
>>>>>> CONFIG_SOUND=y
>>>>>> CONFIG_HPET=y
>>>>>> CONFIG_APPLESMC=y
>>>>>> +CONFIG_PFLASH_CFI01=y
>>>>>> diff --git a/default-configs/x86_64-softmmu.mak
>>>>>> b/default-configs/x86_64-softmmu.mak
>>>>>> index 8895028..eca9284 100644
>>>>>> --- a/default-configs/x86_64-softmmu.mak
>>>>>> +++ b/default-configs/x86_64-softmmu.mak
>>>>>> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
>>>>>> CONFIG_SOUND=y
>>>>>> CONFIG_HPET=y
>>>>>> CONFIG_APPLESMC=y
>>>>>> +CONFIG_PFLASH_CFI01=y
>>>>>> diff --git a/hw/pc.c b/hw/pc.c
>>>>>> index a3e8539..e25354f 100644
>>>>>> --- a/hw/pc.c
>>>>>> +++ b/hw/pc.c
>>>>>> @@ -41,6 +41,7 @@
>>>>>> #include "sysemu.h"
>>>>>> #include "blockdev.h"
>>>>>> #include "ui/qemu-spice.h"
>>>>>> +#include "flash.h"
>>>>>>
>>>>>> /* output Bochs bios info messages */
>>>>>> //#define DEBUG_BIOS
>>>>>> @@ -957,70 +958,154 @@ void pc_cpus_init(const char *cpu_model)
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> -void pc_memory_init(const char *kernel_filename,
>>>>>> - const char *kernel_cmdline,
>>>>>> - const char *initrd_filename,
>>>>>> - ram_addr_t below_4g_mem_size,
>>>>>> - ram_addr_t above_4g_mem_size)
>>>>>> +static void pc_isa_bios_init(ram_addr_t ram_offset, int ram_size)
>>>>>> {
>>>>>> - char *filename;
>>>>>> - int ret, linux_boot, i;
>>>>>> - ram_addr_t ram_addr, bios_offset, option_rom_offset;
>>>>>> - int bios_size, isa_bios_size;
>>>>>> - void *fw_cfg;
>>>>>> -
>>>>>> - linux_boot = (kernel_filename != NULL);
>>>>>> + int isa_bios_size;
>>>>>>
>>>>>> - /* allocate RAM */
>>>>>> - ram_addr = qemu_ram_alloc(NULL, "pc.ram",
>>>>>> - below_4g_mem_size + above_4g_mem_size);
>>>>>> - cpu_register_physical_memory(0, 0xa0000, ram_addr);
>>>>>> - cpu_register_physical_memory(0x100000,
>>>>>> - below_4g_mem_size - 0x100000,
>>>>>> - ram_addr + 0x100000);
>>>>>> - if (above_4g_mem_size> 0) {
>>>>>> - cpu_register_physical_memory(0x100000000ULL,
>>>>>> above_4g_mem_size,
>>>>>> - ram_addr + below_4g_mem_size);
>>>>>> + /* map the last 128KB of the BIOS in ISA space */
>>>>>> + isa_bios_size = ram_size;
>>>>>> + if (isa_bios_size> (128 * 1024)) {
>>>>>> + isa_bios_size = 128 * 1024;
>>>>>> }
>>>>>> + ram_offset = ram_offset + ram_size - isa_bios_size;
>>>>>> + cpu_register_physical_memory(0x100000 - isa_bios_size,
>>>>>> + isa_bios_size,
>>>>>> + ram_offset | IO_MEM_ROM);
>>>>>> +}
>>>>>> +
>>>>>> +static int pc_system_rom_init(void)
>>>>>> +{
>>>>>> + int ret;
>>>>>> + int bios_size;
>>>>>> + ram_addr_t bios_offset;
>>>>>> + char *filename;
>>>>>>
>>>>>> /* BIOS load */
>>>>>> - if (bios_name == NULL)
>>>>>> + if (bios_name == NULL) {
>>>>>> bios_name = BIOS_FILENAME;
>>>>>> + }
>>>>>> filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
>>>>>> if (filename) {
>>>>>> bios_size = get_image_size(filename);
>>>>>> } else {
>>>>>> bios_size = -1;
>>>>>> }
>>>>>> - if (bios_size<= 0 ||
>>>>>> - (bios_size % 65536) != 0) {
>>>>>> - goto bios_error;
>>>>>> +
>>>>>> + if (bios_size<= 0 || (bios_size % 65536) != 0) {
>>>>>> + ret = -1;
>>>>>> + } else {
>>>>>> + bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
>>>>>> + ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size),
>>>>>> -1);
>>>>>> }
>>>>>> - bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
>>>>>> - ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
>>>>>> +
>>>>>> if (ret != 0) {
>>>>>> - bios_error:
>>>>>> fprintf(stderr, "qemu: could not load PC BIOS '%s'\n",
>>>>>> bios_name);
>>>>>> exit(1);
>>>>>> }
>>>>>> +
>>>>>> if (filename) {
>>>>>> qemu_free(filename);
>>>>>> }
>>>>>> - /* map the last 128KB of the BIOS in ISA space */
>>>>>> - isa_bios_size = bios_size;
>>>>>> - if (isa_bios_size> (128 * 1024))
>>>>>> - isa_bios_size = 128 * 1024;
>>>>>> - cpu_register_physical_memory(0x100000 - isa_bios_size,
>>>>>> - isa_bios_size,
>>>>>> - (bios_offset + bios_size -
>>>>>> isa_bios_size) | IO_MEM_ROM);
>>>>>>
>>>>>> - option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
>>>>>> - cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE,
>>>>>> option_rom_offset);
>>>>>> + pc_isa_bios_init(bios_offset, bios_size);
>>>>>>
>>>>>> /* map all the bios at the top of memory */
>>>>>> cpu_register_physical_memory((uint32_t)(-bios_size),
>>>>>> bios_size, bios_offset |
>>>>>> IO_MEM_ROM);
>>>>>>
>>>>>> + return bios_size;
>>>>>> +}
>>>>>> +
>>>>>> +static void pc_system_flash_init(DriveInfo *pflash_drv, int rom_size)
>>>>>> +{
>>>>>> + BlockDriverState *bdrv;
>>>>>> + int64_t size;
>>>>>> + target_phys_addr_t phys_addr;
>>>>>> + ram_addr_t addr;
>>>>>> + int sector_bits, sector_size;
>>>>>> +
>>>>>> + bdrv = NULL;
>>>>>> +
>>>>>> + bdrv = pflash_drv->bdrv;
>>>>>> + size = bdrv_getlength(pflash_drv->bdrv);
>>>>>> + sector_bits = 12;
>>>>>> + sector_size = 1<< sector_bits;
>>>>>> +
>>>>>> + if ((size % sector_size) != 0) {
>>>>>> + fprintf(stderr,
>>>>>> + "qemu: -pflash size must be a multiple of 0x%x\n",
>>>>>> + sector_size);
>>>>>> + exit(1);
>>>>>> + }
>>>>>> +
>>>>>> + phys_addr = 0x100000000ULL - rom_size - size;
>>>>>> + addr = qemu_ram_alloc(NULL, "system.flash", size);
>>>>>> + DPRINTF("flash addr: 0x%lx\n", (int64_t)phys_addr);
>>>>>> + pflash_cfi01_register(phys_addr, addr, bdrv,
>>>>>> + sector_size, size>> sector_bits,
>>>>>> + 4, 0x0000, 0x0000, 0x0000, 0x0000, 0);
>>>>>> +
>>>>>> + if (rom_size == 0) {
>>>>>> + pc_isa_bios_init(addr, size);
>>>>>> + }
>>>>>> +}
>>>>>> +
>>>>>> +static void pc_system_firmware_init(void)
>>>>>> +{
>>>>>> + int flash_present, rom_present;
>>>>>> + int rom_size;
>>>>>> + DriveInfo *pflash_drv;
>>>>>> +
>>>>>> + pflash_drv = drive_get(IF_PFLASH, 0, 0);
>>>>>> + flash_present = (pflash_drv != NULL);
>>>>>> +
>>>>>> + /* Load rom if -bios is used or if -pflash is not used */
>>>>>> + rom_present = ((bios_name != NULL) || !flash_present);
>>>>>> +
>>>>>> + /* If rom is present, then it is mapped just below 4GB */
>>>>>> + if (rom_present) {
>>>>>> + rom_size = pc_system_rom_init();
>>>>>> + } else {
>>>>>> + rom_size = 0;
>>>>>> + }
>>>>>> +
>>>>>> + /* If flash is present, then it is mapped just below the rom, or
>>>>>> + * just below 4GB when rom is not present. */
>>>>>> + if (flash_present) {
>>>>>> + pc_system_flash_init(pflash_drv, rom_size);
>>>>>> + }
>>>>>> +}
>>>>>> +
>>>>>> +void pc_memory_init(const char *kernel_filename,
>>>>>> + const char *kernel_cmdline,
>>>>>> + const char *initrd_filename,
>>>>>> + ram_addr_t below_4g_mem_size,
>>>>>> + ram_addr_t above_4g_mem_size)
>>>>>> +{
>>>>>> + int linux_boot, i;
>>>>>> + ram_addr_t ram_addr, option_rom_offset;
>>>>>> + void *fw_cfg;
>>>>>> +
>>>>>> + linux_boot = (kernel_filename != NULL);
>>>>>> +
>>>>>> + /* allocate RAM */
>>>>>> + ram_addr = qemu_ram_alloc(NULL, "pc.ram",
>>>>>> + below_4g_mem_size + above_4g_mem_size);
>>>>>> + cpu_register_physical_memory(0, 0xa0000, ram_addr);
>>>>>> + cpu_register_physical_memory(0x100000,
>>>>>> + below_4g_mem_size - 0x100000,
>>>>>> + ram_addr + 0x100000);
>>>>>> + if (above_4g_mem_size> 0) {
>>>>>> + cpu_register_physical_memory(0x100000000ULL,
>>>>>> above_4g_mem_size,
>>>>>> + ram_addr + below_4g_mem_size);
>>>>>> + }
>>>>>> +
>>>>>> + /* Initialize ROM or flash ranges for PC firmware */
>>>>>> + pc_system_firmware_init();
>>>>>> +
>>>>>> + option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE);
>>>>>> + cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE,
>>>>>> option_rom_offset);
>>>>>> +
>>>>>> fw_cfg = bochs_bios_init();
>>>>>> rom_set_fw(fw_cfg);
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>
>>>
>>
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH v4] hw/pc: Support system flash memory with -pflash parameter
2011-07-24 0:18 ` Jordan Justen
@ 2011-07-24 0:56 ` Anthony Liguori
0 siblings, 0 replies; 9+ messages in thread
From: Anthony Liguori @ 2011-07-24 0:56 UTC (permalink / raw)
To: Jordan Justen; +Cc: Kevin Wolf, Jordan Justen, qemu-devel
On 07/23/2011 07:18 PM, Jordan Justen wrote:
>> In terms of other flash devices, I don't think it's that simple. Flash is
>> tied to the mobo layout so I don't think index> 0 really makes sense unless
>> you allow a specific mapping address. I doubt that's terribly useful.
>
> I think VM's have a different situation than real hardware. I'm not
> sure an all ROM or all flash decision will work well for qemu. In
> most cases it may work better to make a ROM image available just below
> 4GB, and add a flash image below this ROM.
>
> This allows the qemu's firmware to be updated as usual in
> ${prefix}/share/bios.bin, but still allows a flash memory to be
> available below this. (The flash below the ROM could be used only for
> storing UEFI variables.)
>
> Otherwise when a new qemu is released along with a new firmware image,
> the VM instance using writable flash will continue to use the old
> firmware image.
Yes, that's a feature.
We could have a second nvram for other purposes of course. That could
be defined as index=1.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2011-07-24 0:56 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-08 19:37 [Qemu-devel] [PATCH v4] hw/pc: Support system flash memory with -pflash parameter Jordan Justen
2011-07-16 0:16 ` Jordan Justen
2011-07-23 15:51 ` Anthony Liguori
2011-07-23 20:19 ` Jordan Justen
2011-07-23 21:25 ` Anthony Liguori
2011-07-23 22:06 ` Jordan Justen
2011-07-23 22:26 ` Anthony Liguori
2011-07-24 0:18 ` Jordan Justen
2011-07-24 0:56 ` Anthony Liguori
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.