From patchwork Thu Aug 25 10:15:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Peng X-Patchwork-Id: 9299151 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 99D6A60459 for ; Thu, 25 Aug 2016 10:39:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8AD0229268 for ; Thu, 25 Aug 2016 10:39:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7F9FD2926E; Thu, 25 Aug 2016 10:39:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C781C29268 for ; Thu, 25 Aug 2016 10:39:48 +0000 (UTC) Received: from localhost ([::1]:55514 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bcs4a-0008U6-09 for patchwork-qemu-devel@patchwork.kernel.org; Thu, 25 Aug 2016 06:39:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34633) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bcroo-0003Q9-I7 for qemu-devel@nongnu.org; Thu, 25 Aug 2016 06:23:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bcrom-0001cZ-2c for qemu-devel@nongnu.org; Thu, 25 Aug 2016 06:23:29 -0400 Received: from mga03.intel.com ([134.134.136.65]:15072) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bcrol-0001Ur-Ms for qemu-devel@nongnu.org; Thu, 25 Aug 2016 06:23:27 -0400 Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga103.jf.intel.com with ESMTP; 25 Aug 2016 03:23:27 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,575,1464678000"; d="scan'208";a="160747112" Received: from vmm-docker1.bj.intel.com ([10.240.193.52]) by fmsmga004.fm.intel.com with ESMTP; 25 Aug 2016 03:23:26 -0700 From: Chao Peng To: qemu-devel@nongnu.org Date: Thu, 25 Aug 2016 06:15:05 -0400 Message-Id: <1472120105-29235-13-git-send-email-chao.p.peng@linux.intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1472120105-29235-1-git-send-email-chao.p.peng@linux.intel.com> References: <1472120105-29235-1-git-send-email-chao.p.peng@linux.intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 134.134.136.65 Subject: [Qemu-devel] [RFC PATCH v2 12/12] pc: skip firmware X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Haozhong Zhang , Xiao Guangrong , Eduardo Habkost , "Michael S. Tsirkin" , Paolo Bonzini , gor Mammedov , Richard Henderson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP An ELF format kernel must be specified. Only linux is supported. Signed-off-by: Chao Peng --- hw/i386/pc.c | 92 ++++++++++++++++++++++++++++++++++++++-------------- include/hw/i386/pc.h | 2 ++ 2 files changed, 69 insertions(+), 25 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 4a368de..1362810 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -974,8 +974,43 @@ struct setup_data { uint8_t data[0]; } __attribute__((packed)); -static void load_linux(PCMachineState *pcms, - FWCfgState *fw_cfg) +static void load_linux_efi(PCMachineState *pcms) +{ + unsigned char class; + MachineState *machine = MACHINE(pcms); + FILE *file = fopen(machine->kernel_filename, "rb"); + + if (!file) { + goto err; + } + + if (fseek(file, EI_CLASS, 0) || fread(&class, 1, 1, file) != 1) { + fclose(file); + goto err; + } + fclose(file); + + if (load_elf(machine->kernel_filename, NULL, NULL, &boot_info.entry, + NULL, NULL, 0, EM_X86_64, 0, 0) < 0) { + goto err; + } + + if (class == ELFCLASS64) { + boot_info.long_mode = true; + } else if (class != ELFCLASS32) { + goto err; + } + + boot_info.protected_mode = true; + return; + +err: + fprintf(stderr, "qemu: could not load kernel '%s'\n", + machine->kernel_filename); + exit(1); +} + +static void load_linux_bzimage(PCMachineState *pcms, FWCfgState *fw_cfg) { uint16_t protocol; int setup_size, kernel_size, initrd_size = 0, cmdline_size; @@ -1488,7 +1523,7 @@ void xen_load_linux(PCMachineState *pcms) fw_cfg = fw_cfg_init_io(FW_CFG_IO_BASE); rom_set_fw(fw_cfg); - load_linux(pcms, fw_cfg); + load_linux_bzimage(pcms, fw_cfg); for (i = 0; i < nb_option_roms; i++) { assert(!strcmp(option_rom[i].name, "linuxboot.bin") || !strcmp(option_rom[i].name, "linuxboot_dma.bin") || @@ -1506,7 +1541,7 @@ void pc_memory_init(PCMachineState *pcms, int linux_boot, i; MemoryRegion *ram, *option_rom_mr; MemoryRegion *ram_below_4g, *ram_above_4g; - FWCfgState *fw_cfg; + FWCfgState *fw_cfg = NULL; MachineState *machine = MACHINE(pcms); PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); @@ -1588,36 +1623,42 @@ void pc_memory_init(PCMachineState *pcms, &pcms->hotplug_memory.mr); } - /* Initialize PC system firmware */ - pc_system_firmware_init(rom_memory, !pcmc->pci_enabled); + if (pcms->fw) { + /* Initialize PC system firmware */ + pc_system_firmware_init(rom_memory, !pcmc->pci_enabled); - option_rom_mr = g_malloc(sizeof(*option_rom_mr)); - memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE, - &error_fatal); - vmstate_register_ram_global(option_rom_mr); - memory_region_add_subregion_overlap(rom_memory, - PC_ROM_MIN_VGA, - option_rom_mr, - 1); + option_rom_mr = g_malloc(sizeof(*option_rom_mr)); + memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE, + &error_fatal); + vmstate_register_ram_global(option_rom_mr); + memory_region_add_subregion_overlap(rom_memory, + PC_ROM_MIN_VGA, + option_rom_mr, + 1); - fw_cfg = bochs_bios_init(&address_space_memory, pcms); + fw_cfg = bochs_bios_init(&address_space_memory, pcms); - rom_set_fw(fw_cfg); + rom_set_fw(fw_cfg); - if (pcmc->has_reserved_memory && pcms->hotplug_memory.base) { - uint64_t *val = g_malloc(sizeof(*val)); - PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); - uint64_t res_mem_end = pcms->hotplug_memory.base; + if (pcmc->has_reserved_memory && pcms->hotplug_memory.base) { + uint64_t *val = g_malloc(sizeof(*val)); + PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); + uint64_t res_mem_end = pcms->hotplug_memory.base; - if (!pcmc->broken_reserved_end) { - res_mem_end += memory_region_size(&pcms->hotplug_memory.mr); + if (!pcmc->broken_reserved_end) { + res_mem_end += memory_region_size(&pcms->hotplug_memory.mr); + } + *val = cpu_to_le64(ROUND_UP(res_mem_end, 0x1ULL << 30)); + fw_cfg_add_file(fw_cfg, "etc/reserved-memory-end", val, sizeof(*val)); } - *val = cpu_to_le64(ROUND_UP(res_mem_end, 0x1ULL << 30)); - fw_cfg_add_file(fw_cfg, "etc/reserved-memory-end", val, sizeof(*val)); } if (linux_boot) { - load_linux(pcms, fw_cfg); + if (pcms->fw) { + load_linux_bzimage(pcms, fw_cfg); + } else { + load_linux_efi(pcms); + } } for (i = 0; i < nb_option_roms; i++) { @@ -2347,6 +2388,7 @@ static void pc_machine_initfn(Object *obj) PC_MACHINE_DEFINE_PROP_BOOL(pcms, PC_MACHINE_PIC, pic, true); PC_MACHINE_DEFINE_PROP_BOOL(pcms, PC_MACHINE_PIT, pit, true); PC_MACHINE_DEFINE_PROP_BOOL(pcms, PC_MACHINE_STATIC_PRT, static_prt, false); + PC_MACHINE_DEFINE_PROP_BOOL(pcms, PC_MACHINE_FW, fw, true); } static void pc_machine_reset(void) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 55ab09a..f5e01e1 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -82,6 +82,7 @@ struct PCMachineState { bool pic; bool pit; bool static_prt; + bool fw; }; #define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device" @@ -95,6 +96,7 @@ struct PCMachineState { #define PC_MACHINE_PIC "pic" #define PC_MACHINE_PIT "pit" #define PC_MACHINE_STATIC_PRT "static-prt" +#define PC_MACHINE_FW "fw" /** * PCMachineClass: