From patchwork Mon Sep 2 08:11:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 271722 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 4D7C72C0077 for ; Mon, 2 Sep 2013 18:16:07 +1000 (EST) Received: from localhost ([::1]:37782 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VGPIr-0002IX-6A for incoming@patchwork.ozlabs.org; Mon, 02 Sep 2013 04:16:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37125) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VGPEe-0004Tf-3S for qemu-devel@nongnu.org; Mon, 02 Sep 2013 04:11:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VGPEW-0000fR-Uq for qemu-devel@nongnu.org; Mon, 02 Sep 2013 04:11:44 -0400 Received: from cantor2.suse.de ([195.135.220.15]:40383 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VGPEW-0000fE-LN; Mon, 02 Sep 2013 04:11:36 -0400 Received: from relay1.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 9EE12A538A; Mon, 2 Sep 2013 10:11:35 +0200 (CEST) From: Alexander Graf To: "qemu-ppc@nongnu.org list:PowerPC" Date: Mon, 2 Sep 2013 10:11:16 +0200 Message-Id: <1378109493-41076-2-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1378109493-41076-1-git-send-email-agraf@suse.de> References: <1378109493-41076-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 195.135.220.15 Cc: Blue Swirl , Anthony Liguori , qemu-devel Developers , Aurelien Jarno Subject: [Qemu-devel] [PULL 01/18] PPC: E500: Generate device tree on reset X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Today we generate the device tree once on machine initialization and then store the finalized blob in memory to reload it on reset. This is bad for 2 reasons. First we potentially waste a bunch of RAM for no good reason, as we have all information required to regenerate the device tree available anyways. The second reason is even more important. On machine init when we generate the device tree for the first time, we don't have all of the devices fully initialized yet. But the device tree needs to potentially walk devices to put information about them into the device tree. Move the generation into a reset function. That way we just generate it new every time we reset, solving both of the above issues. Signed-off-by: Alexander Graf --- hw/ppc/e500.c | 52 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index e79612b..9059ff9 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -123,13 +123,14 @@ static void dt_serial_create(void *fdt, unsigned long long offset, } } -static int ppce500_load_device_tree(CPUPPCState *env, - QEMUMachineInitArgs *args, +static int ppce500_load_device_tree(QEMUMachineInitArgs *args, PPCE500Params *params, hwaddr addr, hwaddr initrd_base, - hwaddr initrd_size) + hwaddr initrd_size, + bool dry_run) { + CPUPPCState *env = first_cpu->env_ptr; int ret = -1; uint64_t mem_reg_property[] = { 0, cpu_to_be64(args->ram_size) }; int fdt_size; @@ -369,12 +370,10 @@ static int ppce500_load_device_tree(CPUPPCState *env, } done: - qemu_devtree_dumpdtb(fdt, fdt_size); - ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr); - if (ret < 0) { - goto out; + if (!dry_run) { + qemu_devtree_dumpdtb(fdt, fdt_size); + cpu_physical_memory_write(addr, fdt, fdt_size); } - g_free(fdt); ret = fdt_size; out: @@ -383,6 +382,41 @@ out: return ret; } +typedef struct DeviceTreeParams { + QEMUMachineInitArgs args; + PPCE500Params params; + hwaddr addr; + hwaddr initrd_base; + hwaddr initrd_size; +} DeviceTreeParams; + +static void ppce500_reset_device_tree(void *opaque) +{ + DeviceTreeParams *p = opaque; + ppce500_load_device_tree(&p->args, &p->params, p->addr, p->initrd_base, + p->initrd_size, false); +} + +static int ppce500_prep_device_tree(QEMUMachineInitArgs *args, + PPCE500Params *params, + hwaddr addr, + hwaddr initrd_base, + hwaddr initrd_size) +{ + DeviceTreeParams *p = g_new(DeviceTreeParams, 1); + p->args = *args; + p->params = *params; + p->addr = addr; + p->initrd_base = initrd_base; + p->initrd_size = initrd_size; + + qemu_register_reset(ppce500_reset_device_tree, p); + + /* Issue the device tree loader once, so that we get the size of the blob */ + return ppce500_load_device_tree(args, params, addr, initrd_base, + initrd_size, true); +} + /* Create -kernel TLB entries for BookE. */ static inline hwaddr booke206_page_size_to_tlb(uint64_t size) { @@ -746,7 +780,7 @@ void ppce500_init(QEMUMachineInitArgs *args, PPCE500Params *params) struct boot_info *boot_info; int dt_size; - dt_size = ppce500_load_device_tree(env, args, params, dt_base, + dt_size = ppce500_prep_device_tree(args, params, dt_base, initrd_base, initrd_size); if (dt_size < 0) { fprintf(stderr, "couldn't load device tree\n");