@@ -47,6 +47,14 @@
#define VGABIOS_FILENAME "vgabios.bin"
#define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
+#define UEFI_IA32_FIRMWARE_FILENAME "uefi-ia32.fd"
+#define UEFI_IA32_VGA_GOP_FILENAME "uefi-ia32-vga-gop.rom"
+#define UEFI_IA32_CIRRUS_GOP_FILENAME "uefi-ia32-cirrus-gop.rom"
+
+#define UEFI_X64_FIRMWARE_FILENAME "uefi-x64.fd"
+#define UEFI_X64_VGA_GOP_FILENAME "uefi-x64-vga-gop.rom"
+#define UEFI_X64_CIRRUS_GOP_FILENAME "uefi-x64-cirrus-gop.rom"
+
#define PC_MAX_BIOS_SIZE (4 * 1024 * 1024)
/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */
@@ -1100,6 +1108,12 @@ static CPUState *pc_new_cpu(const char *cpu_model)
return env;
}
+enum {
+ NO_UEFI = 0,
+ UEFI_IA32,
+ UEFI_X64,
+};
+
/* PC hardware initialisation */
static void pc_init1(ram_addr_t ram_size,
const char *boot_device,
@@ -1107,7 +1121,8 @@ static void pc_init1(ram_addr_t ram_size,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model,
- int pci_enabled)
+ int pci_enabled,
+ int uefi_mode)
{
char *filename;
int ret, linux_boot, i;
@@ -1125,6 +1140,28 @@ static void pc_init1(ram_addr_t ram_size,
BlockDriverState *fd[MAX_FD];
int using_vga = cirrus_vga_enabled || std_vga_enabled || vmsvga_enabled;
void *fw_cfg;
+ const char *default_bios_filename;
+ const char *default_vga_filename, *default_cirrus_filename;
+
+ switch(uefi_mode) {
+ case UEFI_IA32:
+ default_bios_filename = UEFI_IA32_FIRMWARE_FILENAME;
+ default_vga_filename = UEFI_IA32_VGA_GOP_FILENAME;
+ default_cirrus_filename = UEFI_IA32_CIRRUS_GOP_FILENAME;
+ break;
+
+ case UEFI_X64:
+ default_bios_filename = UEFI_X64_FIRMWARE_FILENAME;
+ default_vga_filename = UEFI_X64_VGA_GOP_FILENAME;
+ default_cirrus_filename = UEFI_X64_CIRRUS_GOP_FILENAME;
+ break;
+
+ default:
+ default_bios_filename = BIOS_FILENAME;
+ default_vga_filename = VGABIOS_FILENAME;
+ default_cirrus_filename = VGABIOS_CIRRUS_FILENAME;
+ break;
+ }
if (ram_size >= 0xe0000000 ) {
above_4g_mem_size = ram_size - 0xe0000000;
@@ -1176,10 +1213,10 @@ static void pc_init1(ram_addr_t ram_size,
#endif
}
-
/* BIOS load */
- if (bios_name == NULL)
- bios_name = BIOS_FILENAME;
+ if (bios_name == NULL) {
+ bios_name = default_bios_filename;
+ }
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) {
bios_size = get_image_size(filename);
@@ -1218,9 +1255,9 @@ static void pc_init1(ram_addr_t ram_size,
const char *vgabios_filename;
/* VGA BIOS load */
if (cirrus_vga_enabled) {
- vgabios_filename = VGABIOS_CIRRUS_FILENAME;
+ vgabios_filename = default_cirrus_filename;
} else {
- vgabios_filename = VGABIOS_FILENAME;
+ vgabios_filename = default_vga_filename;
}
oprom_area_size = load_option_rom(vgabios_filename, 0xc0000, 0xe0000);
}
@@ -1446,7 +1483,7 @@ static void pc_init_pci(ram_addr_t ram_size,
{
pc_init1(ram_size, boot_device,
kernel_filename, kernel_cmdline,
- initrd_filename, cpu_model, 1);
+ initrd_filename, cpu_model, 1, NO_UEFI);
}
static void pc_init_isa(ram_addr_t ram_size,
@@ -1458,8 +1495,34 @@ static void pc_init_isa(ram_addr_t ram_size,
{
pc_init1(ram_size, boot_device,
kernel_filename, kernel_cmdline,
- initrd_filename, cpu_model, 0);
+ initrd_filename, cpu_model, 0, NO_UEFI);
+}
+
+static void uefi_ia32_pc_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename,
+ const char *kernel_cmdline,
+ const char *initrd_filename,
+ const char *cpu_model)
+{
+ pc_init1(ram_size, boot_device,
+ kernel_filename, kernel_cmdline,
+ initrd_filename, cpu_model, 1, UEFI_IA32);
+}
+
+#ifdef TARGET_X86_64
+static void uefi_x64_pc_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename,
+ const char *kernel_cmdline,
+ const char *initrd_filename,
+ const char *cpu_model)
+{
+ pc_init1(ram_size, boot_device,
+ kernel_filename, kernel_cmdline,
+ initrd_filename, cpu_model, 1, UEFI_X64);
}
+#endif
/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE)
BIOS will read it and start S3 resume at POST Entry */
@@ -1508,11 +1571,37 @@ static QEMUMachine isapc_machine = {
.max_cpus = 1,
};
+static QEMUMachine uefi_machine = {
+ .name = "uefi",
+#ifndef TARGET_X86_64
+ .desc = "UEFI IA32 PC",
+ .init = uefi_ia32_pc_init,
+#else
+ .desc = "UEFI X64 PC",
+ .init = uefi_x64_pc_init,
+#endif
+ .max_cpus = 255,
+};
+
+#ifdef TARGET_X86_64
+static QEMUMachine uefi_ia32_machine = {
+ .name = "uefi32",
+ .desc = "UEFI IA32 PC",
+ .init = uefi_ia32_pc_init,
+ .max_cpus = 255,
+};
+#endif
+
static void pc_machine_init(void)
{
qemu_register_machine(&pc_machine);
qemu_register_machine(&pc_machine_v0_10);
qemu_register_machine(&isapc_machine);
+
+ qemu_register_machine(&uefi_machine);
+#ifdef TARGET_X86_64
+ qemu_register_machine(&uefi_ia32_machine);
+#endif
}
machine_init(pc_machine_init);
For i386, this change adds a 'uefi' machine type. For x86_64, this change adds 'uefi' and 'uefi32' machine types. These machine types will load different bios and video bios images: architecture+machine-type: bios and video bios images --- i386+pc: bios.bin, vgabios-cirrus.bin, vgabios.bin x86_64+pc: bios.bin, vgabios-cirrus.bin, vgabios.bin i386+uefi: uefi-ia32.fd, uefi-ia32-cirrus-gop.rom, uefi-ia32-vga-gop.rom x86_64+uefi32: uefi-ia32.fd, uefi-ia32-cirrus-gop.rom, uefi-ia32-vga-gop.rom x86_64+uefi: uefi-x64.fd, uefi-x64-cirrus-gop.rom, uefi-x64-vga-gop.rom Signed-off-by: Jordan Justen <jljusten@gmail.com> --- hw/pc.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 97 insertions(+), 8 deletions(-)