[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v10 5/8] hw/pc_sysfw: Support system flash memory wi
From: |
Jordan Justen |
Subject: |
[Qemu-devel] [PATCH v10 5/8] hw/pc_sysfw: Support system flash memory with pflash |
Date: |
Sun, 8 Jan 2012 11:51:37 -0800 |
Flash can be enabled by calling pc_system_firmware_init
with the system_flash_enabled parameter being non-zero.
If system_flash_enabled is zero, then the older qemu
rom creation method will be used.
If flash is enabled and a pflash image is found, then
it is used for the system firmware image.
If flash is enabled and a pflash image is not initially
found, then a read-only pflash device is created using
the -bios filename.
KVM cannot execute from a pflash region currently.
Therefore, when KVM is enabled, a (read-only) ram memory
region is created and filled with the contents of the
pflash drive.
Signed-off-by: Jordan Justen <address@hidden>
---
default-configs/i386-softmmu.mak | 1 +
default-configs/x86_64-softmmu.mak | 1 +
hw/pc.c | 2 +-
hw/pc.h | 3 +-
hw/pc_sysfw.c | 172 +++++++++++++++++++++++++++++++++++-
5 files changed, 173 insertions(+), 6 deletions(-)
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index e67ebb3..cd407a9 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -22,3 +22,4 @@ CONFIG_SOUND=y
CONFIG_HPET=y
CONFIG_APPLESMC=y
CONFIG_I8259=y
+CONFIG_PFLASH_CFI01=y
diff --git a/default-configs/x86_64-softmmu.mak
b/default-configs/x86_64-softmmu.mak
index b75757e..47734ea 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -22,3 +22,4 @@ CONFIG_SOUND=y
CONFIG_HPET=y
CONFIG_APPLESMC=y
CONFIG_I8259=y
+CONFIG_PFLASH_CFI01=y
diff --git a/hw/pc.c b/hw/pc.c
index 47e946a..7a7af90 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -999,7 +999,7 @@ void pc_memory_init(MemoryRegion *system_memory,
/* Initialize PC system firmware */
- pc_system_firmware_init(rom_memory);
+ pc_system_firmware_init(rom_memory, 0);
option_rom_mr = g_malloc(sizeof(*option_rom_mr));
memory_region_init_ram(option_rom_mr, "pc.rom", PC_ROM_SIZE);
diff --git a/hw/pc.h b/hw/pc.h
index 227f495..ca5e76b 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -247,7 +247,8 @@ static inline bool isa_ne2000_init(ISABus *bus, int base,
int irq, NICInfo *nd)
}
/* pc_sysfw.c */
-void pc_system_firmware_init(MemoryRegion *rom_memory);
+void pc_system_firmware_init(MemoryRegion *rom_memory,
+ int system_flash_enabled);
/* e820 types */
#define E820_RAM 1
diff --git a/hw/pc_sysfw.c b/hw/pc_sysfw.c
index 3121c95..57ac81c 100644
--- a/hw/pc_sysfw.c
+++ b/hw/pc_sysfw.c
@@ -23,13 +23,151 @@
* THE SOFTWARE.
*/
+#include "hw.h"
#include "pc.h"
+#include "hw/boards.h"
#include "loader.h"
#include "sysemu.h"
+#include "flash.h"
+#include "kvm.h"
#define BIOS_FILENAME "bios.bin"
-static void pc_system_rom_init(MemoryRegion *rom_memory)
+static void pc_isa_bios_init(MemoryRegion *rom_memory,
+ MemoryRegion *flash_mem,
+ int ram_size)
+{
+ int isa_bios_size;
+ MemoryRegion *isa_bios;
+ uint64_t flash_size;
+ void *flash_ptr, *isa_bios_ptr;
+
+ flash_size = memory_region_size(flash_mem);
+
+ /* map the last 128KB of the BIOS in ISA space */
+ isa_bios_size = flash_size;
+ if (isa_bios_size > (128 * 1024)) {
+ isa_bios_size = 128 * 1024;
+ }
+ isa_bios = g_malloc(sizeof(*isa_bios));
+ memory_region_init_ram(isa_bios, "isa-bios", isa_bios_size);
+ vmstate_register_ram_global(isa_bios);
+ memory_region_add_subregion_overlap(rom_memory,
+ 0x100000 - isa_bios_size,
+ isa_bios,
+ 1);
+
+ /* copy ISA rom image from top of flash memory */
+ flash_ptr = memory_region_get_ram_ptr(flash_mem);
+ isa_bios_ptr = memory_region_get_ram_ptr(isa_bios);
+ memcpy(isa_bios_ptr,
+ ((uint8_t*)flash_ptr) + (flash_size - isa_bios_size),
+ isa_bios_size);
+
+ memory_region_set_readonly(isa_bios, true);
+}
+
+static void pc_fw_add_pflash_drv(void)
+{
+ QemuOpts *opts;
+ QEMUMachine *machine;
+ char *filename;
+
+ if (bios_name == NULL) {
+ bios_name = BIOS_FILENAME;
+ }
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+
+ opts = drive_add(IF_PFLASH, -1, filename, "readonly=on");
+ if (opts == NULL) {
+ return;
+ }
+
+ machine = find_default_machine();
+ if (machine == NULL) {
+ return;
+ }
+
+ drive_init(opts, machine->use_scsi);
+}
+
+static void pc_system_flash_init(MemoryRegion *rom_memory,
+ DriveInfo *pflash_drv)
+{
+ BlockDriverState *bdrv;
+ int64_t size;
+ target_phys_addr_t phys_addr;
+ int sector_bits, sector_size;
+ pflash_t *system_flash;
+ MemoryRegion *flash_mem;
+
+ 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: PC system firmware (pflash) must be a multiple of
0x%x\n",
+ sector_size);
+ exit(1);
+ }
+
+ phys_addr = 0x100000000ULL - size;
+ system_flash = pflash_cfi01_register(phys_addr, NULL, "system.flash", size,
+ bdrv, sector_size, size >>
sector_bits,
+ 1, 0x0000, 0x0000, 0x0000, 0x0000, 0);
+ flash_mem = pflash_cfi01_get_memory(system_flash);
+
+ pc_isa_bios_init(rom_memory, flash_mem, size);
+}
+
+static void pc_system_rom_init(MemoryRegion *rom_memory,
+ DriveInfo *pflash_drv)
+{
+ BlockDriverState *bdrv;
+ int64_t size;
+ target_phys_addr_t phys_addr;
+ int sector_bits, sector_size;
+ MemoryRegion *sys_rom;
+ void *buffer;
+ int ret;
+
+ bdrv = pflash_drv->bdrv;
+ size = bdrv_getlength(pflash_drv->bdrv);
+ sector_bits = 9;
+ sector_size = 1 << sector_bits;
+
+ if ((size % sector_size) != 0) {
+ fprintf(stderr,
+ "qemu: PC system rom (pflash) must be a multiple of 0x%x\n",
+ sector_size);
+ exit(1);
+ }
+
+ phys_addr = 0x100000000ULL - size;
+ sys_rom = g_malloc(sizeof(*sys_rom));
+ memory_region_init_ram(sys_rom, "system.rom", size);
+ vmstate_register_ram_global(sys_rom);
+ buffer = memory_region_get_ram_ptr(sys_rom);
+ memory_region_add_subregion(rom_memory, phys_addr, sys_rom);
+
+ /* read the rom content */
+ ret = bdrv_read(bdrv, 0, buffer, size >> sector_bits);
+ if (ret < 0) {
+ memory_region_destroy(sys_rom);
+ g_free(sys_rom);
+ fprintf(stderr,
+ "qemu: Failed to read rom image from pflash drive\n");
+ exit(1);
+ }
+
+ memory_region_set_readonly(sys_rom, true);
+
+ pc_isa_bios_init(rom_memory, sys_rom, size);
+}
+
+static void old_pc_system_rom_init(MemoryRegion *rom_memory)
{
char *filename;
MemoryRegion *bios, *isa_bios;
@@ -84,9 +222,35 @@ static void pc_system_rom_init(MemoryRegion *rom_memory)
bios);
}
-void pc_system_firmware_init(MemoryRegion *rom_memory)
+void pc_system_firmware_init(MemoryRegion *rom_memory,
+ int system_flash_enabled)
{
- pc_system_rom_init(rom_memory);
-}
+ int flash_present;
+ DriveInfo *pflash_drv;
+
+ if (!system_flash_enabled) {
+ old_pc_system_rom_init(rom_memory);
+ return;
+ }
+
+ pflash_drv = drive_get(IF_PFLASH, 0, 0);
+ flash_present = (pflash_drv != NULL);
+ if (!flash_present) {
+ pc_fw_add_pflash_drv();
+ pflash_drv = drive_get(IF_PFLASH, 0, 0);
+ flash_present = (pflash_drv != NULL);
+ }
+
+ if (!flash_present) {
+ fprintf(stderr, "qemu: PC system firmware (pflash) not available\n");
+ exit(1);
+ }
+
+ if (!kvm_enabled()) {
+ pc_system_flash_init(rom_memory, pflash_drv);
+ } else {
+ pc_system_rom_init(rom_memory, pflash_drv);
+ }
+}
--
1.7.1
- [Qemu-devel] [PATCH v10 0/8] PC system flash support, Jordan Justen, 2012/01/08
- [Qemu-devel] [PATCH v10 1/8] blockdev: allow read-only pflash devices, Jordan Justen, 2012/01/08
- [Qemu-devel] [PATCH v10 2/8] pflash_cfi01/02: support read-only pflash devices, Jordan Justen, 2012/01/08
- [Qemu-devel] [PATCH v10 3/8] vl: make find_default_machine externally visible, Jordan Justen, 2012/01/08
- [Qemu-devel] [PATCH v10 4/8] hw/pc: move rom init to pc_sysfw.c, Jordan Justen, 2012/01/08
- [Qemu-devel] [PATCH v10 5/8] hw/pc_sysfw: Support system flash memory with pflash,
Jordan Justen <=
- [Qemu-devel] [PATCH v10 6/8] hw/pc_piix: remove is_default for pc-0.15, Jordan Justen, 2012/01/08
- [Qemu-devel] [PATCH v10 7/8] hw/pc_piix: add pc-1.1, Jordan Justen, 2012/01/08
- [Qemu-devel] [PATCH v10 8/8] pc: enable system flash for pc-1.1, Jordan Justen, 2012/01/08
- Re: [Qemu-devel] [PATCH v10 0/8] PC system flash support, Jordan Justen, 2012/01/08