From nobody Thu May 2 23:26:04 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1518517494750482.7976410360968; Tue, 13 Feb 2018 02:24:54 -0800 (PST) Received: from localhost ([::1]:38365 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1elXld-0002t2-BB for importer@patchew.org; Tue, 13 Feb 2018 05:24:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34439) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1elXjz-0001yn-EU for qemu-devel@nongnu.org; Tue, 13 Feb 2018 05:23:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1elXjv-00060j-8m for qemu-devel@nongnu.org; Tue, 13 Feb 2018 05:23:11 -0500 Received: from mail.sysgo.com ([176.9.12.79]:43740) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1elXju-000609-UC; Tue, 13 Feb 2018 05:23:07 -0500 From: David Engraf To: Alexander Graf , David Gibson Date: Tue, 13 Feb 2018 11:22:58 +0100 Message-Id: <20180213102258.26145-1-david.engraf@sysgo.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180130075847.6023-1-david.engraf@sysgo.com> References: <20180130075847.6023-1-david.engraf@sysgo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 176.9.12.79 Subject: [Qemu-devel] [PATCH v2] PPC: e500: Fix duplicate kernel load and device tree overlap 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: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Engraf Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch fixes an incorrect behavior when the -kernel argument has been specified without -bios. In this case the kernel was loaded twice. At addre= ss 32M as a raw image and afterwards by load_elf/load_uimage at the corresponding load address. In this case the region for the device tree and the raw kernel image may overlap. The patch fixes the behavior by loading the kernel image once with load_elf/load_uimage and skips loading the raw image. It also ensures that the device tree is generated behind bios/kernel/initrd. When here do not use bios_name/size for the kernel and use a more generic name called payload_name/size. Signed-off-by: David Engraf --- hw/ppc/e500.c | 112 ++++++++++++++++++++++++++++++++++--------------------= ---- 1 file changed, 65 insertions(+), 47 deletions(-) diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index c4fe06ea2a..d12b9d6121 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -776,7 +776,6 @@ void ppce500_init(MachineState *machine, PPCE500Params = *params) MemoryRegion *ram =3D g_new(MemoryRegion, 1); PCIBus *pci_bus; CPUPPCState *env =3D NULL; - uint64_t loadaddr; hwaddr kernel_base =3D -1LL; int kernel_size =3D 0; hwaddr dt_base =3D 0; @@ -784,8 +783,10 @@ void ppce500_init(MachineState *machine, PPCE500Params= *params) int initrd_size =3D 0; hwaddr cur_base =3D 0; char *filename; + const char *payload_name; + bool kernel_as_payload; hwaddr bios_entry =3D 0; - target_long bios_size; + target_long payload_size; struct boot_info *boot_info; int dt_size; int i; @@ -913,11 +914,6 @@ void ppce500_init(MachineState *machine, PPCE500Params= *params) /* Register spinning region */ sysbus_create_simple("e500-spin", params->spin_base, NULL); =20 - if (cur_base < (32 * 1024 * 1024)) { - /* u-boot occupies memory up to 32MB, so load blobs above */ - cur_base =3D (32 * 1024 * 1024); - } - if (params->has_mpc8xxx_gpio) { qemu_irq poweroff_irq; =20 @@ -952,36 +948,6 @@ void ppce500_init(MachineState *machine, PPCE500Params= *params) sysbus_mmio_get_region(s, 0)); } =20 - /* Load kernel. */ - if (machine->kernel_filename) { - kernel_base =3D cur_base; - kernel_size =3D load_image_targphys(machine->kernel_filename, - cur_base, - ram_size - cur_base); - if (kernel_size < 0) { - fprintf(stderr, "qemu: could not load kernel '%s'\n", - machine->kernel_filename); - exit(1); - } - - cur_base +=3D kernel_size; - } - - /* Load initrd. */ - if (machine->initrd_filename) { - initrd_base =3D (cur_base + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK; - initrd_size =3D load_image_targphys(machine->initrd_filename, init= rd_base, - ram_size - initrd_base); - - if (initrd_size < 0) { - fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", - machine->initrd_filename); - exit(1); - } - - cur_base =3D initrd_base + initrd_size; - } - /* * Smart firmware defaults ahead! * @@ -997,33 +963,85 @@ void ppce500_init(MachineState *machine, PPCE500Param= s *params) * This ensures backwards compatibility with how we used to expose * -kernel to users but allows them to run through u-boot as well. */ + kernel_as_payload =3D false; if (bios_name =3D=3D NULL) { if (machine->kernel_filename) { - bios_name =3D machine->kernel_filename; + payload_name =3D machine->kernel_filename; + kernel_as_payload =3D true; } else { - bios_name =3D "u-boot.e500"; + payload_name =3D "u-boot.e500"; } + } else { + payload_name =3D bios_name; } - filename =3D qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); =20 - bios_size =3D load_elf(filename, NULL, NULL, &bios_entry, &loadaddr, N= ULL, - 1, PPC_ELF_MACHINE, 0, 0); - if (bios_size < 0) { + filename =3D qemu_find_file(QEMU_FILE_TYPE_BIOS, payload_name); + + payload_size =3D load_elf(filename, NULL, NULL, &bios_entry, &cur_base= , NULL, + 1, PPC_ELF_MACHINE, 0, 0); + if (payload_size < 0) { /* * Hrm. No ELF image? Try a uImage, maybe someone is giving us an * ePAPR compliant kernel */ - kernel_size =3D load_uimage(filename, &bios_entry, &loadaddr, NULL, - NULL, NULL); - if (kernel_size < 0) { + payload_size =3D load_uimage(filename, &bios_entry, &cur_base, NUL= L, + NULL, NULL); + if (payload_size < 0) { fprintf(stderr, "qemu: could not load firmware '%s'\n", filena= me); exit(1); } } + g_free(filename); =20 + if (kernel_as_payload) { + kernel_base =3D cur_base; + kernel_size =3D payload_size; + } + + cur_base +=3D payload_size; + + /* Load bare kernel only if no bios/u-boot has been provided */ + if (machine->kernel_filename && !kernel_as_payload) { + kernel_base =3D cur_base; + kernel_size =3D load_image_targphys(machine->kernel_filename, + cur_base, + ram_size - cur_base); + if (kernel_size < 0) { + fprintf(stderr, "qemu: could not load kernel '%s'\n", + machine->kernel_filename); + exit(1); + } + + cur_base +=3D kernel_size; + } + + if (cur_base < (32 * 1024 * 1024)) { + /* u-boot occupies memory up to 32MB, so load blobs above */ + cur_base =3D (32 * 1024 * 1024); + } + + /* Load initrd. */ + if (machine->initrd_filename) { + initrd_base =3D (cur_base + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK; + initrd_size =3D load_image_targphys(machine->initrd_filename, init= rd_base, + ram_size - initrd_base); + + if (initrd_size < 0) { + fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", + machine->initrd_filename); + exit(1); + } + + cur_base =3D initrd_base + initrd_size; + } + /* Reserve space for dtb */ - dt_base =3D (loadaddr + bios_size + DTC_LOAD_PAD) & ~DTC_PAD_MASK; + dt_base =3D (cur_base + DTC_LOAD_PAD) & ~DTC_PAD_MASK; + if (dt_base + DTB_MAX_SIZE > ram_size) { + fprintf(stderr, "qemu: not enough memory for device tree\n"); + exit(1); + } =20 dt_size =3D ppce500_prep_device_tree(machine, params, dt_base, initrd_base, initrd_size, --=20 2.14.1