From nobody Mon Feb 9 19:39:37 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail header.i=@wdc.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=wdc.com ARC-Seal: i=1; a=rsa-sha256; t=1592335811; cv=none; d=zohomail.com; s=zohoarc; b=IewY/yLk1BpI1AwXYxd6lLQoX4TFUD1x9oMara5nPY54MO2hWMbWtTEMGbfU4hpDzWhsOdHZTYRIAo+naF54FkkFY0apxznCsOE0s4+chzFEkEYZWKspspSrvoAHNgQHooeO2IW8L2NkQb2H+//SGrxVpK4Rkv5Ybkak8f1MVX4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592335811; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=F3EaHX1Z2iwTf1UFAFN1b9CMDg1q9WJQuhqT0moeOlM=; b=aKCJb2p2hUEC9pT9x1zHED3anCXMxyR1yQat+RkXKBIBm3KHHMvi3HJwyPqBURmWDO87DkQcGxsJyoa+DUeUcIfu9rTj6rCoXZzEHlj+9xDf4XbOmaruHa+dNNyBttLkMBYZZHvcDr4sClvOLjyq2i/R+heiS0euCDamd3sRdeo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail header.i=@wdc.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1592335811937281.7392543999134; Tue, 16 Jun 2020 12:30:11 -0700 (PDT) Received: from localhost ([::1]:60224 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jlHHd-0001Fn-GD for importer@patchew.org; Tue, 16 Jun 2020 15:30:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:47274) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jlHF7-0005nk-6w; Tue, 16 Jun 2020 15:27:33 -0400 Received: from esa4.hgst.iphmx.com ([216.71.154.42]:63296) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jlHF5-000622-3V; Tue, 16 Jun 2020 15:27:32 -0400 Received: from h199-255-45-14.hgst.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 17 Jun 2020 03:27:22 +0800 Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jun 2020 12:16:38 -0700 Received: from usa001615.ad.shared (HELO yoda.hgst.com) ([10.86.58.120]) by uls-op-cesaip02.wdc.com with ESMTP; 16 Jun 2020 12:27:22 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1592335651; x=1623871651; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=acVEzmGxMq5i2mw+86R6C3MzLML3ZaDYcYbc+1akf5o=; b=jmfqz4hyDRiXFKa9xOel8peqRfsQjDQOOPVR5x5T8J6Aar6tT/3XFRm9 FT2mXZXLTg78+jHUv5W9c+3XlHQrYaXiiZNZ6W1a8TYCGN0YsdfmXsEtM AiampMjnJH3Sk0WfKis7xx1UkP307f0IyIFgyfLnhAwi7RNB1oZp1bcX2 vIeC9oPNlmYPuCriVPPhmjyAPs+ByNMeL8FZp4VuRvWTZAJfol2vyl7Te M5bUwk7Tn+zyoyU5cz/jxROvlDTuOLweCbBas0BHFlZZV7+NHFd6bHk6G imlp+E7P2vL2OBpzKRooNRZLVk3OCAtKCEM/ouf9t14AQD+b4Va760+jf Q==; IronPort-SDR: gO1Wm8p85DoLhbnr33bFPdDYP42y4KfW1c43zE3FzNf3qIU2CG3rwLuGVZR78lq8ugEJfR4wjM KirRthL2FKcqNZ2I3yt53eQ9yGmiTTof0WRrPpth5z1biGz+dzJqsGAYkFNkLUeHWwQzOqCV2a d1g13rgaxiy07b5IVZCEKxNeQC5y9L2liwcIyl51AE45/Emof9KHOg+0+954g878eqPjSa+fMg BVhE+OQxpSSklUg0NYsk29l8rM+ShWTMt3EAWClSIbA+JwqjEcacrMthnBDuIHqyJetoruNXmd 33E= X-IronPort-AV: E=Sophos;i="5.73,519,1583164800"; d="scan'208";a="140158602" IronPort-SDR: 7b2r1hhEMp2mIy/m15ByOCTts/KNUfhze7rkvoHUvf7iKNJ8Sq3cn+SO9B5Cfew49uy0MNMErR ygM+5oRzLJg5vps4T7JQDlUrDj8Ihp2jg= IronPort-SDR: hxs08aX/4CHFGeO0iW2+33M5o+yPbdXs5Wk3jxXj+8GXL0MKtvVj7z0NgTVQhEXBx5e7CiVxom tU4mvxIS8nfA== WDCIronportException: Internal From: Atish Patra To: qemu-devel@nongnu.org Subject: [PATCH 1/3] riscv: Unify Qemu's reset vector code path Date: Tue, 16 Jun 2020 12:26:58 -0700 Message-Id: <20200616192700.1900260-2-atish.patra@wdc.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200616192700.1900260-1-atish.patra@wdc.com> References: <20200616192700.1900260-1-atish.patra@wdc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.71.154.42; envelope-from=prvs=4293a8cce=atish.patra@wdc.com; helo=esa4.hgst.iphmx.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/16 15:27:22 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 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_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Sagar Karandikar , Bastian Koppelmann , Atish Patra , Alistair Francis , Palmer Dabbelt Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Currently, all riscv machines have identical reset vector code implementations with memory addresses being different for all machines. They can be easily combined into a single function in common code. Move it to common function and let all the machines use the common function. Signed-off-by: Atish Patra --- hw/riscv/boot.c | 46 +++++++++++++++++++++++++++++++++++++++++ hw/riscv/sifive_u.c | 38 +++------------------------------- hw/riscv/spike.c | 38 +++------------------------------- hw/riscv/virt.c | 37 +++------------------------------ include/hw/riscv/boot.h | 2 ++ 5 files changed, 57 insertions(+), 104 deletions(-) diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index adb421b91b68..8ed96da600c9 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -22,12 +22,16 @@ #include "qemu/units.h" #include "qemu/error-report.h" #include "exec/cpu-defs.h" +#include "exec/address-spaces.h" #include "hw/boards.h" #include "hw/loader.h" #include "hw/riscv/boot.h" #include "elf.h" +#include "sysemu/device_tree.h" #include "sysemu/qtest.h" =20 +#include + #if defined(TARGET_RISCV32) # define KERNEL_BOOT_ADDRESS 0x80400000 #else @@ -155,3 +159,45 @@ hwaddr riscv_load_initrd(const char *filename, uint64_= t mem_size, =20 return *start + size; } + +void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base, + hwaddr rom_size, void *fdt) +{ + int i; + /* reset vector */ + uint32_t reset_vec[8] =3D { + 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */ + 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */ + 0xf1402573, /* csrr a0, mhartid */ +#if defined(TARGET_RISCV32) + 0x0182a283, /* lw t0, 24(t0) */ +#elif defined(TARGET_RISCV64) + 0x0182b283, /* ld t0, 24(t0) */ +#endif + 0x00028067, /* jr t0 */ + 0x00000000, + start_addr, /* start: .dword */ + 0x00000000, + /* dtb: */ + }; + + /* copy in the reset vector in little_endian byte order */ + for (i =3D 0; i < sizeof(reset_vec) >> 2; i++) { + reset_vec[i] =3D cpu_to_le32(reset_vec[i]); + } + rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), + rom_base, &address_space_memory); + + /* copy in the device tree */ + if (fdt_pack(fdt) || fdt_totalsize(fdt) > + rom_size - sizeof(reset_vec)) { + error_report("not enough space to store device-tree"); + exit(1); + } + qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt)); + rom_add_blob_fixed_as("mrom.fdt", fdt, fdt_totalsize(fdt), + rom_base + sizeof(reset_vec), + &address_space_memory); + + return; +} diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index f9fef2be9170..c2712570e0d9 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -325,7 +325,6 @@ static void sifive_u_machine_init(MachineState *machine) MemoryRegion *main_mem =3D g_new(MemoryRegion, 1); MemoryRegion *flash0 =3D g_new(MemoryRegion, 1); target_ulong start_addr =3D memmap[SIFIVE_U_DRAM].base; - int i; =20 /* Initialize SoC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, @@ -374,40 +373,9 @@ static void sifive_u_machine_init(MachineState *machin= e) start_addr =3D memmap[SIFIVE_U_FLASH0].base; } =20 - /* reset vector */ - uint32_t reset_vec[8] =3D { - 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */ - 0x02028593, /* addi a1, t0, %pcrel_lo(1b)= */ - 0xf1402573, /* csrr a0, mhartid */ -#if defined(TARGET_RISCV32) - 0x0182a283, /* lw t0, 24(t0) */ -#elif defined(TARGET_RISCV64) - 0x0182b283, /* ld t0, 24(t0) */ -#endif - 0x00028067, /* jr t0 */ - 0x00000000, - start_addr, /* start: .dword */ - 0x00000000, - /* dtb: */ - }; - - /* copy in the reset vector in little_endian byte order */ - for (i =3D 0; i < sizeof(reset_vec) >> 2; i++) { - reset_vec[i] =3D cpu_to_le32(reset_vec[i]); - } - rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), - memmap[SIFIVE_U_MROM].base, &address_space_memor= y); - - /* copy in the device tree */ - if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) > - memmap[SIFIVE_U_MROM].size - sizeof(reset_vec)) { - error_report("not enough space to store device-tree"); - exit(1); - } - qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt)); - rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt), - memmap[SIFIVE_U_MROM].base + sizeof(reset_vec), - &address_space_memory); + /* load the reset vector */ + riscv_setup_rom_reset_vec(start_addr, memmap[SIFIVE_U_MROM].base, + memmap[SIFIVE_U_MROM].size, s->fdt); } =20 static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp) diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 7bbbdb50363d..238eae48716a 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -165,7 +165,6 @@ static void spike_board_init(MachineState *machine) MemoryRegion *system_memory =3D get_system_memory(); MemoryRegion *main_mem =3D g_new(MemoryRegion, 1); MemoryRegion *mask_rom =3D g_new(MemoryRegion, 1); - int i; unsigned int smp_cpus =3D machine->smp.cpus; =20 /* Initialize SOC */ @@ -213,40 +212,9 @@ static void spike_board_init(MachineState *machine) } } =20 - /* reset vector */ - uint32_t reset_vec[8] =3D { - 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */ - 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */ - 0xf1402573, /* csrr a0, mhartid */ -#if defined(TARGET_RISCV32) - 0x0182a283, /* lw t0, 24(t0) */ -#elif defined(TARGET_RISCV64) - 0x0182b283, /* ld t0, 24(t0) */ -#endif - 0x00028067, /* jr t0 */ - 0x00000000, - memmap[SPIKE_DRAM].base, /* start: .dword DRAM_BASE */ - 0x00000000, - /* dtb: */ - }; - - /* copy in the reset vector in little_endian byte order */ - for (i =3D 0; i < sizeof(reset_vec) >> 2; i++) { - reset_vec[i] =3D cpu_to_le32(reset_vec[i]); - } - rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), - memmap[SPIKE_MROM].base, &address_space_memory); - - /* copy in the device tree */ - if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) > - memmap[SPIKE_MROM].size - sizeof(reset_vec)) { - error_report("not enough space to store device-tree"); - exit(1); - } - qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt)); - rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt), - memmap[SPIKE_MROM].base + sizeof(reset_vec), - &address_space_memory); + /* load the reset vector */ + riscv_setup_rom_reset_vec(memmap[SPIKE_DRAM].base, memmap[SPIKE_MROM].= base, + memmap[SPIKE_MROM].size, s->fdt); =20 /* initialize HTIF using symbols found in load_kernel */ htif_mm_init(system_memory, mask_rom, &s->soc.harts[0].env, serial_hd(= 0)); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 4e4c494a7050..a8e2d58cc067 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -536,40 +536,9 @@ static void virt_machine_init(MachineState *machine) start_addr =3D virt_memmap[VIRT_FLASH].base; } =20 - /* reset vector */ - uint32_t reset_vec[8] =3D { - 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */ - 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */ - 0xf1402573, /* csrr a0, mhartid */ -#if defined(TARGET_RISCV32) - 0x0182a283, /* lw t0, 24(t0) */ -#elif defined(TARGET_RISCV64) - 0x0182b283, /* ld t0, 24(t0) */ -#endif - 0x00028067, /* jr t0 */ - 0x00000000, - start_addr, /* start: .dword */ - 0x00000000, - /* dtb: */ - }; - - /* copy in the reset vector in little_endian byte order */ - for (i =3D 0; i < sizeof(reset_vec) >> 2; i++) { - reset_vec[i] =3D cpu_to_le32(reset_vec[i]); - } - rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), - memmap[VIRT_MROM].base, &address_space_memory); - - /* copy in the device tree */ - if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) > - memmap[VIRT_MROM].size - sizeof(reset_vec)) { - error_report("not enough space to store device-tree"); - exit(1); - } - qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt)); - rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt), - memmap[VIRT_MROM].base + sizeof(reset_vec), - &address_space_memory); + /* load the reset vector */ + riscv_setup_rom_reset_vec(start_addr, virt_memmap[VIRT_MROM].base, + virt_memmap[VIRT_MROM].size, s->fdt); =20 /* create PLIC hart topology configuration string */ plic_hart_config_len =3D (strlen(VIRT_PLIC_HART_CONFIG) + 1) * smp_cpu= s; diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index 9daa98da08d7..3e9759c89aa2 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -35,5 +35,7 @@ target_ulong riscv_load_kernel(const char *kernel_filenam= e, symbol_fn_t sym_cb); hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, uint64_t kernel_entry, hwaddr *start); +void riscv_setup_rom_reset_vec(hwaddr saddr, hwaddr rom_base, + hwaddr rom_size, void *fdt); =20 #endif /* RISCV_BOOT_H */ --=20 2.26.2 From nobody Mon Feb 9 19:39:37 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail header.i=@wdc.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=wdc.com ARC-Seal: i=1; a=rsa-sha256; t=1592335740; cv=none; d=zohomail.com; s=zohoarc; b=f6XLmZFVzZXELdSID+NYb+qCwph4LQGNPmT9udxwKD0xshsuteLd5SXdEGbCwGZSqQ//qoDJ18Mw3Gy02ObcBGWs7kBZIHOapdppL23gBxWY5rF4rY//13Z7vqqFVSk77lH73yN/0k3KwXFC2qLIDvKcKuwnG/FImhWXEPMT1sY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592335740; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Iftv7EmbcVgl3tWdrTVs+PVNwsgrMumNc/udDmyyoGg=; b=LqdrxS6O+gr9u+Z0GH0AiHrNRhn2rPW52Ctc4rHyt/iavi1ESXD8sqAQ0cOT/C55DPGiWq3NzfRa02DdPoWhRy0SqX2pHtmQzKwyRKvJUeoGJvXi5Lk5h4O1/4h/qIyM2u3YUmaNexbd+1+q1Ax/vl+VQZYtBZYewvbV+yzNri4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail header.i=@wdc.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 159233574088497.25503600807201; Tue, 16 Jun 2020 12:29:00 -0700 (PDT) Received: from localhost ([::1]:55826 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jlHGV-0007PW-Ci for importer@patchew.org; Tue, 16 Jun 2020 15:28:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:47280) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jlHF7-0005p3-SX; Tue, 16 Jun 2020 15:27:33 -0400 Received: from esa4.hgst.iphmx.com ([216.71.154.42]:63303) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jlHF5-00062x-QV; Tue, 16 Jun 2020 15:27:33 -0400 Received: from h199-255-45-14.hgst.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 17 Jun 2020 03:27:23 +0800 Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jun 2020 12:16:38 -0700 Received: from usa001615.ad.shared (HELO yoda.hgst.com) ([10.86.58.120]) by uls-op-cesaip02.wdc.com with ESMTP; 16 Jun 2020 12:27:22 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1592335651; x=1623871651; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=MfMl52DRfCHWAnQTjNSFH+/lMGzyCvh5/WsZo+lgLb8=; b=UyBD0+QOVpwoXBQ3Kd0WTuyvdi+ybzJkfPzm2GGfMwuInj3fSouBCnn6 ipYIiC8vd/TUi7XJ4iaiRCJt2DiLf4TJ2B+7DsFB6vRnAQCtzGvH+1cT3 NJRzvuwjxrOFN47HqL3kHNR5dL9Uh+BEj4jRjFFTsW7UKis3KI+4/nQzP ItR2pWbQl8SMjT9ejrSvb4KM5mU53nQjHDMYQsNUp+VGCM2Jum3QXL66f TmtNHflqJY5Md1mYndLuYPyj2BSA01QsAQkSsgN50FhTRy2kvaqD2laQx y3nuzNooJPadkqmtxz6kn0bUVtwZvvSbMiBPNCwe3R6Yu9gVoGrVC72LR w==; IronPort-SDR: cO+Bt9mR68FUk1RtYF75tLqrgIEdtUZ9TC01lY5N7AugK3x+9I4zKiPV8wQ6ECvyJv3Vq3pbhh D/uqae5vkqtvV/qHyxTOPoT02ftJ6g4er96E8drHf98ig3ZllAHHPC84rchd5HVuQ7uqG5C0wv A3WTmtjpC/x3PIqVw+vTKUVO0J5d+7iKLFVq+KkWEeEb/WnhgQFzfWmDgmMeon4J7g/wFlq4Z2 sBkvQzXWWvBbSivuyalOlqQoX2SbWvvJ/7h5h22Gex4QZTneDermh8+hTqxldDpA+YW7iS1ZaY vXA= X-IronPort-AV: E=Sophos;i="5.73,519,1583164800"; d="scan'208";a="140158604" IronPort-SDR: wKsLRJhA2O9PhlS3dGUzZgQTB6Gg030yAcuPcv+SNhkTHQjMdXA3q9mZl77Xgcxd1LAXTrrQlL zh9qpB3/nrRVZic188URqTsoq2J+ph1aw= IronPort-SDR: J+EEmO4PYHdNSPvT3ZLzbOQfXXv9hs1MRJCGIFVP7Yp4v1GeCseTO3dHw27RKr9rbj3WpilVzh 3/FiZ17SLDCw== WDCIronportException: Internal From: Atish Patra To: qemu-devel@nongnu.org Subject: [PATCH 2/3] RISC-V: Copy the fdt in dram instead of ROM Date: Tue, 16 Jun 2020 12:26:59 -0700 Message-Id: <20200616192700.1900260-3-atish.patra@wdc.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200616192700.1900260-1-atish.patra@wdc.com> References: <20200616192700.1900260-1-atish.patra@wdc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.71.154.42; envelope-from=prvs=4293a8cce=atish.patra@wdc.com; helo=esa4.hgst.iphmx.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/16 15:27:22 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 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_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Sagar Karandikar , Bastian Koppelmann , Atish Patra , Alistair Francis , Palmer Dabbelt Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Currently, the fdt is copied to the ROM after the reset vector. The firmware has to copy it to DRAM. Instead of this, directly copy the device tree to a pre-computed dram address. The device tree load address should be as far as possible from kernel and initrd images. That's why it is kept at the end of the DRAM or 4GB whichever is lesser. Signed-off-by: Atish Patra --- hw/riscv/boot.c | 45 ++++++++++++++++++++++++++++++----------- hw/riscv/sifive_u.c | 14 ++++++++++++- hw/riscv/spike.c | 14 ++++++++++++- hw/riscv/virt.c | 13 +++++++++++- include/hw/riscv/boot.h | 5 ++++- 5 files changed, 75 insertions(+), 16 deletions(-) diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index 8ed96da600c9..0378b7f1bd58 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -160,25 +160,51 @@ hwaddr riscv_load_initrd(const char *filename, uint64= _t mem_size, return *start + size; } =20 +hwaddr riscv_calc_fdt_load_addr(hwaddr dram_base, uint64_t mem_size, void = *fdt) +{ + hwaddr temp, fdt_addr; + hwaddr dram_end =3D dram_base + mem_size; + int fdtsize =3D fdt_totalsize(fdt); + + if (fdtsize <=3D 0) { + error_report("invalid device-tree"); + exit(1); + } + /* + * We should put fdt as far as possible to avoid kernel/initrd overwri= ting + * its content. But it should be addressable by 32 bit system as well. + * Thus, put it at an aligned address that less than fdt size from end= of + * dram or 4GB whichever is lesser. + */ + temp =3D MIN(dram_end, 4096 * MiB); + fdt_addr =3D QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB); + + return fdt_addr; +} + void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base, - hwaddr rom_size, void *fdt) + hwaddr rom_size, + hwaddr fdt_load_addr, void *fdt) { int i; /* reset vector */ - uint32_t reset_vec[8] =3D { - 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */ - 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */ + uint32_t reset_vec[10] =3D { + 0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */ 0xf1402573, /* csrr a0, mhartid */ #if defined(TARGET_RISCV32) + 0x0202a583, /* lw a1, 32(t0) */ 0x0182a283, /* lw t0, 24(t0) */ #elif defined(TARGET_RISCV64) + 0x0202b583, /* ld a1, 32(t0) */ 0x0182b283, /* ld t0, 24(t0) */ #endif 0x00028067, /* jr t0 */ 0x00000000, start_addr, /* start: .dword */ 0x00000000, - /* dtb: */ + fdt_load_addr, /* fdt_laddr: .dword */ + 0x00000000, + /* fw_dyn: */ }; =20 /* copy in the reset vector in little_endian byte order */ @@ -189,14 +215,9 @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwad= dr rom_base, rom_base, &address_space_memory); =20 /* copy in the device tree */ - if (fdt_pack(fdt) || fdt_totalsize(fdt) > - rom_size - sizeof(reset_vec)) { - error_report("not enough space to store device-tree"); - exit(1); - } qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt)); - rom_add_blob_fixed_as("mrom.fdt", fdt, fdt_totalsize(fdt), - rom_base + sizeof(reset_vec), + + rom_add_blob_fixed_as("fdt", fdt, fdt_totalsize(fdt), fdt_load_addr, &address_space_memory); =20 return; diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index c2712570e0d9..1a1540c7f98d 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -31,6 +31,7 @@ */ =20 #include "qemu/osdep.h" +#include "qemu/units.h" #include "qemu/log.h" #include "qemu/error-report.h" #include "qapi/error.h" @@ -325,6 +326,7 @@ static void sifive_u_machine_init(MachineState *machine) MemoryRegion *main_mem =3D g_new(MemoryRegion, 1); MemoryRegion *flash0 =3D g_new(MemoryRegion, 1); target_ulong start_addr =3D memmap[SIFIVE_U_DRAM].base; + hwaddr fdt_load_addr; =20 /* Initialize SoC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, @@ -369,13 +371,23 @@ static void sifive_u_machine_init(MachineState *machi= ne) } } =20 + /* Compute the fdt load address in dram */ + fdt_load_addr =3D riscv_calc_fdt_load_addr(memmap[SIFIVE_U_DRAM].base, + machine->ram_size, s->fdt); + + if (fdt_load_addr >=3D (memmap[SIFIVE_U_DRAM].base + machine->ram_size= )) { + error_report("Not enough space for FDT after kernel + initrd"); + exit(1); + } + if (s->start_in_flash) { start_addr =3D memmap[SIFIVE_U_FLASH0].base; } =20 /* load the reset vector */ riscv_setup_rom_reset_vec(start_addr, memmap[SIFIVE_U_MROM].base, - memmap[SIFIVE_U_MROM].size, s->fdt); + memmap[SIFIVE_U_MROM].size, + fdt_load_addr, s->fdt); } =20 static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp) diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 238eae48716a..2a34a1382487 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -24,6 +24,7 @@ */ =20 #include "qemu/osdep.h" +#include "qemu/units.h" #include "qemu/log.h" #include "qemu/error-report.h" #include "qapi/error.h" @@ -166,6 +167,7 @@ static void spike_board_init(MachineState *machine) MemoryRegion *main_mem =3D g_new(MemoryRegion, 1); MemoryRegion *mask_rom =3D g_new(MemoryRegion, 1); unsigned int smp_cpus =3D machine->smp.cpus; + hwaddr fdt_load_addr; =20 /* Initialize SOC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc= ), @@ -212,9 +214,19 @@ static void spike_board_init(MachineState *machine) } } =20 + /* Compute the fdt load address in dram */ + fdt_load_addr =3D riscv_calc_fdt_load_addr(memmap[SPIKE_DRAM].base, + machine->ram_size, s->fdt); + + if (fdt_load_addr >=3D (memmap[SPIKE_DRAM].base + machine->ram_size)) { + error_report("Not enough space for FDT after kernel + initrd"); + exit(1); + } + /* load the reset vector */ riscv_setup_rom_reset_vec(memmap[SPIKE_DRAM].base, memmap[SPIKE_MROM].= base, - memmap[SPIKE_MROM].size, s->fdt); + memmap[SPIKE_MROM].size, + fdt_load_addr, s->fdt); =20 /* initialize HTIF using symbols found in load_kernel */ htif_mm_init(system_memory, mask_rom, &s->soc.harts[0].env, serial_hd(= 0)); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index a8e2d58cc067..ebb5dd5c8c1c 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -481,6 +481,7 @@ static void virt_machine_init(MachineState *machine) char *plic_hart_config; size_t plic_hart_config_len; target_ulong start_addr =3D memmap[VIRT_DRAM].base; + hwaddr fdt_load_addr; int i; unsigned int smp_cpus =3D machine->smp.cpus; =20 @@ -536,9 +537,19 @@ static void virt_machine_init(MachineState *machine) start_addr =3D virt_memmap[VIRT_FLASH].base; } =20 + /* Compute the fdt load address in dram */ + fdt_load_addr =3D riscv_calc_fdt_load_addr(memmap[VIRT_DRAM].base, + machine->ram_size, s->fdt); + if (fdt_load_addr >=3D (memmap[VIRT_DRAM].base + machine->ram_size)) { + error_report("Not enough space for FDT after kernel + initrd"); + exit(1); + } + + /* load the reset vector */ riscv_setup_rom_reset_vec(start_addr, virt_memmap[VIRT_MROM].base, - virt_memmap[VIRT_MROM].size, s->fdt); + virt_memmap[VIRT_MROM].size, + fdt_load_addr, s->fdt); =20 /* create PLIC hart topology configuration string */ plic_hart_config_len =3D (strlen(VIRT_PLIC_HART_CONFIG) + 1) * smp_cpu= s; diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index 3e9759c89aa2..b6289a05d952 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -35,7 +35,10 @@ target_ulong riscv_load_kernel(const char *kernel_filena= me, symbol_fn_t sym_cb); hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, uint64_t kernel_entry, hwaddr *start); +hwaddr riscv_calc_fdt_load_addr(hwaddr dram_start, uint64_t dram_size, + void *fdt); void riscv_setup_rom_reset_vec(hwaddr saddr, hwaddr rom_base, - hwaddr rom_size, void *fdt); + hwaddr rom_size, + hwaddr fdt_load_addr, void *fdt); =20 #endif /* RISCV_BOOT_H */ --=20 2.26.2 From nobody Mon Feb 9 19:39:37 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail header.i=@wdc.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=wdc.com ARC-Seal: i=1; a=rsa-sha256; t=1592335741; cv=none; d=zohomail.com; s=zohoarc; b=XcNGkE1Ae4p02LXUM5AAkAwbILujfaI+vn820utwOax8CHGJDBeUd3Mlzc8jbjgnL8LOrhsqaFW6DCEjhAXRSDIggvYf0ptppCVEZV++H2aI4m2d4dAiWw0rA2LAiIKn4Pz6sVm+QigAICt7fA5yb/r5/IipNd1Nn9lgJ0RJ1zU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592335741; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=el2/KDDmU0hGEkIlQkuRc/W7WqkeLZxdjE4vE7wuwq8=; b=I+dl/sA8mrYlXR9xMJWKJzS6ZLYMNpxbW3MkDec6o2MOT0y7ip+RZomJuPiOKLKAfI+5KzyYN7edcYLlUnGOBVR1+qfr2ZGc0Yr+Ennnq7H1/JNdAon/HB4UyoE4fRQ3v2Ce8/FqZ2Xo4Ccdlufa17b9o3KGnWt7tWm2g5zH6jE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail header.i=@wdc.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 159233574156946.80894958760916; Tue, 16 Jun 2020 12:29:01 -0700 (PDT) Received: from localhost ([::1]:55874 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jlHGW-0007Qi-5K for importer@patchew.org; Tue, 16 Jun 2020 15:29:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:47296) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jlHFA-0005tE-8f; Tue, 16 Jun 2020 15:27:36 -0400 Received: from esa4.hgst.iphmx.com ([216.71.154.42]:63296) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jlHF7-000622-S2; Tue, 16 Jun 2020 15:27:35 -0400 Received: from h199-255-45-14.hgst.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 17 Jun 2020 03:27:23 +0800 Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jun 2020 12:16:39 -0700 Received: from usa001615.ad.shared (HELO yoda.hgst.com) ([10.86.58.120]) by uls-op-cesaip02.wdc.com with ESMTP; 16 Jun 2020 12:27:23 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1592335653; x=1623871653; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qeB4ucQioXwAaSmCPZoRfbYELChjOVzX11pPJN936bc=; b=PeeDg72yTUHykr14YaLNM2sBMDiweaBcFuxNeEkPyzq27VN16bydi9X5 nYuYWabI05zf9O5Z3KC2w0cfcyOXMfOjKzhAM/uTlnop+y6/r7AxzZWwr aRp/49KfsDYv8lo2TzVqTK+MeM24uscjClI7bOs/gDqKkjAmuQ+Gjfyt9 RL2VH7J95eKpxFB8AtOLaa0dsdnvuOlDX8sB0v5gbBctf6iYd6mAN7YUy /RwWBCBBPr2EnGGA3Zg+8S6N4yK69e/No7djTUMh7+f9VU1ymVlcf5TjM g4aK17Cc7pnRrFx/37qTCDOH3SPFWFLbKzv/nHBzR7L6CQYWYIttKSb5W Q==; IronPort-SDR: xImD84NK6eISKrqPrsruicUy8Qlb2+XAN18iAg+FEV004sEcRscUfBQjPGVPaFkXq86CRkRLVx D3AYkQs7t3Lo7dCnRe1bixXcDPQB7oio4i3LbfHl8Q183f3qfn5B8QgJ+V69EUCt+apSs7DE1c RDqhckXcoluXEXsEr8I+PJS5/2v+ZtqLn1ktoDEQSOYUjttcckQi+YQxKTGXHE0keVk4hwQYkf Ikj8ITyVYpfGB8BCXA6HDpJ9snaxtd2iZoD55xjyBkc0FQejTM+IhPRSvgm1lfNLp5wNr5/Am+ Ab8= X-IronPort-AV: E=Sophos;i="5.73,519,1583164800"; d="scan'208";a="140158606" IronPort-SDR: 2mh2Fj1EtB+qLpKWTzo2ArUtQxE6Lska3mNe3zq9WIKvWDoz6VCxK7W/Y25AXDishwg8GCJQHk YJ7H7J50G1oD3LYHAetAyK33QIa/7UaaQ= IronPort-SDR: frjhNr+NktBL/ndrYftbjvYzgDrfEp/TAzGkbTTpfHgcn4k/rpE+8Q9J661hUI8lLWWgT04tmZ VTSotJMn3qIA== WDCIronportException: Internal From: Atish Patra To: qemu-devel@nongnu.org Subject: [PATCH 3/3] riscv: Add opensbi firmware dynamic support Date: Tue, 16 Jun 2020 12:27:00 -0700 Message-Id: <20200616192700.1900260-4-atish.patra@wdc.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200616192700.1900260-1-atish.patra@wdc.com> References: <20200616192700.1900260-1-atish.patra@wdc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.71.154.42; envelope-from=prvs=4293a8cce=atish.patra@wdc.com; helo=esa4.hgst.iphmx.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/16 15:27:22 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 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_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Sagar Karandikar , Bastian Koppelmann , Atish Patra , Alistair Francis , Palmer Dabbelt Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" OpenSBI is the default firmware in Qemu and has various firmware loading options. Currently, qemu loader uses fw_jump which has a compile time pre-defined address where fdt & kernel image must reside. This puts a constraint on image size of the Linux kernel depending on the fdt location and available memory. However, fw_dynamic allows the loader to specify the next stage location (i.e. Linux kernel/U-boot) in memory and other configurable boot options available in OpenSBI. Add support for OpenSBI dynamic firmware loading support. This doesn't break existing setup and fw_jump will continue to work as it is. Any other firmware will continue to work without any issues as long as it doesn't expect anything specific from loader in "a2" register. Signed-off-by: Atish Patra --- hw/riscv/boot.c | 32 ++++++++++++++++-- hw/riscv/sifive_u.c | 11 +++++-- hw/riscv/spike.c | 11 +++++-- hw/riscv/virt.c | 11 +++++-- include/hw/riscv/boot.h | 2 +- include/hw/riscv/boot_opensbi.h | 58 +++++++++++++++++++++++++++++++++ 6 files changed, 116 insertions(+), 9 deletions(-) create mode 100644 include/hw/riscv/boot_opensbi.h diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index 0378b7f1bd58..47530f2732cf 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -26,6 +26,7 @@ #include "hw/boards.h" #include "hw/loader.h" #include "hw/riscv/boot.h" +#include "hw/riscv/boot_opensbi.h" #include "elf.h" #include "sysemu/device_tree.h" #include "sysemu/qtest.h" @@ -34,8 +35,10 @@ =20 #if defined(TARGET_RISCV32) # define KERNEL_BOOT_ADDRESS 0x80400000 +#define fw_dynamic_info_data(__val) cpu_to_le32(__val) #else # define KERNEL_BOOT_ADDRESS 0x80200000 +#define fw_dynamic_info_data(__val) cpu_to_le64(__val) #endif =20 void riscv_find_and_load_firmware(MachineState *machine, @@ -183,13 +186,25 @@ hwaddr riscv_calc_fdt_load_addr(hwaddr dram_base, uin= t64_t mem_size, void *fdt) } =20 void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base, - hwaddr rom_size, + hwaddr rom_size, uint64_t kernel_entry, hwaddr fdt_load_addr, void *fdt) { int i; + struct fw_dynamic_info dinfo; + uint64_t dinfo_len; + + dinfo.magic =3D fw_dynamic_info_data(FW_DYNAMIC_INFO_MAGIC_VALUE); + dinfo.version =3D fw_dynamic_info_data(FW_DYNAMIC_INFO_VERSION); + dinfo.next_mode =3D fw_dynamic_info_data(FW_DYNAMIC_INFO_NEXT_MODE_S); + dinfo.next_addr =3D fw_dynamic_info_data(kernel_entry); + dinfo.options =3D 0; + dinfo.boot_hart =3D 0; + dinfo_len =3D sizeof(dinfo); + /* reset vector */ uint32_t reset_vec[10] =3D { 0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */ + 0x02828613, /* addi a2, t0, %pcrel_lo(1b) */ 0xf1402573, /* csrr a0, mhartid */ #if defined(TARGET_RISCV32) 0x0202a583, /* lw a1, 32(t0) */ @@ -199,7 +214,6 @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwadd= r rom_base, 0x0182b283, /* ld t0, 24(t0) */ #endif 0x00028067, /* jr t0 */ - 0x00000000, start_addr, /* start: .dword */ 0x00000000, fdt_load_addr, /* fdt_laddr: .dword */ @@ -214,6 +228,20 @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwad= dr rom_base, rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), rom_base, &address_space_memory); =20 + /** + * copy the dynamic firmware info. This information is specific to + * OpenSBI but doesn't break any other firmware as long as they don't + * expect any certain value in "a2" register. + */ + if (fdt_pack(fdt) || fdt_totalsize(fdt) > + rom_size - dinfo_len) { + error_report("not enough space to store device-tree"); + exit(1); + } + + rom_add_blob_fixed_as("mrom.finfo", &dinfo, dinfo_len, + rom_base + sizeof(reset_vec), + &address_space_memory); /* copy in the device tree */ qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt)); =20 diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 1a1540c7f98d..11b8814b9240 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -327,6 +327,7 @@ static void sifive_u_machine_init(MachineState *machine) MemoryRegion *flash0 =3D g_new(MemoryRegion, 1); target_ulong start_addr =3D memmap[SIFIVE_U_DRAM].base; hwaddr fdt_load_addr; + uint64_t kernel_entry; =20 /* Initialize SoC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, @@ -356,7 +357,7 @@ static void sifive_u_machine_init(MachineState *machine) memmap[SIFIVE_U_DRAM].base, NULL); =20 if (machine->kernel_filename) { - uint64_t kernel_entry =3D riscv_load_kernel(machine->kernel_filena= me, + kernel_entry =3D riscv_load_kernel(machine->kernel_filename, NULL); =20 if (machine->initrd_filename) { @@ -369,6 +370,12 @@ static void sifive_u_machine_init(MachineState *machin= e) qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end", end); } + } else { + /* + * If dynamic firmware is used, it doesn't know where is the next m= ode + * if kernel argument is not set. + */ + kernel_entry =3D 0; } =20 /* Compute the fdt load address in dram */ @@ -386,7 +393,7 @@ static void sifive_u_machine_init(MachineState *machine) =20 /* load the reset vector */ riscv_setup_rom_reset_vec(start_addr, memmap[SIFIVE_U_MROM].base, - memmap[SIFIVE_U_MROM].size, + memmap[SIFIVE_U_MROM].size, kernel_entry, fdt_load_addr, s->fdt); } =20 diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 2a34a1382487..bd29a2b38611 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -168,6 +168,7 @@ static void spike_board_init(MachineState *machine) MemoryRegion *mask_rom =3D g_new(MemoryRegion, 1); unsigned int smp_cpus =3D machine->smp.cpus; hwaddr fdt_load_addr; + uint64_t kernel_entry; =20 /* Initialize SOC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc= ), @@ -199,7 +200,7 @@ static void spike_board_init(MachineState *machine) htif_symbol_callback); =20 if (machine->kernel_filename) { - uint64_t kernel_entry =3D riscv_load_kernel(machine->kernel_filena= me, + kernel_entry =3D riscv_load_kernel(machine->kernel_filename, htif_symbol_callback); =20 if (machine->initrd_filename) { @@ -212,6 +213,12 @@ static void spike_board_init(MachineState *machine) qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end", end); } + } else { + /* + * If dynamic firmware is used, it doesn't know where is the next m= ode + * if kernel argument is not set. + */ + kernel_entry =3D 0; } =20 /* Compute the fdt load address in dram */ @@ -225,7 +232,7 @@ static void spike_board_init(MachineState *machine) =20 /* load the reset vector */ riscv_setup_rom_reset_vec(memmap[SPIKE_DRAM].base, memmap[SPIKE_MROM].= base, - memmap[SPIKE_MROM].size, + memmap[SPIKE_MROM].size, kernel_entry, fdt_load_addr, s->fdt); =20 /* initialize HTIF using symbols found in load_kernel */ diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index ebb5dd5c8c1c..7897eaa97301 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -482,6 +482,7 @@ static void virt_machine_init(MachineState *machine) size_t plic_hart_config_len; target_ulong start_addr =3D memmap[VIRT_DRAM].base; hwaddr fdt_load_addr; + uint64_t kernel_entry; int i; unsigned int smp_cpus =3D machine->smp.cpus; =20 @@ -514,7 +515,7 @@ static void virt_machine_init(MachineState *machine) memmap[VIRT_DRAM].base, NULL); =20 if (machine->kernel_filename) { - uint64_t kernel_entry =3D riscv_load_kernel(machine->kernel_filena= me, + kernel_entry =3D riscv_load_kernel(machine->kernel_filename, NULL); =20 if (machine->initrd_filename) { @@ -527,6 +528,12 @@ static void virt_machine_init(MachineState *machine) qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end", end); } + } else { + /* + * If dynamic firmware is used, it doesn't know where is the next m= ode + * if kernel argument is not set. + */ + kernel_entry =3D 0; } =20 if (drive_get(IF_PFLASH, 0, 0)) { @@ -548,7 +555,7 @@ static void virt_machine_init(MachineState *machine) =20 /* load the reset vector */ riscv_setup_rom_reset_vec(start_addr, virt_memmap[VIRT_MROM].base, - virt_memmap[VIRT_MROM].size, + virt_memmap[VIRT_MROM].size, kernel_entry, fdt_load_addr, s->fdt); =20 /* create PLIC hart topology configuration string */ diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index b6289a05d952..2e7163e3fef2 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -38,7 +38,7 @@ hwaddr riscv_load_initrd(const char *filename, uint64_t m= em_size, hwaddr riscv_calc_fdt_load_addr(hwaddr dram_start, uint64_t dram_size, void *fdt); void riscv_setup_rom_reset_vec(hwaddr saddr, hwaddr rom_base, - hwaddr rom_size, + hwaddr rom_size, hwaddr kernel_entry, hwaddr fdt_load_addr, void *fdt); =20 #endif /* RISCV_BOOT_H */ diff --git a/include/hw/riscv/boot_opensbi.h b/include/hw/riscv/boot_opensb= i.h new file mode 100644 index 000000000000..0d5ddd6c3daf --- /dev/null +++ b/include/hw/riscv/boot_opensbi.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2019 Western Digital Corporation or its affiliates. + * + * Based on include/sbi/{fw_dynamic.h,sbi_scratch.h} from the OpenSBI proj= ect. + */ +#ifndef OPENSBI_H +#define OPENSBI_H + +/** Expected value of info magic ('OSBI' ascii string in hex) */ +#define FW_DYNAMIC_INFO_MAGIC_VALUE 0x4942534f + +/** Maximum supported info version */ +#define FW_DYNAMIC_INFO_VERSION 0x2 + +/** Possible next mode values */ +#define FW_DYNAMIC_INFO_NEXT_MODE_U 0x0 +#define FW_DYNAMIC_INFO_NEXT_MODE_S 0x1 +#define FW_DYNAMIC_INFO_NEXT_MODE_M 0x3 + +enum sbi_scratch_options { + /** Disable prints during boot */ + SBI_SCRATCH_NO_BOOT_PRINTS =3D (1 << 0), + /** Enable runtime debug prints */ + SBI_SCRATCH_DEBUG_PRINTS =3D (1 << 1), +}; + +/** Representation dynamic info passed by previous booting stage */ +struct fw_dynamic_info { + /** Info magic */ + target_long magic; + /** Info version */ + target_long version; + /** Next booting stage address */ + target_long next_addr; + /** Next booting stage mode */ + target_long next_mode; + /** Options for OpenSBI library */ + target_long options; + /** + * Preferred boot HART id + * + * It is possible that the previous booting stage uses same link + * address as the FW_DYNAMIC firmware. In this case, the relocation + * lottery mechanism can potentially overwrite the previous booting + * stage while other HARTs are still running in the previous booting + * stage leading to boot-time crash. To avoid this boot-time crash, + * the previous booting stage can specify last HART that will jump + * to the FW_DYNAMIC firmware as the preferred boot HART. + * + * To avoid specifying a preferred boot HART, the previous booting + * stage can set it to -1UL which will force the FW_DYNAMIC firmware + * to use the relocation lottery mechanism. + */ + target_long boot_hart; +}; + +#endif --=20 2.26.2