From patchwork Wed Feb 1 17:12:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Henrique Barboza X-Patchwork-Id: 13124763 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DEB8DC63797 for ; Wed, 1 Feb 2023 17:13:29 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pNGep-0006bf-S5; Wed, 01 Feb 2023 12:12:28 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pNGem-0006aP-BQ for qemu-devel@nongnu.org; Wed, 01 Feb 2023 12:12:25 -0500 Received: from mail-oi1-x22f.google.com ([2607:f8b0:4864:20::22f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pNGek-0004Iy-Aq for qemu-devel@nongnu.org; Wed, 01 Feb 2023 12:12:24 -0500 Received: by mail-oi1-x22f.google.com with SMTP id dt8so13206114oib.0 for ; Wed, 01 Feb 2023 09:12:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fz356eeLxSTB+G/CsOEbtTXiIQ9xiAjsdTiBBzA1hes=; b=IOOgNhSyEzVwn8El6htRoDacos1PsNk3pOr25gfrDJ/FauYhIaRGq2Gk+unzzPKedL dSAViVyVRJ3urVEeQZC+3FewbIZsyxJcSG5CLmZl1OUoPIMvStjf6Pjb+eeGP+gwtJYz wUpfF5rZZerYXUae70R2HcosAmEBCsrTakAgVrC2kntsgjZhFthFgwv/b5Mt36bSVJfi t+pQQl6L9UChfUlVPeVOR2jiAOlJY+fF3zPzotisZbYO+9swQSToIyA24PSEoa00qifO kRR+QLoTJ4TUJ9MuKZt+3+7LO8W0SydfgtlE8DK0EtkvcahRmp0nGRXarYHg3scuNKYS QbEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fz356eeLxSTB+G/CsOEbtTXiIQ9xiAjsdTiBBzA1hes=; b=bcbqXxnRPatNr+bFMz3M7tY+6ZHNhW84JrNz0RSvCRM7FOO3geeLHe2JvhJNXeSI8s i6G9uV7P2/kpBrFA8kjXF9OWyjN35L7l6MCvkEix75duRiHg/bwYLQQH8v5TkXNljaYC 2wgh5UXVTMZO4mBzG7L/EyQgDqDLdGR/+1JRvf0e+jJjqB4lbKHHGLaJ5Pxowi3b9EJS /o6wjLTxOTAahXMxTpE7WaZx5dvDj21OuhQTs5pbhTuvatU8f7ojvzf05rKC5uxvms1R rUL9gPWMG3UPB61Ac1B+zaH2iFJdqhrXeJb2CvvMnq+SAFQbahlBozKpUuhz+366sODv XKSA== X-Gm-Message-State: AO0yUKXr8kDhZKMfkY4b0HPrEkO13vhzoqydv6skL7LcOXXQOo28RXc6 0jXcqbvcG15uev14XK1sJZD6QxgxLDXrENL8bqk= X-Google-Smtp-Source: AK7set93GmVyCVtHBo9k0o4Ge0qaT6/ae23s2jndQ3MgqqcyXFPRvrQh/qJuBPguJs7FuyGOcgsGNQ== X-Received: by 2002:a05:6808:221b:b0:365:367:7c7a with SMTP id bd27-20020a056808221b00b0036503677c7amr2055225oib.11.1675271540883; Wed, 01 Feb 2023 09:12:20 -0800 (PST) Received: from grind.. ([177.102.69.207]) by smtp.gmail.com with ESMTPSA id k12-20020a056808068c00b003749e231db7sm7100627oig.30.2023.02.01.09.12.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Feb 2023 09:12:20 -0800 (PST) From: Daniel Henrique Barboza To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, alistair.francis@wdc.com, bmeng.cn@gmail.com, Daniel Henrique Barboza Subject: [PATCH v5 1/3] hw/riscv/boot.c: calculate fdt size after fdt_pack() Date: Wed, 1 Feb 2023 14:12:10 -0300 Message-Id: <20230201171212.1219375-2-dbarboza@ventanamicro.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230201171212.1219375-1-dbarboza@ventanamicro.com> References: <20230201171212.1219375-1-dbarboza@ventanamicro.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::22f; envelope-from=dbarboza@ventanamicro.com; helo=mail-oi1-x22f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org fdt_pack() can change the fdt size, meaning that fdt_totalsize() can contain a now deprecated (bigger) value. Reviewed-by: Alistair Francis Signed-off-by: Daniel Henrique Barboza --- hw/riscv/boot.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index cb27798a25..2d03a9a921 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -253,8 +253,13 @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) { uint64_t temp, fdt_addr; hwaddr dram_end = dram_base + mem_size; - int ret, fdtsize = fdt_totalsize(fdt); + int ret = fdt_pack(fdt); + int fdtsize; + /* Should only fail if we've built a corrupted tree */ + g_assert(ret == 0); + + fdtsize = fdt_totalsize(fdt); if (fdtsize <= 0) { error_report("invalid device-tree"); exit(1); @@ -269,9 +274,6 @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end; fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB); - ret = fdt_pack(fdt); - /* Should only fail if we've built a corrupted tree */ - g_assert(ret == 0); /* copy in the device tree */ qemu_fdt_dumpdtb(fdt, fdtsize); From patchwork Wed Feb 1 17:12:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Henrique Barboza X-Patchwork-Id: 13124765 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0805AC38142 for ; Wed, 1 Feb 2023 17:13:43 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pNGet-0006d6-Ny; Wed, 01 Feb 2023 12:12:33 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pNGeo-0006bJ-VO for qemu-devel@nongnu.org; Wed, 01 Feb 2023 12:12:27 -0500 Received: from mail-oi1-x232.google.com ([2607:f8b0:4864:20::232]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pNGem-0004Jb-Qp for qemu-devel@nongnu.org; Wed, 01 Feb 2023 12:12:26 -0500 Received: by mail-oi1-x232.google.com with SMTP id s17so5342048ois.10 for ; Wed, 01 Feb 2023 09:12:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Upg3n6UXcqzGiqp/8YrNQfPE1Y/A4TRC8HGgGpV9Gu0=; b=i+y8PuxYPo2Xkyqe74+MkYUMvR4/cM4OmjCz1avViblKGQgavDHMGtG88Sy6SRU8YJ 65tG7W/gnFkNgKntHnqqgIavMd8iKMZ/AF6w+KxeOzqnW58BLK43/RzWaDHe6FuCWHyN ZSORx9gPJJC4xNKVNDwHMijXmBGEFWvTFVRVOakrUFABHA5VDqwrdlAaNVMWSreKKrG9 OiYzpVOCCBA951/gIGWXwtVVX6JjpvvVI2nHgeh2UyUzNuxoXORGXmrcHjf80XF+e2bQ 8CYhL6AQFsCLtHHnZatumat1TapYs4KB+O9mJ7CEdEGwvqYe1CqMEEbZa8VCClfTYl1g Xm7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Upg3n6UXcqzGiqp/8YrNQfPE1Y/A4TRC8HGgGpV9Gu0=; b=8JhESFP79VhH3qaIzkWVLntFW6v2CKytBzwb1yL4SMdKi+BywMUne+ly0wNETib7ve GuOPnqp/LwMoDc+f9SUsfINvI8kmnGGIaVMiYCO/UteKp5QgR0FzQkclaDswRRQiy8/e k2ariOoyASoZB5iL07xxMSBpVYCUtYzmNoVgQWflBn9lnlVtpC4HtXeTWA6dJyTMrLBR JCDBV9NXxk/20MlZ21drGHpOujq5hzqoy+D1s9w1TQ7+e1MH9ITMamM7hwYtaGZovGG5 aXNI2B+1BUzHo3mxBgiJoTaJwOeHGt3rweqXUsXn0HdvXKIRtKpHkH3ObmFwwtFLlWbT OzjA== X-Gm-Message-State: AO0yUKUdj7Vi+1DSK6X7FcfJ/k44bYc8PdwmcNtNfqyREz6zo+bLeXKx mRECazXuCLeHcz/qSXyPKIYDW3w+XCzMzv1o0eA= X-Google-Smtp-Source: AK7set/xAILLBukjOBVhMhCmgAHgQR+LlQ3Bin78BKbRk6UvKmxXDShgEDA3PA4Se0EIKqPIj0X7MA== X-Received: by 2002:a54:4e8f:0:b0:36a:d348:26d8 with SMTP id c15-20020a544e8f000000b0036ad34826d8mr1272472oiy.52.1675271543202; Wed, 01 Feb 2023 09:12:23 -0800 (PST) Received: from grind.. ([177.102.69.207]) by smtp.gmail.com with ESMTPSA id k12-20020a056808068c00b003749e231db7sm7100627oig.30.2023.02.01.09.12.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Feb 2023 09:12:22 -0800 (PST) From: Daniel Henrique Barboza To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, alistair.francis@wdc.com, bmeng.cn@gmail.com, Daniel Henrique Barboza Subject: [PATCH v5 2/3] hw/riscv: split fdt address calculation from fdt load Date: Wed, 1 Feb 2023 14:12:11 -0300 Message-Id: <20230201171212.1219375-3-dbarboza@ventanamicro.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230201171212.1219375-1-dbarboza@ventanamicro.com> References: <20230201171212.1219375-1-dbarboza@ventanamicro.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::232; envelope-from=dbarboza@ventanamicro.com; helo=mail-oi1-x232.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org A common trend in other archs is to calculate the fdt address, which is usually straightforward, and then calling a function that loads the fdt/dtb by using that address. riscv_load_fdt() is doing a bit too much in comparison. It's calculating the fdt address via an elaborated heuristic to put the FDT at the bottom of DRAM, and "bottom of DRAM" will vary across boards and configurations, then it's actually loading the fdt, and finally it's returning the fdt address used to the caller. Reduce the existing complexity of riscv_load_fdt() by splitting its code into a new function, riscv_compute_fdt_addr(), that will take care of all fdt address logic. riscv_load_fdt() can then be a simple function that just loads a fdt at the given fdt address. We're also taken the opportunity to clarify the intentions and assumptions made by these functions. riscv_load_fdt() is now receiving a hwaddr as fdt_addr because there is no restriction of having to load the fdt in higher addresses that doesn't fit in an uint32_t. Reviewed-by: Alistair Francis Signed-off-by: Daniel Henrique Barboza --- hw/riscv/boot.c | 30 +++++++++++++++++++++++++----- hw/riscv/microchip_pfsoc.c | 6 ++++-- hw/riscv/sifive_u.c | 7 ++++--- hw/riscv/spike.c | 6 +++--- hw/riscv/virt.c | 7 ++++--- include/hw/riscv/boot.h | 4 +++- 6 files changed, 43 insertions(+), 17 deletions(-) diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index 2d03a9a921..2e53494b08 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -249,9 +249,21 @@ void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry) } } -uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) +/* + * The FDT should be put at the farthest point possible to + * avoid overwriting it with the kernel/initrd. + * + * This function makes an assumption that the DRAM is + * contiguous. It also cares about 32-bit systems and + * will limit fdt_addr to be addressable by them even for + * 64-bit CPUs. + * + * The FDT is fdt_packed() during the calculation. + */ +uint64_t riscv_compute_fdt_addr(hwaddr dram_base, uint64_t mem_size, + void *fdt) { - uint64_t temp, fdt_addr; + uint64_t temp; hwaddr dram_end = dram_base + mem_size; int ret = fdt_pack(fdt); int fdtsize; @@ -272,7 +284,17 @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) * end of dram or 3GB whichever is lesser. */ temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end; - fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB); + + return QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB); +} + +/* + * 'fdt_addr' is received as hwaddr because boards might put + * the FDT beyond 32-bit addressing boundary. + */ +void riscv_load_fdt(hwaddr fdt_addr, void *fdt) +{ + uint32_t fdtsize = fdt_totalsize(fdt); /* copy in the device tree */ qemu_fdt_dumpdtb(fdt, fdtsize); @@ -281,8 +303,6 @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) &address_space_memory); qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds, rom_ptr_for_as(&address_space_memory, fdt_addr, fdtsize)); - - return fdt_addr; } void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base, diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c index 82ae5e7023..17499d4152 100644 --- a/hw/riscv/microchip_pfsoc.c +++ b/hw/riscv/microchip_pfsoc.c @@ -641,8 +641,10 @@ static void microchip_icicle_kit_machine_init(MachineState *machine) } /* Compute the fdt load address in dram */ - fdt_load_addr = riscv_load_fdt(memmap[MICROCHIP_PFSOC_DRAM_LO].base, - machine->ram_size, machine->fdt); + fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base, + machine->ram_size, machine->fdt); + riscv_load_fdt(fdt_load_addr, machine->fdt); + /* Load the reset vector */ riscv_setup_rom_reset_vec(machine, &s->soc.u_cpus, firmware_load_addr, memmap[MICROCHIP_PFSOC_ENVM_DATA].base, diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 2fb6ee231f..626d4dc2f3 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -616,9 +616,10 @@ static void sifive_u_machine_init(MachineState *machine) kernel_entry = 0; } - /* Compute the fdt load address in dram */ - fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DEV_DRAM].base, - machine->ram_size, machine->fdt); + fdt_load_addr = riscv_compute_fdt_addr(memmap[SIFIVE_U_DEV_DRAM].base, + machine->ram_size, machine->fdt); + riscv_load_fdt(fdt_load_addr, machine->fdt); + if (!riscv_is_32bit(&s->soc.u_cpus)) { start_addr_hi32 = (uint64_t)start_addr >> 32; } diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 04d236296b..f1114f2c71 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -324,9 +324,9 @@ static void spike_board_init(MachineState *machine) kernel_entry = 0; } - /* Compute the fdt load address in dram */ - fdt_load_addr = riscv_load_fdt(memmap[SPIKE_DRAM].base, - machine->ram_size, machine->fdt); + fdt_load_addr = riscv_compute_fdt_addr(memmap[SPIKE_DRAM].base, + machine->ram_size, machine->fdt); + riscv_load_fdt(fdt_load_addr, machine->fdt); /* load the reset vector */ riscv_setup_rom_reset_vec(machine, &s->soc[0], memmap[SPIKE_DRAM].base, diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index e420254de2..2e0a0cdb17 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1303,9 +1303,10 @@ static void virt_machine_done(Notifier *notifier, void *data) start_addr = virt_memmap[VIRT_FLASH].base; } - /* Compute the fdt load address in dram */ - fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base, - machine->ram_size, machine->fdt); + fdt_load_addr = riscv_compute_fdt_addr(memmap[VIRT_DRAM].base, + machine->ram_size, machine->fdt); + riscv_load_fdt(fdt_load_addr, machine->fdt); + /* load the reset vector */ riscv_setup_rom_reset_vec(machine, &s->soc[0], start_addr, virt_memmap[VIRT_MROM].base, diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index f94653a09b..46de4ec46b 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -47,7 +47,9 @@ target_ulong riscv_load_kernel(MachineState *machine, target_ulong firmware_end_addr, symbol_fn_t sym_cb); void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry); -uint64_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt); +uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size, + void *fdt); +void riscv_load_fdt(hwaddr fdt_addr, void *fdt); void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts, hwaddr saddr, hwaddr rom_base, hwaddr rom_size, From patchwork Wed Feb 1 17:12:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Henrique Barboza X-Patchwork-Id: 13124764 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E2341C6379F for ; Wed, 1 Feb 2023 17:13:29 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pNGex-0006dh-Qu; Wed, 01 Feb 2023 12:12:35 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pNGer-0006cF-Bu for qemu-devel@nongnu.org; Wed, 01 Feb 2023 12:12:29 -0500 Received: from mail-oi1-x22c.google.com ([2607:f8b0:4864:20::22c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pNGep-0004Jx-CD for qemu-devel@nongnu.org; Wed, 01 Feb 2023 12:12:29 -0500 Received: by mail-oi1-x22c.google.com with SMTP id j21so7355195oie.4 for ; Wed, 01 Feb 2023 09:12:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=dcs1yzLvpBWElN3ZJOkxPk7Gw6e8VUiSzo/dfnRmEKA=; b=fMkgTGhiv6MTQ6/qvxrWU7/KnsvNJmkVfwuX98qZ+Al8OO6LOB6bIGC3Q0rMD21gEh 7Jx0KIukDvdnJSgfg82mzJgMcM4LrBOPluK93UVctRp4jxSj/MPzhsm41Ht14a+FvqGt 6jiMki/4MX06Z1XW2Y3M7a2ark54HJ5KtMP0HDS5B0X/zRZVONGuVfvar4+JvPrLLMGG 234o+CX02kGmoFyxMn3E428VaRzdDDaFD3TKMG65u7miH9r26YeY4Z9yVF8UzFBI2Hrk +XpJHwIOaQCS5GYM0CgaODpotZQn89rKf5nM/G1P9daTyyqxFJkO00bKbEECQTxbTJqS iJvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dcs1yzLvpBWElN3ZJOkxPk7Gw6e8VUiSzo/dfnRmEKA=; b=pAgAoio8GXi4abf0F6O43FsdBZZCFQquQYtHgsm8QcyucNMWN08WTZHPXjvpip4Zxr IUXEmvRC/cm1EdkIkW4i0ogc8sPEdG8JLA3UCkmPN0G4T+qqXQsHSs6NqNaRQ5y/lINR 806ilyfuLqIbOtdii7J2Nc3gpNn4/lJ7g9r6uMt0WzdzQ7LExhKZP3qKJvBQ8v8qCQeX V17gQvjA16c77B8srP9bIoiPi7vyZzGUE9TqvYYjPbnjvv6bQjkTy7joqwaJA+eZSZQx ca5cPihJ2MJmKiAjMCoqMU6l3SCzK0o15FT17H273fK4LTMhnbxcbwPwhzJR0rh90eaF z2jQ== X-Gm-Message-State: AO0yUKV5r7Xf0i7nTNd941Wpa4iaDx7FqrOhLkS37ufQFa4VbrmR0Ld4 5LBWebh5HMeYVCMxhTjG0eM6yNKG/GdW7qb6hQE= X-Google-Smtp-Source: AK7set93CCwBmgxfatdMNvx8m4BbVSeW/byNWmmujOROFgQpIwWTjvcDYN64xjIGoHGRtFMAH2eh4A== X-Received: by 2002:a05:6808:1448:b0:378:5a94:8b22 with SMTP id x8-20020a056808144800b003785a948b22mr1884816oiv.47.1675271545372; Wed, 01 Feb 2023 09:12:25 -0800 (PST) Received: from grind.. ([177.102.69.207]) by smtp.gmail.com with ESMTPSA id k12-20020a056808068c00b003749e231db7sm7100627oig.30.2023.02.01.09.12.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Feb 2023 09:12:24 -0800 (PST) From: Daniel Henrique Barboza To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, alistair.francis@wdc.com, bmeng.cn@gmail.com, Daniel Henrique Barboza Subject: [PATCH v5 3/3] hw/riscv: change riscv_compute_fdt_addr() semantics Date: Wed, 1 Feb 2023 14:12:12 -0300 Message-Id: <20230201171212.1219375-4-dbarboza@ventanamicro.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230201171212.1219375-1-dbarboza@ventanamicro.com> References: <20230201171212.1219375-1-dbarboza@ventanamicro.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::22c; envelope-from=dbarboza@ventanamicro.com; helo=mail-oi1-x22c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org As it is now, riscv_compute_fdt_addr() is receiving a dram_base, a mem_size (which is defaulted to MachineState::ram_size in all boards) and the FDT pointer. And it makes a very important assumption: the DRAM interval dram_base + mem_size is contiguous. This is indeed the case for most boards that use a FDT. The Icicle Kit board works with 2 distinct RAM banks that are separated by a gap. We have a lower bank with 1GiB size, a gap follows, then at 64GiB the high memory starts. MachineClass::default_ram_size for this board is set to 1.5Gb, and machine_init() is enforcing it as minimal RAM size, meaning that there we'll always have at least 512 MiB in the Hi RAM area. Using riscv_compute_fdt_addr() in this board is weird because not only the board has sparse RAM, and it's calling it using the base address of the Lo RAM area, but it's also using a mem_size that we have guarantees that it will go up to the Hi RAM. All the function assumptions doesn't work for this board. In fact, what makes the function works at all in this case is a coincidence. Commit 1a475d39ef54 introduced a 3GB boundary for the FDT, down from 4Gb, that is enforced if dram_base is lower than 3072 MiB. For the Icicle Kit board, memmap[MICROCHIP_PFSOC_DRAM_LO].base is 0x80000000 (2 Gb) and it has a 1Gb size, so it will fall in the conditions to put the FDT under a 3Gb address, which happens to be exactly at the end of DRAM_LO. If the base address of the Lo area started later than 3Gb this function would be unusable by the board. Changing any assumptions inside riscv_compute_fdt_addr() can also break it by accident as well. Let's change riscv_compute_fdt_addr() semantics to be appropriate to the Icicle Kit board and for future boards that might have sparse RAM topologies to worry about: - relieve the condition that the dram_base + mem_size area is contiguous, since this is already not the case today; - receive an extra 'dram_size' size attribute that refers to a contiguous RAM block that the board wants the FDT to reside on. Together with 'mem_size' and 'fdt', which are now now being consumed by a MachineState pointer, we're able to make clear assumptions based on the DRAM block and total mem_size available to ensure that the FDT will be put in a valid RAM address. Signed-off-by: Daniel Henrique Barboza Reviewed-by: Alistair Francis --- hw/riscv/boot.c | 35 +++++++++++++++++++++++------------ hw/riscv/microchip_pfsoc.c | 3 ++- hw/riscv/sifive_u.c | 3 ++- hw/riscv/spike.c | 3 ++- hw/riscv/virt.c | 3 ++- include/hw/riscv/boot.h | 2 +- 6 files changed, 32 insertions(+), 17 deletions(-) diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index 2e53494b08..c7e0e50bd8 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -250,33 +250,44 @@ void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry) } /* - * The FDT should be put at the farthest point possible to - * avoid overwriting it with the kernel/initrd. + * This function makes an assumption that the DRAM interval + * 'dram_base' + 'dram_size' is contiguous. * - * This function makes an assumption that the DRAM is - * contiguous. It also cares about 32-bit systems and - * will limit fdt_addr to be addressable by them even for - * 64-bit CPUs. + * Considering that 'dram_end' is the lowest value between + * the end of the DRAM block and MachineState->ram_size, the + * FDT location will vary according to 'dram_base': + * + * - if 'dram_base' is less that 3072 MiB, the FDT will be + * put at the lowest value between 3072 MiB and 'dram_end'; + * + * - if 'dram_base' is higher than 3072 MiB, the FDT will be + * put at 'dram_end'. * * The FDT is fdt_packed() during the calculation. */ -uint64_t riscv_compute_fdt_addr(hwaddr dram_base, uint64_t mem_size, - void *fdt) +uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size, + MachineState *ms) { - uint64_t temp; - hwaddr dram_end = dram_base + mem_size; - int ret = fdt_pack(fdt); + int ret = fdt_pack(ms->fdt); + hwaddr dram_end, temp; int fdtsize; /* Should only fail if we've built a corrupted tree */ g_assert(ret == 0); - fdtsize = fdt_totalsize(fdt); + fdtsize = fdt_totalsize(ms->fdt); if (fdtsize <= 0) { error_report("invalid device-tree"); exit(1); } + /* + * A dram_size == 0, usually from a MemMapEntry[].size element, + * means that the DRAM block goes all the way to ms->ram_size. + */ + dram_end = dram_base; + dram_end += dram_size ? MIN(ms->ram_size, dram_size) : ms->ram_size; + /* * We should put fdt as far as possible to avoid kernel/initrd overwriting * its content. But it should be addressable by 32 bit system as well. diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c index 17499d4152..2b91e49561 100644 --- a/hw/riscv/microchip_pfsoc.c +++ b/hw/riscv/microchip_pfsoc.c @@ -642,7 +642,8 @@ static void microchip_icicle_kit_machine_init(MachineState *machine) /* Compute the fdt load address in dram */ fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base, - machine->ram_size, machine->fdt); + memmap[MICROCHIP_PFSOC_DRAM_LO].size, + machine); riscv_load_fdt(fdt_load_addr, machine->fdt); /* Load the reset vector */ diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 626d4dc2f3..d3ab7a9cda 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -617,7 +617,8 @@ static void sifive_u_machine_init(MachineState *machine) } fdt_load_addr = riscv_compute_fdt_addr(memmap[SIFIVE_U_DEV_DRAM].base, - machine->ram_size, machine->fdt); + memmap[SIFIVE_U_DEV_DRAM].size, + machine); riscv_load_fdt(fdt_load_addr, machine->fdt); if (!riscv_is_32bit(&s->soc.u_cpus)) { diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index f1114f2c71..cc3f6dac17 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -325,7 +325,8 @@ static void spike_board_init(MachineState *machine) } fdt_load_addr = riscv_compute_fdt_addr(memmap[SPIKE_DRAM].base, - machine->ram_size, machine->fdt); + memmap[SPIKE_DRAM].size, + machine); riscv_load_fdt(fdt_load_addr, machine->fdt); /* load the reset vector */ diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 2e0a0cdb17..a061151a6f 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1304,7 +1304,8 @@ static void virt_machine_done(Notifier *notifier, void *data) } fdt_load_addr = riscv_compute_fdt_addr(memmap[VIRT_DRAM].base, - machine->ram_size, machine->fdt); + memmap[VIRT_DRAM].size, + machine); riscv_load_fdt(fdt_load_addr, machine->fdt); /* load the reset vector */ diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index 46de4ec46b..511390f60e 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -48,7 +48,7 @@ target_ulong riscv_load_kernel(MachineState *machine, symbol_fn_t sym_cb); void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry); uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size, - void *fdt); + MachineState *ms); void riscv_load_fdt(hwaddr fdt_addr, void *fdt); void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts, hwaddr saddr,