From nobody Sat Apr 27 21:17:40 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532509351402151.56727985422435; Wed, 25 Jul 2018 02:02:31 -0700 (PDT) Received: from localhost ([::1]:46583 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiFga-0001bN-3x for importer@patchew.org; Wed, 25 Jul 2018 05:02:20 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51132) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiFeJ-00087u-6Z for qemu-devel@nongnu.org; Wed, 25 Jul 2018 05:00:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fiFeG-00023I-9P for qemu-devel@nongnu.org; Wed, 25 Jul 2018 04:59:59 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:40790 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fiFe9-0001pV-SJ; Wed, 25 Jul 2018 04:59:49 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3414D407572B; Wed, 25 Jul 2018 08:59:49 +0000 (UTC) Received: from localhost (ovpn-117-157.ams2.redhat.com [10.36.117.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id B80D02156898; Wed, 25 Jul 2018 08:59:48 +0000 (UTC) From: Stefan Hajnoczi To: Date: Wed, 25 Jul 2018 09:59:38 +0100 Message-Id: <20180725085944.11856-2-stefanha@redhat.com> In-Reply-To: <20180725085944.11856-1-stefanha@redhat.com> References: <20180725085944.11856-1-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Wed, 25 Jul 2018 08:59:49 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Wed, 25 Jul 2018 08:59:49 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'stefanha@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v3 1/7] hw/arm: rename armv7m_load_kernel() 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: Peter Maydell , jim@groklearning.com, mail@steffen-goertz.de, Su Hang , ilg@livius.net, Alistair Francis , Subbaraya Sundeep , Steffen Gortz , qemu-arm@nongnu.org, Joel Stanley , Stefan Hajnoczi , Julia Suvorova 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" ARMv6-M and ARMv8-M need the same kernel loading functionality as ARMv7-M. Rename armv7m_load_kernel() to arm_m_profile_load_kernel() so it's clear that this function isn't specific to ARMv7-M. Signed-off-by: Stefan Hajnoczi Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/arm/Makefile.objs | 1 + include/hw/arm/arm.h | 11 +++-- hw/arm/arm-m-profile.c | 81 +++++++++++++++++++++++++++++++++ hw/arm/armv7m.c | 60 ------------------------ hw/arm/mps2-tz.c | 3 +- hw/arm/mps2.c | 4 +- hw/arm/msf2-som.c | 4 +- hw/arm/netduino2.c | 4 +- hw/arm/stellaris.c | 3 +- default-configs/arm-softmmu.mak | 1 + 10 files changed, 99 insertions(+), 73 deletions(-) create mode 100644 hw/arm/arm-m-profile.c diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index d51fcecaf2..2c43d34c64 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -16,6 +16,7 @@ obj-$(CONFIG_STRONGARM) +=3D collie.o obj-$(CONFIG_VERSATILE) +=3D vexpress.o versatilepb.o obj-$(CONFIG_ZYNQ) +=3D xilinx_zynq.o =20 +obj-$(CONFIG_ARM_M_PROFILE) +=3D arm-m-profile.o obj-$(CONFIG_ARM_V7M) +=3D armv7m.o obj-$(CONFIG_EXYNOS4) +=3D exynos4210.o obj-$(CONFIG_PXA2XX) +=3D pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h index ffed39252d..2b919e57ee 100644 --- a/include/hw/arm/arm.h +++ b/include/hw/arm/arm.h @@ -24,16 +24,17 @@ typedef enum { } arm_endianness; =20 /** - * armv7m_load_kernel: + * arm_m_profile_load_kernel: * @cpu: CPU * @kernel_filename: file to load - * @mem_size: mem_size: maximum image size to load + * @mem_size: maximum image size to load * - * Load the guest image for an ARMv7M system. This must be called by - * any ARMv7M board. (This is necessary to ensure that the CPU resets + * Load the guest image for an ARM M Profile system. This must be called by + * any ARM M Profile board. (This is necessary to ensure that the CPU rese= ts * correctly on system reset, as well as for kernel loading.) */ -void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_= size); +void arm_m_profile_load_kernel(ARMCPU *cpu, const char *kernel_filename, + int mem_size); =20 /* arm_boot.c */ struct arm_boot_info { diff --git a/hw/arm/arm-m-profile.c b/hw/arm/arm-m-profile.c new file mode 100644 index 0000000000..262706ed62 --- /dev/null +++ b/hw/arm/arm-m-profile.c @@ -0,0 +1,81 @@ +/* + * ARM M Profile System emulation. + * + * Copyright (C) 2018 Red Hat, Inc. + * + * Copyright (c) 2006-2007 CodeSourcery. + * Written by Paul Brook + * + * This code is licensed under the GPL. + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" +#include "hw/sysbus.h" +#include "hw/arm/arm.h" +#include "hw/loader.h" +#include "elf.h" +#include "sysemu/qtest.h" +#include "qemu/error-report.h" +#include "exec/address-spaces.h" + +static void arm_m_profile_reset(void *opaque) +{ + ARMCPU *cpu =3D opaque; + + cpu_reset(CPU(cpu)); +} + +void arm_m_profile_load_kernel(ARMCPU *cpu, const char *kernel_filename, i= nt mem_size) +{ + int image_size; + uint64_t entry; + uint64_t lowaddr; + int big_endian; + AddressSpace *as; + int asidx; + CPUState *cs =3D CPU(cpu); + +#ifdef TARGET_WORDS_BIGENDIAN + big_endian =3D 1; +#else + big_endian =3D 0; +#endif + + if (!kernel_filename && !qtest_enabled()) { + error_report("Guest image must be specified (using -kernel)"); + exit(1); + } + + if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) { + asidx =3D ARMASIdx_S; + } else { + asidx =3D ARMASIdx_NS; + } + as =3D cpu_get_address_space(cs, asidx); + + if (kernel_filename) { + image_size =3D load_elf_as(kernel_filename, NULL, NULL, &entry, &l= owaddr, + NULL, big_endian, EM_ARM, 1, 0, as); + if (image_size < 0) { + image_size =3D load_image_targphys_as(kernel_filename, 0, + mem_size, as); + lowaddr =3D 0; + } + if (image_size < 0) { + error_report("Could not load kernel '%s'", kernel_filename); + exit(1); + } + } + + /* CPU objects (unlike devices) are not automatically reset on system + * reset, so we must always register a handler to do so. Unlike + * A-profile CPUs, we don't need to do anything special in the + * handler to arrange that it starts correctly. + * This is arguably the wrong place to do this, but it matches the + * way A-profile does it. Note that this means that every M profile + * board must call this function! + */ + qemu_register_reset(arm_m_profile_reset, cpu); +} diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index 6b07666057..7405a1ec69 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -258,66 +258,6 @@ static const TypeInfo armv7m_info =3D { .class_init =3D armv7m_class_init, }; =20 -static void armv7m_reset(void *opaque) -{ - ARMCPU *cpu =3D opaque; - - cpu_reset(CPU(cpu)); -} - -void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_= size) -{ - int image_size; - uint64_t entry; - uint64_t lowaddr; - int big_endian; - AddressSpace *as; - int asidx; - CPUState *cs =3D CPU(cpu); - -#ifdef TARGET_WORDS_BIGENDIAN - big_endian =3D 1; -#else - big_endian =3D 0; -#endif - - if (!kernel_filename && !qtest_enabled()) { - error_report("Guest image must be specified (using -kernel)"); - exit(1); - } - - if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) { - asidx =3D ARMASIdx_S; - } else { - asidx =3D ARMASIdx_NS; - } - as =3D cpu_get_address_space(cs, asidx); - - if (kernel_filename) { - image_size =3D load_elf_as(kernel_filename, NULL, NULL, &entry, &l= owaddr, - NULL, big_endian, EM_ARM, 1, 0, as); - if (image_size < 0) { - image_size =3D load_image_targphys_as(kernel_filename, 0, - mem_size, as); - lowaddr =3D 0; - } - if (image_size < 0) { - error_report("Could not load kernel '%s'", kernel_filename); - exit(1); - } - } - - /* CPU objects (unlike devices) are not automatically reset on system - * reset, so we must always register a handler to do so. Unlike - * A-profile CPUs, we don't need to do anything special in the - * handler to arrange that it starts correctly. - * This is arguably the wrong place to do this, but it matches the - * way A-profile does it. Note that this means that every M profile - * board must call this function! - */ - qemu_register_reset(armv7m_reset, cpu); -} - static Property bitband_properties[] =3D { DEFINE_PROP_UINT32("base", BitBandState, base, 0), DEFINE_PROP_LINK("source-memory", BitBandState, source_memory, diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c index 22180c56fb..af10ee0cc9 100644 --- a/hw/arm/mps2-tz.c +++ b/hw/arm/mps2-tz.c @@ -487,7 +487,8 @@ static void mps2tz_common_init(MachineState *machine) =20 create_unimplemented_device("FPGA NS PC", 0x48007000, 0x1000); =20 - armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400= 000); + arm_m_profile_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, + 0x400000); } =20 static void mps2tz_class_init(ObjectClass *oc, void *data) diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c index c3946da317..bcc7070104 100644 --- a/hw/arm/mps2.c +++ b/hw/arm/mps2.c @@ -315,8 +315,8 @@ static void mps2_common_init(MachineState *machine) =20 system_clock_scale =3D NANOSECONDS_PER_SECOND / SYSCLK_FRQ; =20 - armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, - 0x400000); + arm_m_profile_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, + 0x400000); } =20 static void mps2_class_init(ObjectClass *oc, void *data) diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c index 2432b5e935..cb21ced472 100644 --- a/hw/arm/msf2-som.c +++ b/hw/arm/msf2-som.c @@ -91,8 +91,8 @@ static void emcraft_sf2_s2s010_init(MachineState *machine) cs_line =3D qdev_get_gpio_in_named(spi_flash, SSI_GPIO_CS, 0); sysbus_connect_irq(SYS_BUS_DEVICE(&soc->spi[0]), 1, cs_line); =20 - armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, - soc->envm_size); + arm_m_profile_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, + soc->envm_size); } =20 static void emcraft_sf2_machine_init(MachineClass *mc) diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c index f936017d4a..e18d377f94 100644 --- a/hw/arm/netduino2.c +++ b/hw/arm/netduino2.c @@ -37,8 +37,8 @@ static void netduino2_init(MachineState *machine) qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3")); object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal); =20 - armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, - FLASH_SIZE); + arm_m_profile_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, + FLASH_SIZE); } =20 static void netduino2_machine_init(MachineClass *mc) diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index dc521b4a5a..68e52367c0 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -1440,7 +1440,8 @@ static void stellaris_init(MachineState *ms, stellari= s_board_info *board) create_unimplemented_device("hibernation", 0x400fc000, 0x1000); create_unimplemented_device("flash-control", 0x400fd000, 0x1000); =20 - armv7m_load_kernel(ARM_CPU(first_cpu), ms->kernel_filename, flash_size= ); + arm_m_profile_load_kernel(ARM_CPU(first_cpu), ms->kernel_filename, + flash_size); } =20 /* FIXME: Figure out how to generate these from stellaris_boards. */ diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.= mak index 834d45cfaf..e704cb6e34 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -48,6 +48,7 @@ CONFIG_ARM11MPCORE=3Dy CONFIG_A9MPCORE=3Dy CONFIG_A15MPCORE=3Dy =20 +CONFIG_ARM_M_PROFILE=3Dy CONFIG_ARM_V7M=3Dy CONFIG_NETDUINO2=3Dy =20 --=20 2.17.1 From nobody Sat Apr 27 21:17:40 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532509581880241.44638789110218; Wed, 25 Jul 2018 02:06:21 -0700 (PDT) Received: from localhost ([::1]:46620 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiFkS-0005Gn-IP for importer@patchew.org; Wed, 25 Jul 2018 05:06:20 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51148) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiFeL-0008A3-NC for qemu-devel@nongnu.org; Wed, 25 Jul 2018 05:00:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fiFeI-00028Z-PT for qemu-devel@nongnu.org; Wed, 25 Jul 2018 05:00:01 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33494 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fiFeC-0001va-AP; Wed, 25 Jul 2018 04:59:52 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9EE6C81A4EA7; Wed, 25 Jul 2018 08:59:51 +0000 (UTC) Received: from localhost (ovpn-117-157.ams2.redhat.com [10.36.117.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id 91A142026D68; Wed, 25 Jul 2018 08:59:50 +0000 (UTC) From: Stefan Hajnoczi To: Date: Wed, 25 Jul 2018 09:59:39 +0100 Message-Id: <20180725085944.11856-3-stefanha@redhat.com> In-Reply-To: <20180725085944.11856-1-stefanha@redhat.com> References: <20180725085944.11856-1-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Wed, 25 Jul 2018 08:59:51 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Wed, 25 Jul 2018 08:59:51 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'stefanha@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v3 2/7] hw/arm: rename TYPE_ARMV7M to TYPE_ARM_M_PROFILE 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: Peter Maydell , jim@groklearning.com, mail@steffen-goertz.de, Su Hang , ilg@livius.net, Alistair Francis , Subbaraya Sundeep , Steffen Gortz , qemu-arm@nongnu.org, Joel Stanley , Stefan Hajnoczi , Julia Suvorova 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" The TYPE_ARMV7M class is really a container for an ARM M Profile CPU, NVIC, and related pieces. It can also be used for ARMv6-M and ARMv8-M. Rename the class since it is not exclusive to ARMv7-M. Signed-off-by: Stefan Hajnoczi Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/arm/Makefile.objs | 1 - include/hw/arm/{armv7m.h =3D> arm-m-profile.h} | 37 ++- include/hw/arm/iotkit.h | 4 +- include/hw/arm/msf2-soc.h | 4 +- include/hw/arm/stm32f205_soc.h | 4 +- hw/arm/arm-m-profile.c | 271 +++++++++++++++++ hw/arm/armv7m.c | 290 ------------------- hw/arm/iotkit.c | 2 +- hw/arm/mps2-tz.c | 1 - hw/arm/mps2.c | 6 +- hw/arm/msf2-soc.c | 2 +- hw/arm/stellaris.c | 4 +- hw/arm/stm32f205_soc.c | 2 +- 13 files changed, 313 insertions(+), 315 deletions(-) rename include/hw/arm/{armv7m.h =3D> arm-m-profile.h} (65%) delete mode 100644 hw/arm/armv7m.c diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 2c43d34c64..b1e4f8f006 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -17,7 +17,6 @@ obj-$(CONFIG_VERSATILE) +=3D vexpress.o versatilepb.o obj-$(CONFIG_ZYNQ) +=3D xilinx_zynq.o =20 obj-$(CONFIG_ARM_M_PROFILE) +=3D arm-m-profile.o -obj-$(CONFIG_ARM_V7M) +=3D armv7m.o obj-$(CONFIG_EXYNOS4) +=3D exynos4210.o obj-$(CONFIG_PXA2XX) +=3D pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o obj-$(CONFIG_DIGIC) +=3D digic.o diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/arm-m-profile.h similarity index 65% rename from include/hw/arm/armv7m.h rename to include/hw/arm/arm-m-profile.h index 78308d1484..ea496d9b88 100644 --- a/include/hw/arm/armv7m.h +++ b/include/hw/arm/arm-m-profile.h @@ -1,14 +1,16 @@ /* - * ARMv7M CPU object + * ARM M Profile CPU class * * Copyright (c) 2017 Linaro Ltd * Written by Peter Maydell * + * Copyright (C) 2018 Red Hat, Inc. + * * This code is licensed under the GPL version 2 or later. */ =20 -#ifndef HW_ARM_ARMV7M_H -#define HW_ARM_ARMV7M_H +#ifndef HW_ARM_ARM_M_PROFILE_H +#define HW_ARM_ARM_M_PROFILE_H =20 #include "hw/sysbus.h" #include "hw/intc/armv7m_nvic.h" @@ -28,12 +30,17 @@ typedef struct { MemoryRegion *source_memory; } BitBandState; =20 -#define TYPE_ARMV7M "armv7m" -#define ARMV7M(obj) OBJECT_CHECK(ARMv7MState, (obj), TYPE_ARMV7M) - #define ARMV7M_NUM_BITBANDS 2 =20 -/* ARMv7M container object. +#define TYPE_ARM_M_PROFILE "arm-m-profile" +#define ARM_M_PROFILE(obj) OBJECT_CHECK(ARMMProfileState, (obj), \ + TYPE_ARM_M_PROFILE) +#define ARM_M_PROFILE_CLASS(klass) \ + OBJECT_CLASS_CHECK(ARMMProfileClass, (klass), TYPE_ARM_M_PROFILE) +#define ARM_M_PROFILE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(ARMMProfileClass, (obj), TYPE_ARM_M_PROFILE) + +/* ARM M Profile container object. * + Unnamed GPIO input lines: external IRQ lines for the NVIC * + Named GPIO output SYSRESETREQ: signalled for guest AIRCR.SYSRESETREQ * + Property "cpu-type": CPU type to instantiate @@ -44,7 +51,7 @@ typedef struct { * + Property "idau": IDAU interface (forwarded to CPU object) * + Property "init-svtor": secure VTOR reset value (forwarded to CPU obje= ct) */ -typedef struct ARMv7MState { +typedef struct { /*< private >*/ SysBusDevice parent_obj; /*< public >*/ @@ -63,6 +70,18 @@ typedef struct ARMv7MState { MemoryRegion *board_memory; Object *idau; uint32_t init_svtor; -} ARMv7MState; +} ARMMProfileState; + +typedef struct { + /*< private >*/ + SysBusDeviceClass parent_class; + + /*< public >*/ + /** + * Initialize the CPU object, for example by setting properties, befor= e it + * gets realized. May be NULL. + */ + void (*cpu_init)(ARMMProfileState *s, Error **errp); +} ARMMProfileClass; =20 #endif diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 2cddde55dd..8b672c2b6c 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -51,7 +51,7 @@ #define IOTKIT_H =20 #include "hw/sysbus.h" -#include "hw/arm/armv7m.h" +#include "hw/arm/arm-m-profile.h" #include "hw/misc/iotkit-secctl.h" #include "hw/misc/tz-ppc.h" #include "hw/misc/tz-mpc.h" @@ -74,7 +74,7 @@ typedef struct IoTKit { SysBusDevice parent_obj; =20 /*< public >*/ - ARMv7MState armv7m; + ARMMProfileState armv7m; IoTKitSecCtl secctl; TZPPC apb_ppc0; TZPPC apb_ppc1; diff --git a/include/hw/arm/msf2-soc.h b/include/hw/arm/msf2-soc.h index 3cfe5c76ee..36d47db274 100644 --- a/include/hw/arm/msf2-soc.h +++ b/include/hw/arm/msf2-soc.h @@ -25,7 +25,7 @@ #ifndef HW_ARM_MSF2_SOC_H #define HW_ARM_MSF2_SOC_H =20 -#include "hw/arm/armv7m.h" +#include "hw/arm/arm-m-profile.h" #include "hw/timer/mss-timer.h" #include "hw/misc/msf2-sysreg.h" #include "hw/ssi/mss-spi.h" @@ -48,7 +48,7 @@ typedef struct MSF2State { SysBusDevice parent_obj; /*< public >*/ =20 - ARMv7MState armv7m; + ARMMProfileState armv7m; =20 char *cpu_type; char *part_name; diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h index 922a733f88..03b2e0a79d 100644 --- a/include/hw/arm/stm32f205_soc.h +++ b/include/hw/arm/stm32f205_soc.h @@ -31,7 +31,7 @@ #include "hw/adc/stm32f2xx_adc.h" #include "hw/or-irq.h" #include "hw/ssi/stm32f2xx_spi.h" -#include "hw/arm/armv7m.h" +#include "hw/arm/arm-m-profile.h" =20 #define TYPE_STM32F205_SOC "stm32f205-soc" #define STM32F205_SOC(obj) \ @@ -54,7 +54,7 @@ typedef struct STM32F205State { =20 char *cpu_type; =20 - ARMv7MState armv7m; + ARMMProfileState armv7m; =20 STM32F2XXSyscfgState syscfg; STM32F2XXUsartState usart[STM_NUM_USARTS]; diff --git a/hw/arm/arm-m-profile.c b/hw/arm/arm-m-profile.c index 262706ed62..b7dd2370d4 100644 --- a/hw/arm/arm-m-profile.c +++ b/hw/arm/arm-m-profile.c @@ -10,6 +10,8 @@ */ =20 #include "qemu/osdep.h" +#include "hw/arm/arm-m-profile.h" +#include "qapi/error.h" #include "qemu-common.h" #include "cpu.h" #include "hw/sysbus.h" @@ -20,6 +22,244 @@ #include "qemu/error-report.h" #include "exec/address-spaces.h" =20 +/* Bitbanded IO. Each word corresponds to a single bit. */ + +/* Get the byte address of the real memory for a bitband access. */ +static inline hwaddr bitband_addr(BitBandState *s, hwaddr offset) +{ + return s->base | (offset & 0x1ffffff) >> 5; +} + +static MemTxResult bitband_read(void *opaque, hwaddr offset, + uint64_t *data, unsigned size, MemTxAttrs = attrs) +{ + BitBandState *s =3D opaque; + uint8_t buf[4]; + MemTxResult res; + int bitpos, bit; + hwaddr addr; + + assert(size <=3D 4); + + /* Find address in underlying memory and round down to multiple of siz= e */ + addr =3D bitband_addr(s, offset) & (-size); + res =3D address_space_read(&s->source_as, addr, attrs, buf, size); + if (res) { + return res; + } + /* Bit position in the N bytes read... */ + bitpos =3D (offset >> 2) & ((size * 8) - 1); + /* ...converted to byte in buffer and bit in byte */ + bit =3D (buf[bitpos >> 3] >> (bitpos & 7)) & 1; + *data =3D bit; + return MEMTX_OK; +} + +static MemTxResult bitband_write(void *opaque, hwaddr offset, uint64_t val= ue, + unsigned size, MemTxAttrs attrs) +{ + BitBandState *s =3D opaque; + uint8_t buf[4]; + MemTxResult res; + int bitpos, bit; + hwaddr addr; + + assert(size <=3D 4); + + /* Find address in underlying memory and round down to multiple of siz= e */ + addr =3D bitband_addr(s, offset) & (-size); + res =3D address_space_read(&s->source_as, addr, attrs, buf, size); + if (res) { + return res; + } + /* Bit position in the N bytes read... */ + bitpos =3D (offset >> 2) & ((size * 8) - 1); + /* ...converted to byte in buffer and bit in byte */ + bit =3D 1 << (bitpos & 7); + if (value & 1) { + buf[bitpos >> 3] |=3D bit; + } else { + buf[bitpos >> 3] &=3D ~bit; + } + return address_space_write(&s->source_as, addr, attrs, buf, size); +} + +static const MemoryRegionOps bitband_ops =3D { + .read_with_attrs =3D bitband_read, + .write_with_attrs =3D bitband_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, + .impl.min_access_size =3D 1, + .impl.max_access_size =3D 4, + .valid.min_access_size =3D 1, + .valid.max_access_size =3D 4, +}; + +static void bitband_init(Object *obj) +{ + BitBandState *s =3D BITBAND(obj); + SysBusDevice *dev =3D SYS_BUS_DEVICE(obj); + + memory_region_init_io(&s->iomem, obj, &bitband_ops, s, + "bitband", 0x02000000); + sysbus_init_mmio(dev, &s->iomem); +} + +static void bitband_realize(DeviceState *dev, Error **errp) +{ + BitBandState *s =3D BITBAND(dev); + + if (!s->source_memory) { + error_setg(errp, "source-memory property not set"); + return; + } + + address_space_init(&s->source_as, s->source_memory, "bitband-source"); +} + +/* Board init. */ + +static const hwaddr bitband_input_addr[ARMV7M_NUM_BITBANDS] =3D { + 0x20000000, 0x40000000 +}; + +static const hwaddr bitband_output_addr[ARMV7M_NUM_BITBANDS] =3D { + 0x22000000, 0x42000000 +}; + +static void arm_m_profile_instance_init(Object *obj) +{ + ARMMProfileState *s =3D ARM_M_PROFILE(obj); + int i; + + /* Can't init the cpu here, we don't yet know which model to use */ + + memory_region_init(&s->container, obj, "arm-m-profile-container", UINT= 64_MAX); + + sysbus_init_child_obj(obj, "nvnic", &s->nvic, sizeof(s->nvic), TYPE_NV= IC); + object_property_add_alias(obj, "num-irq", + OBJECT(&s->nvic), "num-irq", &error_abort); + + for (i =3D 0; i < ARRAY_SIZE(s->bitband); i++) { + sysbus_init_child_obj(obj, "bitband[*]", &s->bitband[i], + sizeof(s->bitband[i]), TYPE_BITBAND); + } +} + +static void arm_m_profile_realize(DeviceState *dev, Error **errp) +{ + ARMMProfileState *s =3D ARM_M_PROFILE(dev); + SysBusDevice *sbd; + Error *err =3D NULL; + int i; + + if (!s->board_memory) { + error_setg(errp, "memory property was not set"); + return; + } + + memory_region_add_subregion_overlap(&s->container, 0, s->board_memory,= -1); + + s->cpu =3D ARM_CPU(object_new(s->cpu_type)); + + object_property_set_link(OBJECT(s->cpu), OBJECT(&s->container), "memor= y", + &error_abort); + if (object_property_find(OBJECT(s->cpu), "idau", NULL)) { + object_property_set_link(OBJECT(s->cpu), s->idau, "idau", &err); + if (err !=3D NULL) { + error_propagate(errp, err); + return; + } + } + if (object_property_find(OBJECT(s->cpu), "init-svtor", NULL)) { + object_property_set_uint(OBJECT(s->cpu), s->init_svtor, + "init-svtor", &err); + if (err !=3D NULL) { + error_propagate(errp, err); + return; + } + } + + /* Tell the CPU where the NVIC is; it will fail realize if it doesn't + * have one. + */ + s->cpu->env.nvic =3D &s->nvic; + + object_property_set_bool(OBJECT(s->cpu), true, "realized", &err); + if (err !=3D NULL) { + error_propagate(errp, err); + return; + } + + /* Note that we must realize the NVIC after the CPU */ + object_property_set_bool(OBJECT(&s->nvic), true, "realized", &err); + if (err !=3D NULL) { + error_propagate(errp, err); + return; + } + + /* Alias the NVIC's input and output GPIOs as our own so the board + * code can wire them up. (We do this in realize because the + * NVIC doesn't create the input GPIO array until realize.) + */ + qdev_pass_gpios(DEVICE(&s->nvic), dev, NULL); + qdev_pass_gpios(DEVICE(&s->nvic), dev, "SYSRESETREQ"); + + /* Wire the NVIC up to the CPU */ + sbd =3D SYS_BUS_DEVICE(&s->nvic); + sysbus_connect_irq(sbd, 0, + qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); + + memory_region_add_subregion(&s->container, 0xe000e000, + sysbus_mmio_get_region(sbd, 0)); + + for (i =3D 0; i < ARRAY_SIZE(s->bitband); i++) { + Object *obj =3D OBJECT(&s->bitband[i]); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(&s->bitband[i]); + + object_property_set_int(obj, bitband_input_addr[i], "base", &err); + if (err !=3D NULL) { + error_propagate(errp, err); + return; + } + object_property_set_link(obj, OBJECT(s->board_memory), + "source-memory", &error_abort); + object_property_set_bool(obj, true, "realized", &err); + if (err !=3D NULL) { + error_propagate(errp, err); + return; + } + + memory_region_add_subregion(&s->container, bitband_output_addr[i], + sysbus_mmio_get_region(sbd, 0)); + } +} + +static Property arm_m_profile_properties[] =3D { + DEFINE_PROP_STRING("cpu-type", ARMMProfileState, cpu_type), + DEFINE_PROP_LINK("memory", ARMMProfileState, board_memory, + TYPE_MEMORY_REGION, MemoryRegion *), + DEFINE_PROP_LINK("idau", ARMMProfileState, idau, + TYPE_IDAU_INTERFACE, Object *), + DEFINE_PROP_UINT32("init-svtor", ARMMProfileState, init_svtor, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void arm_m_profile_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->realize =3D arm_m_profile_realize; + dc->props =3D arm_m_profile_properties; +} + +static const TypeInfo arm_m_profile_info =3D { + .name =3D TYPE_ARM_M_PROFILE, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(ARMMProfileState), + .instance_init =3D arm_m_profile_instance_init, + .class_init =3D arm_m_profile_class_init, +}; + static void arm_m_profile_reset(void *opaque) { ARMCPU *cpu =3D opaque; @@ -79,3 +319,34 @@ void arm_m_profile_load_kernel(ARMCPU *cpu, const char = *kernel_filename, int mem */ qemu_register_reset(arm_m_profile_reset, cpu); } + +static Property bitband_properties[] =3D { + DEFINE_PROP_UINT32("base", BitBandState, base, 0), + DEFINE_PROP_LINK("source-memory", BitBandState, source_memory, + TYPE_MEMORY_REGION, MemoryRegion *), + DEFINE_PROP_END_OF_LIST(), +}; + +static void bitband_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->realize =3D bitband_realize; + dc->props =3D bitband_properties; +} + +static const TypeInfo bitband_info =3D { + .name =3D TYPE_BITBAND, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(BitBandState), + .instance_init =3D bitband_init, + .class_init =3D bitband_class_init, +}; + +static void arm_m_profile_register_types(void) +{ + type_register_static(&bitband_info); + type_register_static(&arm_m_profile_info); +} + +type_init(arm_m_profile_register_types) diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c deleted file mode 100644 index 7405a1ec69..0000000000 --- a/hw/arm/armv7m.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * ARMV7M System emulation. - * - * Copyright (c) 2006-2007 CodeSourcery. - * Written by Paul Brook - * - * This code is licensed under the GPL. - */ - -#include "qemu/osdep.h" -#include "hw/arm/armv7m.h" -#include "qapi/error.h" -#include "qemu-common.h" -#include "cpu.h" -#include "hw/sysbus.h" -#include "hw/arm/arm.h" -#include "hw/loader.h" -#include "elf.h" -#include "sysemu/qtest.h" -#include "qemu/error-report.h" -#include "exec/address-spaces.h" -#include "target/arm/idau.h" - -/* Bitbanded IO. Each word corresponds to a single bit. */ - -/* Get the byte address of the real memory for a bitband access. */ -static inline hwaddr bitband_addr(BitBandState *s, hwaddr offset) -{ - return s->base | (offset & 0x1ffffff) >> 5; -} - -static MemTxResult bitband_read(void *opaque, hwaddr offset, - uint64_t *data, unsigned size, MemTxAttrs = attrs) -{ - BitBandState *s =3D opaque; - uint8_t buf[4]; - MemTxResult res; - int bitpos, bit; - hwaddr addr; - - assert(size <=3D 4); - - /* Find address in underlying memory and round down to multiple of siz= e */ - addr =3D bitband_addr(s, offset) & (-size); - res =3D address_space_read(&s->source_as, addr, attrs, buf, size); - if (res) { - return res; - } - /* Bit position in the N bytes read... */ - bitpos =3D (offset >> 2) & ((size * 8) - 1); - /* ...converted to byte in buffer and bit in byte */ - bit =3D (buf[bitpos >> 3] >> (bitpos & 7)) & 1; - *data =3D bit; - return MEMTX_OK; -} - -static MemTxResult bitband_write(void *opaque, hwaddr offset, uint64_t val= ue, - unsigned size, MemTxAttrs attrs) -{ - BitBandState *s =3D opaque; - uint8_t buf[4]; - MemTxResult res; - int bitpos, bit; - hwaddr addr; - - assert(size <=3D 4); - - /* Find address in underlying memory and round down to multiple of siz= e */ - addr =3D bitband_addr(s, offset) & (-size); - res =3D address_space_read(&s->source_as, addr, attrs, buf, size); - if (res) { - return res; - } - /* Bit position in the N bytes read... */ - bitpos =3D (offset >> 2) & ((size * 8) - 1); - /* ...converted to byte in buffer and bit in byte */ - bit =3D 1 << (bitpos & 7); - if (value & 1) { - buf[bitpos >> 3] |=3D bit; - } else { - buf[bitpos >> 3] &=3D ~bit; - } - return address_space_write(&s->source_as, addr, attrs, buf, size); -} - -static const MemoryRegionOps bitband_ops =3D { - .read_with_attrs =3D bitband_read, - .write_with_attrs =3D bitband_write, - .endianness =3D DEVICE_NATIVE_ENDIAN, - .impl.min_access_size =3D 1, - .impl.max_access_size =3D 4, - .valid.min_access_size =3D 1, - .valid.max_access_size =3D 4, -}; - -static void bitband_init(Object *obj) -{ - BitBandState *s =3D BITBAND(obj); - SysBusDevice *dev =3D SYS_BUS_DEVICE(obj); - - memory_region_init_io(&s->iomem, obj, &bitband_ops, s, - "bitband", 0x02000000); - sysbus_init_mmio(dev, &s->iomem); -} - -static void bitband_realize(DeviceState *dev, Error **errp) -{ - BitBandState *s =3D BITBAND(dev); - - if (!s->source_memory) { - error_setg(errp, "source-memory property not set"); - return; - } - - address_space_init(&s->source_as, s->source_memory, "bitband-source"); -} - -/* Board init. */ - -static const hwaddr bitband_input_addr[ARMV7M_NUM_BITBANDS] =3D { - 0x20000000, 0x40000000 -}; - -static const hwaddr bitband_output_addr[ARMV7M_NUM_BITBANDS] =3D { - 0x22000000, 0x42000000 -}; - -static void armv7m_instance_init(Object *obj) -{ - ARMv7MState *s =3D ARMV7M(obj); - int i; - - /* Can't init the cpu here, we don't yet know which model to use */ - - memory_region_init(&s->container, obj, "armv7m-container", UINT64_MAX); - - sysbus_init_child_obj(obj, "nvnic", &s->nvic, sizeof(s->nvic), TYPE_NV= IC); - object_property_add_alias(obj, "num-irq", - OBJECT(&s->nvic), "num-irq", &error_abort); - - for (i =3D 0; i < ARRAY_SIZE(s->bitband); i++) { - sysbus_init_child_obj(obj, "bitband[*]", &s->bitband[i], - sizeof(s->bitband[i]), TYPE_BITBAND); - } -} - -static void armv7m_realize(DeviceState *dev, Error **errp) -{ - ARMv7MState *s =3D ARMV7M(dev); - SysBusDevice *sbd; - Error *err =3D NULL; - int i; - - if (!s->board_memory) { - error_setg(errp, "memory property was not set"); - return; - } - - memory_region_add_subregion_overlap(&s->container, 0, s->board_memory,= -1); - - s->cpu =3D ARM_CPU(object_new(s->cpu_type)); - - object_property_set_link(OBJECT(s->cpu), OBJECT(&s->container), "memor= y", - &error_abort); - if (object_property_find(OBJECT(s->cpu), "idau", NULL)) { - object_property_set_link(OBJECT(s->cpu), s->idau, "idau", &err); - if (err !=3D NULL) { - error_propagate(errp, err); - return; - } - } - if (object_property_find(OBJECT(s->cpu), "init-svtor", NULL)) { - object_property_set_uint(OBJECT(s->cpu), s->init_svtor, - "init-svtor", &err); - if (err !=3D NULL) { - error_propagate(errp, err); - return; - } - } - - /* Tell the CPU where the NVIC is; it will fail realize if it doesn't - * have one. - */ - s->cpu->env.nvic =3D &s->nvic; - - object_property_set_bool(OBJECT(s->cpu), true, "realized", &err); - if (err !=3D NULL) { - error_propagate(errp, err); - return; - } - - /* Note that we must realize the NVIC after the CPU */ - object_property_set_bool(OBJECT(&s->nvic), true, "realized", &err); - if (err !=3D NULL) { - error_propagate(errp, err); - return; - } - - /* Alias the NVIC's input and output GPIOs as our own so the board - * code can wire them up. (We do this in realize because the - * NVIC doesn't create the input GPIO array until realize.) - */ - qdev_pass_gpios(DEVICE(&s->nvic), dev, NULL); - qdev_pass_gpios(DEVICE(&s->nvic), dev, "SYSRESETREQ"); - - /* Wire the NVIC up to the CPU */ - sbd =3D SYS_BUS_DEVICE(&s->nvic); - sysbus_connect_irq(sbd, 0, - qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); - - memory_region_add_subregion(&s->container, 0xe000e000, - sysbus_mmio_get_region(sbd, 0)); - - for (i =3D 0; i < ARRAY_SIZE(s->bitband); i++) { - Object *obj =3D OBJECT(&s->bitband[i]); - SysBusDevice *sbd =3D SYS_BUS_DEVICE(&s->bitband[i]); - - object_property_set_int(obj, bitband_input_addr[i], "base", &err); - if (err !=3D NULL) { - error_propagate(errp, err); - return; - } - object_property_set_link(obj, OBJECT(s->board_memory), - "source-memory", &error_abort); - object_property_set_bool(obj, true, "realized", &err); - if (err !=3D NULL) { - error_propagate(errp, err); - return; - } - - memory_region_add_subregion(&s->container, bitband_output_addr[i], - sysbus_mmio_get_region(sbd, 0)); - } -} - -static Property armv7m_properties[] =3D { - DEFINE_PROP_STRING("cpu-type", ARMv7MState, cpu_type), - DEFINE_PROP_LINK("memory", ARMv7MState, board_memory, TYPE_MEMORY_REGI= ON, - MemoryRegion *), - DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Objec= t *), - DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0), - DEFINE_PROP_END_OF_LIST(), -}; - -static void armv7m_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc =3D DEVICE_CLASS(klass); - - dc->realize =3D armv7m_realize; - dc->props =3D armv7m_properties; -} - -static const TypeInfo armv7m_info =3D { - .name =3D TYPE_ARMV7M, - .parent =3D TYPE_SYS_BUS_DEVICE, - .instance_size =3D sizeof(ARMv7MState), - .instance_init =3D armv7m_instance_init, - .class_init =3D armv7m_class_init, -}; - -static Property bitband_properties[] =3D { - DEFINE_PROP_UINT32("base", BitBandState, base, 0), - DEFINE_PROP_LINK("source-memory", BitBandState, source_memory, - TYPE_MEMORY_REGION, MemoryRegion *), - DEFINE_PROP_END_OF_LIST(), -}; - -static void bitband_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc =3D DEVICE_CLASS(klass); - - dc->realize =3D bitband_realize; - dc->props =3D bitband_properties; -} - -static const TypeInfo bitband_info =3D { - .name =3D TYPE_BITBAND, - .parent =3D TYPE_SYS_BUS_DEVICE, - .instance_size =3D sizeof(BitBandState), - .instance_init =3D bitband_init, - .class_init =3D bitband_class_init, -}; - -static void armv7m_register_types(void) -{ - type_register_static(&bitband_info); - type_register_static(&armv7m_info); -} - -type_init(armv7m_register_types) diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c index c76d3ed743..bdf854c8b2 100644 --- a/hw/arm/iotkit.c +++ b/hw/arm/iotkit.c @@ -111,7 +111,7 @@ static void iotkit_init(Object *obj) memory_region_init(&s->container, obj, "iotkit-container", UINT64_MAX); =20 sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m), - TYPE_ARMV7M); + TYPE_ARM_M_PROFILE); qdev_prop_set_string(DEVICE(&s->armv7m), "cpu-type", ARM_CPU_TYPE_NAME("cortex-m33")); =20 diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c index af10ee0cc9..114632c94b 100644 --- a/hw/arm/mps2-tz.c +++ b/hw/arm/mps2-tz.c @@ -34,7 +34,6 @@ #include "qapi/error.h" #include "qemu/error-report.h" #include "hw/arm/arm.h" -#include "hw/arm/armv7m.h" #include "hw/or-irq.h" #include "hw/boards.h" #include "exec/address-spaces.h" diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c index bcc7070104..912e1297d5 100644 --- a/hw/arm/mps2.c +++ b/hw/arm/mps2.c @@ -26,7 +26,7 @@ #include "qapi/error.h" #include "qemu/error-report.h" #include "hw/arm/arm.h" -#include "hw/arm/armv7m.h" +#include "hw/arm/arm-m-profile.h" #include "hw/or-irq.h" #include "hw/boards.h" #include "exec/address-spaces.h" @@ -52,7 +52,7 @@ typedef struct { typedef struct { MachineState parent; =20 - ARMv7MState armv7m; + ARMMProfileState armv7m; MemoryRegion psram; MemoryRegion ssram1; MemoryRegion ssram1_m; @@ -172,7 +172,7 @@ static void mps2_common_init(MachineState *machine) g_assert_not_reached(); } =20 - object_initialize(&mms->armv7m, sizeof(mms->armv7m), TYPE_ARMV7M); + object_initialize(&mms->armv7m, sizeof(mms->armv7m), TYPE_ARM_M_PROFIL= E); armv7m =3D DEVICE(&mms->armv7m); qdev_set_parent_bus(armv7m, sysbus_get_default()); switch (mmc->fpga_type) { diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c index dbefade644..09cdc61f44 100644 --- a/hw/arm/msf2-soc.c +++ b/hw/arm/msf2-soc.c @@ -69,7 +69,7 @@ static void m2sxxx_soc_initfn(Object *obj) int i; =20 sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m), - TYPE_ARMV7M); + TYPE_ARM_M_PROFILE); =20 sysbus_init_child_obj(obj, "sysreg", &s->sysreg, sizeof(s->sysreg), TYPE_MSF2_SYSREG); diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index 68e52367c0..42785f5bd1 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -20,7 +20,7 @@ #include "qemu/log.h" #include "exec/address-spaces.h" #include "sysemu/sysemu.h" -#include "hw/arm/armv7m.h" +#include "hw/arm/arm-m-profile.h" #include "hw/char/pl011.h" #include "hw/misc/unimp.h" #include "cpu.h" @@ -1301,7 +1301,7 @@ static void stellaris_init(MachineState *ms, stellari= s_board_info *board) &error_fatal); memory_region_add_subregion(system_memory, 0x20000000, sram); =20 - nvic =3D qdev_create(NULL, TYPE_ARMV7M); + nvic =3D qdev_create(NULL, TYPE_ARM_M_PROFILE); qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES); qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type); object_property_set_link(OBJECT(nvic), OBJECT(get_system_memory()), diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c index c486d06a8b..7de1474ade 100644 --- a/hw/arm/stm32f205_soc.c +++ b/hw/arm/stm32f205_soc.c @@ -50,7 +50,7 @@ static void stm32f205_soc_initfn(Object *obj) int i; =20 sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m), - TYPE_ARMV7M); + TYPE_ARM_M_PROFILE); =20 sysbus_init_child_obj(obj, "syscfg", &s->syscfg, sizeof(s->syscfg), TYPE_STM32F2XX_SYSCFG); --=20 2.17.1 From nobody Sat Apr 27 21:17:40 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 153250935955663.72392476216794; Wed, 25 Jul 2018 02:02:39 -0700 (PDT) Received: from localhost ([::1]:46586 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiFgs-0001oB-Am for importer@patchew.org; Wed, 25 Jul 2018 05:02:38 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51168) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiFeP-0008By-BM for qemu-devel@nongnu.org; Wed, 25 Jul 2018 05:00:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fiFeM-0002Dp-E9 for qemu-devel@nongnu.org; Wed, 25 Jul 2018 05:00:05 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:40796 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fiFeF-00022L-Us; Wed, 25 Jul 2018 04:59:56 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 53D1E407573E; Wed, 25 Jul 2018 08:59:55 +0000 (UTC) Received: from localhost (ovpn-117-157.ams2.redhat.com [10.36.117.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id A230A111AF1B; Wed, 25 Jul 2018 08:59:52 +0000 (UTC) From: Stefan Hajnoczi To: Date: Wed, 25 Jul 2018 09:59:40 +0100 Message-Id: <20180725085944.11856-4-stefanha@redhat.com> In-Reply-To: <20180725085944.11856-1-stefanha@redhat.com> References: <20180725085944.11856-1-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Wed, 25 Jul 2018 08:59:55 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Wed, 25 Jul 2018 08:59:55 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'stefanha@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v3 3/7] hw/arm: make bitbanded IO optional on ARM M Profile 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: Peter Maydell , jim@groklearning.com, mail@steffen-goertz.de, Su Hang , ilg@livius.net, Alistair Francis , Subbaraya Sundeep , Steffen Gortz , qemu-arm@nongnu.org, Joel Stanley , Stefan Hajnoczi , Julia Suvorova 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" Some ARM CPUs have bitbanded IO, a memory region that allows convenient bit access via 32-bit memory loads/stores. This eliminates the need for read-modify-update instruction sequences. This patch makes this optional feature a ARMMProfile qdev property, allowing boards to choose whether they want bitbanding or not. Status of boards: * iotkit (Cortex M33), no bitband * mps2 (Cortex M3), bitband * msf2 (Cortex M3), bitband * stellaris (Cortex M3), bitband * stm32f205 (Cortex M3), bitband Signed-off-by: Stefan Hajnoczi Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- include/hw/arm/arm-m-profile.h | 2 ++ hw/arm/arm-m-profile.c | 38 +++++++++++++++++++--------------- hw/arm/mps2.c | 1 + hw/arm/msf2-soc.c | 1 + hw/arm/stellaris.c | 1 + hw/arm/stm32f205_soc.c | 1 + 6 files changed, 27 insertions(+), 17 deletions(-) diff --git a/include/hw/arm/arm-m-profile.h b/include/hw/arm/arm-m-profile.h index ea496d9b88..1eb7a5c328 100644 --- a/include/hw/arm/arm-m-profile.h +++ b/include/hw/arm/arm-m-profile.h @@ -50,6 +50,7 @@ typedef struct { * devices will be automatically layered on top of this view.) * + Property "idau": IDAU interface (forwarded to CPU object) * + Property "init-svtor": secure VTOR reset value (forwarded to CPU obje= ct) + * + Property "enable-bitband": expose bitbanded IO */ typedef struct { /*< private >*/ @@ -70,6 +71,7 @@ typedef struct { MemoryRegion *board_memory; Object *idau; uint32_t init_svtor; + bool enable_bitband; } ARMMProfileState; =20 typedef struct { diff --git a/hw/arm/arm-m-profile.c b/hw/arm/arm-m-profile.c index b7dd2370d4..8bafd6602d 100644 --- a/hw/arm/arm-m-profile.c +++ b/hw/arm/arm-m-profile.c @@ -212,25 +212,27 @@ static void arm_m_profile_realize(DeviceState *dev, E= rror **errp) memory_region_add_subregion(&s->container, 0xe000e000, sysbus_mmio_get_region(sbd, 0)); =20 - for (i =3D 0; i < ARRAY_SIZE(s->bitband); i++) { - Object *obj =3D OBJECT(&s->bitband[i]); - SysBusDevice *sbd =3D SYS_BUS_DEVICE(&s->bitband[i]); + if (s->enable_bitband) { + for (i =3D 0; i < ARRAY_SIZE(s->bitband); i++) { + Object *obj =3D OBJECT(&s->bitband[i]); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(&s->bitband[i]); =20 - object_property_set_int(obj, bitband_input_addr[i], "base", &err); - if (err !=3D NULL) { - error_propagate(errp, err); - return; - } - object_property_set_link(obj, OBJECT(s->board_memory), - "source-memory", &error_abort); - object_property_set_bool(obj, true, "realized", &err); - if (err !=3D NULL) { - error_propagate(errp, err); - return; - } + object_property_set_int(obj, bitband_input_addr[i], "base", &e= rr); + if (err !=3D NULL) { + error_propagate(errp, err); + return; + } + object_property_set_link(obj, OBJECT(s->board_memory), + "source-memory", &error_abort); + object_property_set_bool(obj, true, "realized", &err); + if (err !=3D NULL) { + error_propagate(errp, err); + return; + } =20 - memory_region_add_subregion(&s->container, bitband_output_addr[i], - sysbus_mmio_get_region(sbd, 0)); + memory_region_add_subregion(&s->container, bitband_output_addr= [i], + sysbus_mmio_get_region(sbd, 0)); + } } } =20 @@ -241,6 +243,8 @@ static Property arm_m_profile_properties[] =3D { DEFINE_PROP_LINK("idau", ARMMProfileState, idau, TYPE_IDAU_INTERFACE, Object *), DEFINE_PROP_UINT32("init-svtor", ARMMProfileState, init_svtor, 0), + DEFINE_PROP_BOOL("enable-bitband", ARMMProfileState, + enable_bitband, false), DEFINE_PROP_END_OF_LIST(), }; =20 diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c index 912e1297d5..b232162dbd 100644 --- a/hw/arm/mps2.c +++ b/hw/arm/mps2.c @@ -186,6 +186,7 @@ static void mps2_common_init(MachineState *machine) g_assert_not_reached(); } qdev_prop_set_string(armv7m, "cpu-type", machine->cpu_type); + qdev_prop_set_bit(armv7m, "enable-bitband", true); object_property_set_link(OBJECT(&mms->armv7m), OBJECT(system_memory), "memory", &error_abort); object_property_set_bool(OBJECT(&mms->armv7m), true, "realized", diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c index 09cdc61f44..fb5d16338f 100644 --- a/hw/arm/msf2-soc.c +++ b/hw/arm/msf2-soc.c @@ -117,6 +117,7 @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Er= ror **errp) armv7m =3D DEVICE(&s->armv7m); qdev_prop_set_uint32(armv7m, "num-irq", 81); qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type); + qdev_prop_set_bit(armv7m, "enable-bitband", true); object_property_set_link(OBJECT(&s->armv7m), OBJECT(get_system_memory(= )), "memory", &error_abort); object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err); diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index 42785f5bd1..cb22684ffe 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -1304,6 +1304,7 @@ static void stellaris_init(MachineState *ms, stellari= s_board_info *board) nvic =3D qdev_create(NULL, TYPE_ARM_M_PROFILE); qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES); qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type); + qdev_prop_set_bit(nvic, "enable-bitband", true); object_property_set_link(OBJECT(nvic), OBJECT(get_system_memory()), "memory", &error_abort); /* This will exit with an error if the user passed us a bad cpu_type */ diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c index 7de1474ade..f78b89d205 100644 --- a/hw/arm/stm32f205_soc.c +++ b/hw/arm/stm32f205_soc.c @@ -109,6 +109,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc,= Error **errp) armv7m =3D DEVICE(&s->armv7m); qdev_prop_set_uint32(armv7m, "num-irq", 96); qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type); + qdev_prop_set_bit(armv7m, "enable-bitband", true); object_property_set_link(OBJECT(&s->armv7m), OBJECT(get_system_memory(= )), "memory", &error_abort); object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err); --=20 2.17.1 From nobody Sat Apr 27 21:17:40 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532509450618820.076403993261; Wed, 25 Jul 2018 02:04:10 -0700 (PDT) Received: from localhost ([::1]:46587 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiFhH-00027Y-Uy for importer@patchew.org; Wed, 25 Jul 2018 05:03:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51203) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiFeT-0008FY-4z for qemu-devel@nongnu.org; Wed, 25 Jul 2018 05:00:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fiFeQ-0002LN-83 for qemu-devel@nongnu.org; Wed, 25 Jul 2018 05:00:09 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:40830 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fiFeH-00024k-FL; Wed, 25 Jul 2018 04:59:57 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D500E407574B; Wed, 25 Jul 2018 08:59:56 +0000 (UTC) Received: from localhost (ovpn-117-157.ams2.redhat.com [10.36.117.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id 82DC22156898; Wed, 25 Jul 2018 08:59:56 +0000 (UTC) From: Stefan Hajnoczi To: Date: Wed, 25 Jul 2018 09:59:41 +0100 Message-Id: <20180725085944.11856-5-stefanha@redhat.com> In-Reply-To: <20180725085944.11856-1-stefanha@redhat.com> References: <20180725085944.11856-1-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Wed, 25 Jul 2018 08:59:56 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Wed, 25 Jul 2018 08:59:56 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'stefanha@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v3 4/7] target/arm: add "cortex-m0" CPU model 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: Peter Maydell , jim@groklearning.com, mail@steffen-goertz.de, Su Hang , ilg@livius.net, Alistair Francis , Subbaraya Sundeep , Steffen Gortz , qemu-arm@nongnu.org, Joel Stanley , Stefan Hajnoczi , Julia Suvorova 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" Define a "cortex-m0" ARMv6-M CPU model. Most of the register reset values set by other CPU models are not relevant for the cut-down ARMv6-M architecture. Signed-off-by: Stefan Hajnoczi Reviewed-by: Peter Maydell --- target/arm/cpu.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 3848ef46aa..7e477c0d23 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1255,6 +1255,15 @@ static void arm11mpcore_initfn(Object *obj) cpu->reset_auxcr =3D 1; } =20 +static void cortex_m0_initfn(Object *obj) +{ + ARMCPU *cpu =3D ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V6); + set_feature(&cpu->env, ARM_FEATURE_M); + + cpu->midr =3D 0x410cc200; +} + static void cortex_m3_initfn(Object *obj) { ARMCPU *cpu =3D ARM_CPU(obj); @@ -1845,6 +1854,8 @@ static const ARMCPUInfo arm_cpus[] =3D { { .name =3D "arm1136", .initfn =3D arm1136_initfn }, { .name =3D "arm1176", .initfn =3D arm1176_initfn }, { .name =3D "arm11mpcore", .initfn =3D arm11mpcore_initfn }, + { .name =3D "cortex-m0", .initfn =3D cortex_m0_initfn, + .class_init =3D arm_v7m_class_init }, { .name =3D "cortex-m3", .initfn =3D cortex_m3_initfn, .class_init =3D arm_v7m_class_init }, { .name =3D "cortex-m4", .initfn =3D cortex_m4_initfn, --=20 2.17.1 From nobody Sat Apr 27 21:17:40 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532509549025146.72285548012394; Wed, 25 Jul 2018 02:05:49 -0700 (PDT) Received: from localhost ([::1]:46617 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiFjv-0004uw-VB for importer@patchew.org; Wed, 25 Jul 2018 05:05:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51221) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiFeV-0008Hj-UV for qemu-devel@nongnu.org; Wed, 25 Jul 2018 05:00:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fiFeT-0002Rg-1J for qemu-devel@nongnu.org; Wed, 25 Jul 2018 05:00:12 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:41920 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fiFeM-0002Di-JV; Wed, 25 Jul 2018 05:00:02 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7E07D68801; Wed, 25 Jul 2018 09:00:01 +0000 (UTC) Received: from localhost (ovpn-117-157.ams2.redhat.com [10.36.117.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id 83A3D7C2F; Wed, 25 Jul 2018 08:59:58 +0000 (UTC) From: Stefan Hajnoczi To: Date: Wed, 25 Jul 2018 09:59:42 +0100 Message-Id: <20180725085944.11856-6-stefanha@redhat.com> In-Reply-To: <20180725085944.11856-1-stefanha@redhat.com> References: <20180725085944.11856-1-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Wed, 25 Jul 2018 09:00:01 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Wed, 25 Jul 2018 09:00:01 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'stefanha@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v3 5/7] loader: add rom transaction API 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: Peter Maydell , jim@groklearning.com, mail@steffen-goertz.de, Su Hang , ilg@livius.net, Alistair Francis , Subbaraya Sundeep , Steffen Gortz , qemu-arm@nongnu.org, Joel Stanley , Stefan Hajnoczi , Julia Suvorova 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" Image file loaders may add a series of roms. If an error occurs partway through loading there is no easy way to drop previously added roms. This patch adds a transaction mechanism that works like this: rom_transaction_begin(); ...call rom_add_*()... rom_transaction_end(ok); If ok is false then roms added in this transaction are dropped. Signed-off-by: Stefan Hajnoczi Reviewed-by: Peter Maydell --- include/hw/loader.h | 19 +++++++++++++++++++ hw/core/loader.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/include/hw/loader.h b/include/hw/loader.h index e98b84b8f9..5235f119a3 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -225,6 +225,25 @@ int rom_check_and_register_reset(void); void rom_set_fw(FWCfgState *f); void rom_set_order_override(int order); void rom_reset_order_override(void); + +/** + * rom_transaction_begin: + * + * Call this before of a series of rom_add_*() calls. Call + * rom_transaction_end() afterwards to commit or abort. These functions a= re + * useful for undoing a series of rom_add_*() calls if image file loading = fails + * partway through. + */ +void rom_transaction_begin(void); + +/** + * rom_transaction_end: + * @commit: true to commit added roms, false to drop added roms + * + * Call this after a series of rom_add_*() calls. See rom_transaction_beg= in(). + */ +void rom_transaction_end(bool commit); + int rom_copy(uint8_t *dest, hwaddr addr, size_t size); void *rom_ptr(hwaddr addr, size_t size); void hmp_info_roms(Monitor *mon, const QDict *qdict); diff --git a/hw/core/loader.c b/hw/core/loader.c index bbb6e65bb5..182abcce28 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -840,6 +840,8 @@ struct Rom { char *fw_dir; char *fw_file; =20 + bool committed; + hwaddr addr; QTAILQ_ENTRY(Rom) next; }; @@ -866,6 +868,8 @@ static void rom_insert(Rom *rom) rom->as =3D &address_space_memory; } =20 + rom->committed =3D false; + /* List is ordered by load address in the same address space */ QTAILQ_FOREACH(item, &roms, next) { if (rom_order_compare(rom, item)) { @@ -1165,6 +1169,39 @@ void rom_reset_order_override(void) fw_cfg_reset_order_override(fw_cfg); } =20 +void rom_transaction_begin(void) +{ + Rom *rom; + + /* Ignore ROMs added without the transaction API */ + QTAILQ_FOREACH(rom, &roms, next) { + rom->committed =3D true; + } +} + +void rom_transaction_end(bool commit) +{ + Rom *rom; + Rom *tmp; + + QTAILQ_FOREACH_SAFE(rom, &roms, next, tmp) { + if (rom->committed) { + continue; + } + if (commit) { + rom->committed =3D true; + } else { + QTAILQ_REMOVE(&roms, rom, next); + g_free(rom->data); + g_free(rom->path); + g_free(rom->name); + g_free(rom->fw_dir); + g_free(rom->fw_file); + g_free(rom); + } + } +} + static Rom *find_rom(hwaddr addr, size_t size) { Rom *rom; --=20 2.17.1 From nobody Sat Apr 27 21:17:40 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532509552194500.85971995136504; Wed, 25 Jul 2018 02:05:52 -0700 (PDT) Received: from localhost ([::1]:46618 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiFjy-0004xs-TI for importer@patchew.org; Wed, 25 Jul 2018 05:05:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51236) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiFeY-0008Kg-AS for qemu-devel@nongnu.org; Wed, 25 Jul 2018 05:00:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fiFeV-0002XQ-Cs for qemu-devel@nongnu.org; Wed, 25 Jul 2018 05:00:14 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33512 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fiFeO-0002HI-Ch; Wed, 25 Jul 2018 05:00:04 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D19BE81A4EBF; Wed, 25 Jul 2018 09:00:03 +0000 (UTC) Received: from localhost (ovpn-117-157.ams2.redhat.com [10.36.117.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id 48803215670C; Wed, 25 Jul 2018 09:00:03 +0000 (UTC) From: Stefan Hajnoczi To: Date: Wed, 25 Jul 2018 09:59:43 +0100 Message-Id: <20180725085944.11856-7-stefanha@redhat.com> In-Reply-To: <20180725085944.11856-1-stefanha@redhat.com> References: <20180725085944.11856-1-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Wed, 25 Jul 2018 09:00:03 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Wed, 25 Jul 2018 09:00:03 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'stefanha@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v3 6/7] loader: Implement .hex file loader 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: Peter Maydell , jim@groklearning.com, mail@steffen-goertz.de, Su Hang , ilg@livius.net, Alistair Francis , Subbaraya Sundeep , Steffen Gortz , qemu-arm@nongnu.org, Joel Stanley , Stefan Hajnoczi , Julia Suvorova 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" From: Su Hang This patch adds Intel Hexadecimal Object File format support to the loader. The file format specification is available here: http://www.piclist.com/techref/fileext/hex/intel.htm This file format is often used with microcontrollers such as the micro:bit, Arduino, STM32, etc. Users expect to be able to run them directly with qemu -kernel program.hex instead of converting to ELF or binary. Signed-off-by: Su Hang Signed-off-by: Stefan Hajnoczi --- include/hw/loader.h | 12 ++ hw/arm/arm-m-profile.c | 3 + hw/core/loader.c | 243 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 258 insertions(+) diff --git a/include/hw/loader.h b/include/hw/loader.h index 5235f119a3..3c112975f4 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -28,6 +28,18 @@ ssize_t load_image_size(const char *filename, void *addr= , size_t size); int load_image_targphys_as(const char *filename, hwaddr addr, uint64_t max_sz, AddressSpace *as); =20 +/**load_targphys_hex_as: + * @filename: Path to the .hex file + * @entry: Store the entry point given by the .hex file + * @as: The AddressSpace to load the .hex file to. The value of + * address_space_memory is used if nothing is supplied here. + * + * Load a fixed .hex file into memory. + * + * Returns the size of the loaded .hex file on success, -1 otherwise. + */ +int load_targphys_hex_as(const char *filename, hwaddr *entry, AddressSpace= *as); + /** load_image_targphys: * Same as load_image_targphys_as(), but doesn't allow the caller to speci= fy * an AddressSpace. diff --git a/hw/arm/arm-m-profile.c b/hw/arm/arm-m-profile.c index 8bafd6602d..441bc1a9c2 100644 --- a/hw/arm/arm-m-profile.c +++ b/hw/arm/arm-m-profile.c @@ -302,6 +302,9 @@ void arm_m_profile_load_kernel(ARMCPU *cpu, const char = *kernel_filename, int mem if (kernel_filename) { image_size =3D load_elf_as(kernel_filename, NULL, NULL, &entry, &l= owaddr, NULL, big_endian, EM_ARM, 1, 0, as); + if (image_size < 0) { + image_size =3D load_targphys_hex_as(kernel_filename, &entry, a= s); + } if (image_size < 0) { image_size =3D load_image_targphys_as(kernel_filename, 0, mem_size, as); diff --git a/hw/core/loader.c b/hw/core/loader.c index 182abcce28..9ce5f45d5c 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -1323,3 +1323,246 @@ void hmp_info_roms(Monitor *mon, const QDict *qdict) } } } + +typedef enum HexRecord HexRecord; +enum HexRecord { + DATA_RECORD =3D 0, + EOF_RECORD, + EXT_SEG_ADDR_RECORD, + START_SEG_ADDR_RECORD, + EXT_LINEAR_ADDR_RECORD, + START_LINEAR_ADDR_RECORD, +}; + +#define DATA_FIELD_MAX_LEN 0xff +#define LEN_EXCEPT_DATA 0x5 +/* 0x5 =3D sizeof(byte_count) + sizeof(address) + sizeof(record_type) + + * sizeof(checksum) */ +typedef struct { + uint8_t byte_count; + uint16_t address; + uint8_t record_type; + uint8_t data[DATA_FIELD_MAX_LEN]; + uint8_t checksum; +} HexLine; + +/* return 0 or -1 if error */ +static bool parse_record(HexLine *line, uint8_t *our_checksum, const uint8= _t c, + uint32_t *index, const bool in_process) +{ + /* +-------+---------------+-------+---------------------+--------+ + * | byte | |record | | | + * | count | address | type | data |checksum| + * +-------+---------------+-------+---------------------+--------+ + * ^ ^ ^ ^ ^ ^ + * |1 byte | 2 bytes |1 byte | 0-255 bytes | 1 byte | + */ + uint8_t value =3D 0; + uint32_t idx =3D *index; + /* ignore space */ + if (g_ascii_isspace(c)) { + return true; + } + if (!g_ascii_isxdigit(c) || !in_process) { + return false; + } + value =3D g_ascii_xdigit_value(c); + value =3D idx & 0x1 ? value & 0xf : value << 4; + if (idx < 2) { + line->byte_count |=3D value; + } else if (2 <=3D idx && idx < 6) { + line->address <<=3D 4; + line->address +=3D g_ascii_xdigit_value(c); + } else if (6 <=3D idx && idx < 8) { + line->record_type |=3D value; + } else if (8 <=3D idx && idx < 8 + 2 * line->byte_count) { + line->data[(idx - 8) >> 1] |=3D value; + } else if (8 + 2 * line->byte_count <=3D idx && + idx < 10 + 2 * line->byte_count) { + line->checksum |=3D value; + } else { + return false; + } + *our_checksum +=3D value; + ++(*index); + return true; +} + +typedef struct { + const char *filename; + HexLine line; + uint8_t *bin_buf; + hwaddr *start_addr; + int total_size; + uint32_t next_address_to_write; + uint32_t current_address; + uint32_t current_rom_index; + uint32_t rom_start_address; + AddressSpace *as; +} HexParser; + +/* return size or -1 if error */ +static int handle_record_type(HexParser *parser) +{ + HexLine *line =3D &(parser->line); + switch (line->record_type) { + case DATA_RECORD: + parser->current_address =3D + (parser->next_address_to_write & 0xffff0000) | line->address; + /* verify this is a contiguous block of memory */ + if (parser->current_address !=3D parser->next_address_to_write) { + if (parser->current_rom_index !=3D 0) { + rom_add_blob_fixed_as(parser->filename, parser->bin_buf, + parser->current_rom_index, + parser->rom_start_address, parser->a= s); + } + parser->rom_start_address =3D parser->current_address; + parser->current_rom_index =3D 0; + } + + /* copy from line buffer to output bin_buf */ + memcpy(parser->bin_buf + parser->current_rom_index, line->data, + line->byte_count); + parser->current_rom_index +=3D line->byte_count; + parser->total_size +=3D line->byte_count; + /* save next address to write */ + parser->next_address_to_write =3D + parser->current_address + line->byte_count; + break; + + case EOF_RECORD: + if (parser->current_rom_index !=3D 0) { + rom_add_blob_fixed_as(parser->filename, parser->bin_buf, + parser->current_rom_index, + parser->rom_start_address, parser->as); + } + return parser->total_size; + case EXT_SEG_ADDR_RECORD: + case EXT_LINEAR_ADDR_RECORD: + if (line->byte_count !=3D 2 && line->address !=3D 0) { + return -1; + } + + if (parser->current_rom_index !=3D 0) { + rom_add_blob_fixed_as(parser->filename, parser->bin_buf, + parser->current_rom_index, + parser->rom_start_address, parser->as); + } + + /* save next address to write, + * in case of non-contiguous block of memory */ + parser->next_address_to_write =3D + line->record_type =3D=3D EXT_SEG_ADDR_RECORD + ? ((line->data[0] << 12) | (line->data[1] << 4)) + : ((line->data[0] << 24) | (line->data[1] << 16)); + parser->rom_start_address =3D parser->next_address_to_write; + parser->current_rom_index =3D 0; + break; + + case START_SEG_ADDR_RECORD: + if (line->byte_count !=3D 4 && line->address !=3D 0) { + return -1; + } + + /* x86 16-bit CS:IP segmented addressing */ + *(parser->start_addr) =3D (((line->data[0] << 8) | line->data[1]) = << 4) | + (line->data[2] << 8) | line->data[3]; + break; + + case START_LINEAR_ADDR_RECORD: + if (line->byte_count !=3D 4 && line->address !=3D 0) { + return -1; + } + + *(parser->start_addr) =3D (line->data[0] << 24) | (line->data[1] <= < 16) | + (line->data[2] << 8) | (line->data[3]); + break; + + default: + return -1; + } + + return parser->total_size; +} + +/* return size or -1 if error */ +static int parse_hex_blob(const char *filename, hwaddr *addr, uint8_t *hex= _blob, + size_t hex_blob_size, AddressSpace *as) +{ + bool in_process =3D false; /* avoid re-enter and + * check whether record begin with ':' */ + uint8_t *end =3D hex_blob + hex_blob_size; + uint8_t our_checksum =3D 0; + uint32_t record_index =3D 0; + HexParser parser =3D { + .filename =3D filename, + .bin_buf =3D g_malloc(hex_blob_size), + .start_addr =3D addr, + .as =3D as, + }; + + rom_transaction_begin(); + + for (; hex_blob < end; ++hex_blob) { + switch (*hex_blob) { + case '\r': + case '\n': + if (!in_process) { + break; + } + + in_process =3D false; + if ((LEN_EXCEPT_DATA + parser.line.byte_count) * 2 !=3D + record_index || + our_checksum !=3D 0) { + parser.total_size =3D -1; + goto out; + } + + if (handle_record_type(&parser) =3D=3D -1) { + parser.total_size =3D -1; + goto out; + } + break; + + /* start of a new record. */ + case ':': + memset(&parser.line, 0, sizeof(HexLine)); + in_process =3D true; + record_index =3D 0; + break; + + /* decoding lines */ + default: + if (!parse_record(&parser.line, &our_checksum, *hex_blob, + &record_index, in_process)) { + parser.total_size =3D -1; + goto out; + } + break; + } + } + +out: + g_free(parser.bin_buf); + rom_transaction_end(parser.total_size !=3D -1); + return parser.total_size; +} + +/* return size or -1 if error */ +int load_targphys_hex_as(const char *filename, hwaddr *entry, AddressSpace= *as) +{ + gsize hex_blob_size; + gchar *hex_blob; + int total_size =3D 0; + + if (!g_file_get_contents(filename, &hex_blob, &hex_blob_size, NULL)) { + return -1; + } + + total_size =3D parse_hex_blob(filename, entry, (uint8_t *)hex_blob, + hex_blob_size, as); + + g_free(hex_blob); + return total_size; +} --=20 2.17.1 From nobody Sat Apr 27 21:17:40 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532509705901416.29933177567386; Wed, 25 Jul 2018 02:08:25 -0700 (PDT) Received: from localhost ([::1]:46640 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiFmJ-0006fC-MB for importer@patchew.org; Wed, 25 Jul 2018 05:08:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51243) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiFeZ-0008Lt-Js for qemu-devel@nongnu.org; Wed, 25 Jul 2018 05:00:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fiFeW-0002Yd-M3 for qemu-devel@nongnu.org; Wed, 25 Jul 2018 05:00:15 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:51854 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fiFeQ-0002L7-77; Wed, 25 Jul 2018 05:00:06 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 74A9C401DEA9; Wed, 25 Jul 2018 09:00:05 +0000 (UTC) Received: from localhost (ovpn-117-157.ams2.redhat.com [10.36.117.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id 213E72026D68; Wed, 25 Jul 2018 09:00:04 +0000 (UTC) From: Stefan Hajnoczi To: Date: Wed, 25 Jul 2018 09:59:44 +0100 Message-Id: <20180725085944.11856-8-stefanha@redhat.com> In-Reply-To: <20180725085944.11856-1-stefanha@redhat.com> References: <20180725085944.11856-1-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Wed, 25 Jul 2018 09:00:05 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Wed, 25 Jul 2018 09:00:05 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'stefanha@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v3 7/7] Add QTest testcase for the Intel Hexadecimal 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: Peter Maydell , jim@groklearning.com, mail@steffen-goertz.de, Su Hang , ilg@livius.net, Alistair Francis , Subbaraya Sundeep , Steffen Gortz , qemu-arm@nongnu.org, Joel Stanley , Stefan Hajnoczi , Julia Suvorova 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" From: Su Hang 'test.hex' file is a bare metal ARM software stored in Hexadecimal Object Format. When it's loaded by QEMU, it will print "Hello world!\n" on console. `pre_store` array in 'hexloader-test.c' file, stores the binary format of 'test.hex' file, which is used to verify correctness. Reviewed-by: Stefan Hajnoczi Suggested-by: Steffen Gortz Suggested-by: Stefan Hajnoczi Signed-off-by: Su Hang Signed-off-by: Stefan Hajnoczi --- MAINTAINERS | 6 +++ configure | 4 ++ tests/Makefile.include | 2 + tests/hexloader-test.c | 56 ++++++++++++++++++++++++++++ tests/hex-loader-check-data/test.hex | 12 ++++++ 5 files changed, 80 insertions(+) create mode 100644 tests/hexloader-test.c create mode 100644 tests/hex-loader-check-data/test.hex diff --git a/MAINTAINERS b/MAINTAINERS index 666e936812..c48d9271cf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1323,6 +1323,12 @@ F: hw/core/generic-loader.c F: include/hw/core/generic-loader.h F: docs/generic-loader.txt =20 +Intel Hexadecimal Object File Loader +M: Su Hang +S: Maintained +F: tests/hexloader-test.c +F: tests/hex-loader-check-data/test.hex + CHRP NVRAM M: Thomas Huth S: Maintained diff --git a/configure b/configure index 2a7796ea80..db97930314 100755 --- a/configure +++ b/configure @@ -7382,6 +7382,10 @@ for test_file in $(find $source_path/tests/acpi-test= -data -type f) do FILES=3D"$FILES tests/acpi-test-data$(echo $test_file | sed -e 's/.*ac= pi-test-data//')" done +for test_file in $(find $source_path/tests/hex-loader-check-data -type f) +do + FILES=3D"$FILES tests/hex-loader-check-data$(echo $test_file | sed -e = 's/.*hex-loader-check-data//')" +done mkdir -p $DIRS for f in $FILES ; do if [ -e "$source_path/$f" ] && [ "$pwd_is_source_path" !=3D "y" ]; then diff --git a/tests/Makefile.include b/tests/Makefile.include index a49282704e..760a0f18b6 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -386,6 +386,7 @@ check-qtest-arm-y +=3D tests/test-arm-mptimer$(EXESUF) gcov-files-arm-y +=3D hw/timer/arm_mptimer.c check-qtest-arm-y +=3D tests/boot-serial-test$(EXESUF) check-qtest-arm-y +=3D tests/sdhci-test$(EXESUF) +check-qtest-arm-y +=3D tests/hexloader-test$(EXESUF) =20 check-qtest-aarch64-y =3D tests/numa-test$(EXESUF) check-qtest-aarch64-y +=3D tests/sdhci-test$(EXESUF) @@ -773,6 +774,7 @@ tests/qmp-test$(EXESUF): tests/qmp-test.o tests/device-introspect-test$(EXESUF): tests/device-introspect-test.o tests/rtc-test$(EXESUF): tests/rtc-test.o tests/m48t59-test$(EXESUF): tests/m48t59-test.o +tests/hexloader-test$(EXESUF): tests/hexloader-test.o tests/endianness-test$(EXESUF): tests/endianness-test.o tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y) tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y) diff --git a/tests/hexloader-test.c b/tests/hexloader-test.c new file mode 100644 index 0000000000..78b566f8b1 --- /dev/null +++ b/tests/hexloader-test.c @@ -0,0 +1,56 @@ +/* + * QTest testcase for the Intel Hexadecimal Object File Loader + * + * Authors: + * Su Hang 2018 + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "libqtest.h" + +#define BIN_SIZE 146 + +static unsigned char pre_store[BIN_SIZE] =3D { + 4, 208, 159, 229, 22, 0, 0, 235, 254, 255, 255, 234, 152, 16, = 1, + 0, 4, 176, 45, 229, 0, 176, 141, 226, 12, 208, 77, 226, 8, = 0, + 11, 229, 6, 0, 0, 234, 8, 48, 27, 229, 0, 32, 211, 229, = 44, + 48, 159, 229, 0, 32, 131, 229, 8, 48, 27, 229, 1, 48, 131, = 226, + 8, 48, 11, 229, 8, 48, 27, 229, 0, 48, 211, 229, 0, 0, = 83, + 227, 244, 255, 255, 26, 0, 0, 160, 225, 0, 208, 139, 226, 4, = 176, + 157, 228, 30, 255, 47, 225, 0, 16, 31, 16, 0, 72, 45, 233, = 4, + 176, 141, 226, 8, 0, 159, 229, 230, 255, 255, 235, 0, 0, 160, = 225, + 0, 136, 189, 232, 132, 0, 1, 0, 0, 16, 31, 16, 72, 101, = 108, + 108, 111, 32, 119, 111, 114, 108, 100, 33, 10, 0}; + +/* success if no crash or abort */ +static void hex_loader_test(void) +{ + unsigned int i; + unsigned char memory_content[BIN_SIZE]; + const unsigned int base_addr =3D 0x00010000; + + QTestState *s =3D qtest_startf( + "-M emcraft-sf2 -nographic -kernel ./tests/hex-loader-check-data/t= est.hex"); + + for (i =3D 0; i < BIN_SIZE; ++i) { + memory_content[i] =3D qtest_readb(s, base_addr + i); + g_assert_cmpuint(memory_content[i], =3D=3D, pre_store[i]); + } + qtest_quit(s); +} + +int main(int argc, char **argv) +{ + int ret; + + g_test_init(&argc, &argv, NULL); + + qtest_add_func("/tmp/hex_loader", hex_loader_test); + ret =3D g_test_run(); + + return ret; +} diff --git a/tests/hex-loader-check-data/test.hex b/tests/hex-loader-check-= data/test.hex new file mode 100644 index 0000000000..7e99b452f5 --- /dev/null +++ b/tests/hex-loader-check-data/test.hex @@ -0,0 +1,12 @@ +:020000040001F9 +:1000000004D09FE5160000EBFEFFFFEA9810010008 +:1000100004B02DE500B08DE20CD04DE208000BE5F8 +:10002000060000EA08301BE50020D3E52C309FE5F0 +:10003000002083E508301BE5013083E208300BE542 +:1000400008301BE50030D3E5000053E3F4FFFF1A4E +:100050000000A0E100D08BE204B09DE41EFF2FE180 +:1000600000101F1000482DE904B08DE208009FE544 +:10007000E6FFFFEB0000A0E10088BDE8840001007E +:1000800000101F1048656C6C6F20776F726C6421D4 +:020090000A0064 +:00000001FF --=20 2.17.1