From nobody Fri May 17 03:12:58 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 155411076507090.0441991736019; Mon, 1 Apr 2019 02:26:05 -0700 (PDT) Received: from localhost ([127.0.0.1]:37031 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hAtCe-0001R8-2j for importer@patchew.org; Mon, 01 Apr 2019 05:26:04 -0400 Received: from eggs.gnu.org ([209.51.188.92]:39788) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hAqYy-0002h6-JZ for qemu-devel@nongnu.org; Mon, 01 Apr 2019 02:36:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hAqYx-0003fk-0x for qemu-devel@nongnu.org; Mon, 01 Apr 2019 02:36:56 -0400 Received: from mail-cys01nam02on0709.outbound.protection.outlook.com ([2a01:111:f400:fe45::709]:39830 helo=NAM02-CY1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hAqYw-0003el-JQ for qemu-devel@nongnu.org; Mon, 01 Apr 2019 02:36:54 -0400 Received: from BN6PR2201MB1124.namprd22.prod.outlook.com (10.174.90.167) by BN6PR2201MB1010.namprd22.prod.outlook.com (10.174.90.39) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1750.17; Mon, 1 Apr 2019 06:36:52 +0000 Received: from BN6PR2201MB1124.namprd22.prod.outlook.com ([fe80::e8a8:347d:f4a5:ff10]) by BN6PR2201MB1124.namprd22.prod.outlook.com ([fe80::e8a8:347d:f4a5:ff10%2]) with mapi id 15.20.1750.017; Mon, 1 Apr 2019 06:36:52 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=wavesemi.onmicrosoft.com; s=selector1-wavecomp-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=cpAlvIUDHDu/2Ih83fxsNxGFM89/xSMOhPHzKDejshs=; b=d1LuDkTnfHWqxnsQAxZMa0vpQMigso5YGSucM63LZ4eEnmjPx90WhfllEvasQZmFiDWZVphQjToH7qWoWdOjCx0MdAHg7RmpPAGQrZfIbWc42w/on8sH4jTSdm2PSM0nQSl6GQCr4b4HnQ5JCJ6GVvOp5Kf73Oq6hZ3gcEs0VFc= From: Archer Yan To: "qemu-devel@nongnu.org" Thread-Topic: [PATCH] Support load kernel(vmlinux)/dtb/initrd separately for Boston in QEMU. Thread-Index: AQHU6FVKHfmon/uo+UuNkEs/DlrNkg== Date: Mon, 1 Apr 2019 06:36:51 +0000 Message-ID: <20190401063639.18341-1-ayan@wavecomp.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: HK2PR03CA0053.apcprd03.prod.outlook.com (2603:1096:202:17::23) To BN6PR2201MB1124.namprd22.prod.outlook.com (2603:10b6:405:35::39) authentication-results: spf=none (sender IP is ) smtp.mailfrom=ayan@wavecomp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-mailer: git-send-email 2.17.1 x-originating-ip: [218.108.86.174] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 8620fbc6-50bf-4894-0377-08d6b66c6caf x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(5600139)(711020)(4605104)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060)(7193020); SRVR:BN6PR2201MB1010; x-ms-traffictypediagnostic: BN6PR2201MB1010: x-microsoft-antispam-prvs: x-forefront-prvs: 0994F5E0C5 x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(396003)(366004)(376002)(346002)(136003)(39840400004)(199004)(189003)(6506007)(50226002)(86362001)(66066001)(105586002)(2351001)(486006)(106356001)(6436002)(71190400001)(71200400001)(36756003)(386003)(26005)(25786009)(186003)(102836004)(6916009)(52116002)(6486002)(2501003)(14454004)(305945005)(6512007)(8676002)(99286004)(53936002)(107886003)(7736002)(5660300002)(4326008)(478600001)(45080400002)(2616005)(476003)(6116002)(3846002)(316002)(1076003)(5640700003)(68736007)(81166006)(2906002)(97736004)(256004)(8936002)(81156014); DIR:OUT; SFP:1102; SCL:1; SRVR:BN6PR2201MB1010; H:BN6PR2201MB1124.namprd22.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; received-spf: None (protection.outlook.com: wavecomp.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: nD5bu8UuVrtamy2XH/J5cxH3IN5qOhvn9gm+ln2sOc5ol60VT/fwP//xl1+qFswgftqb6vslEZSlncGolUBTMPBPjppu57WQwwcPgum2a+8A/8TXrsRR0NZLKMfRbpCDdHAVbK/82nKg6LCdSqXbNl6qGyzvphjUHd/UrQOAyn0rDkkTMlw56AJbh86kvBrp0VCEhdEp3ooFbFhgRwPmfUSKsE5ZQxMqE4QrlB0ex5QuVXyUX7WUVfcrSFmauJK2E4G7bTGUtA615D128aXioO74giD3SQbduGpp6OU0fqMl/0o8zbPBwIgG48uXtikemZ0AtHuWx3tDlH6NwkBPch9lWXXesd1+s2Xx7/IUesPIVfb89MgkMJ7I2KY5Z2MzHIvJD/qruYttMP/ypj8HJglzCgtAYXUqEtMVdcat8kc= Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: wavecomp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8620fbc6-50bf-4894-0377-08d6b66c6caf X-MS-Exchange-CrossTenant-originalarrivaltime: 01 Apr 2019 06:36:51.8638 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 463607d3-1db3-40a0-8a29-970c56230104 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR2201MB1010 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 2a01:111:f400:fe45::709 X-Mailman-Approved-At: Mon, 01 Apr 2019 05:16:35 -0400 Subject: [Qemu-devel] [PATCH] Support load kernel(vmlinux)/dtb/initrd separately for Boston in QEMU. 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: Archer Yan 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 boston in QEMU only supports boot with FIT format. Since ELF file can provide symbol infomation in debug, this patch enables Boston boot from vmlinux&dtb. Signed-off-by: Archer Yan --- hw/mips/boston.c | 224 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 201 insertions(+), 23 deletions(-) diff --git a/hw/mips/boston.c b/hw/mips/boston.c index e5bab3cadc..5910ffdc8a 100644 --- a/hw/mips/boston.c +++ b/hw/mips/boston.c @@ -39,6 +39,10 @@ #include "sysemu/device_tree.h" #include "sysemu/sysemu.h" #include "sysemu/qtest.h" +#include "elf.h" +#include "sysemu/kvm.h" +#include "hw/mips/mips.h" +#include "qemu/option.h" =20 #include =20 @@ -58,6 +62,11 @@ typedef struct { =20 hwaddr kernel_entry; hwaddr fdt_base; + long kernel_size; + + uint64_t initrd_size; + uint64_t initrd_start; + uint64_t initrd_offset; } BostonState; =20 enum boston_plat_reg { @@ -328,31 +337,59 @@ static void gen_firmware(uint32_t *p, hwaddr kernel_e= ntry, hwaddr fdt_addr, stl_p(p++, 0x03200009); /* jr $25 */ } =20 -static const void *boston_fdt_filter(void *opaque, const void *fdt_orig, - const void *match_data, hwaddr *load_= addr) +typedef uint64_t (*xlate_to_kseg0)(void *, uint64_t); +static xlate_to_kseg0 get_xlate_to_kseg0_fn(BostonState *s) +{ + /* Check where the kernel has been linked */ + if (s->kernel_entry & 0x80000000ll) { + if (kvm_enabled()) { + error_report("KVM guest kernels must be linked in useg. " + "Did you forget to enable CONFIG_KVM_GUEST?"); + return NULL; + } + return cpu_mips_phys_to_kseg0; + } else { + /* if kernel entry is in useg it is probably a KVM T&E kernel */ + mips_um_ksegs_enable(); + return cpu_mips_kvm_um_phys_to_kseg0; + } +} + +/*Adapt fdt to insert initrd parameters*/ +static int boston_initrd_fdt(BostonState *s, void *fdt) { - BostonState *s =3D BOSTON(opaque); - MachineState *machine =3D s->mach; const char *cmdline; + char *args_str =3D NULL; + MachineState *machine =3D s->mach; + int initrd_args_len =3D 64; int err; - void *fdt; - size_t fdt_sz, ram_low_sz, ram_high_sz; + size_t ram_low_sz, ram_high_sz; + uint64_t (*xlate_to_kseg0_fn) (void *opaque, uint64_t addr); =20 - fdt_sz =3D fdt_totalsize(fdt_orig) * 2; - fdt =3D g_malloc0(fdt_sz); + cmdline =3D (machine->kernel_cmdline && machine->kernel_cmdline[0]) + ? machine->kernel_cmdline : " "; + xlate_to_kseg0_fn =3D get_xlate_to_kseg0_fn(s); + if (NULL =3D=3D xlate_to_kseg0_fn) { + fprintf(stderr, "couldn't get xlate_to_kseg0\n"); + return -1; + } =20 - err =3D fdt_open_into(fdt_orig, fdt, fdt_sz); - if (err) { - fprintf(stderr, "unable to open FDT\n"); - return NULL; + s->initrd_start =3D xlate_to_kseg0_fn(NULL, s->initrd_offset); + + if (s->initrd_size) { + args_str =3D g_malloc(strlen(cmdline) + initrd_args_len); + if (args_str !=3D NULL) { + sprintf((char *)args_str, "rd_start=3D0x%lx rd_size=3D0x%lx %s= ", + s->initrd_start, s->initrd_size, cmdline); + cmdline =3D args_str; + } } =20 - cmdline =3D (machine->kernel_cmdline && machine->kernel_cmdline[0]) - ? machine->kernel_cmdline : " "; err =3D qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline); if (err < 0) { fprintf(stderr, "couldn't set /chosen/bootargs\n"); - return NULL; + g_free(args_str); + return -1; } =20 ram_low_sz =3D MIN(256 * MiB, machine->ram_size); @@ -360,10 +397,41 @@ static const void *boston_fdt_filter(void *opaque, co= nst void *fdt_orig, qemu_fdt_setprop_sized_cells(fdt, "/memory@0", "reg", 1, 0x00000000, 1, ram_low_sz, 1, 0x90000000, 1, ram_high_sz); + g_free(args_str); + return 0; +} =20 - fdt =3D g_realloc(fdt, fdt_totalsize(fdt)); - qemu_fdt_dumpdtb(fdt, fdt_sz); +static const void *boston_fdt_filter(void *opaque, const void *fdt_orig, + const void *match_data, hwaddr *load_= addr) +{ + BostonState *s =3D BOSTON(opaque); + MachineState *machine =3D s->mach; + int err; + void *fdt; + int fdt_sz; + if (machine->dtb) { + /*Use QEMU cmd specified dtb*/ + fdt =3D load_device_tree(machine->dtb, &fdt_sz); + } else { + /*Use default dtb contained in FIT image*/ + fdt_sz =3D fdt_totalsize(fdt_orig) * 2; + fdt =3D g_malloc0(fdt_sz); + + err =3D fdt_open_into(fdt_orig, fdt, fdt_sz); + if (err) { + fprintf(stderr, "unable to open FDT\n"); + return NULL; + } + + fdt =3D g_realloc(fdt, fdt_totalsize(fdt)); + } =20 + err =3D boston_initrd_fdt(s, fdt); + if (err) { + return NULL; + } + + qemu_fdt_dumpdtb(fdt, fdt_sz); s->fdt_base =3D *load_addr; =20 return fdt; @@ -391,6 +459,99 @@ static const struct fit_loader boston_fit_loader =3D { .kernel_filter =3D boston_kernel_filter, }; =20 +static int boston_load_dtb(BostonState *s) +{ + void *fdt =3D NULL; + int size =3D 0; + int err; + MachineState *machine =3D s->mach; + hwaddr load_addr; + hwaddr kernel_end =3D 0xffffffff80100000 + s->kernel_size; + + fdt =3D load_device_tree(machine->dtb, &size); + if (!fdt) { + fprintf(stderr, "Couldn't open dtb file %s\n", machine->dtb); + return -1; + } + load_addr =3D ROUND_UP(kernel_end, 64 * KiB) + (10 * MiB); + err =3D boston_initrd_fdt(s, fdt); + if (err) { + return -1; + } + + qemu_fdt_dumpdtb(fdt, size); + + s->fdt_base =3D load_addr; + load_addr =3D cpu_mips_kseg0_to_phys(s, load_addr); + rom_add_blob_fixed("fdt@boston", fdt, size, load_addr); + + return 0; + +} + +static int boston_load_initrd(BostonState *s) +{ + int64_t initrd_size =3D 0; + ram_addr_t initrd_offset =3D 0; + int ram_low_size; + MachineState *machine =3D s->mach; + ram_low_size =3D MIN(machine->ram_size, 256 * MiB); + if (machine->initrd_filename) { + initrd_size =3D get_image_size(machine->initrd_filename); + if (initrd_size > 0) { + /* + * The kernel allocates the bootmap memory in the low memory a= fter + * the initrd. It takes at most 128kiB for 2GB RAM and 4kiB + * pages. + */ + initrd_offset =3D (ram_low_size - initrd_size + - (128 * KiB) + - ~INITRD_PAGE_MASK) & INITRD_PAGE_MASK; + + initrd_size =3D load_image_targphys(machine->initrd_filename, + initrd_offset, + ram_size - initrd_offset); + } + if (initrd_size =3D=3D (target_ulong) -1) { + error_report("could not load initial ram disk '%s'", + machine->initrd_filename); + return -1; + } + } + s->initrd_offset =3D initrd_offset; + s->initrd_size =3D initrd_size; + return 0; +} + +static int boston_load_kernel(BostonState *s) +{ + int64_t kernel_entry, kernel_high; + long kernel_size; + int big_endian; + MachineState *machine =3D s->mach; + +#ifdef TARGET_WORDS_BIGENDIAN + big_endian =3D 1; +#else + big_endian =3D 0; +#endif + + kernel_size =3D load_elf(machine->kernel_filename, NULL, + cpu_mips_kseg0_to_phys, NULL, + (uint64_t *)&kernel_entry, NULL, + (uint64_t *)&kernel_high, big_endian, EM_MIPS, = 1, 0); + if (kernel_size < 0) { + error_report("could not load kernel '%s': %s", + machine->kernel_filename, + load_elf_strerror(kernel_size)); + return -1; + } + + s->kernel_entry =3D kernel_entry; + s->kernel_size =3D kernel_size; + return 0; +} + static inline XilinxPCIEHost * xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr, hwaddr cfg_base, uint64_t cfg_size, @@ -433,7 +594,7 @@ static void boston_mach_init(MachineState *machine) PCIDevice *ahci; DriveInfo *hd[6]; Chardev *chr; - int fw_size, fit_err; + int fw_size, load_err; bool is_64b; =20 if ((machine->ram_size % GiB) || @@ -533,12 +694,29 @@ static void boston_mach_init(MachineState *machine) exit(1); } } else if (machine->kernel_filename) { - fit_err =3D load_fit(&boston_fit_loader, machine->kernel_filename,= s); - if (fit_err) { - error_printf("unable to load FIT image\n"); - exit(1); + if (machine->initrd_filename) { + load_err =3D boston_load_initrd(s); + if (load_err) { + error_printf("unable to separately load initrd image\n"); + exit(1); + } + } + load_err =3D load_fit(&boston_fit_loader, machine->kernel_filename= , s); + if (load_err) { + error_printf("unable to load FIT image, try load as ELF\n"); + load_err =3D boston_load_kernel(s); + if (load_err) { + error_printf("unable to separately load kernel image\n"); + exit(1); + } + if (machine->dtb) { + load_err =3D boston_load_dtb(s); + if (load_err) { + error_printf("unable to separately load dtb image\n"); + exit(1); + } + } } - gen_firmware(memory_region_get_ram_ptr(flash) + 0x7c00000, s->kernel_entry, s->fdt_base, is_64b); } else if (!qtest_enabled()) { --=20 2.17.1