Re: [Qemu-devel] [PATCH v1 3/3] raspi: Add "raspi3" machine type
Hi, On 02/15/2018 02:39 PM, Peter Maydell wrote: On 8 February 2018 at 05:50, Pekka Enbergwrote: This patch adds a "raspi3" machine type, which can now be selected as the machine to run on by users via the "-M" command line option to QEMU. The machine type does *not* ignore memory transaction failures so we likely need to add some dummy devices later when people run something more complicated than what I'm using for testing. Signed-off-by: Pekka Enberg --- hw/arm/raspi.c | 21 + 1 file changed, 21 insertions(+) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 66fe10e376..048ff23a51 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -187,3 +187,24 @@ static void raspi2_machine_init(MachineClass *mc) mc->ignore_memory_transaction_failures = true; }; DEFINE_MACHINE("raspi2", raspi2_machine_init) + +static void raspi3_init(MachineState *machine) +{ +raspi_init(machine, 3); +} + +static void raspi3_machine_init(MachineClass *mc) +{ +mc->desc = "Raspberry Pi 3"; +mc->init = raspi3_init; +mc->block_default_type = IF_SD; +mc->no_parallel = 1; +mc->no_floppy = 1; +mc->no_cdrom = 1; +mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a53"); +mc->max_cpus = BCM2836_NCPUS; +mc->min_cpus = BCM2836_NCPUS; +mc->default_cpus = BCM2836_NCPUS; +mc->default_ram_size = 1024 * 1024 * 1024; +} +DEFINE_MACHINE("raspi3", raspi3_machine_init) Hi. This patch breaks "make check", because it adds the raspi3 to the arm-softmmu (32-bit guest CPUs only) build, where the cortex-a53 CPU doesn't exist: e104462:xenial:qemu$ ./build/x86/arm-softmmu/qemu-system-arm -M raspi3 ** ERROR:/home/petmay01/linaro/qemu-from-laptop/qemu/qom/object.c:372:object_initialize_with_type: assertion failed: (type != NULL) Aborted (core dumped) The usual way we avoid this is that 64-bit only boards are in their own source file, which is only compiled if the right CONFIG_FOO is set by default-configs/aarch64-softmmu.mak. In this case splitting the 64-bit board into its own source file would be weird and awkward, so the simple thing is to guard the raspi3 bits with #ifdef TARGET_AARCH64. (You might think we could define a CONFIG_RASPI3 in aarch64-softmmu.mak and #ifdef on it, but for some reason we don't expose those CONFIG_* to C code, possibly just because we've never needed to in the past...) Since this was the only code change needed, I'm just going to make it and apply the patchset to target-arm.next, rather than ask you to do a respin. (There was also a stray space-at-end-of-line in patch 2 which checkpatch grumbles about; I'll fix that up too.) Oh, it would have helped if I had actually read the whole thread before sending out v2. If I understood correctly, you only applied the first two patches (sorry about that trailing whitespace!). You therefore can just pick patch 3 from the v2 as the first two patches are unchanged. Regards, - Pekka
Re: [Qemu-devel] [PATCH v1 1/3] bcm2836: Make CPU type configurable
On 02/15/2018 01:48 PM, Peter Maydell wrote: On 8 February 2018 at 05:50, Pekka Enbergwrote: This patch adds a "cpu-type" property to BCM2836 SoC in preparation for reusing the code for the Raspberry Pi 3, which has a different processor model. Signed-off-by: Pekka Enberg --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -135,6 +135,8 @@ static void raspi2_init(MachineState *machine) /* Setup the SOC */ object_property_add_const_link(OBJECT(>soc), "ram", OBJECT(>ram), _abort); +object_property_set_str(OBJECT(>soc), machine->cpu_type, "cpu-type", +_abort); object_property_set_int(OBJECT(>soc), smp_cpus, "enabled-cpus", _abort); object_property_set_int(OBJECT(>soc), 0xa21041, "board-rev", @@ -166,6 +168,7 @@ static void raspi2_machine_init(MachineClass *mc) mc->no_parallel = 1; mc->no_floppy = 1; mc->no_cdrom = 1; +mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"); mc->max_cpus = BCM2836_NCPUS; mc->min_cpus = BCM2836_NCPUS; mc->default_cpus = BCM2836_NCPUS; This change means that instead of ignoring the user's -cpu argument we'll now unconditionally accept it even if it's nonsense for this board. Neither behaviour is great. However, the patchset to allow boards to easily specify the valid set of CPU types is still in code review: https://lists.gnu.org/archive/html/qemu-devel/2018-02/msg00308.html so I'm happy to take this as-is, and we'll add the validity check when that patchset goes in. I wondered about that too, but I applied the "monkey see, monkey do" approach to your review comments of the previous attempt. :-) But indeed, I also think we can fix this later in the tree. - Pekka
[Qemu-devel] [PATCH v2 2/3] raspi: Raspberry Pi 3 support
This patch adds Raspberry Pi 3 support to hw/arm/raspi.c. The differences to Pi 2 are: - Firmware address - Board ID - Board revision The CPU is different too, but that's going to be configured as part of the machine default CPU when we introduce a new machine type. The patch was written from scratch by me but the logic is similar to Zoltán Baldaszti's previous work, which I used as a reference (with permission from the author): https://github.com/bztsrc/qemu-raspi3 Signed-off-by: Pekka Enberg--- hw/arm/raspi.c | 31 +-- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index c24a4a1b14..66fe10e376 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -5,6 +5,9 @@ * Rasperry Pi 2 emulation Copyright (c) 2015, Microsoft * Written by Andrew Baumann * + * Raspberry Pi 3 emulation Copyright (c) 2018 Zoltán Baldaszti + * Upstream code cleanup (c) 2018 Pekka Enberg + * * This code is licensed under the GNU GPLv2 and later. */ @@ -22,10 +25,11 @@ #define SMPBOOT_ADDR0x300 /* this should leave enough space for ATAGS */ #define MVBAR_ADDR 0x400 /* secure vectors */ #define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */ -#define FIRMWARE_ADDR 0x8000 /* Pi loads kernel.img here by default */ +#define FIRMWARE_ADDR_2 0x8000 /* Pi 2 loads kernel.img here by default */ +#define FIRMWARE_ADDR_3 0x8 /* Pi 3 loads kernel.img here by default */ /* Table of Linux board IDs for different Pi versions */ -static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43}; +static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44}; typedef struct RasPiState { BCM2836State soc; @@ -83,8 +87,8 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) binfo.secure_board_setup = true; binfo.secure_boot = true; -/* Pi2 requires SMP setup */ -if (version == 2) { +/* Pi2 and Pi3 requires SMP setup */ +if (version >= 2) { binfo.smp_loader_start = SMPBOOT_ADDR; binfo.write_secondary_boot = write_smpboot; binfo.secondary_cpu_reset_hook = reset_secondary; @@ -94,15 +98,16 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) * the normal Linux boot process */ if (machine->firmware) { +hwaddr firmware_addr = version == 3 ? FIRMWARE_ADDR_3 : FIRMWARE_ADDR_2; /* load the firmware image (typically kernel.img) */ -r = load_image_targphys(machine->firmware, FIRMWARE_ADDR, -ram_size - FIRMWARE_ADDR); +r = load_image_targphys(machine->firmware, firmware_addr, +ram_size - firmware_addr); if (r < 0) { error_report("Failed to load firmware from %s", machine->firmware); exit(1); } -binfo.entry = FIRMWARE_ADDR; +binfo.entry = firmware_addr; binfo.firmware_loaded = true; } else { binfo.kernel_filename = machine->kernel_filename; @@ -113,7 +118,7 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) arm_load_kernel(ARM_CPU(first_cpu), ); } -static void raspi2_init(MachineState *machine) +static void raspi_init(MachineState *machine, int version) { RasPiState *s = g_new0(RasPiState, 1); uint32_t vcram_size; @@ -139,7 +144,8 @@ static void raspi2_init(MachineState *machine) _abort); object_property_set_int(OBJECT(>soc), smp_cpus, "enabled-cpus", _abort); -object_property_set_int(OBJECT(>soc), 0xa21041, "board-rev", +int board_rev = version == 3 ? 0xa02082 : 0xa21041; +object_property_set_int(OBJECT(>soc), board_rev, "board-rev", _abort); object_property_set_bool(OBJECT(>soc), true, "realized", _abort); @@ -157,7 +163,12 @@ static void raspi2_init(MachineState *machine) vcram_size = object_property_get_uint(OBJECT(>soc), "vcram-size", _abort); -setup_boot(machine, 2, machine->ram_size - vcram_size); +setup_boot(machine, version, machine->ram_size - vcram_size); +} + +static void raspi2_init(MachineState *machine) +{ +raspi_init(machine, 2); } static void raspi2_machine_init(MachineClass *mc) -- 2.14.3
[Qemu-devel] [PATCH v2 3/3] raspi: Add "raspi3" machine type
This patch adds a "raspi3" machine type, which can now be selected as the machine to run on by users via the "-M" command line option to QEMU. The machine type does *not* ignore memory transaction failures so we likely need to add some dummy devices later when people run something more complicated than what I'm using for testing. Signed-off-by: Pekka Enberg--- hw/arm/raspi.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 66fe10e376..ff54f45e3e 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -187,3 +187,26 @@ static void raspi2_machine_init(MachineClass *mc) mc->ignore_memory_transaction_failures = true; }; DEFINE_MACHINE("raspi2", raspi2_machine_init) + +#ifdef TARGET_AARCH64 +static void raspi3_init(MachineState *machine) +{ +raspi_init(machine, 3); +} + +static void raspi3_machine_init(MachineClass *mc) +{ +mc->desc = "Raspberry Pi 3"; +mc->init = raspi3_init; +mc->block_default_type = IF_SD; +mc->no_parallel = 1; +mc->no_floppy = 1; +mc->no_cdrom = 1; +mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a53"); +mc->max_cpus = BCM2836_NCPUS; +mc->min_cpus = BCM2836_NCPUS; +mc->default_cpus = BCM2836_NCPUS; +mc->default_ram_size = 1024 * 1024 * 1024; +} +DEFINE_MACHINE("raspi3", raspi3_machine_init) +#endif -- 2.14.3
[Qemu-devel] [PATCH v2 1/3] bcm2836: Make CPU type configurable
This patch adds a "cpu-type" property to BCM2836 SoC in preparation for reusing the code for the Raspberry Pi 3, which has a different processor model. Signed-off-by: Pekka Enberg--- hw/arm/bcm2836.c | 17 + hw/arm/raspi.c | 3 +++ include/hw/arm/bcm2836.h | 1 + 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c index 8c43291112..40e8b25a46 100644 --- a/hw/arm/bcm2836.c +++ b/hw/arm/bcm2836.c @@ -26,14 +26,6 @@ static void bcm2836_init(Object *obj) { BCM2836State *s = BCM2836(obj); -int n; - -for (n = 0; n < BCM2836_NCPUS; n++) { -object_initialize(>cpus[n], sizeof(s->cpus[n]), - "cortex-a15-" TYPE_ARM_CPU); -object_property_add_child(obj, "cpu[*]", OBJECT(>cpus[n]), - _abort); -} object_initialize(>control, sizeof(s->control), TYPE_BCM2836_CONTROL); object_property_add_child(obj, "control", OBJECT(>control), NULL); @@ -59,6 +51,14 @@ static void bcm2836_realize(DeviceState *dev, Error **errp) /* common peripherals from bcm2835 */ +obj = OBJECT(dev); +for (n = 0; n < BCM2836_NCPUS; n++) { +object_initialize(>cpus[n], sizeof(s->cpus[n]), + s->cpu_type); +object_property_add_child(obj, "cpu[*]", OBJECT(>cpus[n]), + _abort); +} + obj = object_property_get_link(OBJECT(dev), "ram", ); if (obj == NULL) { error_setg(errp, "%s: required ram link not found: %s", @@ -150,6 +150,7 @@ static void bcm2836_realize(DeviceState *dev, Error **errp) } static Property bcm2836_props[] = { +DEFINE_PROP_STRING("cpu-type", BCM2836State, cpu_type), DEFINE_PROP_UINT32("enabled-cpus", BCM2836State, enabled_cpus, BCM2836_NCPUS), DEFINE_PROP_END_OF_LIST() }; diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index cd5fa8c3dc..c24a4a1b14 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -135,6 +135,8 @@ static void raspi2_init(MachineState *machine) /* Setup the SOC */ object_property_add_const_link(OBJECT(>soc), "ram", OBJECT(>ram), _abort); +object_property_set_str(OBJECT(>soc), machine->cpu_type, "cpu-type", +_abort); object_property_set_int(OBJECT(>soc), smp_cpus, "enabled-cpus", _abort); object_property_set_int(OBJECT(>soc), 0xa21041, "board-rev", @@ -166,6 +168,7 @@ static void raspi2_machine_init(MachineClass *mc) mc->no_parallel = 1; mc->no_floppy = 1; mc->no_cdrom = 1; +mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"); mc->max_cpus = BCM2836_NCPUS; mc->min_cpus = BCM2836_NCPUS; mc->default_cpus = BCM2836_NCPUS; diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h index 76de1996af..4758b4ae54 100644 --- a/include/hw/arm/bcm2836.h +++ b/include/hw/arm/bcm2836.h @@ -25,6 +25,7 @@ typedef struct BCM2836State { DeviceState parent_obj; /*< public >*/ +char *cpu_type; uint32_t enabled_cpus; ARMCPU cpus[BCM2836_NCPUS]; -- 2.14.3
[Qemu-devel] [PATCH v2 0/3] Raspberry Pi 3 support
This patch series adds support for Raspberry Pi 3 as a new machine model "raspi3", which is an extension of the "raspi2" model with the following differences: - Default CPU type is "cortex-a53" - Firmware is at address 0x8 - Board ID is 0xc44 and board revision is 0xa02082 The patches were written by me but I used Zoltán Baldaszti's previous work as a reference (with permission from the author): https://github.com/bztsrc/qemu-raspi3 Also available from: g...@github.com:penberg/qemu.git raspi3/v2 Changes from v1 to v2: - Wrap Raspberry Pi 3 machine definition with TARGET_AARCH64 (Peter Maydell) Pekka Enberg (3): bcm2836: Make CPU type configurable raspi: Raspberry Pi 3 support raspi: Add "raspi3" machine type hw/arm/bcm2836.c | 17 --- hw/arm/raspi.c | 57 +++- include/hw/arm/bcm2836.h | 1 + 3 files changed, 57 insertions(+), 18 deletions(-) -- 2.14.3
Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 0/3] Sam460ex emulation
On 15.02.2018 22:27, BALATON Zoltan wrote: > Remaining patches for Sam460ex emulation. The original cover letter > with more details is here: > > http://lists.nongnu.org/archive/html/qemu-ppc/2017-08/msg00112.html > > We'll need to also add binaries for firmware (customised u-boot > version) and dtb but I'm not sure how to submit those. For the dtb, I think you could simply provide a patch that adds the dts file to the pc-bios directory and another one that adds the dtb. Just like it is already done with pc-bios/bamboo.dts / pc-bios/bamboo.dtb. For u-boot, can you use the same upstream level as e500 ? I.e. check whether "git submodule status roms/u-boot" is fine for you? If that's ok, just do a "git submodule update roms/u-boot" and build uboot from that directory - you then can submit a binary patch with that file for pc-bios, too. In case you need another u-boot version, I think you've got to update the submodule to the newer upstream version first, and then also rebuild the e500 binary... Cumbersome, but that's necessary since we've got to ship the u-boot sources in the QEMU release tarballs, too, to be compliant with the GPL. Thomas
[Qemu-devel] [Bug 1331334] Re: driftfix=none and migration on Win7 guest causes time to go 10 times as fast
OK, thanks for checking again! So I'm closing this ticket now. ** Changed in: qemu Status: Incomplete => Fix Released -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1331334 Title: driftfix=none and migration on Win7 guest causes time to go 10 times as fast Status in QEMU: Fix Released Bug description: With -rtc base=localtime,clock=host,driftfix=none on a Win7 guest, stopping it with migration and then starting it again about 1 hour later makes the guest time go 10 times as fast as real time until Windows is rebooted. I have tried qith qemu-2.0.0 and the problem still exists there. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1331334/+subscriptions
Re: [Qemu-devel] [PULL 00/10] migration queue
On 15.02.2018 21:19, Dr. David Alan Gilbert wrote: > * Peter Maydell (peter.mayd...@linaro.org) wrote: >> On 14 February 2018 at 15:39, Dr. David Alan Gilbert (git) >>wrote: >>> From: "Dr. David Alan Gilbert" >>> >>> The following changes since commit bec9c64ef7be8063f1192608b83877bc5c9ea217: >>> >>> Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into >>> staging (2018-02-13 18:24:08 +) >>> >>> are available in the Git repository at: >>> >>> git://github.com/dagrh/qemu.git tags/pull-migration-20180214a >>> >>> for you to fetch changes up to 3e0c8050ebba3f55dc2d92b3790a3cfb80786d07: >>> >>> migration: pass MigrationState to migrate_init() (2018-02-14 10:37:09 >>> +) >>> >>> >>> Migration pull 20180214 >>> >>> Note that the 'Add test for migration to bad destination' displays >>> a 'Connection refused' during running, but still gives the correct exit >>> code and OK (It's checking that the source doesn't fail when >>> it can't connect, so that's the right error). >>> If it's particularly disliked that patch can be skipped individually. >>> >>> >> >> Hi. This fails 'make check' on aarch64 host: >> QTEST_QEMU_BINARY=hppa-softmmu/qemu-system-hppa >> QTEST_QEMU_IMG=qemu-img MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( >> ${RANDOM >> :-0} % 255 + 1))} gtester -k --verbose -m=quick tests/boot-serial-test >> tests/qmp-test tests/device-introspect-test test >> s/qom-test tests/test-hmp >> TEST: tests/boot-serial-test... (pid=2306) >> /hppa/boot-serial/hppa: ** >> ERROR:/home/pm215/qemu/tests/boot-serial-test.c:137:check_guest_output: >> assertion failed: (output_ok) >> FAIL >> GTester: last random seed: R02S43359b02a322915508b897be44a0e9c6 >> (pid=7220) >> FAIL: tests/boot-serial-test > > I can't obviously see a reason why it should in any way affect that > test; however I'll try and grab an aarch64 box tomorrow. For the records: It's a bug in the boot-serial tester. I've just sent a mail with a fix: "tests/boot-serial-test: Fix problem with timeout due to dropped characters". Thomas
[Qemu-devel] [PATCH] tests/boot-serial-test: Fix problem with timeout due to dropped characters
Commit 92b540dac9fc3a5 introduce a counter to handle the timeouts in a better way. But in case ccnt reaches 512, the current read character is ignored - and if that character is part of the string that we are looking for, the test fails to match the string. Almost all of the tests look for a string within the first 512 bytes of firmware output, so the problem never triggered there. But the hppa test that has been added recently looks for a longer string at the very end of a long output, thus there's a chance that we miss a character there so that the test fails unexpectedly. Fix it by *not* reading and dropping a character if the counter reaches 512. Fixes: 92b540dac9fc3a572c7342edd0b073000f5a6abf Signed-off-by: Thomas Huth--- @Peter: Since this fixes the problem with running "make check", could you maybe apply this directly to the master branch? Thanks, and sorry for the inconvenience! tests/boot-serial-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c index ea87a80..696f7a3 100644 --- a/tests/boot-serial-test.c +++ b/tests/boot-serial-test.c @@ -101,7 +101,7 @@ static void check_guest_output(const testdef_t *test, int fd) /* Poll serial output... Wait at most 60 seconds */ for (i = 0; i < 6000; ++i) { ccnt = 0; -while ((nbr = read(fd, , 1)) == 1 && ccnt++ < 512) { +while (ccnt++ < 512 && (nbr = read(fd, , 1)) == 1) { if (ch == test->expect[pos]) { pos += 1; if (test->expect[pos] == '\0') { -- 1.8.3.1
Re: [Qemu-devel] [PATCH qemu v7 2/4] vfio/pci: Relax DMA map errors for MMIO regions
On Wed, Feb 14, 2018 at 08:55:41AM -0700, Alex Williamson wrote: > On Wed, 14 Feb 2018 19:09:16 +1100 > Alexey Kardashevskiywrote: > > > On 14/02/18 12:33, David Gibson wrote: > > > On Tue, Feb 13, 2018 at 07:20:56PM +1100, Alexey Kardashevskiy wrote: > > >> On 13/02/18 16:41, David Gibson wrote: > > >>> On Tue, Feb 13, 2018 at 04:36:30PM +1100, David Gibson wrote: > > On Tue, Feb 13, 2018 at 12:15:52PM +1100, Alexey Kardashevskiy wrote: > > > On 13/02/18 03:06, Alex Williamson wrote: > > >> On Mon, 12 Feb 2018 18:05:54 +1100 > > >> Alexey Kardashevskiy wrote: > > >> > > >>> On 12/02/18 16:19, David Gibson wrote: > > On Fri, Feb 09, 2018 at 06:55:01PM +1100, Alexey Kardashevskiy > > wrote: > > > At the moment if vfio_memory_listener is registered in the system > > > memory > > > address space, it maps/unmaps every RAM memory region for DMA. > > > It expects system page size aligned memory sections so > > > vfio_dma_map > > > would not fail and so far this has been the case. A mapping > > > failure > > > would be fatal. A side effect of such behavior is that some MMIO > > > pages > > > would not be mapped silently. > > > > > > However we are going to change MSIX BAR handling so we will end > > > having > > > non-aligned sections in vfio_memory_listener (more details is in > > > the next patch) and vfio_dma_map will exit QEMU. > > > > > > In order to avoid fatal failures on what previously was not a > > > failure and > > > was just silently ignored, this checks the section alignment to > > > the smallest supported IOMMU page size and prints an error if not > > > aligned; > > > it also prints an error if vfio_dma_map failed despite the page > > > size check. > > > Both errors are not fatal; only MMIO RAM regions are checked > > > (aka "RAM device" regions). > > > > > > If the amount of errors printed is overwhelming, the MSIX > > > relocation > > > could be used to avoid excessive error output. > > > > > > This is unlikely to cause any behavioral change. > > > > > > Signed-off-by: Alexey Kardashevskiy > > > > There are some relatively superficial problems noted below. > > > > But more fundamentally, this feels like it's extending an existing > > hack past the point of usefulness. > > > > The explicit check for is_ram_device() here has always bothered me > > - > > it's not like a real bus bridge magically knows whether a target > > address maps to RAM or not. > > > > What I think is really going on is that even for systems without an > > IOMMU, it's not really true to say that the PCI address space maps > > directly onto address_space_memory. Instead, there's a large, but > > much less than 2^64 sized, "upstream window" at address 0 on the > > PCI > > bus, which is identity mapped to the system bus. Details will vary > > with the system, but in practice we expect nothing but RAM to be in > > that window. Addresses not within that window won't be mapped to > > the > > system bus but will just be broadcast on the PCI bus and might be > > picked up as a p2p transaction. > > >>> > > >>> Currently this p2p works only via the IOMMU, direct p2p is not > > >>> possible as > > >>> the guest needs to know physical MMIO addresses to make p2p work > > >>> and it > > >>> does not. > > >> > > >> /me points to the Direct Translated P2P section of the ACS spec, > > >> though > > >> it's as prone to spoofing by the device as ATS. In any case, p2p > > >> reflected from the IOMMU is still p2p and offloads the CPU even if > > >> bandwidth suffers vs bare metal depending on if the data doubles back > > >> over any links. Thanks, > > > > > > Sure, I was just saying that p2p via IOMMU won't be as simple as > > > broadcast > > > on the PCI bus, IOMMU needs to be programmed in advance to make this > > > work, > > > and current that broadcast won't work for the passed through devices. > > > > > > > Well, sure, p2p in a guest with passthrough devices clearly needs to > > be translated through the IOMMU (and p2p from a passthrough to an > > emulated device is essentially impossible). > > > > But.. what does that have to do with this code. This is the memory > > area watcher, looking for memory regions being mapped directly into > > the PCI space. NOT IOMMU regions, since those are handled separately > > by
Re: [Qemu-devel] [PULL 2/3] tests: Enable boot-serial-test for hppa
On 16.02.2018 00:55, Philippe Mathieu-Daudé wrote: > On 02/04/2018 07:23 PM, Richard Henderson wrote: >> Reviewed-by: Thomas Huth>> Signed-off-by: Richard Henderson >> --- >> tests/boot-serial-test.c | 1 + >> tests/Makefile.include | 2 ++ >> 2 files changed, 3 insertions(+) >> >> diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c >> index 418c5b92dc..ea87a80be7 100644 >> --- a/tests/boot-serial-test.c >> +++ b/tests/boot-serial-test.c >> @@ -87,6 +87,7 @@ static testdef_t tests[] = { >>sizeof(kernel_plml605), kernel_plml605 }, >> { "moxie", "moxiesim", "", "TT", sizeof(bios_moxiesim), 0, >> bios_moxiesim }, >> { "arm", "raspi2", "", "TT", sizeof(bios_raspi2), 0, bios_raspi2 }, >> +{ "hppa", "hppa", "", "SeaBIOS wants SYSTEM HALT" }, >> >> { NULL } >> }; >> diff --git a/tests/Makefile.include b/tests/Makefile.include >> index ca82e0c0cc..83def6994c 100644 >> --- a/tests/Makefile.include >> +++ b/tests/Makefile.include >> @@ -299,6 +299,8 @@ gcov-files-x86_64-y = $(subst >> i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y) >> >> check-qtest-alpha-y = tests/boot-serial-test$(EXESUF) >> >> +check-qtest-hppa-y = tests/boot-serial-test$(EXESUF) >> + >> check-qtest-m68k-y = tests/boot-serial-test$(EXESUF) >> >> check-qtest-microblaze-y = tests/boot-serial-test$(EXESUF) >> > > I got this failure in 2 different branches: > > GTESTER check-qtest-hppa > ** > ERROR:tests/boot-serial-test.c:137:check_guest_output: assertion failed: > (output_ok) > GTester: last random seed: R02S55e7df877597841c1b3b62962e410123 > make: *** [check-qtest-hppa] Error 1 > make: *** Waiting for unfinished jobs Uh, oh, I actually can also reproduce this on my laptop when putting a lot of load on the system (make -j10 in another window). I think I know what the problem is: I've introduced a counter in commit 92b540dac9fc3a5 to handle the timeouts in a better way. But in case ccnt reaches 512, the current read character is ignored - and if that character is part of the string that we are looking for, the test fails to match the string. Almost all of the tests look for a string within the first 512 bytes of firmware output, so the problem never triggered there. But the hppa test looks for a string at the very end of a long output, so that's likely the reason that the problem triggered here. The fix is pretty simple: diff a/tests/boot-serial-test.c b/tests/boot-serial-test.c --- a/tests/boot-serial-test.c +++ b/tests/boot-serial-test.c @@ -117,7 +117,7 @@ static void check_guest_output(const testdef_t *test, int fd) /* Poll serial output... Wait at most 60 seconds */ for (i = 0; i < 6000; ++i) { ccnt = 0; -while ((nbr = read(fd, , 1)) == 1 && ccnt++ < 512) { +while (ccnt++ < 512 && (nbr = read(fd, , 1)) == 1) { if (ch == test->expect[pos]) { pos += 1; if (test->expect[pos] == '\0') { I'll submit this as a proper patch... Thomas
Re: [Qemu-devel] [QEMU-PPC] [PATCH V4 2/2] ppc/spapr-caps: For pseries-2.12 change spapr-cap defaults
On Fri, Feb 16, 2018 at 01:33:28PM +1100, Suraj Jitindar Singh wrote: > For the pseries-2.12 machine type, make the spapr-caps SPAPR_CAP_CFPC > and SPAPR_CAP_SBBC default to workaround. Thus if the host is capable > the guest will be able to take advantage of these workarounds by default. > Otherwise if the host doesn't have these capabilities qemu will fail to > start and they will have to be explicitly disabled on the command line > with: > -machine pseries,cap-cfpc=broken,cap-sbbc=broken > > Signed-off-by: Suraj Jitindar SinghI've decided to hold off on this for a little bit longer for two reasons: 1) I realised how badly it will break things for machines which don't yet updated firmware (both POWER8 and POWER9) which includes a very large proportion of test machines. 2) I've looked more closely at what x86 has done. For themthe mitigations are controlled by CPU options, not machine level, but the "plain" types are still the unmitigated variants, with variants for the versions with microcode updated with mitigations. See https://www.qemu.org/2018/02/14/qemu-2-11-1-and-spectre-update/ > > --- > > V2 -> V3: > - Set caps to workaround in the class default rather than the >pseries-2.12 initialiser. > --- > hw/ppc/spapr.c | 6 -- > hw/ppc/spapr_caps.c | 10 ++ > 2 files changed, 14 insertions(+), 2 deletions(-) > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > index 83c9d66dd5..69f59aabf1 100644 > --- a/hw/ppc/spapr.c > +++ b/hw/ppc/spapr.c > @@ -3915,8 +3915,8 @@ static void spapr_machine_class_init(ObjectClass *oc, > void *data) > smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF; > smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON; > smc->default_caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_ON; > -smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN; > -smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN; > +smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND; > +smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND; > smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN; > spapr_caps_add_properties(smc, _abort); > } > @@ -4000,6 +4000,8 @@ static void > spapr_machine_2_11_class_options(MachineClass *mc) > > spapr_machine_2_12_class_options(mc); > smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_ON; > +smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN; > +smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN; > SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_11); > } > > diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c > index 99a4b71d19..7b0ecb3eca 100644 > --- a/hw/ppc/spapr_caps.c > +++ b/hw/ppc/spapr_caps.c > @@ -283,11 +283,21 @@ static sPAPRCapabilities > default_caps_with_cpu(sPAPRMachineState *spapr, > > caps = smc->default_caps; > > +if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, > + 0, spapr->max_compat_pvr)) { > +caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN; > +} > + > if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_07, >0, spapr->max_compat_pvr)) { > caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF; > } > > +if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06_PLUS, > + 0, spapr->max_compat_pvr)) { > +caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN; > +} > + > if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06, >0, spapr->max_compat_pvr)) { > caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_OFF; -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
Re: [Qemu-devel] [PATCH v2 3/3] ppc: Add aCube Sam460ex board
On Thu, Feb 15, 2018 at 10:27:06PM +0100, BALATON Zoltan wrote: > Add emulation of aCube Sam460ex board based on AMCC 460EX embedded SoC. > This is not a complete implementation yet with a lot of components > still missing but enough for the U-Boot firmware to start and to boot > a Linux kernel or AROS. > > Signed-off-by: François Revol> Signed-off-by: BALATON Zoltan > --- > > v2: > - Rebased to latest changes on master > - Replaced printfs with error_report This has a conflict in hw/ppc/Makefile.objs. Looks like it was based on some other patch that added ppc440_pcix.o. That's not there upstream. > > default-configs/ppc-softmmu.mak| 2 + > default-configs/ppcemb-softmmu.mak | 1 + > hw/ppc/Makefile.objs | 3 +- > hw/ppc/sam460ex.c | 603 > + > 4 files changed, 608 insertions(+), 1 deletion(-) > create mode 100644 hw/ppc/sam460ex.c > > diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak > index 76e29cf..4d7be45 100644 > --- a/default-configs/ppc-softmmu.mak > +++ b/default-configs/ppc-softmmu.mak > @@ -21,6 +21,8 @@ CONFIG_E500=y > CONFIG_OPENPIC_KVM=$(call land,$(CONFIG_E500),$(CONFIG_KVM)) > CONFIG_PLATFORM_BUS=y > CONFIG_ETSEC=y > +# For Sam460ex > +CONFIG_USB_EHCI_SYSBUS=y > CONFIG_SM501=y > CONFIG_IDE_SII3112=y > CONFIG_I2C=y > diff --git a/default-configs/ppcemb-softmmu.mak > b/default-configs/ppcemb-softmmu.mak > index bc5e1b3..67d18b2 100644 > --- a/default-configs/ppcemb-softmmu.mak > +++ b/default-configs/ppcemb-softmmu.mak > @@ -15,6 +15,7 @@ CONFIG_PTIMER=y > CONFIG_I8259=y > CONFIG_XILINX=y > CONFIG_XILINX_ETHLITE=y > +CONFIG_USB_EHCI_SYSBUS=y > CONFIG_SM501=y > CONFIG_IDE_SII3112=y > CONFIG_I2C=y > diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs > index bddc742..86d82a6 100644 > --- a/hw/ppc/Makefile.objs > +++ b/hw/ppc/Makefile.objs > @@ -13,7 +13,8 @@ endif > obj-$(CONFIG_PSERIES) += spapr_rtas_ddw.o > # PowerPC 4xx boards > obj-y += ppc4xx_devs.o ppc405_uc.o > -obj-$(CONFIG_PPC4XX) += ppc4xx_pci.o ppc405_boards.o ppc440_bamboo.o > ppc440_pcix.o > +obj-$(CONFIG_PPC4XX) += ppc4xx_pci.o ppc405_boards.o > +obj-$(CONFIG_PPC4XX) += ppc440_bamboo.o ppc440_pcix.o ppc440_uc.o sam460ex.o > # PReP > obj-$(CONFIG_PREP) += prep.o > obj-$(CONFIG_PREP) += prep_systemio.o > diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c > new file mode 100644 > index 000..ff99cf9 > --- /dev/null > +++ b/hw/ppc/sam460ex.c > @@ -0,0 +1,603 @@ > +/* > + * QEMU aCube Sam460ex board emulation > + * > + * Copyright (c) 2012 François Revol > + * Copyright (c) 2016-2018 BALATON Zoltan > + * > + * This file is derived from hw/ppc440_bamboo.c, > + * the copyright for that material belongs to the original owners. > + * > + * This work is licensed under the GNU GPL license version 2 or later. > + * > + */ > + > +#include "qemu/osdep.h" > +#include "qemu-common.h" > +#include "qemu/cutils.h" > +#include "qemu/error-report.h" > +#include "qapi/error.h" > +#include "hw/hw.h" > +#include "sysemu/blockdev.h" > +#include "hw/boards.h" > +#include "sysemu/kvm.h" > +#include "kvm_ppc.h" > +#include "sysemu/device_tree.h" > +#include "sysemu/block-backend.h" > +#include "hw/loader.h" > +#include "elf.h" > +#include "exec/address-spaces.h" > +#include "exec/memory.h" > +#include "hw/ppc/ppc440.h" > +#include "hw/ppc/ppc405.h" > +#include "hw/block/flash.h" > +#include "sysemu/sysemu.h" > +#include "sysemu/qtest.h" > +#include "hw/sysbus.h" > +#include "hw/char/serial.h" > +#include "hw/i2c/ppc4xx_i2c.h" > +#include "hw/i2c/smbus.h" > +#include "hw/usb/hcd-ehci.h" > + > +#define BINARY_DEVICE_TREE_FILE "sam460ex.dtb" > +#define UBOOT_FILENAME "u-boot-sam460-20100605.bin" > +/* to extract the official U-Boot bin from the updater: */ > +/* dd bs=1 skip=$(($(stat -c '%s' updater/updater-460) - 0x8)) \ > + if=updater/updater-460 of=u-boot-sam460-20100605.bin */ > + > +/* from Sam460 U-Boot include/configs/Sam460ex.h */ > +#define FLASH_BASE 0xfff0 > +#define FLASH_BASE_H 0x4 > +#define FLASH_SIZE (1 << 20) > +#define UBOOT_LOAD_BASE0xfff8 > +#define UBOOT_SIZE 0x0008 > +#define UBOOT_ENTRY0xfffc > + > +/* from U-Boot */ > +#define EPAPR_MAGIC (0x45504150) > +#define KERNEL_ADDR 0x100 > +#define FDT_ADDR 0x180 > +#define RAMDISK_ADDR 0x190 > + > +/* Sam460ex IRQ MAP: > + IRQ0 = ETH_INT > + IRQ1 = FPGA_INT > + IRQ2 = PCI_INT (PCIA, PCIB, PCIC, PCIB) > + IRQ3 = FPGA_INT2 > + IRQ11 = RTC_INT > + IRQ12 = SM502_INT > +*/ > + > +#define SDRAM_NR_BANKS 4 > + > +/* FIXME: See u-boot.git 8ac41e, also fix in ppc440_uc.c */ > +static const unsigned int ppc460ex_sdram_bank_sizes[] = { > +1024 << 20, 512 << 20, 256 << 20, 128 << 20, 64 << 20, 32 << 20, 0 > +}; > + > +struct boot_info { > +uint32_t dt_base; > +
[Qemu-devel] [PATCH 2/2] target/sh4: convert to TranslatorOps
This was fairly straightforward since it had already been converted to DisasContextBase; just had to add TARGET_TOO_MANY to the switch in tb_stop. Signed-off-by: Emilio G. Cota--- target/sh4/translate.c | 175 + 1 file changed, 90 insertions(+), 85 deletions(-) diff --git a/target/sh4/translate.c b/target/sh4/translate.c index 012156b..5a2274f 100644 --- a/target/sh4/translate.c +++ b/target/sh4/translate.c @@ -2258,126 +2258,131 @@ static int decode_gusa(DisasContext *ctx, CPUSH4State *env, int *pmax_insns) } #endif -void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb) +static int sh4_tr_init_disas_context(DisasContextBase *dcbase, + CPUState *cs, int max_insns) { +DisasContext *ctx = container_of(dcbase, DisasContext, base); CPUSH4State *env = cs->env_ptr; -DisasContext ctx; -target_ulong pc_start; -int num_insns; -int max_insns; - -pc_start = tb->pc; -ctx.base.pc_next = pc_start; -ctx.tbflags = (uint32_t)tb->flags; -ctx.envflags = tb->flags & TB_FLAG_ENVFLAGS_MASK; -ctx.base.is_jmp = DISAS_NEXT; -ctx.memidx = (ctx.tbflags & (1u << SR_MD)) == 0 ? 1 : 0; +int bound; + +ctx->tbflags = (uint32_t)ctx->base.tb->flags; +ctx->envflags = ctx->base.tb->flags & TB_FLAG_ENVFLAGS_MASK; +ctx->memidx = (ctx->tbflags & (1u << SR_MD)) == 0 ? 1 : 0; /* We don't know if the delayed pc came from a dynamic or static branch, so assume it is a dynamic branch. */ -ctx.delayed_pc = -1; /* use delayed pc from env pointer */ -ctx.base.tb = tb; -ctx.base.singlestep_enabled = cs->singlestep_enabled; -ctx.features = env->features; -ctx.has_movcal = (ctx.tbflags & TB_FLAG_PENDING_MOVCA); -ctx.gbank = ((ctx.tbflags & (1 << SR_MD)) && - (ctx.tbflags & (1 << SR_RB))) * 0x10; -ctx.fbank = ctx.tbflags & FPSCR_FR ? 0x10 : 0; - -max_insns = tb_cflags(tb) & CF_COUNT_MASK; -if (max_insns == 0) { -max_insns = CF_COUNT_MASK; -} -max_insns = MIN(max_insns, TCG_MAX_INSNS); +ctx->delayed_pc = -1; /* use delayed pc from env pointer */ +ctx->features = env->features; +ctx->has_movcal = (ctx->tbflags & TB_FLAG_PENDING_MOVCA); +ctx->gbank = ((ctx->tbflags & (1 << SR_MD)) && + (ctx->tbflags & (1 << SR_RB))) * 0x10; +ctx->fbank = ctx->tbflags & FPSCR_FR ? 0x10 : 0; /* Since the ISA is fixed-width, we can bound by the number of instructions remaining on the page. */ -num_insns = -(ctx.base.pc_next | TARGET_PAGE_MASK) / 2; -max_insns = MIN(max_insns, num_insns); - -/* Single stepping means just that. */ -if (ctx.base.singlestep_enabled || singlestep) { -max_insns = 1; -} - -gen_tb_start(tb); -num_insns = 0; +bound = -(ctx->base.pc_next | TARGET_PAGE_MASK) / 2; +max_insns = MIN(max_insns, bound); +return max_insns; +} +static int sh4_tr_tb_start(DisasContextBase *dcbase, CPUState *cs, + int max_insns) +{ #ifdef CONFIG_USER_ONLY -if (ctx.tbflags & GUSA_MASK) { -num_insns = decode_gusa(, env, _insns); +DisasContext *ctx = container_of(dcbase, DisasContext, base); +CPUSH4State *env = cs->env_ptr; + +if (ctx->tbflags & GUSA_MASK) { +ctx->base.num_insns = decode_gusa(ctx, env, _insns); } #endif +return max_insns; +} -while (ctx.base.is_jmp == DISAS_NEXT - && num_insns < max_insns - && !tcg_op_buf_full()) { -tcg_gen_insn_start(ctx.base.pc_next, ctx.envflags); -num_insns++; +static void sh4_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) +{ +DisasContext *ctx = container_of(dcbase, DisasContext, base); -if (unlikely(cpu_breakpoint_test(cs, ctx.base.pc_next, BP_ANY))) { -/* We have hit a breakpoint - make sure PC is up-to-date */ -gen_save_cpu_state(, true); -gen_helper_debug(cpu_env); -ctx.base.is_jmp = DISAS_NORETURN; -/* The address covered by the breakpoint must be included in - [tb->pc, tb->pc + tb->size) in order to for it to be - properly cleared -- thus we increment the PC here so that - the logic setting tb->size below does the right thing. */ -ctx.base.pc_next += 2; -break; -} +tcg_gen_insn_start(ctx->base.pc_next, ctx->envflags); +} -if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) { -gen_io_start(); -} +static bool sh4_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, +const CPUBreakpoint *bp) +{ +DisasContext *ctx = container_of(dcbase, DisasContext, base); -ctx.opcode = cpu_lduw_code(env, ctx.base.pc_next); - decode_opc(); -ctx.base.pc_next += 2; -} -if (tb_cflags(tb) & CF_LAST_IO) { -
Re: [Qemu-devel] [PATCH v2 1/3] ppc4xx: Add device models found in PPC440 core SoCs
On Thu, Feb 15, 2018 at 10:27:06PM +0100, BALATON Zoltan wrote: > These devices are found in newer SoCs based on 440 core e.g. the 460EX > (http://www.embeddeddeveloper.com/assets/processors/amcc/datasheets/ > PP460EX_DS2063.pdf) > > Signed-off-by: BALATON ZoltanApplied, thanks. > --- > > v2: > - Rebased to latest changes on master > - Removed printfs > > hw/ppc/ppc440.h| 26 + > hw/ppc/ppc440_uc.c | 1159 > > include/hw/pci/pcie_host.h |2 +- > 3 files changed, 1186 insertions(+), 1 deletion(-) > create mode 100644 hw/ppc/ppc440.h > create mode 100644 hw/ppc/ppc440_uc.c > > diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h > new file mode 100644 > index 000..ad27db1 > --- /dev/null > +++ b/hw/ppc/ppc440.h > @@ -0,0 +1,26 @@ > +/* > + * QEMU PowerPC 440 shared definitions > + * > + * Copyright (c) 2012 François Revol > + * Copyright (c) 2016-2018 BALATON Zoltan > + * > + * This work is licensed under the GNU GPL license version 2 or later. > + * > + */ > + > +#ifndef PPC440_H > +#define PPC440_H > + > +#include "hw/ppc/ppc.h" > + > +void ppc4xx_l2sram_init(CPUPPCState *env); > +void ppc4xx_cpr_init(CPUPPCState *env); > +void ppc4xx_sdr_init(CPUPPCState *env); > +void ppc440_sdram_init(CPUPPCState *env, int nbanks, > + MemoryRegion *ram_memories, > + hwaddr *ram_bases, hwaddr *ram_sizes, > + int do_init); > +void ppc4xx_ahb_init(CPUPPCState *env); > +void ppc460ex_pcie_init(CPUPPCState *env); > + > +#endif /* PPC440_H */ > diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c > new file mode 100644 > index 000..4e2523a > --- /dev/null > +++ b/hw/ppc/ppc440_uc.c > @@ -0,0 +1,1159 @@ > +/* > + * QEMU PowerPC 440 embedded processors emulation > + * > + * Copyright (c) 2012 François Revol > + * Copyright (c) 2016-2018 BALATON Zoltan > + * > + * This work is licensed under the GNU GPL license version 2 or later. > + * > + */ > + > +#include "qemu/osdep.h" > +#include "qemu-common.h" > +#include "qemu/cutils.h" > +#include "qemu/error-report.h" > +#include "qapi/error.h" > +#include "cpu.h" > +#include "hw/hw.h" > +#include "exec/address-spaces.h" > +#include "exec/memory.h" > +#include "hw/ppc/ppc.h" > +#include "hw/pci/pci.h" > +#include "sysemu/block-backend.h" > +#include "hw/ppc/ppc440.h" > + > +/*/ > +/* L2 Cache as SRAM */ > +/* FIXME:fix names */ > +enum { > +DCR_L2CACHE_BASE = 0x30, > +DCR_L2CACHE_CFG = DCR_L2CACHE_BASE, > +DCR_L2CACHE_CMD, > +DCR_L2CACHE_ADDR, > +DCR_L2CACHE_DATA, > +DCR_L2CACHE_STAT, > +DCR_L2CACHE_CVER, > +DCR_L2CACHE_SNP0, > +DCR_L2CACHE_SNP1, > +DCR_L2CACHE_END = DCR_L2CACHE_SNP1, > +}; > + > +/* base is 460ex-specific, cf. U-Boot, ppc4xx-isram.h */ > +enum { > +DCR_ISRAM0_BASE = 0x20, > +DCR_ISRAM0_SB0CR = DCR_ISRAM0_BASE, > +DCR_ISRAM0_SB1CR, > +DCR_ISRAM0_SB2CR, > +DCR_ISRAM0_SB3CR, > +DCR_ISRAM0_BEAR, > +DCR_ISRAM0_BESR0, > +DCR_ISRAM0_BESR1, > +DCR_ISRAM0_PMEG, > +DCR_ISRAM0_CID, > +DCR_ISRAM0_REVID, > +DCR_ISRAM0_DPC, > +DCR_ISRAM0_END= DCR_ISRAM0_DPC > +}; > + > +enum { > +DCR_ISRAM1_BASE = 0xb0, > +DCR_ISRAM1_SB0CR = DCR_ISRAM1_BASE, > +/* single bank */ > +DCR_ISRAM1_BEAR = DCR_ISRAM1_BASE + 0x04, > +DCR_ISRAM1_BESR0, > +DCR_ISRAM1_BESR1, > +DCR_ISRAM1_PMEG, > +DCR_ISRAM1_CID, > +DCR_ISRAM1_REVID, > +DCR_ISRAM1_DPC, > +DCR_ISRAM1_END= DCR_ISRAM1_DPC > +}; > + > +typedef struct ppc4xx_l2sram_t { > +MemoryRegion bank[4]; > +uint32_t l2cache[8]; > +uint32_t isram0[11]; > +} ppc4xx_l2sram_t; > + > +#ifdef MAP_L2SRAM > +static void l2sram_update_mappings(ppc4xx_l2sram_t *l2sram, > + uint32_t isarc, uint32_t isacntl, > + uint32_t dsarc, uint32_t dsacntl) > +{ > +if (l2sram->isarc != isarc || > +(l2sram->isacntl & 0x8000) != (isacntl & 0x8000)) { > +if (l2sram->isacntl & 0x8000) { > +/* Unmap previously assigned memory region */ > +memory_region_del_subregion(get_system_memory(), > +>isarc_ram); > +} > +if (isacntl & 0x8000) { > +/* Map new instruction memory region */ > +memory_region_add_subregion(get_system_memory(), isarc, > +>isarc_ram); > +} > +} > +if (l2sram->dsarc != dsarc || > +(l2sram->dsacntl & 0x8000) != (dsacntl & 0x8000)) { > +if (l2sram->dsacntl & 0x8000) { > +/* Beware not to unmap the region we just mapped */ > +if (!(isacntl & 0x8000) || l2sram->dsarc != isarc) { > +/* Unmap previously assigned memory region */ > +
[Qemu-devel] [PATCH 1/2] translator: pass max_insns to tb_start
sh4 will need it. Signed-off-by: Emilio G. Cota--- accel/tcg/translator.c | 2 +- include/exec/translator.h | 3 ++- target/alpha/translate.c | 3 ++- target/arm/translate-a64.c | 4 +++- target/arm/translate.c | 4 +++- target/hppa/translate.c| 4 +++- target/i386/translate.c| 3 ++- 7 files changed, 16 insertions(+), 7 deletions(-) diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c index 23c6602..4ab6f8d 100644 --- a/accel/tcg/translator.c +++ b/accel/tcg/translator.c @@ -64,7 +64,7 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db, /* Start translating. */ gen_tb_start(db->tb); -ops->tb_start(db, cpu); +max_insns = ops->tb_start(db, cpu, max_insns); tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */ while (true) { diff --git a/include/exec/translator.h b/include/exec/translator.h index e2dc2a0..0182ada 100644 --- a/include/exec/translator.h +++ b/include/exec/translator.h @@ -81,6 +81,7 @@ typedef struct DisasContextBase { * @tb_start: * Emit any code required before the start of the main loop, * after the generic gen_tb_start(). + * Return max_insns, modified if necessary. * * @insn_start: * Emit the tcg_gen_insn_start opcode. @@ -108,7 +109,7 @@ typedef struct DisasContextBase { typedef struct TranslatorOps { int (*init_disas_context)(DisasContextBase *db, CPUState *cpu, int max_insns); -void (*tb_start)(DisasContextBase *db, CPUState *cpu); +int (*tb_start)(DisasContextBase *db, CPUState *cpu, int max_insns); void (*insn_start)(DisasContextBase *db, CPUState *cpu); bool (*breakpoint_check)(DisasContextBase *db, CPUState *cpu, const CPUBreakpoint *bp); diff --git a/target/alpha/translate.c b/target/alpha/translate.c index 73a1b5e..b603dbd 100644 --- a/target/alpha/translate.c +++ b/target/alpha/translate.c @@ -2963,8 +2963,9 @@ static int alpha_tr_init_disas_context(DisasContextBase *dcbase, return MIN(max_insns, bound); } -static void alpha_tr_tb_start(DisasContextBase *db, CPUState *cpu) +static int alpha_tr_tb_start(DisasContextBase *db, CPUState *cpu, int max_insns) { +return max_insns; } static void alpha_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 1c88539..7aa47ee 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -12080,9 +12080,11 @@ static int aarch64_tr_init_disas_context(DisasContextBase *dcbase, return max_insns; } -static void aarch64_tr_tb_start(DisasContextBase *db, CPUState *cpu) +static int aarch64_tr_tb_start(DisasContextBase *db, CPUState *cpu, + int max_insns) { tcg_clear_temp_count(); +return max_insns; } static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) diff --git a/target/arm/translate.c b/target/arm/translate.c index 1270022..bdee04e 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -12060,7 +12060,8 @@ static int arm_tr_init_disas_context(DisasContextBase *dcbase, return max_insns; } -static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu) +static int arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu, + int max_insns) { DisasContext *dc = container_of(dcbase, DisasContext, base); @@ -12102,6 +12103,7 @@ static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu) store_cpu_field(tmp, condexec_bits); } tcg_clear_temp_count(); +return max_insns; } static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) diff --git a/target/hppa/translate.c b/target/hppa/translate.c index b4b74a8..c816ad1 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -4726,7 +4726,8 @@ static int hppa_tr_init_disas_context(DisasContextBase *dcbase, return bound; } -static void hppa_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) +static int hppa_tr_tb_start(DisasContextBase *dcbase, CPUState *cs, +int max_insns) { DisasContext *ctx = container_of(dcbase, DisasContext, base); @@ -4738,6 +4739,7 @@ static void hppa_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) ctx->psw_n_nonzero = true; } ctx->null_lab = NULL; +return max_insns; } static void hppa_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) diff --git a/target/i386/translate.c b/target/i386/translate.c index 0135415..7527e8d 100644 --- a/target/i386/translate.c +++ b/target/i386/translate.c @@ -8472,8 +8472,9 @@ static int i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu, return max_insns; } -static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu) +static int i386_tr_tb_start(DisasContextBase *db, CPUState *cpu, int max_insns) { +return
[Qemu-devel] [PATCH 0/2] target/sh4: translator loop conversion
Tested on Aurelien's debian sh4 image. There's a twist in this conversion in that max_insns might be modified by .tb_start; this is what patch 1 introduces. Note that I've sent patches for converting other targets to the translation loop; those have not yet hit master so in patch 1 I am ignoring the corresponding targets. Thanks, Emilio
[Qemu-devel] [Bug 1331334] Re: driftfix=none and migration on Win7 guest causes time to go 10 times as fast
I am unable to reproduce this with qemu 2.11.0 -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1331334 Title: driftfix=none and migration on Win7 guest causes time to go 10 times as fast Status in QEMU: Incomplete Bug description: With -rtc base=localtime,clock=host,driftfix=none on a Win7 guest, stopping it with migration and then starting it again about 1 hour later makes the guest time go 10 times as fast as real time until Windows is rebooted. I have tried qith qemu-2.0.0 and the problem still exists there. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1331334/+subscriptions
Re: [Qemu-devel] [RFC PATCH] capstone: fix building using system package
What is interesting with this patch, is that, forcing use of system capstone, Travis builds ran much faster; longest build took 40min: https://travis-ci.org/philmd/qemu/builds/341979248 This revealed (without profiling yet) that compiling the capstone C++ takes some time... mingw32@i7-4600U# time make subdir-capstone CC cs.o CC utils.o CC SStream.o CC MCInstrDesc.o CC MCRegisterInfo.o CC arch/ARM/ARMDisassembler.o CC arch/ARM/ARMInstPrinter.o CC arch/ARM/ARMMapping.o CC arch/ARM/ARMModule.o CC arch/AArch64/AArch64BaseInfo.o CC arch/AArch64/AArch64Disassembler.o CC arch/AArch64/AArch64InstPrinter.o CC arch/AArch64/AArch64Mapping.o CC arch/AArch64/AArch64Module.o CC arch/Mips/MipsDisassembler.o CC arch/Mips/MipsInstPrinter.o CC arch/Mips/MipsMapping.o CC arch/Mips/MipsModule.o CC arch/PowerPC/PPCDisassembler.o CC arch/PowerPC/PPCInstPrinter.o CC arch/PowerPC/PPCMapping.o CC arch/PowerPC/PPCModule.o CC arch/Sparc/SparcDisassembler.o CC arch/Sparc/SparcInstPrinter.o CC arch/Sparc/SparcMapping.o CC arch/Sparc/SparcModule.o CC arch/SystemZ/SystemZDisassembler.o CC arch/SystemZ/SystemZInstPrinter.o CC arch/SystemZ/SystemZMapping.o CC arch/SystemZ/SystemZModule.o CC arch/SystemZ/SystemZMCTargetDesc.o CC arch/X86/X86DisassemblerDecoder.o CC arch/X86/X86Disassembler.o CC arch/X86/X86IntelInstPrinter.o CC arch/X86/X86ATTInstPrinter.o CC arch/X86/X86Mapping.o CC arch/X86/X86Module.o CC arch/XCore/XCoreDisassembler.o CC arch/XCore/XCoreInstPrinter.o CC arch/XCore/XCoreMapping.o CC arch/XCore/XCoreModule.o CC MCInst.o AR capstone.lib i686-w64-mingw32.shared-ar: creating capstone/capstone.lib make: 'subdir-capstone' is up to date. real0m35.391s user0m32.857s sys 0m2.414s Not that bad after all. So I still dunno why this patch improved build time... On 02/15/2018 02:35 PM, Philippe Mathieu-Daudé wrote: > The use of is recommended by the upstream project: > http://www.capstone-engine.org/lang_c.html > However when building the in-tree cloned submodule, the header is accessible > via . > > This fixes building on Gentoo (and Haiku OS - not supported since > 898be3e0415): > CC disas.o > /sources/qemu-2.11.0/include/disas/capstone.h:6:22: fatal error: > capstone.h: No such file or directory > #include >^~~~ > > On Haiku `pkg-config --cflags capstone` reports "-I/usr/develop/headers". > > Bug: https://bugs.gentoo.org/647570 > Reported-by: Zoltán Mizsei> Signed-off-by: Philippe Mathieu-Daudé > --- > RFC because this might be a Gentoo portage issue. > > configure| 1 + > include/disas/capstone.h | 6 +- > 2 files changed, 6 insertions(+), 1 deletion(-) > > diff --git a/configure b/configure > index 913e14839d..3657a61a35 100755 > --- a/configure > +++ b/configure > @@ -7017,6 +7017,7 @@ if [ "$dtc_internal" = "yes" ]; then >echo "config-host.h: subdir-dtc" >> $config_host_mak > fi > if [ "$capstone" = "git" -o "$capstone" = "internal" ]; then > + echo "CONFIG_LIBCAPSTONE_INTERNAL=y" >> $config_host_mak >echo "config-host.h: subdir-capstone" >> $config_host_mak > fi > if test -n "$LIBCAPSTONE"; then > diff --git a/include/disas/capstone.h b/include/disas/capstone.h > index 84e214956d..aea9601f41 100644 > --- a/include/disas/capstone.h > +++ b/include/disas/capstone.h > @@ -3,9 +3,13 @@ > > #ifdef CONFIG_CAPSTONE > > +#ifdef CONFIG_LIBCAPSTONE_INTERNAL > #include > - > #else > +#include > +#endif /* CONFIG_LIBCAPSTONE_INTERNAL */ > + > +#else /* CONFIG_CAPSTONE */ > > /* Just enough to allow backends to init without ifdefs. */ > > signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH 01/02] fix issue where a branch to pc+4 confuses GDB because pc and npc are set to the same value
All, I think that the issue I pointed out the list is not a QEMU bug at all but a GDB bug. GDB's sparc software single step implementation seems to be what is stuck. It always re-sets the breakpoint at the current instruction in this case. It calculates the breakpoint offsets by analyzing the instruction and doesn't take this edge case into account. It does not appear to receive an invalid npc value from QEMU as I thought it was. Steven
Re: [Qemu-devel] [QEMU-PPC] [PATCH V4 1/2] ppc/spapr-caps: Disallow setting workaround for spapr-cap-ibs
On Fri, Feb 16, 2018 at 01:33:27PM +1100, Suraj Jitindar Singh wrote: > The spapr-cap cap-ibs can only have values broken or fixed as there is > no explicit workaround required. Currently setting the value workaround > for this cap will hit an assert if the guest makes the hcall > h_get_cpu_characteristics. > > Report an error when attempting to apply the setting with a more helpful > error message. > > Reported-by: Satheesh Rajendran> Signed-off-by: Suraj Jitindar Singh Applied, thanks. > > --- > > V3 -> V4: > - Add this patch back from V1 to replace >"ppc/spapr-caps: Convert spapr-cap-ibs to be a boolean" >as this was deemed to be a better solution > --- > hw/ppc/spapr_caps.c | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c > index e69d308560..99a4b71d19 100644 > --- a/hw/ppc/spapr_caps.c > +++ b/hw/ppc/spapr_caps.c > @@ -205,7 +205,9 @@ static void cap_safe_bounds_check_apply(sPAPRMachineState > *spapr, uint8_t val, > static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr, > uint8_t val, Error **errp) > { > -if (tcg_enabled() && val) { > +if (val == SPAPR_CAP_WORKAROUND) { /* Can only be Broken or Fixed */ > +error_setg(errp, "Requested safe indirect branch capability level > \"workaround\" not valid, try cap-ibs=fixed"); > +} else if (tcg_enabled() && val) { > /* TODO - for now only allow broken for TCG */ > error_setg(errp, "Requested safe indirect branch capability level > not supported by tcg, try a different value for cap-ibs"); > } else if (kvm_enabled() && (val > > kvmppc_get_cap_safe_indirect_branch())) { > @@ -263,7 +265,7 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = { > }, > [SPAPR_CAP_IBS] = { > .name = "ibs", > -.description = "Indirect Branch Serialisation" VALUE_DESC_TRISTATE, > +.description = "Indirect Branch Serialisation (broken, fixed)", > .index = SPAPR_CAP_IBS, > .get = spapr_cap_get_tristate, > .set = spapr_cap_set_tristate, -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
[Qemu-devel] [QEMU-PPC] [PATCH V4 2/2] ppc/spapr-caps: For pseries-2.12 change spapr-cap defaults
For the pseries-2.12 machine type, make the spapr-caps SPAPR_CAP_CFPC and SPAPR_CAP_SBBC default to workaround. Thus if the host is capable the guest will be able to take advantage of these workarounds by default. Otherwise if the host doesn't have these capabilities qemu will fail to start and they will have to be explicitly disabled on the command line with: -machine pseries,cap-cfpc=broken,cap-sbbc=broken Signed-off-by: Suraj Jitindar Singh--- V2 -> V3: - Set caps to workaround in the class default rather than the pseries-2.12 initialiser. --- hw/ppc/spapr.c | 6 -- hw/ppc/spapr_caps.c | 10 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 83c9d66dd5..69f59aabf1 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3915,8 +3915,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF; smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON; smc->default_caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_ON; -smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN; -smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN; +smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND; +smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND; smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN; spapr_caps_add_properties(smc, _abort); } @@ -4000,6 +4000,8 @@ static void spapr_machine_2_11_class_options(MachineClass *mc) spapr_machine_2_12_class_options(mc); smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_ON; +smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN; +smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN; SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_11); } diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 99a4b71d19..7b0ecb3eca 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -283,11 +283,21 @@ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr, caps = smc->default_caps; +if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, + 0, spapr->max_compat_pvr)) { +caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN; +} + if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_07, 0, spapr->max_compat_pvr)) { caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF; } +if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06_PLUS, + 0, spapr->max_compat_pvr)) { +caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN; +} + if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06, 0, spapr->max_compat_pvr)) { caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_OFF; -- 2.13.6
[Qemu-devel] [QEMU-PPC] [PATCH V4 1/2] ppc/spapr-caps: Disallow setting workaround for spapr-cap-ibs
The spapr-cap cap-ibs can only have values broken or fixed as there is no explicit workaround required. Currently setting the value workaround for this cap will hit an assert if the guest makes the hcall h_get_cpu_characteristics. Report an error when attempting to apply the setting with a more helpful error message. Reported-by: Satheesh RajendranSigned-off-by: Suraj Jitindar Singh --- V3 -> V4: - Add this patch back from V1 to replace "ppc/spapr-caps: Convert spapr-cap-ibs to be a boolean" as this was deemed to be a better solution --- hw/ppc/spapr_caps.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index e69d308560..99a4b71d19 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -205,7 +205,9 @@ static void cap_safe_bounds_check_apply(sPAPRMachineState *spapr, uint8_t val, static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp) { -if (tcg_enabled() && val) { +if (val == SPAPR_CAP_WORKAROUND) { /* Can only be Broken or Fixed */ +error_setg(errp, "Requested safe indirect branch capability level \"workaround\" not valid, try cap-ibs=fixed"); +} else if (tcg_enabled() && val) { /* TODO - for now only allow broken for TCG */ error_setg(errp, "Requested safe indirect branch capability level not supported by tcg, try a different value for cap-ibs"); } else if (kvm_enabled() && (val > kvmppc_get_cap_safe_indirect_branch())) { @@ -263,7 +265,7 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = { }, [SPAPR_CAP_IBS] = { .name = "ibs", -.description = "Indirect Branch Serialisation" VALUE_DESC_TRISTATE, +.description = "Indirect Branch Serialisation (broken, fixed)", .index = SPAPR_CAP_IBS, .get = spapr_cap_get_tristate, .set = spapr_cap_set_tristate, -- 2.13.6
[Qemu-devel] [PATCH v3 7/7] hw/sd: move sdcard legacy API to "hw/sd/sdcard_legacy.h"
omap_mmc.c is the last user left. Signed-off-by: Philippe Mathieu-Daudé--- include/hw/sd/sd.h| 16 -- include/hw/sd/sdcard_legacy.h | 50 +++ hw/sd/omap_mmc.c | 2 +- hw/sd/sd.c| 1 + 4 files changed, 52 insertions(+), 17 deletions(-) create mode 100644 include/hw/sd/sdcard_legacy.h diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h index 4491db98de..58528b4d2c 100644 --- a/include/hw/sd/sd.h +++ b/include/hw/sd/sd.h @@ -131,22 +131,6 @@ typedef struct { void (*set_readonly)(DeviceState *dev, bool readonly); } SDBusClass; -/* Legacy functions to be used only by non-qdevified callers */ -SDState *sd_init(BlockBackend *bs, bool is_spi); -int sd_do_command(SDState *sd, SDRequest *req, - uint8_t *response); -void sd_write_data(SDState *sd, uint8_t value); -uint8_t sd_read_data(SDState *sd); -void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert); -/* sd_enable should not be used -- it is only used on the nseries boards, - * where it is part of a broken implementation of the MMC card slot switch - * (there should be two card slots which are multiplexed to a single MMC - * controller, but instead we model it with one card and controller and - * disable the card when the second slot is selected, so it looks like the - * second slot is always empty). - */ -void sd_enable(SDState *sd, bool enable); - /* Functions to be used by qdevified callers (working via * an SDBus rather than directly with SDState) */ diff --git a/include/hw/sd/sdcard_legacy.h b/include/hw/sd/sdcard_legacy.h new file mode 100644 index 00..8681f8089b --- /dev/null +++ b/include/hw/sd/sdcard_legacy.h @@ -0,0 +1,50 @@ +/* + * SD Memory Card emulation (deprecated legacy API) + * + * Copyright (c) 2006 Andrzej Zaborowski + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *notice, this list of conditions and the following disclaimer in + *the documentation and/or other materials provided with the + *distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef HW_SDCARD_LEGACY_H +#define HW_SDCARD_LEGACY_H + +#include "hw/sd/sd.h" + +/* Legacy functions to be used only by non-qdevified callers */ +SDState *sd_init(BlockBackend *blk, bool is_spi); +int sd_do_command(SDState *card, SDRequest *request, uint8_t *response); +void sd_write_data(SDState *card, uint8_t value); +uint8_t sd_read_data(SDState *card); +void sd_set_cb(SDState *card, qemu_irq readonly, qemu_irq insert); + +/* sd_enable should not be used -- it is only used on the nseries boards, + * where it is part of a broken implementation of the MMC card slot switch + * (there should be two card slots which are multiplexed to a single MMC + * controller, but instead we model it with one card and controller and + * disable the card when the second slot is selected, so it looks like the + * second slot is always empty). + */ +void sd_enable(SDState *card, bool enable); + +#endif /* HW_SDCARD_LEGACY_H */ diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c index 5b47cadf11..be14ac4f40 100644 --- a/hw/sd/omap_mmc.c +++ b/hw/sd/omap_mmc.c @@ -19,7 +19,7 @@ #include "qemu/osdep.h" #include "hw/hw.h" #include "hw/arm/omap.h" -#include "hw/sd/sd.h" +#include "hw/sd/sdcard_legacy.h" struct omap_mmc_s { qemu_irq irq; diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 72d32f7845..ae2d915977 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -34,6 +34,7 @@ #include "hw/hw.h" #include "sysemu/block-backend.h" #include "hw/sd/sd.h" +#include "hw/sd/sdcard_legacy.h" #include "qapi/error.h" #include "qemu/bitmap.h" #include "hw/qdev-properties.h" -- 2.16.1
[Qemu-devel] [PATCH v3 1/7] hw/sd/milkymist-memcard: use qemu_log_mask()
Signed-off-by: Philippe Mathieu-DaudéReviewed-by: Alistair Francis Acked-by: Michael Walle --- hw/sd/milkymist-memcard.c | 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c index 341da88552..1292c0c099 100644 --- a/hw/sd/milkymist-memcard.c +++ b/hw/sd/milkymist-memcard.c @@ -22,11 +22,12 @@ */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "hw/hw.h" #include "hw/sysbus.h" #include "sysemu/sysemu.h" #include "trace.h" -#include "qemu/error-report.h" +#include "include/qapi/error.h" #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" #include "hw/sd/sd.h" @@ -138,8 +139,8 @@ static uint64_t memcard_read(void *opaque, hwaddr addr, } else { r = s->response[s->response_read_ptr++]; if (s->response_read_ptr > s->response_len) { -error_report("milkymist_memcard: " -"read more cmd bytes than available. Clipping."); +qemu_log_mask(LOG_GUEST_ERROR, "milkymist_memcard: " + "read more cmd bytes than available. Clipping."); s->response_read_ptr = 0; } } @@ -163,8 +164,9 @@ static uint64_t memcard_read(void *opaque, hwaddr addr, break; default: -error_report("milkymist_memcard: read access to unknown register 0x" -TARGET_FMT_plx, addr << 2); +qemu_log_mask(LOG_UNIMP, "milkymist_memcard: " + "read access to unknown register 0x%" HWADDR_PRIx "\n", + addr << 2); break; } @@ -220,8 +222,9 @@ static void memcard_write(void *opaque, hwaddr addr, uint64_t value, break; default: -error_report("milkymist_memcard: write access to unknown register 0x" -TARGET_FMT_plx, addr << 2); +qemu_log_mask(LOG_UNIMP, "milkymist_memcard: " + "write access to unknown register 0x%" HWADDR_PRIx " " + "(value 0x%" PRIx64 ")\n", addr << 2, value); break; } } -- 2.16.1
[Qemu-devel] [PATCH v3 4/7] hw/sd/ssi-sd: use the SDBus API, connect the SDCard to the bus
On reset the bus will reset the card, we can now drop the device_reset() call. Signed-off-by: Philippe Mathieu-DaudéReviewed-by: Alistair Francis --- hw/sd/ssi-sd.c | 32 +++- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c index f88f509e0a..ae04b6641b 100644 --- a/hw/sd/ssi-sd.c +++ b/hw/sd/ssi-sd.c @@ -47,7 +47,7 @@ typedef struct { int32_t arglen; int32_t response_pos; int32_t stopping; -SDState *sd; +SDBus sdbus; } ssi_sd_state; #define TYPE_SSI_SD "ssi-sd" @@ -100,7 +100,7 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val) request.arg = (s->cmdarg[0] << 24) | (s->cmdarg[1] << 16) | (s->cmdarg[2] << 8) | s->cmdarg[3]; DPRINTF("CMD%d arg 0x%08x\n", s->cmd, request.arg); -s->arglen = sd_do_command(s->sd, , longresp); +s->arglen = sdbus_do_command(>sdbus, , longresp); if (s->arglen <= 0) { s->arglen = 1; s->response[0] = 4; @@ -177,7 +177,7 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val) DPRINTF("Response 0x%02x\n", s->response[s->response_pos]); return s->response[s->response_pos++]; } -if (sd_data_ready(s->sd)) { +if (sdbus_data_ready(>sdbus)) { DPRINTF("Data read\n"); s->mode = SSI_SD_DATA_START; } else { @@ -190,8 +190,8 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val) s->mode = SSI_SD_DATA_READ; return 0xfe; case SSI_SD_DATA_READ: -val = sd_read_data(s->sd); -if (!sd_data_ready(s->sd)) { +val = sdbus_read_data(>sdbus); +if (!sdbus_data_ready(>sdbus)) { DPRINTF("Data read end\n"); s->mode = SSI_SD_CMD; } @@ -242,13 +242,24 @@ static const VMStateDescription vmstate_ssi_sd = { static void ssi_sd_realize(SSISlave *d, Error **errp) { ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, d); +DeviceState *carddev; DriveInfo *dinfo; +Error *err = NULL; +qbus_create_inplace(>sdbus, sizeof(s->sdbus), TYPE_SD_BUS, +DEVICE(d), "sd-bus"); + +/* Create and plug in the sd card */ /* FIXME use a qdev drive property instead of drive_get_next() */ dinfo = drive_get_next(IF_SD); -s->sd = sd_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, true); -if (s->sd == NULL) { -error_setg(errp, "Device initialization failed."); +carddev = qdev_create(>sdbus.qbus, TYPE_SD_CARD); +if (dinfo) { +qdev_prop_set_drive(carddev, "drive", blk_by_legacy_dinfo(dinfo), ); +} +object_property_set_bool(OBJECT(carddev), true, "spi", ); +object_property_set_bool(OBJECT(carddev), true, "realized", ); +if (err) { +error_setg(errp, "failed to init SD card: %s", error_get_pretty(err)); return; } } @@ -264,11 +275,6 @@ static void ssi_sd_reset(DeviceState *dev) s->arglen = 0; s->response_pos = 0; s->stopping = 0; - -/* Since we're still using the legacy SD API the card is not plugged - * into any bus, and we must reset it manually. - */ -device_reset(DEVICE(s->sd)); } static void ssi_sd_class_init(ObjectClass *klass, void *data) -- 2.16.1
[Qemu-devel] [RFC PATCH v3 5/7] hw/sd/pl181: expose a SDBus and connect the SDCard to it
using the sdbus_*() API. Signed-off-by: Philippe Mathieu-Daudé--- RFC because how pl181_sdbus_create_inplace() doing class_init(SDBus) in realize(pl181) seems weird... from http://lists.nongnu.org/archive/html/qemu-devel/2018-02/msg01268.html: I think you have to change that sd_set_cb() code now. If you look at sd_cardchange() it uses "is this SD card object on an SDBus" to determine whether to notify the controller via the old-API IRQ lines, or using the set_inserted() and set_readonly() callbacks on the SDBusClass. This previous series intended to enforce a cleaner OOP design, adding a TYPE_SD_BUS_MASTER_INTERFACE TypeInfo: http://lists.nongnu.org/archive/html/qemu-devel/2017-12/msg02322.html http://lists.nongnu.org/archive/html/qemu-devel/2017-12/msg02326.html http://lists.nongnu.org/archive/html/qemu-devel/2017-12/msg02327.html --- hw/sd/pl181.c | 59 --- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c index 3ba1f7dd23..97e85e4a64 100644 --- a/hw/sd/pl181.c +++ b/hw/sd/pl181.c @@ -33,7 +33,7 @@ typedef struct PL181State { SysBusDevice parent_obj; MemoryRegion iomem; -SDState *card; +SDBus sdbus; uint32_t clock; uint32_t power; uint32_t cmdarg; @@ -179,7 +179,7 @@ static void pl181_send_command(PL181State *s) request.cmd = s->cmd & PL181_CMD_INDEX; request.arg = s->cmdarg; DPRINTF("Command %d %08x\n", request.cmd, request.arg); -rlen = sd_do_command(s->card, , response); +rlen = sdbus_do_command(>sdbus, , response); if (rlen < 0) goto error; if (s->cmd & PL181_CMD_RESPONSE) { @@ -223,12 +223,12 @@ static void pl181_fifo_run(PL181State *s) int is_read; is_read = (s->datactrl & PL181_DATA_DIRECTION) != 0; -if (s->datacnt != 0 && (!is_read || sd_data_ready(s->card)) +if (s->datacnt != 0 && (!is_read || sdbus_data_ready(>sdbus)) && !s->linux_hack) { if (is_read) { n = 0; while (s->datacnt && s->fifo_len < PL181_FIFO_LEN) { -value |= (uint32_t)sd_read_data(s->card) << (n * 8); +value |= (uint32_t)sdbus_read_data(>sdbus) << (n * 8); s->datacnt--; n++; if (n == 4) { @@ -249,7 +249,7 @@ static void pl181_fifo_run(PL181State *s) } n--; s->datacnt--; -sd_write_data(s->card, value & 0xff); +sdbus_write_data(>sdbus, value & 0xff); value >>= 8; } } @@ -477,13 +477,6 @@ static void pl181_reset(DeviceState *d) s->linux_hack = 0; s->mask[0] = 0; s->mask[1] = 0; - -/* We can assume our GPIO outputs have been wired up now */ -sd_set_cb(s->card, s->cardstatus[0], s->cardstatus[1]); -/* Since we're still using the legacy SD API the card is not plugged - * into any bus, and we must reset it manually. - */ -device_reset(DEVICE(s->card)); } static void pl181_init(Object *obj) @@ -499,16 +492,52 @@ static void pl181_init(Object *obj) qdev_init_gpio_out(dev, s->cardstatus, 2); } +static void pl181_set_readonly(DeviceState *dev, bool level) +{ +PL181State *s = (PL181State *)dev; + +qemu_set_irq(s->cardstatus[0], level); +} + +static void pl181_set_inserted(DeviceState *dev, bool level) +{ +PL181State *s = (PL181State *)dev; + +qemu_set_irq(s->cardstatus[1], level); +} + +static void pl181_sdbus_create_inplace(SDBus *sdbus, DeviceState *dev) +{ +SDBusClass *sbc; + +qbus_create_inplace(sdbus, sizeof(SDBus), TYPE_SD_BUS, dev, "sd-bus"); + +/* pl181_sdbus_class_init */ +sbc = SD_BUS_GET_CLASS(sdbus); +sbc->set_inserted = pl181_set_inserted; +sbc->set_readonly = pl181_set_readonly; +} + static void pl181_realize(DeviceState *dev, Error **errp) { PL181State *s = PL181(dev); +DeviceState *carddev; DriveInfo *dinfo; +Error *err = NULL; + +pl181_sdbus_create_inplace(>sdbus, dev); +/* Create and plug in the sd card */ /* FIXME use a qdev drive property instead of drive_get_next() */ dinfo = drive_get_next(IF_SD); -s->card = sd_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, false); -if (s->card == NULL) { -error_setg(errp, "sd_init failed"); +carddev = qdev_create(>sdbus.qbus, TYPE_SD_CARD); +if (dinfo) { +qdev_prop_set_drive(carddev, "drive", blk_by_legacy_dinfo(dinfo), ); +} +object_property_set_bool(OBJECT(carddev), true, "realized", ); +if (err) { +error_setg(errp, "failed to init SD card: %s", error_get_pretty(err)); +return; } } -- 2.16.1
[Qemu-devel] [PATCH v3 6/7] hw/sd: make sd_data_ready() static
It belongs to the legacy API (the last user has been converted). Signed-off-by: Philippe Mathieu-Daudé--- include/hw/sd/sd.h | 1 - hw/sd/sd.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h index bf1eb0713c..4491db98de 100644 --- a/include/hw/sd/sd.h +++ b/include/hw/sd/sd.h @@ -138,7 +138,6 @@ int sd_do_command(SDState *sd, SDRequest *req, void sd_write_data(SDState *sd, uint8_t value); uint8_t sd_read_data(SDState *sd); void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert); -bool sd_data_ready(SDState *sd); /* sd_enable should not be used -- it is only used on the nseries boards, * where it is part of a broken implementation of the MMC card slot switch * (there should be two card slots which are multiplexed to a single MMC diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 9ac9b63ff8..72d32f7845 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -1885,7 +1885,7 @@ uint8_t sd_read_data(SDState *sd) return ret; } -bool sd_data_ready(SDState *sd) +static bool sd_data_ready(SDState *sd) { return sd->state == sd_sendingdata_state; } -- 2.16.1
[Qemu-devel] [PATCH v3 2/7] hw/sd/milkymist-memcard: split realize() out of SysBusDevice init()
Create the SDCard in the realize() function. Suggested-by: Michael WalleSigned-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Acked-by: Michael Walle --- hw/sd/milkymist-memcard.c | 28 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c index 1292c0c099..a8e65892c7 100644 --- a/hw/sd/milkymist-memcard.c +++ b/hw/sd/milkymist-memcard.c @@ -257,27 +257,31 @@ static void milkymist_memcard_reset(DeviceState *d) device_reset(DEVICE(s->card)); } -static int milkymist_memcard_init(SysBusDevice *dev) +static void milkymist_memcard_init(Object *obj) +{ +MilkymistMemcardState *s = MILKYMIST_MEMCARD(obj); +SysBusDevice *dev = SYS_BUS_DEVICE(obj); + +memory_region_init_io(>regs_region, OBJECT(s), _mmio_ops, s, +"milkymist-memcard", R_MAX * 4); +sysbus_init_mmio(dev, >regs_region); +} + +static void milkymist_memcard_realize(DeviceState *dev, Error **errp) { MilkymistMemcardState *s = MILKYMIST_MEMCARD(dev); -DriveInfo *dinfo; BlockBackend *blk; +DriveInfo *dinfo; /* FIXME use a qdev drive property instead of drive_get_next() */ dinfo = drive_get_next(IF_SD); blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL; s->card = sd_init(blk, false); if (s->card == NULL) { -return -1; +error_setg(errp, "failed to init SD card"); +return; } - s->enabled = blk && blk_is_inserted(blk); - -memory_region_init_io(>regs_region, OBJECT(s), _mmio_ops, s, -"milkymist-memcard", R_MAX * 4); -sysbus_init_mmio(dev, >regs_region); - -return 0; } static const VMStateDescription vmstate_milkymist_memcard = { @@ -300,9 +304,8 @@ static const VMStateDescription vmstate_milkymist_memcard = { static void milkymist_memcard_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); -SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); -k->init = milkymist_memcard_init; +dc->realize = milkymist_memcard_realize; dc->reset = milkymist_memcard_reset; dc->vmsd = _milkymist_memcard; /* Reason: init() method uses drive_get_next() */ @@ -313,6 +316,7 @@ static const TypeInfo milkymist_memcard_info = { .name = TYPE_MILKYMIST_MEMCARD, .parent= TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(MilkymistMemcardState), +.instance_init = milkymist_memcard_init, .class_init= milkymist_memcard_class_init, }; -- 2.16.1
[Qemu-devel] [PATCH v3 3/7] hw/sd/milkymist-memcard: expose a SDBus and connect the SDCard to it
using the sdbus_*() API. Signed-off-by: Philippe Mathieu-DaudéReviewed-by: Alistair Francis Acked-by: Michael Walle --- hw/sd/milkymist-memcard.c | 38 +- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c index a8e65892c7..5570c1e9a0 100644 --- a/hw/sd/milkymist-memcard.c +++ b/hw/sd/milkymist-memcard.c @@ -69,7 +69,7 @@ struct MilkymistMemcardState { SysBusDevice parent_obj; MemoryRegion regs_region; -SDState *card; +SDBus sdbus; int command_write_ptr; int response_read_ptr; @@ -105,7 +105,7 @@ static void memcard_sd_command(MilkymistMemcardState *s) req.crc = s->command[5]; s->response[0] = req.cmd; -s->response_len = sd_do_command(s->card, , s->response+1); +s->response_len = sdbus_do_command(>sdbus, , s->response + 1); s->response_read_ptr = 0; if (s->response_len == 16) { @@ -150,10 +150,10 @@ static uint64_t memcard_read(void *opaque, hwaddr addr, r = 0x; } else { r = 0; -r |= sd_read_data(s->card) << 24; -r |= sd_read_data(s->card) << 16; -r |= sd_read_data(s->card) << 8; -r |= sd_read_data(s->card); +r |= sdbus_read_data(>sdbus) << 24; +r |= sdbus_read_data(>sdbus) << 16; +r |= sdbus_read_data(>sdbus) << 8; +r |= sdbus_read_data(>sdbus); } break; case R_CLK2XDIV: @@ -207,10 +207,10 @@ static void memcard_write(void *opaque, hwaddr addr, uint64_t value, if (!s->enabled) { break; } -sd_write_data(s->card, (value >> 24) & 0xff); -sd_write_data(s->card, (value >> 16) & 0xff); -sd_write_data(s->card, (value >> 8) & 0xff); -sd_write_data(s->card, value & 0xff); +sdbus_write_data(>sdbus, (value >> 24) & 0xff); +sdbus_write_data(>sdbus, (value >> 16) & 0xff); +sdbus_write_data(>sdbus, (value >> 8) & 0xff); +sdbus_write_data(>sdbus, value & 0xff); break; case R_ENABLE: s->regs[addr] = value; @@ -251,10 +251,6 @@ static void milkymist_memcard_reset(DeviceState *d) for (i = 0; i < R_MAX; i++) { s->regs[i] = 0; } -/* Since we're still using the legacy SD API the card is not plugged - * into any bus, and we must reset it manually. - */ -device_reset(DEVICE(s->card)); } static void milkymist_memcard_init(Object *obj) @@ -270,15 +266,23 @@ static void milkymist_memcard_init(Object *obj) static void milkymist_memcard_realize(DeviceState *dev, Error **errp) { MilkymistMemcardState *s = MILKYMIST_MEMCARD(dev); +DeviceState *carddev; BlockBackend *blk; DriveInfo *dinfo; +Error *err = NULL; +qbus_create_inplace(>sdbus, sizeof(s->sdbus), TYPE_SD_BUS, +dev, "sd-bus"); + +/* Create and plug in the sd card */ /* FIXME use a qdev drive property instead of drive_get_next() */ dinfo = drive_get_next(IF_SD); blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL; -s->card = sd_init(blk, false); -if (s->card == NULL) { -error_setg(errp, "failed to init SD card"); +carddev = qdev_create(>sdbus.qbus, TYPE_SD_CARD); +qdev_prop_set_drive(carddev, "drive", blk, ); +object_property_set_bool(OBJECT(carddev), true, "realized", ); +if (err) { +error_setg(errp, "failed to init SD card: %s", error_get_pretty(err)); return; } s->enabled = blk && blk_is_inserted(blk); -- 2.16.1
[Qemu-devel] [PATCH v3 0/7] SDHCI: convert legacy devices to the SDBus API (part 6)
Hi, Since v2: - pl181: remove legacy sd_set_cb() (Peter) Since v1: - rebased on /master (Peter sdcard reset() patches) - fix milkymist-mmc from previous seris using instance_init (Michael Walle) This series convert 3 devices using the legacy SDCard API to the SDBus API: - milkymist-mmc - pl181 - ssi-sd Then move the legacy API to a separate header "sdcard_legacy.h". Now the OMAP MMC is the last device using the legacy API, but need to get QOM'ified first. Having a common sdbus interface simplify qtesting (next series) This series is not related to the previous set (4/5) and can be applied independently. Regards, Phil. $ git backport-diff 001/7:[] [--] 'hw/sd/milkymist-memcard: use qemu_log_mask()' 002/7:[] [--] 'hw/sd/milkymist-memcard: split realize() out of SysBusDevice init()' 003/7:[] [--] 'hw/sd/milkymist-memcard: expose a SDBus and connect the SDCard to it' 004/7:[] [--] 'hw/sd/ssi-sd: use the SDBus API, connect the SDCard to the bus' 005/7:[0034] [FC] 'hw/sd/pl181: expose a SDBus and connect the SDCard to it' 006/7:[down] 'hw/sd: make sd_data_ready() static' 007/7:[0003] [FC] 'hw/sd: move sdcard legacy API to "hw/sd/sdcard_legacy.h"' Philippe Mathieu-Daudé (7): hw/sd/milkymist-memcard: use qemu_log_mask() hw/sd/milkymist-memcard: split realize() out of SysBusDevice init() hw/sd/milkymist-memcard: expose a SDBus and connect the SDCard to it hw/sd/ssi-sd: use the SDBus API, connect the SDCard to the bus hw/sd/pl181: expose a SDBus and connect the SDCard to it hw/sd: make sd_data_ready() static hw/sd: move sdcard legacy API to "hw/sd/sdcard_legacy.h" include/hw/sd/sd.h| 17 - include/hw/sd/sdcard_legacy.h | 50 ++ hw/sd/milkymist-memcard.c | 81 --- hw/sd/omap_mmc.c | 2 +- hw/sd/pl181.c | 59 +++ hw/sd/sd.c| 3 +- hw/sd/ssi-sd.c| 32 ++--- 7 files changed, 162 insertions(+), 82 deletions(-) create mode 100644 include/hw/sd/sdcard_legacy.h -- 2.16.1
[Qemu-devel] [PATCH 2/4] target/mips: convert to DisasContextBase
Signed-off-by: Emilio G. Cota--- target/mips/translate.c | 346 1 file changed, 175 insertions(+), 171 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index a133205..aefd729 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -1430,17 +1430,15 @@ static TCGv_i64 msa_wr_d[64]; } while(0) typedef struct DisasContext { -struct TranslationBlock *tb; -target_ulong pc, saved_pc; +DisasContextBase base; +target_ulong saved_pc; uint32_t opcode; -int singlestep_enabled; int insn_flags; int32_t CP0_Config1; /* Routine used to access memory */ int mem_idx; TCGMemOp default_tcg_memop_mask; uint32_t hflags, saved_hflags; -DisasJumpType is_jmp; target_ulong btarget; bool ulri; int kscrexist; @@ -1517,8 +1515,9 @@ static const char * const msaregnames[] = { if (MIPS_DEBUG_DISAS) { \ qemu_log_mask(CPU_LOG_TB_IN_ASM, \ TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \ - ctx->pc, ctx->opcode, op, ctx->opcode >> 26,\ - ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \ + ctx->base.pc_next, ctx->opcode, op, \ + ctx->opcode >> 26, ctx->opcode & 0x3F, \ + ((ctx->opcode >> 16) & 0x1F)); \ } \ } while (0) @@ -1594,9 +1593,9 @@ static inline void gen_save_pc(target_ulong pc) static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) { LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); -if (do_save_pc && ctx->pc != ctx->saved_pc) { -gen_save_pc(ctx->pc); -ctx->saved_pc = ctx->pc; +if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { +gen_save_pc(ctx->base.pc_next); +ctx->saved_pc = ctx->base.pc_next; } if (ctx->hflags != ctx->saved_hflags) { tcg_gen_movi_i32(hflags, ctx->hflags); @@ -1635,7 +1634,7 @@ static inline void generate_exception_err(DisasContext *ctx, int excp, int err) gen_helper_raise_exception_err(cpu_env, texcp, terr); tcg_temp_free_i32(terr); tcg_temp_free_i32(texcp); -ctx->is_jmp = DISAS_EXCP; +ctx->base.is_jmp = DISAS_EXCP; } static inline void generate_exception(DisasContext *ctx, int excp) @@ -2126,7 +2125,7 @@ static void gen_base_offset_addr (DisasContext *ctx, TCGv addr, static target_ulong pc_relative_pc (DisasContext *ctx) { -target_ulong pc = ctx->pc; +target_ulong pc = ctx->base.pc_next; if (ctx->hflags & MIPS_HFLAG_BMASK) { int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4; @@ -4275,12 +4274,12 @@ static void gen_trap (DisasContext *ctx, uint32_t opc, static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) { -if (unlikely(ctx->singlestep_enabled)) { +if (unlikely(ctx->base.singlestep_enabled)) { return false; } #ifndef CONFIG_USER_ONLY -return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); +return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); #else return true; #endif @@ -4291,10 +4290,10 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) if (use_goto_tb(ctx, dest)) { tcg_gen_goto_tb(n); gen_save_pc(dest); -tcg_gen_exit_tb((uintptr_t)ctx->tb + n); +tcg_gen_exit_tb((uintptr_t)ctx->base.tb + n); } else { gen_save_pc(dest); -if (ctx->singlestep_enabled) { +if (ctx->base.singlestep_enabled) { save_cpu_state(ctx, 0); gen_helper_raise_exception_debug(cpu_env); } @@ -4317,7 +4316,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, if (ctx->hflags & MIPS_HFLAG_BMASK) { #ifdef MIPS_DEBUG_DISAS LOG_DISAS("Branch in delay / forbidden slot at PC 0x" - TARGET_FMT_lx "\n", ctx->pc); + TARGET_FMT_lx "\n", ctx->base.pc_next); #endif generate_exception_end(ctx, EXCP_RI); goto out; @@ -4335,7 +4334,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, gen_load_gpr(t1, rt); bcond_compute = 1; } -btgt = ctx->pc + insn_bytes + offset; +btgt = ctx->base.pc_next + insn_bytes + offset; break; case OPC_BGEZ: case OPC_BGEZAL: @@ -4354,7 +4353,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, gen_load_gpr(t0, rs); bcond_compute = 1; } -btgt = ctx->pc + insn_bytes + offset; +btgt = ctx->base.pc_next + insn_bytes +
[Qemu-devel] [PATCH 3/4] target/mips: use *ctx for DisasContext
No changes to the logic here; this is just to make the diff that follows easier to read. While at it, remove the unnecessary 'struct' in 'struct TranslationBlock'. Note that checkpatch complains with a false positive: ERROR: space prohibited after that '&' (ctx:WxW) #75: FILE: target/mips/translate.c:20220: +ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; ^ Signed-off-by: Emilio G. Cota--- target/mips/translate.c | 166 1 file changed, 84 insertions(+), 82 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index aefd729..08bd140 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -20194,55 +20194,57 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) } } -void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb) +void gen_intermediate_code(CPUState *cs, TranslationBlock *tb) { CPUMIPSState *env = cs->env_ptr; -DisasContext ctx; +DisasContext ctx1; +DisasContext *ctx = target_ulong next_page_start; int max_insns; int insn_bytes; int is_slot; -ctx.base.tb = tb; -ctx.base.pc_first = tb->pc; -ctx.base.pc_next = tb->pc; -ctx.base.is_jmp = DISAS_NEXT; -ctx.base.singlestep_enabled = cs->singlestep_enabled; -ctx.base.num_insns = 0; - -next_page_start = (ctx.base.pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; -ctx.saved_pc = -1; -ctx.insn_flags = env->insn_flags; -ctx.CP0_Config1 = env->CP0_Config1; -ctx.btarget = 0; -ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; -ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; -ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3; -ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1; -ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1; -ctx.PAMask = env->PAMask; -ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; -ctx.eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; -ctx.sc = (env->CP0_Config3 >> CP0C3_SC) & 1; -ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift; -ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; +ctx->base.tb = tb; +ctx->base.pc_first = tb->pc; +ctx->base.pc_next = tb->pc; +ctx->base.is_jmp = DISAS_NEXT; +ctx->base.singlestep_enabled = cs->singlestep_enabled; +ctx->base.num_insns = 0; + +next_page_start = (ctx->base.pc_first & TARGET_PAGE_MASK) + +TARGET_PAGE_SIZE; +ctx->saved_pc = -1; +ctx->insn_flags = env->insn_flags; +ctx->CP0_Config1 = env->CP0_Config1; +ctx->btarget = 0; +ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; +ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; +ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3; +ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1; +ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1; +ctx->PAMask = env->PAMask; +ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; +ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; +ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1; +ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift; +ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; /* Restore delay slot state from the tb context. */ -ctx.hflags = (uint32_t)ctx.base.tb->flags; /* FIXME: maybe use 64 bits? */ -ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; -ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || +ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ +ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; +ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); -ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1; -ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; -ctx.nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; -ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; -restore_cpu_state(env, ); +ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1; +ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; +ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; +ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; +restore_cpu_state(env, ctx); #ifdef CONFIG_USER_ONLY -ctx.mem_idx = MIPS_HFLAG_UM; +ctx->mem_idx = MIPS_HFLAG_UM; #else -ctx.mem_idx = hflags_mmu_index(ctx.hflags); +ctx->mem_idx = hflags_mmu_index(ctx->hflags); #endif -ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ? - MO_UNALN : MO_ALIGN; +ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ? + MO_UNALN : MO_ALIGN; max_insns = tb_cflags(tb) & CF_COUNT_MASK; if (max_insns == 0) { max_insns = CF_COUNT_MASK; @@ -20251,74 +20253,74 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb) max_insns = TCG_MAX_INSNS;
[Qemu-devel] [PATCH 0/4] target/mips: translator loop conversion
Tested with Aurelien's debian wheezy image for mips64. The third patch is just to improve the diff--saves about 20% of diff lines in patch 4, but feel free to squash it with the latter. Thanks, Emilio
[Qemu-devel] [PATCH 1/4] target/mips: convert to DisasJumpType
Signed-off-by: Emilio G. Cota--- target/mips/translate.c | 186 +++- 1 file changed, 91 insertions(+), 95 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index d05ee67..a133205 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -36,6 +36,7 @@ #include "target/mips/trace.h" #include "trace-tcg.h" +#include "exec/translator.h" #include "exec/log.h" #define MIPS_DEBUG_DISAS 0 @@ -1439,7 +1440,7 @@ typedef struct DisasContext { int mem_idx; TCGMemOp default_tcg_memop_mask; uint32_t hflags, saved_hflags; -int bstate; +DisasJumpType is_jmp; target_ulong btarget; bool ulri; int kscrexist; @@ -1460,13 +1461,8 @@ typedef struct DisasContext { bool abs2008; } DisasContext; -enum { -BS_NONE = 0, /* We go out of the TB without reaching a branch or an - * exception condition */ -BS_STOP = 1, /* We want to stop translation for any reason */ -BS_BRANCH = 2, /* We reached a branch condition */ -BS_EXCP = 3, /* We reached an exception condition */ -}; +#define DISAS_STOP DISAS_TARGET_0 +#define DISAS_EXCP DISAS_TARGET_1 static const char * const regnames[] = { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3", @@ -1639,7 +1635,7 @@ static inline void generate_exception_err(DisasContext *ctx, int excp, int err) gen_helper_raise_exception_err(cpu_env, texcp, terr); tcg_temp_free_i32(terr); tcg_temp_free_i32(texcp); -ctx->bstate = BS_EXCP; +ctx->is_jmp = DISAS_EXCP; } static inline void generate_exception(DisasContext *ctx, int excp) @@ -5334,10 +5330,10 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_io_end(); } /* Break the TB to be able to take timer interrupts immediately - after reading count. BS_STOP isn't sufficient, we need to ensure - we break completely out of translated code. */ + after reading count. DISAS_STOP isn't sufficient, we need to + ensure we break completely out of translated code. */ gen_save_pc(ctx->pc + 4); -ctx->bstate = BS_EXCP; +ctx->is_jmp = DISAS_EXCP; rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -5905,7 +5901,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_pagegrain(cpu_env, arg); rn = "PageGrain"; -ctx->bstate = BS_STOP; +ctx->is_jmp = DISAS_STOP; break; case 2: CP0_CHECK(ctx->sc); @@ -5966,7 +5962,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 0: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_hwrena(cpu_env, arg); -ctx->bstate = BS_STOP; +ctx->is_jmp = DISAS_STOP; rn = "HWREna"; break; default: @@ -6028,30 +6024,30 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 0: save_cpu_state(ctx, 1); gen_helper_mtc0_status(cpu_env, arg); -/* BS_STOP isn't good enough here, hflags may have changed. */ +/* DISAS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); -ctx->bstate = BS_EXCP; +ctx->is_jmp = DISAS_EXCP; rn = "Status"; break; case 1: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_intctl(cpu_env, arg); /* Stop translation as we may have switched the execution mode */ -ctx->bstate = BS_STOP; +ctx->is_jmp = DISAS_STOP; rn = "IntCtl"; break; case 2: check_insn(ctx, ISA_MIPS32R2); gen_helper_mtc0_srsctl(cpu_env, arg); /* Stop translation as we may have switched the execution mode */ -ctx->bstate = BS_STOP; +ctx->is_jmp = DISAS_STOP; rn = "SRSCtl"; break; case 3: check_insn(ctx, ISA_MIPS32R2); gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); /* Stop translation as we may have switched the execution mode */ -ctx->bstate = BS_STOP; +ctx->is_jmp = DISAS_STOP; rn = "SRSMap"; break; default: @@ -6063,11 +6059,11 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 0: save_cpu_state(ctx, 1); gen_helper_mtc0_cause(cpu_env, arg); -/* Stop translation as we may have triggered an interrupt. BS_STOP - * isn't sufficient, we need to ensure we break out of translated - *
[Qemu-devel] [PATCH 4/4] target/mips: convert to TranslatorOps
Notes: - DISAS_TOO_MANY replaces the former "break" in the translation loop. However, care must be taken not to overwrite a previous condition in is_jmp; that's why in translate_insn we first check is_jmp and return if it's != DISAS_NEXT. - Added an assert in translate_insn, before exiting due to an exception, to make sure that is_jmp is set to DISAS_EXCP (the exception generation function always sets it.) - Added an assert for the default case in is_jmp's switch. Signed-off-by: Emilio G. Cota--- target/mips/translate.c | 229 1 file changed, 115 insertions(+), 114 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 08bd140..22eee49 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -1432,6 +1432,7 @@ static TCGv_i64 msa_wr_d[64]; typedef struct DisasContext { DisasContextBase base; target_ulong saved_pc; +target_ulong next_page_start; uint32_t opcode; int insn_flags; int32_t CP0_Config1; @@ -20194,24 +20195,13 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) } } -void gen_intermediate_code(CPUState *cs, TranslationBlock *tb) +static int mips_tr_init_disas_context(DisasContextBase *dcbase, + CPUState *cs, int max_insns) { +DisasContext *ctx = container_of(dcbase, DisasContext, base); CPUMIPSState *env = cs->env_ptr; -DisasContext ctx1; -DisasContext *ctx = -target_ulong next_page_start; -int max_insns; -int insn_bytes; -int is_slot; - -ctx->base.tb = tb; -ctx->base.pc_first = tb->pc; -ctx->base.pc_next = tb->pc; -ctx->base.is_jmp = DISAS_NEXT; -ctx->base.singlestep_enabled = cs->singlestep_enabled; -ctx->base.num_insns = 0; -next_page_start = (ctx->base.pc_first & TARGET_PAGE_MASK) + +ctx->next_page_start = (ctx->base.pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; ctx->saved_pc = -1; ctx->insn_flags = env->insn_flags; @@ -20245,99 +20235,103 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb) #endif ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ? MO_UNALN : MO_ALIGN; -max_insns = tb_cflags(tb) & CF_COUNT_MASK; -if (max_insns == 0) { -max_insns = CF_COUNT_MASK; -} -if (max_insns > TCG_MAX_INSNS) { -max_insns = TCG_MAX_INSNS; -} -LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx->mem_idx, ctx->hflags); -gen_tb_start(tb); -while (ctx->base.is_jmp == DISAS_NEXT) { -tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, - ctx->btarget); -ctx->base.num_insns++; +LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, + ctx->hflags); +return max_insns; +} -if (unlikely(cpu_breakpoint_test(cs, ctx->base.pc_next, BP_ANY))) { -save_cpu_state(ctx, 1); -ctx->base.is_jmp = DISAS_NORETURN; -gen_helper_raise_exception_debug(cpu_env); -/* The address covered by the breakpoint must be included in - [tb->pc, tb->pc + tb->size) in order to for it to be - properly cleared -- thus we increment the PC here so that - the logic setting tb->size below does the right thing. */ -ctx->base.pc_next += 4; -goto done_generating; -} +static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) +{ +} -if (ctx->base.num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) { -gen_io_start(); -} +static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) +{ +DisasContext *ctx = container_of(dcbase, DisasContext, base); -is_slot = ctx->hflags & MIPS_HFLAG_BMASK; -if (!(ctx->hflags & MIPS_HFLAG_M16)) { -ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next); -insn_bytes = 4; -decode_opc(env, ctx); -} else if (ctx->insn_flags & ASE_MICROMIPS) { -ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next); -insn_bytes = decode_micromips_opc(env, ctx); -} else if (ctx->insn_flags & ASE_MIPS16) { -ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next); -insn_bytes = decode_mips16_opc(env, ctx); -} else { -generate_exception_end(ctx, EXCP_RI); -break; -} +tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, + ctx->btarget); +} -if (ctx->hflags & MIPS_HFLAG_BMASK) { -if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 | -MIPS_HFLAG_FBNSLOT))) { -/* force to generate branch as there is neither delay nor - forbidden slot */ -is_slot = 1; -} -
Re: [Qemu-devel] [PATCHv2 0/2] target/ppc: convert to generic translation loop
On Thu, Feb 15, 2018 at 02:51:47PM -0500, Emilio G. Cota wrote: > Changes from v1: > - Removed use of translator_loop_temp_check; call tcg_check_temp_count > directly. > - Add R-b's. Applied to ppc-for-2.12, thanks. > > Thanks, > > Emilio > -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: PGP signature
Re: [Qemu-devel] [PULL 2/3] tests: Enable boot-serial-test for hppa
On Thu, Feb 15, 2018 at 8:55 PM, Philippe Mathieu-Daudéwrote: > On 02/04/2018 07:23 PM, Richard Henderson wrote: >> Reviewed-by: Thomas Huth >> Signed-off-by: Richard Henderson >> --- >> tests/boot-serial-test.c | 1 + >> tests/Makefile.include | 2 ++ >> 2 files changed, 3 insertions(+) >> >> diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c >> index 418c5b92dc..ea87a80be7 100644 >> --- a/tests/boot-serial-test.c >> +++ b/tests/boot-serial-test.c >> @@ -87,6 +87,7 @@ static testdef_t tests[] = { >>sizeof(kernel_plml605), kernel_plml605 }, >> { "moxie", "moxiesim", "", "TT", sizeof(bios_moxiesim), 0, >> bios_moxiesim }, >> { "arm", "raspi2", "", "TT", sizeof(bios_raspi2), 0, bios_raspi2 }, >> +{ "hppa", "hppa", "", "SeaBIOS wants SYSTEM HALT" }, >> >> { NULL } >> }; >> diff --git a/tests/Makefile.include b/tests/Makefile.include >> index ca82e0c0cc..83def6994c 100644 >> --- a/tests/Makefile.include >> +++ b/tests/Makefile.include >> @@ -299,6 +299,8 @@ gcov-files-x86_64-y = $(subst >> i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y) >> >> check-qtest-alpha-y = tests/boot-serial-test$(EXESUF) >> >> +check-qtest-hppa-y = tests/boot-serial-test$(EXESUF) >> + >> check-qtest-m68k-y = tests/boot-serial-test$(EXESUF) >> >> check-qtest-microblaze-y = tests/boot-serial-test$(EXESUF) >> > > I got this failure in 2 different branches: > > GTESTER check-qtest-hppa > ** > ERROR:tests/boot-serial-test.c:137:check_guest_output: assertion failed: > (output_ok) > GTester: last random seed: R02S55e7df877597841c1b3b62962e410123 > make: *** [check-qtest-hppa] Error 1 > make: *** Waiting for unfinished jobs > > https://travis-ci.org/philmd/qemu/jobs/341959060 which is not always reproducible... rebuilding this job worked. > "compiler": "gcc", > "env": "CONFIG=\"--disable-linux-user\"", > "dist": "trusty", > "os": "linux" > > https://travis-ci.org/philmd/qemu/jobs/341979253 > "compiler": "gcc", > "env": "CONFIG=\"--with-coroutine=ucontext --disable-linux-user\"", > "dist": "trusty", > "os": "linux"
Re: [Qemu-devel] [RFC PATCH] capstone: fix building using system package
Hi, afaik (but not tested) pkgconfig --cflags reports /includes on linux, and it does the same on Haiku too. I'm not against to change our capstone recipe, but please, if you can check it on Linux and report it back, as i don't want to break other software. Thanks for the nice talk, guys! --miqlas 2018-02-15 19:39 keltezéssel, Philippe Mathieu-Daudé írta: Hi Sergei, On 02/15/2018 03:21 PM, Sergei Trofimovich wrote: On Thu, 15 Feb 2018 14:35:39 -0300 Philippe Mathieu-Daudéwrote: #else +#include I think it's incorrect. 'pkg-config' already reports 'capstone/' path: $ pkg-config --cflags capstone -I/usr/include/capstone Glad to hear feedback from a Gentoo developer! Ok so the problem Haiku only, which we don't support anymore. $ ls /usr/include/capstone/capstone.h /usr/include/capstone/capstone.h Thus I would guess #include is still correct for system include path as well (contradicts the example). My guess is the example is probabilisticly safer for people compiling without using 'pkg-config'. qemu just needs to use 'pkg-config' to discover the include path and libs. Maybe new capstone release has different pkgconfig setup? I think it is safer to drop this patch. Thanks for your review! Phil.
Re: [Qemu-devel] [PULL 2/3] tests: Enable boot-serial-test for hppa
On 02/04/2018 07:23 PM, Richard Henderson wrote: > Reviewed-by: Thomas Huth> Signed-off-by: Richard Henderson > --- > tests/boot-serial-test.c | 1 + > tests/Makefile.include | 2 ++ > 2 files changed, 3 insertions(+) > > diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c > index 418c5b92dc..ea87a80be7 100644 > --- a/tests/boot-serial-test.c > +++ b/tests/boot-serial-test.c > @@ -87,6 +87,7 @@ static testdef_t tests[] = { >sizeof(kernel_plml605), kernel_plml605 }, > { "moxie", "moxiesim", "", "TT", sizeof(bios_moxiesim), 0, bios_moxiesim > }, > { "arm", "raspi2", "", "TT", sizeof(bios_raspi2), 0, bios_raspi2 }, > +{ "hppa", "hppa", "", "SeaBIOS wants SYSTEM HALT" }, > > { NULL } > }; > diff --git a/tests/Makefile.include b/tests/Makefile.include > index ca82e0c0cc..83def6994c 100644 > --- a/tests/Makefile.include > +++ b/tests/Makefile.include > @@ -299,6 +299,8 @@ gcov-files-x86_64-y = $(subst > i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y) > > check-qtest-alpha-y = tests/boot-serial-test$(EXESUF) > > +check-qtest-hppa-y = tests/boot-serial-test$(EXESUF) > + > check-qtest-m68k-y = tests/boot-serial-test$(EXESUF) > > check-qtest-microblaze-y = tests/boot-serial-test$(EXESUF) > I got this failure in 2 different branches: GTESTER check-qtest-hppa ** ERROR:tests/boot-serial-test.c:137:check_guest_output: assertion failed: (output_ok) GTester: last random seed: R02S55e7df877597841c1b3b62962e410123 make: *** [check-qtest-hppa] Error 1 make: *** Waiting for unfinished jobs https://travis-ci.org/philmd/qemu/jobs/341959060 "compiler": "gcc", "env": "CONFIG=\"--disable-linux-user\"", "dist": "trusty", "os": "linux" https://travis-ci.org/philmd/qemu/jobs/341979253 "compiler": "gcc", "env": "CONFIG=\"--with-coroutine=ucontext --disable-linux-user\"", "dist": "trusty", "os": "linux"
[Qemu-devel] [PATCH 1/3] target/sparc: convert to DisasJumpType
Signed-off-by: Emilio G. Cota--- target/sparc/translate.c | 27 +++ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 71e0853..730e25d 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -30,6 +30,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/translator.h" #include "exec/log.h" #include "asi.h" @@ -69,7 +70,7 @@ typedef struct DisasContext { target_ulong pc;/* current Program Counter: integer or DYNAMIC_PC */ target_ulong npc; /* next PC: integer or DYNAMIC_PC or JUMP_PC */ target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */ -int is_br; +DisasJumpType is_jmp; int mem_idx; bool fpu_enabled; bool address_mask_32bit; @@ -995,7 +996,7 @@ static void gen_branch_a(DisasContext *dc, target_ulong pc1) gen_set_label(l1); gen_goto_tb(dc, 1, npc + 4, npc + 8); -dc->is_br = 1; +dc->is_jmp = DISAS_NORETURN; } static void gen_branch_n(DisasContext *dc, target_ulong pc1) @@ -1078,7 +1079,7 @@ static void gen_exception(DisasContext *dc, int which) t = tcg_const_i32(which); gen_helper_raise_exception(cpu_env, t); tcg_temp_free_i32(t); -dc->is_br = 1; +dc->is_jmp = DISAS_NORETURN; } static void gen_check_align(TCGv addr, int mask) @@ -3346,7 +3347,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) if (cond == 8) { /* An unconditional trap ends the TB. */ -dc->is_br = 1; +dc->is_jmp = DISAS_NORETURN; goto jmp_insn; } else { /* A conditional trap falls through to the next insn. */ @@ -4326,7 +4327,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) save_state(dc); gen_op_next_insn(); tcg_gen_exit_tb(0); -dc->is_br = 1; +dc->is_jmp = DISAS_NORETURN; break; case 0x6: /* V9 wrfprs */ tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); @@ -4335,7 +4336,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) save_state(dc); gen_op_next_insn(); tcg_gen_exit_tb(0); -dc->is_br = 1; +dc->is_jmp = DISAS_NORETURN; break; case 0xf: /* V9 sir, nop if user */ #if !defined(CONFIG_USER_ONLY) @@ -4463,7 +4464,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) save_state(dc); gen_op_next_insn(); tcg_gen_exit_tb(0); -dc->is_br = 1; +dc->is_jmp = DISAS_NORETURN; #endif } break; @@ -4619,7 +4620,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) save_state(dc); gen_op_next_insn(); tcg_gen_exit_tb(0); -dc->is_br = 1; +dc->is_jmp = DISAS_NORETURN; break; case 1: // htstate // XXX gen_op_wrhtstate(); @@ -5685,7 +5686,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) } else if (dc->npc == JUMP_PC) { /* we can do a static jump */ gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond); -dc->is_br = 1; +dc->is_jmp = DISAS_NORETURN; } else { dc->pc = dc->npc; dc->npc = dc->npc + 4; @@ -5747,6 +5748,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock * tb) pc_start = tb->pc; dc->pc = pc_start; last_pc = dc->pc; +dc->is_jmp = DISAS_NEXT; dc->npc = (target_ulong) tb->cs_base; dc->cc_op = CC_OP_DYNAMIC; dc->mem_idx = tb->flags & TB_FLAG_MMU_MASK; @@ -5791,7 +5793,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock * tb) } gen_helper_debug(cpu_env); tcg_gen_exit_tb(0); -dc->is_br = 1; +dc->is_jmp = DISAS_NORETURN; goto exit_gen_loop; } @@ -5803,8 +5805,9 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock * tb) disas_sparc_insn(dc, insn); -if (dc->is_br) +if (dc->is_jmp == DISAS_NORETURN) { break; +} /* if the next PC is different, we
[Qemu-devel] [PATCH 3/3] target/sparc: convert to TranslatorOps
Notes: - Moved the cross-page check from the end of translate_insn to init_disas_context. Signed-off-by: Emilio G. Cota--- target/sparc/translate.c | 181 +++ 1 file changed, 88 insertions(+), 93 deletions(-) diff --git a/target/sparc/translate.c b/target/sparc/translate.c index da77a27..5a25a51 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -5732,105 +5732,94 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) } } -void gen_intermediate_code(CPUState *cs, TranslationBlock * tb) +static int sparc_tr_init_disas_context(DisasContextBase *dcbase, + CPUState *cs, int max_insns) { +DisasContext *dc = container_of(dcbase, DisasContext, base); CPUSPARCState *env = cs->env_ptr; -DisasContext dc1, *dc = -int max_insns; -unsigned int insn; - -memset(dc, 0, sizeof(DisasContext)); -dc->base.tb = tb; -dc->base.pc_first = tb->pc; -dc->base.pc_next = tb->pc; -dc->base.is_jmp = DISAS_NEXT; -dc->base.num_insns = 0; -dc->base.singlestep_enabled = cs->singlestep_enabled; +int bound; dc->pc = dc->base.pc_first; -dc->npc = (target_ulong) tb->cs_base; +dc->npc = (target_ulong)dc->base.tb->cs_base; dc->cc_op = CC_OP_DYNAMIC; -dc->mem_idx = tb->flags & TB_FLAG_MMU_MASK; +dc->mem_idx = dc->base.tb->flags & TB_FLAG_MMU_MASK; dc->def = >def; -dc->fpu_enabled = tb_fpu_enabled(tb->flags); -dc->address_mask_32bit = tb_am_enabled(tb->flags); +dc->fpu_enabled = tb_fpu_enabled(dc->base.tb->flags); +dc->address_mask_32bit = tb_am_enabled(dc->base.tb->flags); #ifndef CONFIG_USER_ONLY -dc->supervisor = (tb->flags & TB_FLAG_SUPER) != 0; +dc->supervisor = (dc->base.tb->flags & TB_FLAG_SUPER) != 0; #endif #ifdef TARGET_SPARC64 dc->fprs_dirty = 0; -dc->asi = (tb->flags >> TB_FLAG_ASI_SHIFT) & 0xff; +dc->asi = (dc->base.tb->flags >> TB_FLAG_ASI_SHIFT) & 0xff; #ifndef CONFIG_USER_ONLY -dc->hypervisor = (tb->flags & TB_FLAG_HYPER) != 0; +dc->hypervisor = (dc->base.tb->flags & TB_FLAG_HYPER) != 0; #endif #endif +/* + * if we reach a page boundary, we stop generation so that the + * PC of a TT_TFAULT exception is always in the right page + */ +bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4; +return MIN(max_insns, bound); +} -max_insns = tb_cflags(tb) & CF_COUNT_MASK; -if (max_insns == 0) { -max_insns = CF_COUNT_MASK; -} -if (max_insns > TCG_MAX_INSNS) { -max_insns = TCG_MAX_INSNS; -} -if (singlestep) { -max_insns = 1; -} +static void sparc_tr_tb_start(DisasContextBase *db, CPUState *cs) +{ +} -gen_tb_start(tb); -do { -if (dc->npc & JUMP_PC) { -assert(dc->jump_pc[1] == dc->pc + 4); -tcg_gen_insn_start(dc->pc, dc->jump_pc[0] | JUMP_PC); -} else { -tcg_gen_insn_start(dc->pc, dc->npc); -} -dc->base.num_insns++; +static void sparc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) +{ +DisasContext *dc = container_of(dcbase, DisasContext, base); -if (unlikely(cpu_breakpoint_test(cs, dc->base.pc_next, BP_ANY))) { -if (dc->pc != dc->base.pc_first) { -save_state(dc); -} -gen_helper_debug(cpu_env); -tcg_gen_exit_tb(0); -dc->base.is_jmp = DISAS_NORETURN; -dc->base.pc_next += 4; -goto exit_gen_loop; -} +if (dc->npc & JUMP_PC) { +assert(dc->jump_pc[1] == dc->pc + 4); +tcg_gen_insn_start(dc->pc, dc->jump_pc[0] | JUMP_PC); +} else { +tcg_gen_insn_start(dc->pc, dc->npc); +} +} -if (dc->base.num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) { -gen_io_start(); -} +static bool sparc_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, + const CPUBreakpoint *bp) +{ +DisasContext *dc = container_of(dcbase, DisasContext, base); -insn = cpu_ldl_code(env, dc->pc); -dc->base.pc_next += 4; +if (dc->pc != dc->base.pc_first) { +save_state(dc); +} +gen_helper_debug(cpu_env); +tcg_gen_exit_tb(0); +dc->base.is_jmp = DISAS_NORETURN; +/* update pc_next so that the current instruction is included in tb->size */ +dc->base.pc_next += 4; +return true; +} -disas_sparc_insn(dc, insn); +static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) +{ +DisasContext *dc = container_of(dcbase, DisasContext, base); +CPUSPARCState *env = cs->env_ptr; +unsigned int insn; -if (dc->base.is_jmp == DISAS_NORETURN) { -break; -} -/* if the next PC is different, we abort now */ -if (dc->pc != dc->base.pc_next) { -break; -} -/* if we reach a
[Qemu-devel] [PATCH v3 0/5] Initial write support for MTP objects
v3: 3/5: Add a property that sets r/w to on/off (default:off) Restructure ifdefs 4/5: Sort the response codes 5/5: Use actual names for fields in the dataset Copy uint16_t to wchar_t and use wcstombs to get char type for filename v2: 3/5: Set mtp store flag to read only 4/5: Fix compiler warnings and change default file permissions 5/5: Fix file permissions These patches implement write support for Qemu's MTP emulation. Simple tests such as delete/move/edit/copy work ok. Current issues/TODO: - File transfers > 4GB has not been tested and will probably not work - Some (or most) MTP clients don't advertise hidden files and folders (names that start with a .) even though iiuc Qemu MTP does advertise these files. This can confuse certain applications such as text editors or git. - Also related, file editors typically run fsync when saving. Depending on the MTP client, it may choose not to implement it (such as simple-mtpfs that runs on top of fuse). - Needs more testing :) Bandan Das (5): usb-mtp: Add one more argument when building results usb-mtp: print parent path in IN_IGNORED trace fn usb-mtp: Support delete of mtp objects usb-mtp: Introduce write support for MTP objects usb-mtp: Advertise SendObjectInfo for write support hw/usb/dev-mtp.c | 467 +++ 1 file changed, 438 insertions(+), 29 deletions(-) -- 2.14.3
[Qemu-devel] [PATCH v3 2/5] usb-mtp: print parent path in IN_IGNORED trace fn
Fix a possible null dereference when deleting a folder and its contents. An ignored event might be received for its contents after the parent folder is deleted which will return a null object. Signed-off-by: Bandan Das--- hw/usb/dev-mtp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index b55aa8205e..63f8f3b90b 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -540,9 +540,8 @@ static void inotify_watchfn(void *arg) break; case IN_IGNORED: -o = usb_mtp_object_lookup_name(parent, event->name, event->len); -trace_usb_mtp_inotify_event(s->dev.addr, o->path, - event->mask, "Obj ignored"); +trace_usb_mtp_inotify_event(s->dev.addr, parent->path, + event->mask, "Obj parent dir ignored"); break; default: -- 2.14.3
[Qemu-devel] [PATCH v3 3/5] usb-mtp: Support delete of mtp objects
Write of existing objects by the initiator is acheived by making a temporary buffer with the new changes, deleting the old file and then writing a new file with the same name. Also, add a "readonly" property which needs to be set to false for deletion to work. Signed-off-by: Bandan Das--- hw/usb/dev-mtp.c | 123 +++ 1 file changed, 123 insertions(+) diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index 63f8f3b90b..5ef77f3e9f 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -46,6 +46,7 @@ enum mtp_code { CMD_GET_OBJECT_HANDLES = 0x1007, CMD_GET_OBJECT_INFO= 0x1008, CMD_GET_OBJECT = 0x1009, +CMD_DELETE_OBJECT = 0x100b, CMD_GET_PARTIAL_OBJECT = 0x101b, CMD_GET_OBJECT_PROPS_SUPPORTED = 0x9801, CMD_GET_OBJECT_PROP_DESC = 0x9802, @@ -62,6 +63,8 @@ enum mtp_code { RES_INVALID_STORAGE_ID = 0x2008, RES_INVALID_OBJECT_HANDLE = 0x2009, RES_INVALID_OBJECT_FORMAT_CODE = 0x200b, +RES_STORE_READ_ONLY= 0x200e, +RES_PARTIAL_DELETE = 0x2012, RES_SPEC_BY_FORMAT_UNSUPPORTED = 0x2014, RES_INVALID_PARENT_OBJECT = 0x201a, RES_INVALID_PARAMETER = 0x201d, @@ -172,6 +175,7 @@ struct MTPState { MTPControl *result; uint32_t session; uint32_t next_handle; +bool readonly; QTAILQ_HEAD(, MTPObject) objects; #ifdef CONFIG_INOTIFY1 @@ -799,6 +803,7 @@ static MTPData *usb_mtp_get_device_info(MTPState *s, MTPControl *c) CMD_GET_NUM_OBJECTS, CMD_GET_OBJECT_HANDLES, CMD_GET_OBJECT_INFO, +CMD_DELETE_OBJECT, CMD_GET_OBJECT, CMD_GET_PARTIAL_OBJECT, CMD_GET_OBJECT_PROPS_SUPPORTED, @@ -1113,6 +1118,116 @@ static MTPData *usb_mtp_get_object_prop_value(MTPState *s, MTPControl *c, return d; } +/* Return correct return code for a delete event */ +enum { +ALL_DELETE, +PARTIAL_DELETE, +READ_ONLY, +}; + +/* Assumes that children, if any, have been already freed */ +static void usb_mtp_object_free_one(MTPState *s, MTPObject *o) +{ +#ifndef CONFIG_INOTIFY1 +assert(o->nchildren == 0); +QTAILQ_REMOVE(>objects, o, next); +g_free(o->name); +g_free(o->path); +g_free(o); +#endif +} + +static int usb_mtp_deletefn(MTPState *s, MTPObject *o, uint32_t trans) +{ +MTPObject *iter, *iter2; +bool partial_delete = false; +bool success = false; + +/* + * TODO: Add support for Protection Status + */ + +QLIST_FOREACH(iter, >children, list) { +if (iter->format == FMT_ASSOCIATION) { +QLIST_FOREACH(iter2, >children, list) { +usb_mtp_deletefn(s, iter2, trans); +} +} +} + +if (o->format == FMT_UNDEFINED_OBJECT) { +if (remove(o->path)) { +partial_delete = true; +} else { +usb_mtp_object_free_one(s, o); +success = true; +} +} + +if (o->format == FMT_ASSOCIATION) { +if (rmdir(o->path)) { +partial_delete = true; +} else { +usb_mtp_object_free_one(s, o); +success = true; +} +} + +if (success && partial_delete) { +return PARTIAL_DELETE; +} +if (!success && partial_delete) { +return READ_ONLY; +} +return ALL_DELETE; +} + +static void usb_mtp_object_delete(MTPState *s, uint32_t handle, + uint32_t format_code, uint32_t trans) +{ +MTPObject *o; +int ret; + +/* Return error if store is read-only */ +if (!FLAG_SET(s, MTP_FLAG_WRITABLE)) { +usb_mtp_queue_result(s, RES_STORE_READ_ONLY, + trans, 0, 0, 0, 0); +return; +} + +if (format_code != 0) { +usb_mtp_queue_result(s, RES_SPEC_BY_FORMAT_UNSUPPORTED, + trans, 0, 0, 0, 0); +return; +} + +if (handle == 0xFFF) { +o = QTAILQ_FIRST(>objects); +} else { +o = usb_mtp_object_lookup(s, handle); +} +if (o == NULL) { +usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, + trans, 0, 0, 0, 0); +return; +} + +ret = usb_mtp_deletefn(s, o, trans); +if (ret == PARTIAL_DELETE) { +usb_mtp_queue_result(s, RES_PARTIAL_DELETE, + trans, 0, 0, 0, 0); +return; +} else if (ret == READ_ONLY) { +usb_mtp_queue_result(s, RES_STORE_READ_ONLY, trans, + 0, 0, 0, 0); +return; +} else { +usb_mtp_queue_result(s, RES_OK, trans, + 0, 0, 0, 0); +return; +} +} + static void usb_mtp_command(MTPState *s, MTPControl *c) { MTPData *data_in = NULL; @@ -1239,6 +1354,9 @@ static void usb_mtp_command(MTPState *s, MTPControl *c)
[Qemu-devel] [PATCH v3 1/5] usb-mtp: Add one more argument when building results
The response to a SendObjectInfo consists of the storageid, parent obejct handle and the handle reserved for the new incoming object Signed-off-by: Bandan Das--- hw/usb/dev-mtp.c | 50 +++--- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index 94c2e94f10..b55aa8205e 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -765,7 +765,8 @@ static void usb_mtp_add_time(MTPData *data, time_t time) /* --- */ static void usb_mtp_queue_result(MTPState *s, uint16_t code, uint32_t trans, - int argc, uint32_t arg0, uint32_t arg1) + int argc, uint32_t arg0, uint32_t arg1, + uint32_t arg2) { MTPControl *c = g_new0(MTPControl, 1); @@ -778,6 +779,9 @@ static void usb_mtp_queue_result(MTPState *s, uint16_t code, uint32_t trans, if (argc > 1) { c->argv[1] = arg1; } +if (argc > 2) { +c->argv[2] = arg2; +} assert(s->result == NULL); s->result = c; @@ -1119,7 +1123,7 @@ static void usb_mtp_command(MTPState *s, MTPControl *c) /* sanity checks */ if (c->code >= CMD_CLOSE_SESSION && s->session == 0) { usb_mtp_queue_result(s, RES_SESSION_NOT_OPEN, - c->trans, 0, 0, 0); + c->trans, 0, 0, 0, 0); return; } @@ -1131,12 +1135,12 @@ static void usb_mtp_command(MTPState *s, MTPControl *c) case CMD_OPEN_SESSION: if (s->session) { usb_mtp_queue_result(s, RES_SESSION_ALREADY_OPEN, - c->trans, 1, s->session, 0); + c->trans, 1, s->session, 0, 0); return; } if (c->argv[0] == 0) { usb_mtp_queue_result(s, RES_INVALID_PARAMETER, - c->trans, 0, 0, 0); + c->trans, 0, 0, 0, 0); return; } trace_usb_mtp_op_open_session(s->dev.addr); @@ -1165,7 +1169,7 @@ static void usb_mtp_command(MTPState *s, MTPControl *c) if (c->argv[0] != QEMU_STORAGE_ID && c->argv[0] != 0x) { usb_mtp_queue_result(s, RES_INVALID_STORAGE_ID, - c->trans, 0, 0, 0); + c->trans, 0, 0, 0, 0); return; } data_in = usb_mtp_get_storage_info(s, c); @@ -1175,12 +1179,12 @@ static void usb_mtp_command(MTPState *s, MTPControl *c) if (c->argv[0] != QEMU_STORAGE_ID && c->argv[0] != 0x) { usb_mtp_queue_result(s, RES_INVALID_STORAGE_ID, - c->trans, 0, 0, 0); + c->trans, 0, 0, 0, 0); return; } if (c->argv[1] != 0x) { usb_mtp_queue_result(s, RES_SPEC_BY_FORMAT_UNSUPPORTED, - c->trans, 0, 0, 0); + c->trans, 0, 0, 0, 0); return; } if (c->argv[2] == 0x || @@ -1191,12 +1195,12 @@ static void usb_mtp_command(MTPState *s, MTPControl *c) } if (o == NULL) { usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, - c->trans, 0, 0, 0); + c->trans, 0, 0, 0, 0); return; } if (o->format != FMT_ASSOCIATION) { usb_mtp_queue_result(s, RES_INVALID_PARENT_OBJECT, - c->trans, 0, 0, 0); + c->trans, 0, 0, 0, 0); return; } usb_mtp_object_readdir(s, o); @@ -1212,7 +1216,7 @@ static void usb_mtp_command(MTPState *s, MTPControl *c) o = usb_mtp_object_lookup(s, c->argv[0]); if (o == NULL) { usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, - c->trans, 0, 0, 0); + c->trans, 0, 0, 0, 0); return; } data_in = usb_mtp_get_object_info(s, c, o); @@ -1221,18 +1225,18 @@ static void usb_mtp_command(MTPState *s, MTPControl *c) o = usb_mtp_object_lookup(s, c->argv[0]); if (o == NULL) { usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, - c->trans, 0, 0, 0); + c->trans, 0, 0, 0, 0); return; } if (o->format == FMT_ASSOCIATION) { usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, - c->trans, 0, 0, 0); + c->trans, 0, 0, 0, 0); return; } data_in = usb_mtp_get_object(s, c, o); if (data_in == NULL) {
[Qemu-devel] [PATCH v6 11/12] s390-ccw: set cp_receive mask only when needed and consume pending service irqs
It is possible while waiting for multiple types of external interrupts that we might have pending irqs remaining between irq consumption and irq-type disabling. Those interrupts could potentially propagate to the guest after IPL completes and cause unwanted behavior. As it is today, the SCLP will only recognize write events that are enabled by the control program's send and receive masks. To limit the window for, and prevent further irqs from, ASCII console events (specifically keystrokes), we should only enable the control program's receive mask when we need it. As an additional measure, once we've disabled/cleared the control program's receive mask, we will print an empty string in order to consume any pending service interrupt. Signed-off-by: Collin L. Walling--- pc-bios/s390-ccw/menu.c | 5 + pc-bios/s390-ccw/s390-ccw.h | 1 + pc-bios/s390-ccw/sclp.c | 10 -- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/pc-bios/s390-ccw/menu.c b/pc-bios/s390-ccw/menu.c index 9601043..14410a8 100644 --- a/pc-bios/s390-ccw/menu.c +++ b/pc-bios/s390-ccw/menu.c @@ -11,6 +11,7 @@ #include "menu.h" #include "s390-ccw.h" +#include "sclp.h" #define KEYCODE_NO_INP '\0' #define KEYCODE_ESCAPE '\033' @@ -117,8 +118,12 @@ static int get_index(void) memset(buf, 0, sizeof(buf)); +sclp_set_write_mask(SCLP_EVENT_MASK_MSG_ASCII, SCLP_EVENT_MASK_MSG_ASCII); len = read_prompt(buf, sizeof(buf)); +sclp_set_write_mask(0, SCLP_EVENT_MASK_MSG_ASCII); +sclp_print(""); /* Clear any pending service int */ + /* If no input, boot default */ if (len == 0) { return 0; diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h index a7e6253..ebdcf86 100644 --- a/pc-bios/s390-ccw/s390-ccw.h +++ b/pc-bios/s390-ccw/s390-ccw.h @@ -69,6 +69,7 @@ unsigned int get_loadparm_index(void); /* sclp.c */ void sclp_print(const char *string); +void sclp_set_write_mask(uint32_t receive_mask, uint32_t send_mask); void sclp_setup(void); void sclp_get_loadparm_ascii(char *loadparm); int sclp_read(char *str, size_t count); diff --git a/pc-bios/s390-ccw/sclp.c b/pc-bios/s390-ccw/sclp.c index abce139..21076f8 100644 --- a/pc-bios/s390-ccw/sclp.c +++ b/pc-bios/s390-ccw/sclp.c @@ -46,23 +46,21 @@ static int sclp_service_call(unsigned int command, void *sccb) return 0; } -static void sclp_set_write_mask(void) +void sclp_set_write_mask(uint32_t receive_mask, uint32_t send_mask) { WriteEventMask *sccb = (void *)_sccb; sccb->h.length = sizeof(WriteEventMask); sccb->mask_length = sizeof(unsigned int); -sccb->receive_mask = SCLP_EVENT_MASK_MSG_ASCII; -sccb->cp_receive_mask = SCLP_EVENT_MASK_MSG_ASCII; -sccb->send_mask = SCLP_EVENT_MASK_MSG_ASCII; -sccb->cp_send_mask = SCLP_EVENT_MASK_MSG_ASCII; +sccb->cp_receive_mask = receive_mask; +sccb->cp_send_mask = send_mask; sclp_service_call(SCLP_CMD_WRITE_EVENT_MASK, sccb); } void sclp_setup(void) { -sclp_set_write_mask(); +sclp_set_write_mask(0, SCLP_EVENT_MASK_MSG_ASCII); } static int _strlen(const char *str) -- 2.7.4
[Qemu-devel] [PATCH 2/3] target/sparc: convert to DisasContextBase
Notes: - pc and npc are left unmodified, since they can point to out-of-TB jump targets. - Got rid of last_pc in gen_intermediate_code(), using base.pc_next instead. Only update pc_next (1) on a breakpoint (so that tb->size includes the insn), and (2) after reading the current instruction from memory. This allows us to use base.pc_next in the BP check, which is what the translator loop does. - The original meaning of ctx.singlestep is cs->singlestep_enabled || singlestep , which required a little extra work since base.singlestep_enabled only gets its value from cs->singlestep_enabled. Signed-off-by: Emilio G. Cota--- target/sparc/translate.c | 90 +--- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 730e25d..da77a27 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -67,14 +67,13 @@ static TCGv_i64 cpu_fpr[TARGET_DPREGS]; #include "exec/gen-icount.h" typedef struct DisasContext { +DisasContextBase base; target_ulong pc;/* current Program Counter: integer or DYNAMIC_PC */ target_ulong npc; /* next PC: integer or DYNAMIC_PC or JUMP_PC */ target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */ -DisasJumpType is_jmp; int mem_idx; bool fpu_enabled; bool address_mask_32bit; -bool singlestep; #ifndef CONFIG_USER_ONLY bool supervisor; #ifdef TARGET_SPARC64 @@ -83,7 +82,6 @@ typedef struct DisasContext { #endif uint32_t cc_op; /* current CC operation */ -struct TranslationBlock *tb; sparc_def_t *def; TCGv_i32 t32[3]; TCGv ttl[5]; @@ -342,13 +340,13 @@ static inline TCGv gen_dest_gpr(DisasContext *dc, int reg) static inline bool use_goto_tb(DisasContext *s, target_ulong pc, target_ulong npc) { -if (unlikely(s->singlestep)) { +if (unlikely(s->base.singlestep_enabled || singlestep)) { return false; } #ifndef CONFIG_USER_ONLY -return (pc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) && - (npc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK); +return (pc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) && + (npc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK); #else return true; #endif @@ -362,7 +360,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, tcg_gen_goto_tb(tb_num); tcg_gen_movi_tl(cpu_pc, pc); tcg_gen_movi_tl(cpu_npc, npc); -tcg_gen_exit_tb((uintptr_t)s->tb + tb_num); +tcg_gen_exit_tb((uintptr_t)s->base.tb + tb_num); } else { /* jump to another page: currently not optimized */ tcg_gen_movi_tl(cpu_pc, pc); @@ -996,7 +994,7 @@ static void gen_branch_a(DisasContext *dc, target_ulong pc1) gen_set_label(l1); gen_goto_tb(dc, 1, npc + 4, npc + 8); -dc->is_jmp = DISAS_NORETURN; +dc->base.is_jmp = DISAS_NORETURN; } static void gen_branch_n(DisasContext *dc, target_ulong pc1) @@ -1079,7 +1077,7 @@ static void gen_exception(DisasContext *dc, int which) t = tcg_const_i32(which); gen_helper_raise_exception(cpu_env, t); tcg_temp_free_i32(t); -dc->is_jmp = DISAS_NORETURN; +dc->base.is_jmp = DISAS_NORETURN; } static void gen_check_align(TCGv addr, int mask) @@ -2437,7 +2435,7 @@ static void gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn) default: /* ??? In theory, this should be raise DAE_invalid_asi. But the SS-20 roms do ldstuba [%l0] #ASI_M_CTL, %o1. */ -if (tb_cflags(dc->tb) & CF_PARALLEL) { +if (tb_cflags(dc->base.tb) & CF_PARALLEL) { gen_helper_exit_atomic(cpu_env); } else { TCGv_i32 r_asi = tcg_const_i32(da.asi); @@ -3347,7 +3345,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) if (cond == 8) { /* An unconditional trap ends the TB. */ -dc->is_jmp = DISAS_NORETURN; +dc->base.is_jmp = DISAS_NORETURN; goto jmp_insn; } else { /* A conditional trap falls through to the next insn. */ @@ -4327,7 +4325,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) save_state(dc); gen_op_next_insn(); tcg_gen_exit_tb(0); -dc->is_jmp = DISAS_NORETURN; +dc->base.is_jmp = DISAS_NORETURN; break; case 0x6: /* V9 wrfprs */ tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); @@ -4336,7 +4334,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
Re: [Qemu-devel] [PATCH 07/30] hw/arm: use the BYTE-based definitions
On 02/15/2018 08:03 PM, Alistair Francis wrote: > On Thu, Feb 15, 2018 at 2:39 PM, Philippe Mathieu-Daudé> wrote: >> Hi Alistair, >> >> On 02/15/2018 07:31 PM, Alistair Francis wrote: >>> On Wed, Feb 14, 2018 at 8:28 PM, Philippe Mathieu-Daudé >>> wrote: It ease code review, unit is explicit. Signed-off-by: Philippe Mathieu-Daudé >>> >>> The logic looks good. >>> >>> Did you do this automatically? If so you should include the commands >>> in the commit message. >> >> I added in the cover: >> >> Patches generated using: >> >> $ git grep -E '(1024|2048|4096|8192|(<<|>>).?(10|20|30))' hw/ include/hw/ >> >> and modified manually. > > It should be in the commit message as well, that way it's forever in the tree. I first wanted to avoid duplicating the same command in all the patches from this series, but since they might be cherry-picked independently, this is a good idea, will do. >> >> I use the --cccmd scripts/get_maintainer.pl which select reviewer emails >> for each patch but don't include them in the cover, this is annoying... >> >>> >>> Reviewed-by: Alistair Francis >> >> Thanks! >> >> There is one more use in "raspi: Add "raspi3" machine type" I'll >> update/respin once Peter merged it: >> >> diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c >> -mc->default_ram_size = 1024 * 1024 * 1024; >> +mc->default_ram_size = 1 * G_BYTE; > > You can keep my Reveiwed-by with this change as well. Thanks. > > Alistair > >> >>> >>> Alistair >>> --- include/hw/arm/stm32f205_soc.h | 4 ++-- hw/arm/boot.c | 6 +++--- hw/arm/collie.c| 4 ++-- hw/arm/digic_boards.c | 6 +++--- hw/arm/gumstix.c | 2 +- hw/arm/integratorcp.c | 2 +- hw/arm/mainstone.c | 2 +- hw/arm/musicpal.c | 8 hw/arm/omap_sx1.c | 8 hw/arm/raspi.c | 2 +- hw/arm/stellaris.c | 4 ++-- hw/arm/versatilepb.c | 4 ++-- hw/arm/vexpress.c | 6 +++--- hw/arm/virt.c | 4 ++-- hw/arm/xilinx_zynq.c | 4 ++-- hw/misc/aspeed_sdmc.c | 8 hw/misc/imx7_gpr.c | 2 +- hw/misc/omap_gpmc.c| 4 ++-- hw/ssi/aspeed_smc.c| 28 ++-- 19 files changed, 54 insertions(+), 54 deletions(-) diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h index 922a733f88..e30ae33c65 100644 --- a/include/hw/arm/stm32f205_soc.h +++ b/include/hw/arm/stm32f205_soc.h @@ -43,9 +43,9 @@ #define STM_NUM_SPIS 3 #define FLASH_BASE_ADDRESS 0x0800 -#define FLASH_SIZE (1024 * 1024) +#define FLASH_SIZE (1 * M_BYTE) #define SRAM_BASE_ADDRESS 0x2000 -#define SRAM_SIZE (128 * 1024) +#define SRAM_SIZE (128 * K_BYTE) typedef struct STM32F205State { /*< private >*/ diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 05108bc42f..0552284d57 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -984,7 +984,7 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data) * the initrd at 128MB. */ info->initrd_start = info->loader_start + -MIN(info->ram_size / 2, 128 * 1024 * 1024); +MIN(info->ram_size / 2, 128 * M_BYTE); /* Assume that raw images are linux kernels, and ELF images are not. */ kernel_size = arm_load_elf(info, _entry, _low_addr, @@ -1069,13 +1069,13 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data) * * Let's play safe and prealign it to 2MB to give us some space. */ -align = 2 * 1024 * 1024; +align = 2 * M_BYTE; } else { /* * Some 32bit kernels will trash anything in the 4K page the * initrd ends in, so make sure the DTB isn't caught up in that. */ -align = 4096; +align = 4 * K_BYTE; } /* Place the DTB after the initrd in memory with alignment. */ diff --git a/hw/arm/collie.c b/hw/arm/collie.c index f8c566e2e5..1695863629 100644 --- a/hw/arm/collie.c +++ b/hw/arm/collie.c @@ -39,12 +39,12 @@ static void collie_init(MachineState *machine) dinfo = drive_get(IF_PFLASH, 0, 0); pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x0200, dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, -(64 * 1024), 512, 4, 0x00, 0x00,
[Qemu-devel] [PATCH v6 08/12] s390-ccw: read stage2 boot loader data to find menu
Read the stage2 boot loader data block-by-block. We scan the current block for the string "zIPL" to detect the start of the boot menu banner. We then load the adjacent blocks (previous block and next block) to account for the possibility of menu data spanning multiple blocks. Signed-off-by: Collin L. WallingReviewed-by: Thomas Huth --- pc-bios/s390-ccw/bootmap.c | 94 +++--- pc-bios/s390-ccw/bootmap.h | 23 +++- pc-bios/s390-ccw/menu.c| 5 +++ pc-bios/s390-ccw/menu.h| 1 + 4 files changed, 116 insertions(+), 7 deletions(-) diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index a94638d..5358301 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -13,6 +13,7 @@ #include "bootmap.h" #include "virtio.h" #include "bswap.h" +#include "menu.h" #ifdef DEBUG /* #define DEBUG_FALLBACK */ @@ -83,6 +84,10 @@ static void jump_to_IPL_code(uint64_t address) static unsigned char _bprs[8*1024]; /* guessed "max" ECKD sector size */ static const int max_bprs_entries = sizeof(_bprs) / sizeof(ExtEckdBlockPtr); +static uint8_t _s2[MAX_SECTOR_SIZE * 3] __attribute__((__aligned__(PAGE_SIZE))); +static void *s2_prev_blk = _s2; +static void *s2_cur_blk = _s2 + MAX_SECTOR_SIZE; +static void *s2_next_blk = _s2 + MAX_SECTOR_SIZE * 2; static inline void verify_boot_info(BootInfo *bip) { @@ -182,7 +187,76 @@ static block_number_t load_eckd_segments(block_number_t blk, uint64_t *address) return block_nr; } -static void run_eckd_boot_script(block_number_t bmt_block_nr) +static bool find_zipl_boot_menu_banner(int *offset) +{ +int i; + +/* Menu banner starts with "zIPL" */ +for (i = 0; i < virtio_get_block_size() - 4; i++) { +if (magic_match(s2_cur_blk + i, ZIPL_MAGIC_EBCDIC)) { +*offset = i; +return true; +} +} + +return false; +} + +static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) +{ +block_number_t cur_block_nr; +block_number_t prev_block_nr = 0; +block_number_t next_block_nr = 0; +EckdStage1b *s1b = (void *)sec; +int offset; +int i; + +/* Get Stage1b data */ +memset(sec, FREE_SPACE_FILLER, sizeof(sec)); +read_block(s1b_block_nr, s1b, "Cannot read stage1b boot loader"); + +memset(_s2, FREE_SPACE_FILLER, sizeof(_s2)); + +/* Get Stage2 data */ +for (i = 0; i < STAGE2_BLK_CNT_MAX; i++) { +cur_block_nr = eckd_block_num(>seek[i].chs); + +if (!cur_block_nr) { +break; +} + +read_block(cur_block_nr, s2_cur_blk, "Cannot read stage2 boot loader"); + +if (find_zipl_boot_menu_banner()) { +/* Load the adjacent blocks to account for the + * possibility of menu data spanning multiple blocks. + */ +if (prev_block_nr) { +read_block(prev_block_nr, s2_prev_blk, + "Cannot read stage2 boot loader"); +} + +if (i + 1 < STAGE2_BLK_CNT_MAX) { +next_block_nr = eckd_block_num(>seek[i + 1].chs); +} + +if (next_block_nr) { +read_block(next_block_nr, s2_next_blk, + "Cannot read stage2 boot loader"); +} + +return menu_get_zipl_boot_index(s2_cur_blk, offset); +} + +prev_block_nr = cur_block_nr; +} + +sclp_print("No zipl boot menu data found. Booting default entry."); +return 0; +} + +static void run_eckd_boot_script(block_number_t bmt_block_nr, + block_number_t s1b_block_nr) { int i; unsigned int loadparm = get_loadparm_index(); @@ -191,6 +265,10 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr) BootMapTable *bmt = (void *)sec; BootMapScript *bms = (void *)sec; +if (menu_check_flags(BOOT_MENU_FLAG_CMD_OPTS | BOOT_MENU_FLAG_ZIPL_OPTS)) { +loadparm = eckd_get_boot_menu_index(s1b_block_nr); +} + debug_print_int("loadparm", loadparm); IPL_assert(loadparm <= MAX_TABLE_ENTRIES, "loadparm value greater than" " maximum number of boot entries allowed"); @@ -223,7 +301,7 @@ static void ipl_eckd_cdl(void) XEckdMbr *mbr; EckdCdlIpl2 *ipl2 = (void *)sec; IplVolumeLabel *vlbl = (void *)sec; -block_number_t bmt_block_nr; +block_number_t bmt_block_nr, s1b_block_nr; /* we have just read the block #0 and recognized it as "IPL1" */ sclp_print("CDL\n"); @@ -241,6 +319,9 @@ static void ipl_eckd_cdl(void) /* save pointer to Boot Map Table */ bmt_block_nr = eckd_block_num(>blockptr.xeckd.bptr.chs); +/* save pointer to Stage1b Data */ +s1b_block_nr = eckd_block_num(>stage1.seek[0].chs); + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); read_block(2, vlbl, "Cannot read Volume Label at block 2");
[Qemu-devel] [PATCH 0/3] target/sparc: translator loop conversion
Tested by booting a NetBSD guest. Thanks, Emilio
Re: [Qemu-devel] [PATCH v2 1/1] hw: register: Run post_write hook on reset
On Mon, Feb 5, 2018 at 10:44 AM, Alistair Franciswrote: > Ensure that the post write hook is called during reset. This allows us > to rely on the post write functions instead of having to call them from > the reset() function. > > Signed-off-by: Alistair Francis > Reviewed-by: Philippe Mathieu-Daudé Ping! > --- > > V2: > - Update the header documentation > > include/hw/register.h | 6 +++--- > hw/core/register.c| 8 > 2 files changed, 11 insertions(+), 3 deletions(-) > > diff --git a/include/hw/register.h b/include/hw/register.h > index de2414e6b4..5796584588 100644 > --- a/include/hw/register.h > +++ b/include/hw/register.h > @@ -34,7 +34,7 @@ typedef struct RegisterInfoArray RegisterInfoArray; > * immediately before the actual write. The returned value is what is > written, > * giving the handler a chance to modify the written value. > * @post_write: Post write callback. Passed the written value. Most write > side > - * effects should be implemented here. > + * effects should be implemented here. This is called during device reset. > * > * @post_read: Post read callback. Passes the value that is about to be > returned > * for a read. The return value from this function is what is ultimately > read, > @@ -135,8 +135,8 @@ uint64_t register_read(RegisterInfo *reg, uint64_t re, > const char* prefix, > bool debug); > > /** > - * reset a register > - * @reg: register to reset > + * Resets a register. This will also call the post_write hook if it exists. > + * @reg: The register to reset. > */ > > void register_reset(RegisterInfo *reg); > diff --git a/hw/core/register.c b/hw/core/register.c > index 900294b9c4..0741a1af32 100644 > --- a/hw/core/register.c > +++ b/hw/core/register.c > @@ -159,13 +159,21 @@ uint64_t register_read(RegisterInfo *reg, uint64_t re, > const char* prefix, > > void register_reset(RegisterInfo *reg) > { > +const RegisterAccessInfo *ac; > + > g_assert(reg); > > if (!reg->data || !reg->access) { > return; > } > > +ac = reg->access; > + > register_write_val(reg, reg->access->reset); > + > +if (ac->post_write) { > +ac->post_write(reg, reg->access->reset); > +} > } > > void register_init(RegisterInfo *reg) > -- > 2.14.1 >
[Qemu-devel] [PATCH v6 02/12] s390-ccw: refactor eckd_block_num to use CHS
Add new cylinder/head/sector struct. Use it to calculate eckd block numbers instead of a BootMapPointer (which used eckd chs anyway). Signed-off-by: Collin L. Walling--- pc-bios/s390-ccw/bootmap.c | 28 ++-- pc-bios/s390-ccw/bootmap.h | 8 ++-- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index 286de40..9534f56 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -95,32 +95,32 @@ static inline void verify_boot_info(BootInfo *bip) "Bad block size in zIPL section of the 1st record."); } -static block_number_t eckd_block_num(BootMapPointer *p) +static block_number_t eckd_block_num(EckdCHS *chs) { const uint64_t sectors = virtio_get_sectors(); const uint64_t heads = virtio_get_heads(); -const uint64_t cylinder = p->eckd.cylinder -+ ((p->eckd.head & 0xfff0) << 12); -const uint64_t head = p->eckd.head & 0x000f; +const uint64_t cylinder = chs->cylinder ++ ((chs->head & 0xfff0) << 12); +const uint64_t head = chs->head & 0x000f; const block_number_t block = sectors * heads * cylinder + sectors * head - + p->eckd.sector + + chs->sector - 1; /* block nr starts with zero */ return block; } static bool eckd_valid_address(BootMapPointer *p) { -const uint64_t head = p->eckd.head & 0x000f; +const uint64_t head = p->eckd.chs.head & 0x000f; if (head >= virtio_get_heads() -|| p->eckd.sector > virtio_get_sectors() -|| p->eckd.sector <= 0) { +|| p->eckd.chs.sector > virtio_get_sectors() +|| p->eckd.chs.sector <= 0) { return false; } if (!virtio_guessed_disk_nature() && -eckd_block_num(p) >= virtio_get_blocks()) { +eckd_block_num(>eckd.chs) >= virtio_get_blocks()) { return false; } @@ -140,7 +140,7 @@ static block_number_t load_eckd_segments(block_number_t blk, uint64_t *address) do { more_data = false; for (j = 0;; j++) { -block_nr = eckd_block_num((void *)&(bprs[j].xeckd)); +block_nr = eckd_block_num([j].xeckd.bptr.chs); if (is_null_block_number(block_nr)) { /* end of chunk */ break; } @@ -198,7 +198,7 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr) memset(sec, FREE_SPACE_FILLER, sizeof(sec)); read_block(bmt_block_nr, sec, "Cannot read Boot Map Table"); -block_nr = eckd_block_num((void *)>entry[loadparm]); +block_nr = eckd_block_num(>entry[loadparm].xeckd.bptr.chs); IPL_assert(block_nr != -1, "Cannot find Boot Map Table Entry"); memset(sec, FREE_SPACE_FILLER, sizeof(sec)); @@ -206,7 +206,7 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr) for (i = 0; bms->entry[i].type == BOOT_SCRIPT_LOAD; i++) { address = bms->entry[i].address.load_address; -block_nr = eckd_block_num(&(bms->entry[i].blkptr)); +block_nr = eckd_block_num(>entry[i].blkptr.xeckd.bptr.chs); do { block_nr = load_eckd_segments(block_nr, ); @@ -239,7 +239,7 @@ static void ipl_eckd_cdl(void) "Non-ECKD device type in zIPL section of IPL2 record."); /* save pointer to Boot Map Table */ -bmt_block_nr = eckd_block_num((void *)>blockptr); +bmt_block_nr = eckd_block_num(>blockptr.xeckd.bptr.chs); memset(sec, FREE_SPACE_FILLER, sizeof(sec)); read_block(2, vlbl, "Cannot read Volume Label at block 2"); @@ -300,7 +300,7 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) verify_boot_info(bip); /* save pointer to Boot Map Table */ -bmt_block_nr = eckd_block_num((void *)>bp.ipl.bm_ptr.eckd.bptr); +bmt_block_nr = eckd_block_num(>bp.ipl.bm_ptr.eckd.bptr.chs); run_eckd_boot_script(bmt_block_nr); /* no return */ diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h index 850b655..7a13c9b 100644 --- a/pc-bios/s390-ccw/bootmap.h +++ b/pc-bios/s390-ccw/bootmap.h @@ -32,10 +32,14 @@ typedef struct FbaBlockPtr { uint16_t blockct; } __attribute__ ((packed)) FbaBlockPtr; -typedef struct EckdBlockPtr { -uint16_t cylinder; /* cylinder/head/sector is an address of the block */ +typedef struct EckdCHS { +uint16_t cylinder; uint16_t head; uint8_t sector; +} __attribute__ ((packed)) EckdCHS; + +typedef struct EckdBlockPtr { +EckdCHS chs; /* cylinder/head/sector is an address of the block */ uint16_t size; uint8_t count; /* (size_in_blocks-1); * it's 0 for TablePtr, ScriptPtr, and SectionPtr */ -- 2.7.4
[Qemu-devel] [PATCH v3 5/5] usb-mtp: Advertise SendObjectInfo for write support
This patch implements a dummy ObjectInfo structure so that it's easy to typecast the incoming data. If the metadata is valid, write_pending is set. Also, the incoming filename is utf-16, so, instead of depending on external libraries, just implement a simple function to get the filename Signed-off-by: Bandan Das--- hw/usb/dev-mtp.c | 130 ++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index 4f369e1277..e015bbe771 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -47,6 +47,7 @@ enum mtp_code { CMD_GET_OBJECT_INFO= 0x1008, CMD_GET_OBJECT = 0x1009, CMD_DELETE_OBJECT = 0x100b, +CMD_SEND_OBJECT_INFO = 0x100c, CMD_SEND_OBJECT= 0x100d, CMD_GET_PARTIAL_OBJECT = 0x101b, CMD_GET_OBJECT_PROPS_SUPPORTED = 0x9801, @@ -67,8 +68,10 @@ enum mtp_code { RES_STORE_FULL = 0x200c, RES_STORE_READ_ONLY= 0x200e, RES_PARTIAL_DELETE = 0x2012, +RES_STORE_NOT_AVAILABLE= 0x2013, RES_SPEC_BY_FORMAT_UNSUPPORTED = 0x2014, RES_INVALID_OBJECTINFO = 0x2015, +RES_DESTINATION_UNSUPPORTED= 0x2020, RES_INVALID_PARENT_OBJECT = 0x201a, RES_INVALID_PARAMETER = 0x201d, RES_SESSION_ALREADY_OPEN = 0x201e, @@ -196,6 +199,34 @@ struct MTPState { } dataset; }; +/* + * ObjectInfo dataset received from initiator + * Fields we don't care about are ignored + */ +typedef struct { +uint32_t storage_id; /*unused*/ +uint16_t format; +uint16_t protection_status; /*unused*/ +uint32_t size; +uint16_t thumb_format; /*unused*/ +uint32_t thumb_comp_sz; /*unused*/ +uint32_t thumb_pix_width; /*unused*/ +uint32_t thumb_pix_height; /*unused*/ +uint32_t image_pix_width; /*unused*/ +uint32_t image_pix_height; /*unused*/ +uint32_t image_bit_depth; /*unused*/ +uint32_t parent; /*unused*/ +uint16_t assoc_type; +uint32_t assoc_desc; +uint32_t seq_no; /*unused*/ +uint8_t length; /*part of filename field*/ +uint16_t filename[0]; +char date_created[0]; /*unused*/ +char date_modified[0]; /*unused*/ +char keywords[0]; /*unused*/ +/* string and other data follows */ +} QEMU_PACKED ObjectInfo; + #define TYPE_USB_MTP "usb-mtp" #define USB_MTP(obj) OBJECT_CHECK(MTPState, (obj), TYPE_USB_MTP) @@ -815,6 +846,7 @@ static MTPData *usb_mtp_get_device_info(MTPState *s, MTPControl *c) CMD_GET_OBJECT_HANDLES, CMD_GET_OBJECT_INFO, CMD_DELETE_OBJECT, +CMD_SEND_OBJECT_INFO, CMD_SEND_OBJECT, CMD_GET_OBJECT, CMD_GET_PARTIAL_OBJECT, @@ -1243,7 +1275,7 @@ static void usb_mtp_object_delete(MTPState *s, uint32_t handle, static void usb_mtp_command(MTPState *s, MTPControl *c) { MTPData *data_in = NULL; -MTPObject *o; +MTPObject *o = NULL; uint32_t nres = 0, res0 = 0; /* sanity checks */ @@ -1390,6 +1422,37 @@ static void usb_mtp_command(MTPState *s, MTPControl *c) nres = 1; res0 = data_in->length; break; +case CMD_SEND_OBJECT_INFO: +/* First parameter points to storage id or is 0 */ +if (c->argv[0] && (c->argv[0] != QEMU_STORAGE_ID)) { +usb_mtp_queue_result(s, RES_STORE_NOT_AVAILABLE, c->trans, + 0, 0, 0, 0); +} else if (c->argv[1] && !c->argv[0]) { +/* If second parameter is specified, first must also be specified */ +usb_mtp_queue_result(s, RES_DESTINATION_UNSUPPORTED, c->trans, + 0, 0, 0, 0); +} else { +uint32_t handle = c->argv[1]; +if (handle == 0x || handle == 0) { +/* root object */ +o = QTAILQ_FIRST(>objects); +} else { +o = usb_mtp_object_lookup(s, handle); +} +if (o == NULL) { +usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, c->trans, + 0, 0, 0, 0); +} +if (o->format != FMT_ASSOCIATION) { +usb_mtp_queue_result(s, RES_INVALID_PARENT_OBJECT, c->trans, + 0, 0, 0, 0); +} +} +if (o) { +s->dataset.parent_handle = o->handle; +} +s->data_out = usb_mtp_data_alloc(c); +return; case CMD_SEND_OBJECT: if (!s->write_pending) { usb_mtp_queue_result(s, RES_INVALID_OBJECTINFO, @@ -1499,6 +1562,19 @@ mode_t getumask(void) return mask; } +static void utf16_to_str(uint8_t len, uint16_t *arr, char *name) +{ +int count; +wchar_t *wstr = g_new0(wchar_t, len); + +for (count = 0; count < len; count++) { +wstr[count] = (wchar_t)arr[count]; +} + +
[Qemu-devel] [PATCH v6 12/12] s390-ccw: interactive boot menu for scsi
Interactive boot menu for scsi. This follows a similar procedure as the interactive menu for eckd dasd. An example follows: s390x Enumerated Boot Menu. 3 entries detected. Select from index 0 to 2. Signed-off-by: Collin L. WallingReviewed-by: Thomas Huth --- pc-bios/s390-ccw/bootmap.c | 4 pc-bios/s390-ccw/main.c| 1 + pc-bios/s390-ccw/menu.c| 14 ++ pc-bios/s390-ccw/menu.h| 1 + 4 files changed, 20 insertions(+) diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index 5358301..a75550f 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -568,6 +568,10 @@ static void ipl_scsi(void) debug_print_int("program table entries", program_table_entries); IPL_assert(program_table_entries != 0, "Empty Program Table"); +if (menu_check_flags(BOOT_MENU_FLAG_CMD_OPTS)) { +loadparm = menu_get_enum_boot_index(program_table_entries); +} + debug_print_int("loadparm", loadparm); IPL_assert(loadparm <= MAX_TABLE_ENTRIES, "loadparm value greater than" " maximum number of boot entries allowed"); diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c index c643a6b..2226871 100644 --- a/pc-bios/s390-ccw/main.c +++ b/pc-bios/s390-ccw/main.c @@ -92,6 +92,7 @@ static void menu_setup(void) switch (iplb.pbt) { case S390_IPL_TYPE_CCW: +case S390_IPL_TYPE_QEMU_SCSI: menu_set_parms(qipl.boot_menu_flags, qipl.boot_menu_timeout); return; } diff --git a/pc-bios/s390-ccw/menu.c b/pc-bios/s390-ccw/menu.c index 14410a8..d104327 100644 --- a/pc-bios/s390-ccw/menu.c +++ b/pc-bios/s390-ccw/menu.c @@ -215,6 +215,20 @@ int menu_get_zipl_boot_index(const void *stage2, int offset) return get_boot_index(ct - 1); } +int menu_get_enum_boot_index(int entries) +{ +char tmp[4]; + +sclp_print("s390x Enumerated Boot Menu.\n\n"); + +sclp_print(uitoa(entries, tmp, sizeof(tmp))); +sclp_print(" entries detected. Select from boot index 0 to "); +sclp_print(uitoa(entries - 1, tmp, sizeof(tmp))); +sclp_print(".\n\n"); + +return get_boot_index(entries); +} + void menu_set_parms(uint8_t boot_menu_flag, uint32_t boot_menu_timeout) { flags = boot_menu_flag; diff --git a/pc-bios/s390-ccw/menu.h b/pc-bios/s390-ccw/menu.h index c603de3..790516c 100644 --- a/pc-bios/s390-ccw/menu.h +++ b/pc-bios/s390-ccw/menu.h @@ -18,6 +18,7 @@ #define BOOT_MENU_FLAG_ZIPL_OPTS 0x40 int menu_get_zipl_boot_index(const void *stage2, int offset); +int menu_get_enum_boot_index(int entries); void menu_set_parms(uint8_t boot_menu_flags, uint32_t boot_menu_timeout); bool menu_check_flags(uint8_t check_flags); -- 2.7.4
[Qemu-devel] [PATCH v3 4/5] usb-mtp: Introduce write support for MTP objects
Allow write operations on behalf of the initiator. The precursor to write is the sending of the write metadata that consists of the ObjectInfo dataset. This patch introduces a flag that is set when the responder is ready to receive write data based on a previous SendObjectInfo operation by the initiator (The SendObjectInfo implementation is in a later patch) Signed-off-by: Bandan Das--- hw/usb/dev-mtp.c | 159 ++- 1 file changed, 157 insertions(+), 2 deletions(-) diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index 5ef77f3e9f..4f369e1277 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -47,6 +47,7 @@ enum mtp_code { CMD_GET_OBJECT_INFO= 0x1008, CMD_GET_OBJECT = 0x1009, CMD_DELETE_OBJECT = 0x100b, +CMD_SEND_OBJECT= 0x100d, CMD_GET_PARTIAL_OBJECT = 0x101b, CMD_GET_OBJECT_PROPS_SUPPORTED = 0x9801, CMD_GET_OBJECT_PROP_DESC = 0x9802, @@ -63,9 +64,11 @@ enum mtp_code { RES_INVALID_STORAGE_ID = 0x2008, RES_INVALID_OBJECT_HANDLE = 0x2009, RES_INVALID_OBJECT_FORMAT_CODE = 0x200b, +RES_STORE_FULL = 0x200c, RES_STORE_READ_ONLY= 0x200e, RES_PARTIAL_DELETE = 0x2012, RES_SPEC_BY_FORMAT_UNSUPPORTED = 0x2014, +RES_INVALID_OBJECTINFO = 0x2015, RES_INVALID_PARENT_OBJECT = 0x201a, RES_INVALID_PARAMETER = 0x201d, RES_SESSION_ALREADY_OPEN = 0x201e, @@ -183,6 +186,14 @@ struct MTPState { int inotifyfd; QTAILQ_HEAD(events, MTPMonEntry) events; #endif +/* Responder is expecting a write operation */ +bool write_pending; +struct { +uint32_t parent_handle; +uint16_t format; +uint32_t size; +char *filename; +} dataset; }; #define TYPE_USB_MTP "usb-mtp" @@ -804,6 +815,7 @@ static MTPData *usb_mtp_get_device_info(MTPState *s, MTPControl *c) CMD_GET_OBJECT_HANDLES, CMD_GET_OBJECT_INFO, CMD_DELETE_OBJECT, +CMD_SEND_OBJECT, CMD_GET_OBJECT, CMD_GET_PARTIAL_OBJECT, CMD_GET_OBJECT_PROPS_SUPPORTED, @@ -1378,6 +1390,14 @@ static void usb_mtp_command(MTPState *s, MTPControl *c) nres = 1; res0 = data_in->length; break; +case CMD_SEND_OBJECT: +if (!s->write_pending) { +usb_mtp_queue_result(s, RES_INVALID_OBJECTINFO, + c->trans, 0, 0, 0, 0); +return; +} +s->data_out = usb_mtp_data_alloc(c); +return; case CMD_GET_OBJECT_PROPS_SUPPORTED: if (c->argv[0] != FMT_UNDEFINED_OBJECT && c->argv[0] != FMT_ASSOCIATION) { @@ -1472,12 +1492,133 @@ static void usb_mtp_cancel_packet(USBDevice *dev, USBPacket *p) fprintf(stderr, "%s\n", __func__); } +mode_t getumask(void) +{ +mode_t mask = umask(0); +umask(mask); +return mask; +} + +static void usb_mtp_write_data(MTPState *s) +{ +MTPData *d = s->data_out; +MTPObject *parent = +usb_mtp_object_lookup(s, s->dataset.parent_handle); +char *path = NULL; +int rc = -1; +mode_t mask = ~getumask() & 0666; + +assert(d != NULL); + +if (parent == NULL || !s->write_pending) { +usb_mtp_queue_result(s, RES_INVALID_OBJECTINFO, d->trans, + 0, 0, 0, 0); +return; +} + +if (s->dataset.filename) { +path = g_strdup_printf("%s/%s", parent->path, s->dataset.filename); +if (s->dataset.format == FMT_ASSOCIATION) { +d->fd = mkdir(path, mask); +goto free; +} +if (s->dataset.size < d->length) { +usb_mtp_queue_result(s, RES_STORE_FULL, d->trans, + 0, 0, 0, 0); +goto done; +} +d->fd = open(path, O_CREAT | O_WRONLY, mask); +if (d->fd == -1) { +usb_mtp_queue_result(s, RES_STORE_FULL, d->trans, + 0, 0, 0, 0); +goto done; +} + +/* + * Return success if initiator sent 0 sized data + */ +if (!s->dataset.size) { +goto success; +} + +rc = write(d->fd, d->data, s->dataset.size); +if (rc == -1) { +usb_mtp_queue_result(s, RES_STORE_FULL, d->trans, + 0, 0, 0, 0); +goto done; +} +if (rc != s->dataset.size) { +usb_mtp_queue_result(s, RES_INCOMPLETE_TRANSFER, d->trans, + 0, 0, 0, 0); +goto done; +} +} + +success: +usb_mtp_queue_result(s, RES_OK, d->trans, + 0, 0, 0, 0); + +done: +/* + * The write dataset is kept around and freed only + * on success or if another write request comes in + */ +if (d->fd != -1) {
[Qemu-devel] [PATCH v6 00/12] Interactive Boot Menu for DASD and SCSI Guests on s390x
--- [v6] --- - cleaned up libc.c - expanded timeout field in QemuIPLB from 2 bytes to 4 bytes - we can now store the timeout value from command line as ms - sclp_set_write_mask now accepts two parameters: - receive_mask - send_mask - the write mask for receive is only set when we need it (reading user inp) and cleared when we no longer need it (no longer reading user inp) - pending irq code cleaned up - bootmap code for scsi fixed up -- it has the same limitations as DASD, so I added some similar checks in ipl_scsi --- [Summary] --- These patches implement a boot menu for ECKD DASD and SCSI guests on s390x. The menu will only appear if the disk has been configured for IPL with the zIPL tool and with the following QEMU command line options: -boot menu=on[,splash-time=X] and/or -machine loadparm='prompt' The following must be specified for the device to be IPL'd from: -device ...,bootindex=1 or via the following libvirt domain xml: or ... Where X is some positive integer representing time in milliseconds. must be specified for the device to be IPL'd from A loadparm other than 'prompt' will disable the menu and just boot the specified entry. If no boot options are specified, we will attempt to use the values provided by zipl (ECKD DASD only). Collin L. Walling (12): s390-ccw: refactor boot map table code s390-ccw: refactor eckd_block_num to use CHS s390-ccw: refactor IPL structs s390-ccw: update libc s390-ccw: move auxiliary IPL data to separate location s390-ccw: parse and set boot menu options s390-ccw: set up interactive boot menu parameters s390-ccw: read stage2 boot loader data to find menu s390-ccw: print zipl boot menu s390-ccw: read user input for boot index via the SCLP console s390-ccw: set cp_receive mask only when needed and consume pending service irqs s390-ccw: interactive boot menu for scsi hw/s390x/ipl.c | 67 +++- hw/s390x/ipl.h | 18 +++- pc-bios/s390-ccw/Makefile | 2 +- pc-bios/s390-ccw/bootmap.c | 180 - pc-bios/s390-ccw/bootmap.h | 78 ++ pc-bios/s390-ccw/iplb.h | 16 ++- pc-bios/s390-ccw/libc.c | 89 pc-bios/s390-ccw/libc.h | 37 ++- pc-bios/s390-ccw/main.c | 48 + pc-bios/s390-ccw/menu.c | 241 pc-bios/s390-ccw/menu.h | 25 + pc-bios/s390-ccw/s390-ccw.h | 3 + pc-bios/s390-ccw/sclp.c | 29 -- pc-bios/s390-ccw/virtio.c | 2 +- 14 files changed, 734 insertions(+), 101 deletions(-) create mode 100644 pc-bios/s390-ccw/libc.c create mode 100644 pc-bios/s390-ccw/menu.c create mode 100644 pc-bios/s390-ccw/menu.h -- 2.7.4
[Qemu-devel] [PATCH v6 06/12] s390-ccw: parse and set boot menu options
Set boot menu options for an s390 guest and store them in the iplb. These options are set via the QEMU command line option: -boot menu=on|off[,splash-time=X] or via the libvirt domain xml: Where X represents some positive integer representing milliseconds. Any value set for loadparm will override all boot menu options. If loadparm=PROMPT, then the menu will be enabled without a timeout. The absence of any boot options on the command line will flag to later use the zipl boot loader values. Signed-off-by: Collin L. WallingReviewed-by: Janosch Frank Reviewed-by: Thomas Huth --- hw/s390x/ipl.c | 48 hw/s390x/ipl.h | 9 +++-- pc-bios/s390-ccw/iplb.h | 6 -- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 31565ce..c8109f5 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -23,6 +23,9 @@ #include "hw/s390x/ebcdic.h" #include "ipl.h" #include "qemu/error-report.h" +#include "qemu/config-file.h" +#include "qemu/cutils.h" +#include "qemu/option.h" #define KERN_IMAGE_START0x01UL #define KERN_PARM_AREA 0x010480UL @@ -219,6 +222,50 @@ static Property s390_ipl_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static void s390_ipl_set_boot_menu(IplParameterBlock *iplb) +{ +QemuOptsList *plist = qemu_find_opts("boot-opts"); +QemuOpts *opts = QTAILQ_FIRST(>head); +uint8_t *flags; +uint32_t *timeout; +const char *tmp; +unsigned long splash_time = 0; + +switch (iplb->pbt) { +case S390_IPL_TYPE_CCW: +case S390_IPL_TYPE_QEMU_SCSI: +flags = >qipl.boot_menu_flags; +timeout = >qipl.boot_menu_timeout; +break; +default: +error_report("boot menu is not supported for this device type."); +return; +} + +/* In the absence of -boot menu, use zipl parameters */ +if (!qemu_opt_get(opts, "menu")) { +*flags = BOOT_MENU_FLAG_ZIPL_OPTS; +} else if (boot_menu) { +*flags = BOOT_MENU_FLAG_CMD_OPTS; + +tmp = qemu_opt_get(opts, "splash-time"); + +if (tmp && qemu_strtoul(tmp, NULL, 10, _time)) { +error_report("splash-time is invalid, forcing it to 0."); +splash_time = 0; +return; +} + +if (splash_time > 0x) { +error_report("splash-time is too large, forcing it to max value."); +splash_time = 0x; +return; +} + +*timeout = cpu_to_be32(splash_time); +} +} + static bool s390_gen_initial_iplb(S390IPLState *ipl) { DeviceState *dev_st; @@ -435,6 +482,7 @@ void s390_ipl_prepare_cpu(S390CPU *cpu) } ipl->iplb.qipl.netboot_start_addr = cpu_to_be64(ipl->start_addr); } +s390_ipl_set_boot_menu(>iplb); s390_ipl_prepare_qipl(cpu); } diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h index cab8a97..7c3cab8 100644 --- a/hw/s390x/ipl.h +++ b/hw/s390x/ipl.h @@ -60,10 +60,15 @@ typedef struct IplBlockQemuScsi IplBlockQemuScsi; #define QIPL_ADDRESS 0xcc +#define BOOT_MENU_FLAG_CMD_OPTS 0x80 +#define BOOT_MENU_FLAG_ZIPL_OPTS 0x40 + struct QemuIplParameters { -uint8_t reserved1[4]; +uint8_t boot_menu_flags; +uint8_t reserved1; +uint32_t boot_menu_timeout; uint64_t netboot_start_addr; -uint8_t reserved2[16]; +uint8_t reserved2[14]; } QEMU_PACKED; typedef struct QemuIplParameters QemuIplParameters; diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h index 1266884..e8e442d 100644 --- a/pc-bios/s390-ccw/iplb.h +++ b/pc-bios/s390-ccw/iplb.h @@ -75,9 +75,11 @@ extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); #define QIPL_ADDRESS 0xcc struct QemuIplParameters { -uint8_t reserved1[4]; +uint8_t boot_menu_flags; +uint8_t reserved1; +uint32_t boot_menu_timeout; uint64_t netboot_start_addr; -uint8_t reserved2[16]; +uint8_t reserved2[14]; } __attribute__ ((packed)); typedef struct QemuIplParameters QemuIplParameters; -- 2.7.4
[Qemu-devel] [PATCH v6 07/12] s390-ccw: set up interactive boot menu parameters
Reads boot menu flag and timeout values from the iplb and sets the respective fields for the menu. Signed-off-by: Collin L. WallingReviewed-by: Thomas Huth --- pc-bios/s390-ccw/Makefile | 2 +- pc-bios/s390-ccw/main.c | 24 pc-bios/s390-ccw/menu.c | 26 ++ pc-bios/s390-ccw/menu.h | 23 +++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 pc-bios/s390-ccw/menu.c create mode 100644 pc-bios/s390-ccw/menu.h diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile index 9f7904f..1712c2d 100644 --- a/pc-bios/s390-ccw/Makefile +++ b/pc-bios/s390-ccw/Makefile @@ -9,7 +9,7 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw) .PHONY : all clean build-all -OBJECTS = start.o main.o bootmap.o sclp.o virtio.o virtio-scsi.o virtio-blkdev.o libc.o +OBJECTS = start.o main.o bootmap.o sclp.o virtio.o virtio-scsi.o virtio-blkdev.o libc.o menu.o QEMU_CFLAGS := $(filter -W%, $(QEMU_CFLAGS)) QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -msoft-float QEMU_CFLAGS += -march=z900 -fPIE -fno-strict-aliasing diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c index e41b264..c643a6b 100644 --- a/pc-bios/s390-ccw/main.c +++ b/pc-bios/s390-ccw/main.c @@ -11,6 +11,7 @@ #include "libc.h" #include "s390-ccw.h" #include "virtio.h" +#include "menu.h" char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE))); static SubChannelId blk_schid = { .one = 1 }; @@ -18,6 +19,9 @@ IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); static char loadparm[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; QemuIplParameters qipl; +#define LOADPARM_PROMPT "PROMPT " +#define LOADPARM_EMPTY "" + /* * Priniciples of Operations (SA22-7832-09) chapter 17 requires that * a subsystem-identification is at 184-187 and bytes 188-191 are zero @@ -74,6 +78,25 @@ static bool find_dev(Schib *schib, int dev_no) return false; } +static void menu_setup(void) +{ +if (memcmp(loadparm, LOADPARM_PROMPT, 8) == 0) { +menu_set_parms(BOOT_MENU_FLAG_CMD_OPTS, 0); +return; +} + +/* If loadparm was set to any other value, then do not enable menu */ +if (memcmp(loadparm, LOADPARM_EMPTY, 8) != 0) { +return; +} + +switch (iplb.pbt) { +case S390_IPL_TYPE_CCW: +menu_set_parms(qipl.boot_menu_flags, qipl.boot_menu_timeout); +return; +} +} + static void virtio_setup(void) { Schib schib; @@ -117,6 +140,7 @@ static void virtio_setup(void) default: panic("List-directed IPL not supported yet!\n"); } +menu_setup(); } else { for (ssid = 0; ssid < 0x3; ssid++) { blk_schid.ssid = ssid; diff --git a/pc-bios/s390-ccw/menu.c b/pc-bios/s390-ccw/menu.c new file mode 100644 index 000..3056cfc --- /dev/null +++ b/pc-bios/s390-ccw/menu.c @@ -0,0 +1,26 @@ +/* + * QEMU S390 Interactive Boot Menu + * + * Copyright 2018 IBM Corp. + * Author: Collin L. Walling + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "menu.h" + +static uint8_t flags; +static uint64_t timeout; + +void menu_set_parms(uint8_t boot_menu_flag, uint32_t boot_menu_timeout) +{ +flags = boot_menu_flag; +timeout = boot_menu_timeout; +} + +int menu_check_flags(uint8_t check_flags) +{ +return flags & check_flags; +} diff --git a/pc-bios/s390-ccw/menu.h b/pc-bios/s390-ccw/menu.h new file mode 100644 index 000..7df4114 --- /dev/null +++ b/pc-bios/s390-ccw/menu.h @@ -0,0 +1,23 @@ +/* + * QEMU S390 Interactive Boot Menu + * + * Copyright 2018 IBM Corp. + * Author: Collin L. Walling + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#ifndef MENU_H +#define MENU_H + +#include "libc.h" + +#define BOOT_MENU_FLAG_CMD_OPTS 0x80 +#define BOOT_MENU_FLAG_ZIPL_OPTS 0x40 + +void menu_set_parms(uint8_t boot_menu_flags, uint32_t boot_menu_timeout); +bool menu_check_flags(uint8_t check_flags); + +#endif /* MENU_H */ -- 2.7.4
[Qemu-devel] [PATCH v6 10/12] s390-ccw: read user input for boot index via the SCLP console
Implements an sclp_read function to capture input from the console and a wrapper function that handles parsing certain characters and adding input to a buffer. The input is checked for any erroneous values and is handled appropriately. A prompt will persist until input is entered or the timeout expires (if one was set). Example: Please choose (default will boot in 10 seconds): Correct input will boot the respective boot index. If the user's input is empty, 0, or if the timeout expires, then the default zipl entry will be chosen. If the input is within the range of available boot entries, then the selection will be booted. Any erroneous input will cancel the timeout and re-prompt the user. Signed-off-by: Collin L. WallingReviewed-by: Thomas Huth --- pc-bios/s390-ccw/menu.c | 146 +++- pc-bios/s390-ccw/s390-ccw.h | 2 + pc-bios/s390-ccw/sclp.c | 19 ++ pc-bios/s390-ccw/virtio.c | 2 +- 4 files changed, 167 insertions(+), 2 deletions(-) diff --git a/pc-bios/s390-ccw/menu.c b/pc-bios/s390-ccw/menu.c index 9631ac0..9601043 100644 --- a/pc-bios/s390-ccw/menu.c +++ b/pc-bios/s390-ccw/menu.c @@ -12,16 +12,160 @@ #include "menu.h" #include "s390-ccw.h" +#define KEYCODE_NO_INP '\0' +#define KEYCODE_ESCAPE '\033' +#define KEYCODE_BACKSP '\177' +#define KEYCODE_ENTER '\r' + /* Offsets from zipl fields to zipl banner start */ #define ZIPL_TIMEOUT_OFFSET 138 #define ZIPL_FLAG_OFFSET140 +#define TOD_CLOCK_MILLISECOND 0x3e8000 + static uint8_t flags; static uint64_t timeout; +static inline void enable_clock_int(void) +{ +uint64_t tmp = 0; + +asm volatile( +"stctg 0,0,%0\n" +"oi 6+%0, 0x8\n" +"lctlg 0,0,%0" +: : "Q" (tmp) : "memory" +); +} + +static inline void disable_clock_int(void) +{ +uint64_t tmp = 0; + +asm volatile( +"stctg 0,0,%0\n" +"ni 6+%0, 0xf7\n" +"lctlg 0,0,%0" +: : "Q" (tmp) : "memory" +); +} + +static inline void set_clock_comparator(uint64_t time) +{ +asm volatile("sckc %0" : : "Q" (time)); +} + +static inline bool check_clock_int(void) +{ +uint16_t *code = (uint16_t *)0x86; /* low-core external interrupt code */ + +consume_sclp_int(); + +return *code == 0x1004; +} + +static int read_prompt(char *buf, size_t len) +{ +char inp[2] = {}; +uint8_t idx = 0; +uint64_t time; + +if (timeout) { +time = get_clock() + timeout * TOD_CLOCK_MILLISECOND; +set_clock_comparator(time); +enable_clock_int(); +timeout = 0; +} + +while (!check_clock_int()) { + +sclp_read(inp, 1); /* Process only one character at a time */ + +switch (inp[0]) { +case KEYCODE_NO_INP: +case KEYCODE_ESCAPE: +continue; +case KEYCODE_BACKSP: +if (idx > 0) { +buf[--idx] = 0; +sclp_print("\b \b"); +} +continue; +case KEYCODE_ENTER: +disable_clock_int(); +return idx; +default: +/* Echo input and add to buffer */ +if (idx < len) { +buf[idx++] = inp[0]; +sclp_print(inp); +} +} +} + +disable_clock_int(); +*buf = 0; + +return 0; +} + +static int get_index(void) +{ +char buf[10]; +int len; +int i; + +memset(buf, 0, sizeof(buf)); + +len = read_prompt(buf, sizeof(buf)); + +/* If no input, boot default */ +if (len == 0) { +return 0; +} + +/* Check for erroneous input */ +for (i = 0; i < len; i++) { +if (!isdigit(buf[i])) { +return -1; +} +} + +return atoui(buf); +} + +static void boot_menu_prompt(bool retry) +{ +char tmp[6]; + +if (retry) { +sclp_print("\nError: undefined configuration" + "\nPlease choose:\n"); +} else if (timeout > 0) { +sclp_print("Please choose (default will boot in "); +sclp_print(uitoa(timeout / 1000, tmp, sizeof(tmp))); +sclp_print(" seconds):\n"); +} else { +sclp_print("Please choose:\n"); +} +} + static int get_boot_index(int entries) { -return 0; /* Implemented next patch */ +int boot_index; +bool retry = false; +char tmp[5]; + +do { +boot_menu_prompt(retry); +boot_index = get_index(); +retry = true; +} while (boot_index < 0 || boot_index >= entries); + +sclp_print("\nBooting entry #"); +sclp_print(uitoa(boot_index, tmp, sizeof(tmp))); + +return boot_index; } static void zipl_println(const char *data, size_t len) diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h index 25d4d21..a7e6253 100644 --- a/pc-bios/s390-ccw/s390-ccw.h +++ b/pc-bios/s390-ccw/s390-ccw.h @@ -71,6 +71,7 @@ unsigned int get_loadparm_index(void);
Re: [Qemu-devel] [PATCH 3/9] nbd: BLOCK_STATUS for standard get_block_status function: server part
On 02/15/2018 07:51 AM, Vladimir Sementsov-Ogievskiy wrote: Minimal realization: only one extent in server answer is supported. Signed-off-by: Vladimir Sementsov-Ogievskiy--- include/block/nbd.h | 33 ++ nbd/common.c| 10 ++ nbd/server.c| 310 +++- 3 files changed, 352 insertions(+), 1 deletion(-) @@ -200,9 +227,15 @@ enum { #define NBD_REPLY_TYPE_NONE 0 #define NBD_REPLY_TYPE_OFFSET_DATA 1 #define NBD_REPLY_TYPE_OFFSET_HOLE 2 +#define NBD_REPLY_TYPE_BLOCK_STATUS 5 Stale; see nbd.git commit 56c77720 which changed this to 3. +++ b/nbd/server.c @@ -82,6 +82,15 @@ struct NBDExport { static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); +/* NBDExportMetaContexts represents list of selected by + * NBD_OPT_SET_META_CONTEXT contexts to be exported. */ represents a list of contexts to be exported, as selected by NBD_OPT_SET_META_CONTEXT. +typedef struct NBDExportMetaContexts { +char export_name[NBD_MAX_NAME_SIZE + 1]; Would this work as const char * pointing at some other storage, instead of having to copy into this storage? +bool valid; /* means that negotiation of the option finished without + errors */ +bool base_allocation; /* export base:allocation context (block status) */ +} NBDExportMetaContexts; + struct NBDClient { @@ -636,6 +646,201 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, return QIO_CHANNEL(tioc); } +/* nbd_alloc_read_size_string + * + * Read string in format + * uint32_t len + * len bytes string (not 0-terminated) + * String is allocated and pointer returned as @buf + * + * Return -errno on I/O error, 0 if option was completely handled by + * sending a reply about inconsistent lengths, or 1 on success. */ +static int nbd_alloc_read_size_string(NBDClient *client, char **buf, + Error **errp) +{ +int ret; +uint32_t len; + +ret = nbd_opt_read(client, , sizeof(len), errp); +if (ret <= 0) { +return ret; +} +cpu_to_be32s(); + +*buf = g_try_malloc(len + 1); I'd rather check that len is sane prior to trying to malloc. Otherwise, a malicious client can convince us to waste time/space doing a large malloc before we finally realize that we can't read that many bytes after all. And in fact, if you check len in advance, you can probably just use g_malloc() instead of g_try_malloc() (g_try_malloc() makes sense on a 1M allocation, where we can still allocate smaller stuff in reporting the error; but since NBD limits strings to 4k, if we fail at allocating 4k, we are probably already so hosed that our attempts to report the failure will also run out of memory and abort, so why not just abort now). +if (*buf == NULL) { +error_setg(errp, "No memory"); +return -ENOMEM; +} +(*buf)[len] = '\0'; + +ret = nbd_opt_read(client, *buf, len, errp); +if (ret <= 0) { +g_free(*buf); +*buf = NULL; +} + +return ret; +} + +/* nbd_read_size_string Will resume review here... -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
[Qemu-devel] [PATCH v6 09/12] s390-ccw: print zipl boot menu
When the boot menu options are present and the guest's disk has been configured by the zipl tool, then the user will be presented with an interactive boot menu with labeled entries. An example of what the menu might look like: zIPL v1.37.1-build-20170714 interactive boot menu. 0. default (linux-4.13.0) 1. linux-4.13.0 2. performance 3. kvm Signed-off-by: Collin L. WallingReviewed-by: Thomas Huth --- pc-bios/s390-ccw/menu.c | 49 - 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/pc-bios/s390-ccw/menu.c b/pc-bios/s390-ccw/menu.c index 5790e0c..9631ac0 100644 --- a/pc-bios/s390-ccw/menu.c +++ b/pc-bios/s390-ccw/menu.c @@ -10,13 +10,60 @@ */ #include "menu.h" +#include "s390-ccw.h" + +/* Offsets from zipl fields to zipl banner start */ +#define ZIPL_TIMEOUT_OFFSET 138 +#define ZIPL_FLAG_OFFSET140 static uint8_t flags; static uint64_t timeout; +static int get_boot_index(int entries) +{ +return 0; /* Implemented next patch */ +} + +static void zipl_println(const char *data, size_t len) +{ +char buf[len + 2]; + +ebcdic_to_ascii(data, buf, len); +buf[len] = '\n'; +buf[len + 1] = '\0'; + +sclp_print(buf); +} + int menu_get_zipl_boot_index(const void *stage2, int offset) { -return 0; /* implemented next patch */ +const char *data = stage2 + offset; +uint16_t zipl_flag = *(uint16_t *)(data - ZIPL_FLAG_OFFSET); +uint16_t zipl_timeout = *(uint16_t *)(data - ZIPL_TIMEOUT_OFFSET); +size_t len; +int ct; + +if (flags & BOOT_MENU_FLAG_ZIPL_OPTS) { +if (!zipl_flag) { +return 0; /* Boot default */ +} +timeout = zipl_timeout * 1000; +} + +/* Print and count all menu items, including the banner */ +for (ct = 0; *data; ct++) { +len = strlen(data); +zipl_println(data, len); +data += len + 1; + +if (ct < 2) { +sclp_print("\n"); +} +} + +sclp_print("\n"); + +return get_boot_index(ct - 1); } void menu_set_parms(uint8_t boot_menu_flag, uint32_t boot_menu_timeout) -- 2.7.4
[Qemu-devel] [PATCH v6 03/12] s390-ccw: refactor IPL structs
ECKD DASDs have different IPL structures for CDL and LDL formats. The current Ipl1 and Ipl2 structs follow the CDL format, so we prepend "EckdCdl" to them. Boot info for LDL has been moved to a new struct: EckdLdlIpl1. Signed-off-by: Collin L. WallingAcked-by: Janosch Frank Reviewed-by: Thomas Huth --- pc-bios/s390-ccw/bootmap.c | 12 ++-- pc-bios/s390-ccw/bootmap.h | 37 + 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index 9534f56..a94638d 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -221,7 +221,7 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr) static void ipl_eckd_cdl(void) { XEckdMbr *mbr; -Ipl2 *ipl2 = (void *)sec; +EckdCdlIpl2 *ipl2 = (void *)sec; IplVolumeLabel *vlbl = (void *)sec; block_number_t bmt_block_nr; @@ -231,7 +231,7 @@ static void ipl_eckd_cdl(void) memset(sec, FREE_SPACE_FILLER, sizeof(sec)); read_block(1, ipl2, "Cannot read IPL2 record at block 1"); -mbr = >u.x.mbr; +mbr = >mbr; IPL_assert(magic_match(mbr, ZIPL_MAGIC), "No zIPL section in IPL2 record."); IPL_assert(block_size_ok(mbr->blockptr.xeckd.bptr.size), "Bad block size in zIPL section of IPL2 record."); @@ -281,7 +281,7 @@ static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode) static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) { block_number_t bmt_block_nr; -BootInfo *bip = (void *)(sec + 0x70); /* BootInfo is MBR for LDL */ +EckdLdlIpl1 *ipl1 = (void *)sec; if (mode != ECKD_LDL_UNLABELED) { print_eckd_ldl_msg(mode); @@ -292,15 +292,15 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) memset(sec, FREE_SPACE_FILLER, sizeof(sec)); read_block(0, sec, "Cannot read block 0 to grab boot info."); if (mode == ECKD_LDL_UNLABELED) { -if (!magic_match(bip->magic, ZIPL_MAGIC)) { +if (!magic_match(ipl1->bip.magic, ZIPL_MAGIC)) { return; /* not applicable layout */ } sclp_print("unlabeled LDL.\n"); } -verify_boot_info(bip); +verify_boot_info(>bip); /* save pointer to Boot Map Table */ -bmt_block_nr = eckd_block_num(>bp.ipl.bm_ptr.eckd.bptr.chs); +bmt_block_nr = eckd_block_num(>bip.bp.ipl.bm_ptr.eckd.bptr.chs); run_eckd_boot_script(bmt_block_nr); /* no return */ diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h index 7a13c9b..1ddc08f 100644 --- a/pc-bios/s390-ccw/bootmap.h +++ b/pc-bios/s390-ccw/bootmap.h @@ -240,22 +240,27 @@ typedef struct BootInfo { /* @ 0x70, record #0 */ } bp; } __attribute__ ((packed)) BootInfo; /* see also XEckdMbr */ -typedef struct Ipl1 { -unsigned char key[4]; /* == "IPL1" */ -unsigned char data[24]; -} __attribute__((packed)) Ipl1; - -typedef struct Ipl2 { -unsigned char key[4]; /* == "IPL2" */ -union { -unsigned char data[144]; -struct { -unsigned char reserved1[92-4]; -XEckdMbr mbr; -unsigned char reserved2[144-(92-4)-sizeof(XEckdMbr)]; -} x; -} u; -} __attribute__((packed)) Ipl2; +/* + * Structs for IPL + */ +#define STAGE2_BLK_CNT_MAX 24 /* Stage 1b can load up to 24 blocks */ + +typedef struct EckdCdlIpl1 { +uint8_t key[4]; /* == "IPL1" */ +uint8_t data[24]; +} __attribute__((packed)) EckdCdlIpl1; + +typedef struct EckdCdlIpl2 { +uint8_t key[4]; /* == "IPL2" */ +uint8_t reserved0[88]; +XEckdMbr mbr; +uint8_t reserved[24]; +} __attribute__((packed)) EckdCdlIpl2; + +typedef struct EckdLdlIpl1 { +uint8_t reserved[112]; +BootInfo bip; /* BootInfo is MBR for LDL */ +} __attribute__((packed)) EckdLdlIpl1; typedef struct IplVolumeLabel { unsigned char key[4]; /* == "VOL1" */ -- 2.7.4
[Qemu-devel] [PATCH v6 05/12] s390-ccw: move auxiliary IPL data to separate location
The s390-ccw firmware needs some information in support of the boot process which is not available on the native machine. Examples are the netboot firmware load address and now the boot menu parameters. While storing that data in unused fields of the IPL parameter block works, that approach could create problems if the parameter block definition should change in the future. Because then a guest could overwrite these fields using the set IPLB diagnose. In fact the data in question is of more global nature and not really tied to an IPL device, so separating it is rather logical. This commit introduces a new structure to hold firmware relevant IPL parameters set by QEMU. The data is stored at location 204 (dec) and can contain up to 7 32-bit words. This area is available to programming in the z/Architecture Principles of Operation and can thus safely be used by the firmware until the IPL has completed. Signed-off-by: Viktor Mihajlovski--- hw/s390x/ipl.c | 19 ++- hw/s390x/ipl.h | 13 +++-- pc-bios/s390-ccw/iplb.h | 14 -- pc-bios/s390-ccw/main.c | 6 +- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 0d06fc1..31565ce 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -399,6 +399,21 @@ void s390_reipl_request(void) qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); } +static void s390_ipl_prepare_qipl(S390CPU *cpu) +{ +S390IPLState *ipl = get_ipl_device(); +uint8_t *addr; +uint64_t len = 4096; + +addr = cpu_physical_memory_map(cpu->env.psa, , 1); +if (!addr || len < QIPL_ADDRESS + sizeof(QemuIplParameters)) { +error_report("Cannot set QEMU IPL parameters"); +return; +} +memcpy(addr + QIPL_ADDRESS, >iplb.qipl, sizeof(QemuIplParameters)); +cpu_physical_memory_unmap(addr, len, 1, len); +} + void s390_ipl_prepare_cpu(S390CPU *cpu) { S390IPLState *ipl = get_ipl_device(); @@ -418,8 +433,10 @@ void s390_ipl_prepare_cpu(S390CPU *cpu) error_report_err(err); vm_stop(RUN_STATE_INTERNAL_ERROR); } -ipl->iplb.ccw.netboot_start_addr = cpu_to_be64(ipl->start_addr); +ipl->iplb.qipl.netboot_start_addr = cpu_to_be64(ipl->start_addr); } +s390_ipl_prepare_qipl(cpu); + } static void s390_ipl_reset(DeviceState *dev) diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h index 8a705e0..cab8a97 100644 --- a/hw/s390x/ipl.h +++ b/hw/s390x/ipl.h @@ -16,8 +16,7 @@ #include "cpu.h" struct IplBlockCcw { -uint64_t netboot_start_addr; -uint8_t reserved0[77]; +uint8_t reserved0[85]; uint8_t ssid; uint16_t devno; uint8_t vm_flags; @@ -59,6 +58,15 @@ typedef struct IplBlockQemuScsi IplBlockQemuScsi; #define DIAG308_FLAGS_LP_VALID 0x80 +#define QIPL_ADDRESS 0xcc + +struct QemuIplParameters { +uint8_t reserved1[4]; +uint64_t netboot_start_addr; +uint8_t reserved2[16]; +} QEMU_PACKED; +typedef struct QemuIplParameters QemuIplParameters; + union IplParameterBlock { struct { uint32_t len; @@ -74,6 +82,7 @@ union IplParameterBlock { IplBlockFcp fcp; IplBlockQemuScsi scsi; }; +QemuIplParameters qipl; } QEMU_PACKED; struct { uint8_t reserved1[110]; diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h index 890aed9..1266884 100644 --- a/pc-bios/s390-ccw/iplb.h +++ b/pc-bios/s390-ccw/iplb.h @@ -13,8 +13,7 @@ #define IPLB_H struct IplBlockCcw { -uint64_t netboot_start_addr; -uint8_t reserved0[77]; +uint8_t reserved0[85]; uint8_t ssid; uint16_t devno; uint8_t vm_flags; @@ -73,6 +72,17 @@ typedef struct IplParameterBlock IplParameterBlock; extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); +#define QIPL_ADDRESS 0xcc + +struct QemuIplParameters { +uint8_t reserved1[4]; +uint64_t netboot_start_addr; +uint8_t reserved2[16]; +} __attribute__ ((packed)); +typedef struct QemuIplParameters QemuIplParameters; + +extern QemuIplParameters qipl; + #define S390_IPL_TYPE_FCP 0x00 #define S390_IPL_TYPE_CCW 0x02 #define S390_IPL_TYPE_QEMU_SCSI 0xff diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c index e857ce4..e41b264 100644 --- a/pc-bios/s390-ccw/main.c +++ b/pc-bios/s390-ccw/main.c @@ -16,6 +16,7 @@ char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE))); static SubChannelId blk_schid = { .one = 1 }; IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); static char loadparm[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +QemuIplParameters qipl; /* * Priniciples of Operations (SA22-7832-09) chapter 17 requires that @@ -81,6 +82,7 @@ static void virtio_setup(void) uint16_t dev_no; char ldp[] = "LOADPARM=[]\n"; VDev *vdev = virtio_get_device(); +QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS; /* * We
[Qemu-devel] [PATCH v6 01/12] s390-ccw: refactor boot map table code
Some ECKD bootmap code was using structs designed for SCSI. Even though this works, it confuses readability. Add a new BootMapTable struct to assist with readability in bootmap entry code. Also: - replace ScsiMbr in ECKD code with appropriate structs - fix read_block messages to reflect BootMapTable - fixup ipl_scsi to use BootMapTable (referred to as Program Table) - defined value for maximum table entries Signed-off-by: Collin L. Walling--- pc-bios/s390-ccw/bootmap.c | 60 +- pc-bios/s390-ccw/bootmap.h | 14 +-- 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index 67a6123..286de40 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -182,24 +182,24 @@ static block_number_t load_eckd_segments(block_number_t blk, uint64_t *address) return block_nr; } -static void run_eckd_boot_script(block_number_t mbr_block_nr) +static void run_eckd_boot_script(block_number_t bmt_block_nr) { int i; unsigned int loadparm = get_loadparm_index(); block_number_t block_nr; uint64_t address; -ScsiMbr *bte = (void *)sec; /* Eckd bootmap table entry */ +BootMapTable *bmt = (void *)sec; BootMapScript *bms = (void *)sec; debug_print_int("loadparm", loadparm); -IPL_assert(loadparm < 31, "loadparm value greater than" +IPL_assert(loadparm <= MAX_TABLE_ENTRIES, "loadparm value greater than" " maximum number of boot entries allowed"); memset(sec, FREE_SPACE_FILLER, sizeof(sec)); -read_block(mbr_block_nr, sec, "Cannot read MBR"); +read_block(bmt_block_nr, sec, "Cannot read Boot Map Table"); -block_nr = eckd_block_num((void *)&(bte->blockptr[loadparm])); -IPL_assert(block_nr != -1, "No Boot Map"); +block_nr = eckd_block_num((void *)>entry[loadparm]); +IPL_assert(block_nr != -1, "Cannot find Boot Map Table Entry"); memset(sec, FREE_SPACE_FILLER, sizeof(sec)); read_block(block_nr, sec, "Cannot read Boot Map Script"); @@ -223,7 +223,7 @@ static void ipl_eckd_cdl(void) XEckdMbr *mbr; Ipl2 *ipl2 = (void *)sec; IplVolumeLabel *vlbl = (void *)sec; -block_number_t block_nr; +block_number_t bmt_block_nr; /* we have just read the block #0 and recognized it as "IPL1" */ sclp_print("CDL\n"); @@ -238,8 +238,8 @@ static void ipl_eckd_cdl(void) IPL_assert(mbr->dev_type == DEV_TYPE_ECKD, "Non-ECKD device type in zIPL section of IPL2 record."); -/* save pointer to Boot Script */ -block_nr = eckd_block_num((void *)&(mbr->blockptr)); +/* save pointer to Boot Map Table */ +bmt_block_nr = eckd_block_num((void *)>blockptr); memset(sec, FREE_SPACE_FILLER, sizeof(sec)); read_block(2, vlbl, "Cannot read Volume Label at block 2"); @@ -249,7 +249,7 @@ static void ipl_eckd_cdl(void) "Invalid magic of volser block"); print_volser(vlbl->f.volser); -run_eckd_boot_script(block_nr); +run_eckd_boot_script(bmt_block_nr); /* no return */ } @@ -280,7 +280,7 @@ static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode) static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) { -block_number_t block_nr; +block_number_t bmt_block_nr; BootInfo *bip = (void *)(sec + 0x70); /* BootInfo is MBR for LDL */ if (mode != ECKD_LDL_UNLABELED) { @@ -299,8 +299,10 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) } verify_boot_info(bip); -block_nr = eckd_block_num((void *)&(bip->bp.ipl.bm_ptr.eckd.bptr)); -run_eckd_boot_script(block_nr); +/* save pointer to Boot Map Table */ +bmt_block_nr = eckd_block_num((void *)>bp.ipl.bm_ptr.eckd.bptr); + +run_eckd_boot_script(bmt_block_nr); /* no return */ } @@ -325,7 +327,7 @@ static void print_eckd_msg(void) static void ipl_eckd(void) { -ScsiMbr *mbr = (void *)sec; +XEckdMbr *mbr = (void *)sec; LDL_VTOC *vlbl = (void *)sec; print_eckd_msg(); @@ -449,10 +451,8 @@ static void zipl_run(ScsiBlockPtr *pte) static void ipl_scsi(void) { ScsiMbr *mbr = (void *)sec; -uint8_t *ns, *ns_end; int program_table_entries = 0; -const int pte_len = sizeof(ScsiBlockPtr); -ScsiBlockPtr *prog_table_entry = NULL; +BootMapTable *prog_table = (void *)sec; unsigned int loadparm = get_loadparm_index(); /* Grab the MBR */ @@ -467,34 +467,28 @@ static void ipl_scsi(void) debug_print_int("MBR Version", mbr->version_id); IPL_check(mbr->version_id == 1, "Unknown MBR layout version, assuming version 1"); -debug_print_int("program table", mbr->blockptr[0].blockno); -IPL_assert(mbr->blockptr[0].blockno, "No Program Table"); +debug_print_int("program table", mbr->pt.blockno); +IPL_assert(mbr->pt.blockno, "No Program Table"); /* Parse the program table */ -read_block(mbr->blockptr[0].blockno, sec, -
Re: [Qemu-devel] [PATCH v4 10/20] sdcard: handle the Security Specification commands
On Thu, Feb 15, 2018 at 2:13 PM, Philippe Mathieu-Daudéwrote: > returning sd_illegal, since they are not implemented. > > Signed-off-by: Philippe Mathieu-Daudé > --- > hw/sd/sd.c | 11 +++ > 1 file changed, 11 insertions(+) > > diff --git a/hw/sd/sd.c b/hw/sd/sd.c > index 30acd04ad7..0457f5214b 100644 > --- a/hw/sd/sd.c > +++ b/hw/sd/sd.c > @@ -1551,6 +1551,17 @@ static sd_rsp_type_t sd_app_command(SDState *sd, > } > break; > > +case 18:/* Reserved for SD security applications */ > +case 25: > +case 26: > +case 38: > +case 43 ... 49: > +/* Refer to the "SD Specifications Part3 Security Specification" for > + * information about the SD Security Features */ The */ should be on a new line. Otherwise: Reviewed-by: Alistair Francis Alistair > +qemu_log_mask(LOG_UNIMP, "SD: CMD%i Security not implemented\n", > + req.cmd); > +return sd_illegal; > + > default: > /* Fall back to standard commands. */ > return sd_normal_command(sd, req); > -- > 2.16.1 > >
[Qemu-devel] [PATCH v6 04/12] s390-ccw: update libc
Moved: memcmp from bootmap.h to libc.h (renamed from _memcmp) strlen from sclp.c to libc.h (renamed from _strlen) Added C standard functions: isdigit Added non C-standard function: uitoa atoui Signed-off-by: Collin L. WallingAcked-by: Christian Borntraeger Reviewed-by: Janosch Frank --- pc-bios/s390-ccw/Makefile | 2 +- pc-bios/s390-ccw/libc.c | 89 +++ pc-bios/s390-ccw/libc.h | 37 ++-- pc-bios/s390-ccw/main.c | 17 + 4 files changed, 126 insertions(+), 19 deletions(-) create mode 100644 pc-bios/s390-ccw/libc.c diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile index 6d0c2ee..9f7904f 100644 --- a/pc-bios/s390-ccw/Makefile +++ b/pc-bios/s390-ccw/Makefile @@ -9,7 +9,7 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw) .PHONY : all clean build-all -OBJECTS = start.o main.o bootmap.o sclp.o virtio.o virtio-scsi.o virtio-blkdev.o +OBJECTS = start.o main.o bootmap.o sclp.o virtio.o virtio-scsi.o virtio-blkdev.o libc.o QEMU_CFLAGS := $(filter -W%, $(QEMU_CFLAGS)) QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -msoft-float QEMU_CFLAGS += -march=z900 -fPIE -fno-strict-aliasing diff --git a/pc-bios/s390-ccw/libc.c b/pc-bios/s390-ccw/libc.c new file mode 100644 index 000..a144388 --- /dev/null +++ b/pc-bios/s390-ccw/libc.c @@ -0,0 +1,89 @@ +/* + * libc-style definitions and functions + * + * Copyright 2018 IBM Corp. + * Author(s): Collin L. Walling + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include "libc.h" +#include "s390-ccw.h" + +/** + * atoui: + * @str: the string to be converted. + * + * Given a string @str, convert it to an integer. Leading spaces are + * ignored. Any other non-numerical value will terminate the conversion + * and return 0. This function only handles numbers between 0 and + * UINT64_MAX inclusive. + * + * Returns: an integer converted from the string @str, or the number 0 + * if an error occurred. + */ +uint64_t atoui(const char *str) +{ +int val = 0; + +if (!str || !str[0]) { +return 0; +} + +while (*str == ' ') { +str++; +} + +while (*str) { +if (!isdigit(*str)) { +break; +} +val = val * 10 + *str - '0'; +str++; +} + +return val; +} + +/** + * uitoa: + * @num: an integer (base 10) to be converted. + * @str: a pointer to a string to store the conversion. + * @len: the length of the passed string. + * + * Given an integer @num, convert it to a string. The string @str must be + * allocated beforehand. The resulting string will be null terminated and + * returned. This function only handles numbers between 0 and UINT64_MAX + * inclusive. + * + * Returns: the string @str of the converted integer @num + */ +char *uitoa(uint64_t num, char *str, size_t len) +{ +size_t num_idx = 0; +uint64_t tmp = num; + +IPL_assert(str != NULL, "uitoa: no space allocated to store string"); + +/* Get index to ones place */ +while ((tmp /= 10) != 0) { +num_idx++; +} + +/* Check if we have enough space for num and null */ +IPL_assert(len > num_idx, "uitoa: array too small for conversion"); + +str[num_idx + 1] = '\0'; + +/* Convert int to string */ +while (num_idx >= 0) { +str[num_idx] = num % 10 + '0'; +num /= 10; +num_idx--; +} + +return str; +} diff --git a/pc-bios/s390-ccw/libc.h b/pc-bios/s390-ccw/libc.h index 0142ea8..63ece70 100644 --- a/pc-bios/s390-ccw/libc.h +++ b/pc-bios/s390-ccw/libc.h @@ -1,6 +1,8 @@ /* * libc-style definitions and functions * + * Copyright (c) 2013 Alexander Graf + * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -19,7 +21,7 @@ typedef unsigned long long uint64_t; static inline void *memset(void *s, int c, size_t n) { -int i; +size_t i; unsigned char *p = s; for (i = 0; i < n; i++) { @@ -33,7 +35,7 @@ static inline void *memcpy(void *s1, const void *s2, size_t n) { uint8_t *dest = s1; const uint8_t *src = s2; -int i; +size_t i; for (i = 0; i < n; i++) { dest[i] = src[i]; @@ -42,4 +44,35 @@ static inline void *memcpy(void *s1, const void *s2, size_t n) return s1; } +static inline int memcmp(const void *s1, const void *s2, size_t n) +{ +size_t i; +const uint8_t *p1 = s1, *p2 = s2; + +for (i = 0; i < n; i++) { +if (p1[i] != p2[i]) { +return p1[i] > p2[i] ? 1 :
Re: [Qemu-devel] [PATCH 07/30] hw/arm: use the BYTE-based definitions
On Thu, Feb 15, 2018 at 2:39 PM, Philippe Mathieu-Daudéwrote: > Hi Alistair, > > On 02/15/2018 07:31 PM, Alistair Francis wrote: >> On Wed, Feb 14, 2018 at 8:28 PM, Philippe Mathieu-Daudé >> wrote: >>> It ease code review, unit is explicit. >>> >>> Signed-off-by: Philippe Mathieu-Daudé >> >> The logic looks good. >> >> Did you do this automatically? If so you should include the commands >> in the commit message. > > I added in the cover: > > Patches generated using: > > $ git grep -E '(1024|2048|4096|8192|(<<|>>).?(10|20|30))' hw/ include/hw/ > > and modified manually. It should be in the commit message as well, that way it's forever in the tree. > > I use the --cccmd scripts/get_maintainer.pl which select reviewer emails > for each patch but don't include them in the cover, this is annoying... > >> >> Reviewed-by: Alistair Francis > > Thanks! > > There is one more use in "raspi: Add "raspi3" machine type" I'll > update/respin once Peter merged it: > > diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c > -mc->default_ram_size = 1024 * 1024 * 1024; > +mc->default_ram_size = 1 * G_BYTE; You can keep my Reveiwed-by with this change as well. Alistair > >> >> Alistair >> >>> --- >>> include/hw/arm/stm32f205_soc.h | 4 ++-- >>> hw/arm/boot.c | 6 +++--- >>> hw/arm/collie.c| 4 ++-- >>> hw/arm/digic_boards.c | 6 +++--- >>> hw/arm/gumstix.c | 2 +- >>> hw/arm/integratorcp.c | 2 +- >>> hw/arm/mainstone.c | 2 +- >>> hw/arm/musicpal.c | 8 >>> hw/arm/omap_sx1.c | 8 >>> hw/arm/raspi.c | 2 +- >>> hw/arm/stellaris.c | 4 ++-- >>> hw/arm/versatilepb.c | 4 ++-- >>> hw/arm/vexpress.c | 6 +++--- >>> hw/arm/virt.c | 4 ++-- >>> hw/arm/xilinx_zynq.c | 4 ++-- >>> hw/misc/aspeed_sdmc.c | 8 >>> hw/misc/imx7_gpr.c | 2 +- >>> hw/misc/omap_gpmc.c| 4 ++-- >>> hw/ssi/aspeed_smc.c| 28 ++-- >>> 19 files changed, 54 insertions(+), 54 deletions(-) >>> >>> diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h >>> index 922a733f88..e30ae33c65 100644 >>> --- a/include/hw/arm/stm32f205_soc.h >>> +++ b/include/hw/arm/stm32f205_soc.h >>> @@ -43,9 +43,9 @@ >>> #define STM_NUM_SPIS 3 >>> >>> #define FLASH_BASE_ADDRESS 0x0800 >>> -#define FLASH_SIZE (1024 * 1024) >>> +#define FLASH_SIZE (1 * M_BYTE) >>> #define SRAM_BASE_ADDRESS 0x2000 >>> -#define SRAM_SIZE (128 * 1024) >>> +#define SRAM_SIZE (128 * K_BYTE) >>> >>> typedef struct STM32F205State { >>> /*< private >*/ >>> diff --git a/hw/arm/boot.c b/hw/arm/boot.c >>> index 05108bc42f..0552284d57 100644 >>> --- a/hw/arm/boot.c >>> +++ b/hw/arm/boot.c >>> @@ -984,7 +984,7 @@ static void arm_load_kernel_notify(Notifier *notifier, >>> void *data) >>> * the initrd at 128MB. >>> */ >>> info->initrd_start = info->loader_start + >>> -MIN(info->ram_size / 2, 128 * 1024 * 1024); >>> +MIN(info->ram_size / 2, 128 * M_BYTE); >>> >>> /* Assume that raw images are linux kernels, and ELF images are not. >>> */ >>> kernel_size = arm_load_elf(info, _entry, _low_addr, >>> @@ -1069,13 +1069,13 @@ static void arm_load_kernel_notify(Notifier >>> *notifier, void *data) >>> * >>> * Let's play safe and prealign it to 2MB to give us some >>> space. >>> */ >>> -align = 2 * 1024 * 1024; >>> +align = 2 * M_BYTE; >>> } else { >>> /* >>> * Some 32bit kernels will trash anything in the 4K page >>> the >>> * initrd ends in, so make sure the DTB isn't caught up in >>> that. >>> */ >>> -align = 4096; >>> +align = 4 * K_BYTE; >>> } >>> >>> /* Place the DTB after the initrd in memory with alignment. */ >>> diff --git a/hw/arm/collie.c b/hw/arm/collie.c >>> index f8c566e2e5..1695863629 100644 >>> --- a/hw/arm/collie.c >>> +++ b/hw/arm/collie.c >>> @@ -39,12 +39,12 @@ static void collie_init(MachineState *machine) >>> dinfo = drive_get(IF_PFLASH, 0, 0); >>> pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x0200, >>> dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, >>> -(64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0); >>> +64 * K_BYTE, 512, 4, 0x00, 0x00, 0x00, 0x00, 0); >>> >>> dinfo = drive_get(IF_PFLASH, 0, 1); >>> pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x0200, >>> dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, >>> -(64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0); >>> +
Re: [Qemu-devel] [PATCH v5 3/6] bcm2836: Use the Cortex-A7 instead of Cortex-A15
On Thu, Feb 15, 2018 at 5:23 AM, Philippe Mathieu-Daudéwrote: > Hi Peter, > > On 02/01/2018 09:42 PM, Alistair Francis wrote: >> The BCM2836 uses a Cortex-A7 not a Cortex-A15. Update the device to use >> the correct CPU. >> https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2836/QA7_rev3.4.pdf > > Can you add these lines with reference to the commits? > > When the BCM2836 was introduced (bad5623690b) the Cortex-A7 was not > available, so the very similar Cortex-A15 was used. > > Since dcf578ed8ce we can model the correct core. > > Thanks! Added! I'm not sure when I'll send the next version out though. Alistair > > Phil. > >> Signed-off-by: Alistair Francis >> Reviewed-by: Philippe Mathieu-Daudé >> Reviewed-by: Igor Mammedov >> --- >> V3: >> - Use ARM_CPU_TYPE_NAME() macro >> V2: >> - Fix the BCM2836 CPU >> >> hw/arm/bcm2836.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c >> index 8c43291112..c42484 100644 >> --- a/hw/arm/bcm2836.c >> +++ b/hw/arm/bcm2836.c >> @@ -30,7 +30,7 @@ static void bcm2836_init(Object *obj) >> >> for (n = 0; n < BCM2836_NCPUS; n++) { >> object_initialize(>cpus[n], sizeof(s->cpus[n]), >> - "cortex-a15-" TYPE_ARM_CPU); >> + ARM_CPU_TYPE_NAME("cortex-a7")); >> object_property_add_child(obj, "cpu[*]", OBJECT(>cpus[n]), >>_abort); >> } >>
Re: [Qemu-devel] [PATCH 07/30] hw/arm: use the BYTE-based definitions
Hi Alistair, On 02/15/2018 07:31 PM, Alistair Francis wrote: > On Wed, Feb 14, 2018 at 8:28 PM, Philippe Mathieu-Daudé> wrote: >> It ease code review, unit is explicit. >> >> Signed-off-by: Philippe Mathieu-Daudé > > The logic looks good. > > Did you do this automatically? If so you should include the commands > in the commit message. I added in the cover: Patches generated using: $ git grep -E '(1024|2048|4096|8192|(<<|>>).?(10|20|30))' hw/ include/hw/ and modified manually. I use the --cccmd scripts/get_maintainer.pl which select reviewer emails for each patch but don't include them in the cover, this is annoying... > > Reviewed-by: Alistair Francis Thanks! There is one more use in "raspi: Add "raspi3" machine type" I'll update/respin once Peter merged it: diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c -mc->default_ram_size = 1024 * 1024 * 1024; +mc->default_ram_size = 1 * G_BYTE; > > Alistair > >> --- >> include/hw/arm/stm32f205_soc.h | 4 ++-- >> hw/arm/boot.c | 6 +++--- >> hw/arm/collie.c| 4 ++-- >> hw/arm/digic_boards.c | 6 +++--- >> hw/arm/gumstix.c | 2 +- >> hw/arm/integratorcp.c | 2 +- >> hw/arm/mainstone.c | 2 +- >> hw/arm/musicpal.c | 8 >> hw/arm/omap_sx1.c | 8 >> hw/arm/raspi.c | 2 +- >> hw/arm/stellaris.c | 4 ++-- >> hw/arm/versatilepb.c | 4 ++-- >> hw/arm/vexpress.c | 6 +++--- >> hw/arm/virt.c | 4 ++-- >> hw/arm/xilinx_zynq.c | 4 ++-- >> hw/misc/aspeed_sdmc.c | 8 >> hw/misc/imx7_gpr.c | 2 +- >> hw/misc/omap_gpmc.c| 4 ++-- >> hw/ssi/aspeed_smc.c| 28 ++-- >> 19 files changed, 54 insertions(+), 54 deletions(-) >> >> diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h >> index 922a733f88..e30ae33c65 100644 >> --- a/include/hw/arm/stm32f205_soc.h >> +++ b/include/hw/arm/stm32f205_soc.h >> @@ -43,9 +43,9 @@ >> #define STM_NUM_SPIS 3 >> >> #define FLASH_BASE_ADDRESS 0x0800 >> -#define FLASH_SIZE (1024 * 1024) >> +#define FLASH_SIZE (1 * M_BYTE) >> #define SRAM_BASE_ADDRESS 0x2000 >> -#define SRAM_SIZE (128 * 1024) >> +#define SRAM_SIZE (128 * K_BYTE) >> >> typedef struct STM32F205State { >> /*< private >*/ >> diff --git a/hw/arm/boot.c b/hw/arm/boot.c >> index 05108bc42f..0552284d57 100644 >> --- a/hw/arm/boot.c >> +++ b/hw/arm/boot.c >> @@ -984,7 +984,7 @@ static void arm_load_kernel_notify(Notifier *notifier, >> void *data) >> * the initrd at 128MB. >> */ >> info->initrd_start = info->loader_start + >> -MIN(info->ram_size / 2, 128 * 1024 * 1024); >> +MIN(info->ram_size / 2, 128 * M_BYTE); >> >> /* Assume that raw images are linux kernels, and ELF images are not. */ >> kernel_size = arm_load_elf(info, _entry, _low_addr, >> @@ -1069,13 +1069,13 @@ static void arm_load_kernel_notify(Notifier >> *notifier, void *data) >> * >> * Let's play safe and prealign it to 2MB to give us some >> space. >> */ >> -align = 2 * 1024 * 1024; >> +align = 2 * M_BYTE; >> } else { >> /* >> * Some 32bit kernels will trash anything in the 4K page the >> * initrd ends in, so make sure the DTB isn't caught up in >> that. >> */ >> -align = 4096; >> +align = 4 * K_BYTE; >> } >> >> /* Place the DTB after the initrd in memory with alignment. */ >> diff --git a/hw/arm/collie.c b/hw/arm/collie.c >> index f8c566e2e5..1695863629 100644 >> --- a/hw/arm/collie.c >> +++ b/hw/arm/collie.c >> @@ -39,12 +39,12 @@ static void collie_init(MachineState *machine) >> dinfo = drive_get(IF_PFLASH, 0, 0); >> pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x0200, >> dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, >> -(64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0); >> +64 * K_BYTE, 512, 4, 0x00, 0x00, 0x00, 0x00, 0); >> >> dinfo = drive_get(IF_PFLASH, 0, 1); >> pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x0200, >> dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, >> -(64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0); >> +64 * K_BYTE, 512, 4, 0x00, 0x00, 0x00, 0x00, 0); >> >> sysbus_create_simple("scoop", 0x4080, NULL); >> >> diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c >> index 9f11dcd11f..04e52e776f 100644 >> --- a/hw/arm/digic_boards.c >> +++ b/hw/arm/digic_boards.c >> @@ -126,8 +126,8 @@ static void digic_load_rom(DigicBoardState *s, hwaddr >> addr, >> static
Re: [Qemu-devel] [PATCH v4 19/20] sdcard: add a 'uhs' property, update the OCR register ACCEPT_SWITCH_1V8 bit
On Thu, Feb 15, 2018 at 2:13 PM, Philippe Mathieu-Daudéwrote: > Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Alistair > --- > hw/sd/sd.c | 4 > 1 file changed, 4 insertions(+) > > diff --git a/hw/sd/sd.c b/hw/sd/sd.c > index ada96f5574..b9429b06ca 100644 > --- a/hw/sd/sd.c > +++ b/hw/sd/sd.c > @@ -93,6 +93,7 @@ struct SDState { > /* Configurable properties */ > BlockBackend *blk; > bool spi; > +uint8_t uhs_supported; > > uint32_t mode;/* current card mode, one of SDCardModes */ > int32_t state;/* current card state, one of SDCardStates */ > @@ -292,6 +293,8 @@ static void sd_set_ocr(SDState *sd) > { > /* All voltages OK */ > sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK; > + > +sd->ocr = FIELD_DP32(sd->ocr, OCR, ACCEPT_SWITCH_1V8, > !!sd->uhs_supported); > } > > static void sd_ocr_powerup(void *opaque) > @@ -2189,6 +2192,7 @@ static Property sd_properties[] = { > * board to ensure that ssi transfers only occur when the chip select > * is asserted. */ > DEFINE_PROP_BOOL("spi", SDState, spi, false), > +DEFINE_PROP_UINT8("uhs", SDState, uhs_supported, UHS_NOT_SUPPORTED), > DEFINE_PROP_END_OF_LIST() > }; > > -- > 2.16.1 > >
Re: [Qemu-devel] [PATCH v4 11/20] sdcard: use a more descriptive label 'unimplemented_spi_cmd'
On Thu, Feb 15, 2018 at 2:13 PM, Philippe Mathieu-Daudéwrote: > Suggested-by: Alistair Francis > Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Alistair > --- > hw/sd/sd.c | 22 +- > 1 file changed, 13 insertions(+), 9 deletions(-) > > diff --git a/hw/sd/sd.c b/hw/sd/sd.c > index 0457f5214b..4f82638735 100644 > --- a/hw/sd/sd.c > +++ b/hw/sd/sd.c > @@ -1183,8 +1183,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, > SDRequest req) > > /* Block write commands (Class 4) */ > case 24: /* CMD24: WRITE_SINGLE_BLOCK */ > -if (sd->spi) > -goto unimplemented_cmd; > +if (sd->spi) { > +goto unimplemented_spi_cmd; > +} > switch (sd->state) { > case sd_transfer_state: > /* Writing in SPI mode not implemented. */ > @@ -1209,8 +1210,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, > SDRequest req) > break; > > case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */ > -if (sd->spi) > -goto unimplemented_cmd; > +if (sd->spi) { > +goto unimplemented_spi_cmd; > +} > switch (sd->state) { > case sd_transfer_state: > /* Writing in SPI mode not implemented. */ > @@ -1250,8 +1252,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, > SDRequest req) > break; > > case 27: /* CMD27: PROGRAM_CSD */ > -if (sd->spi) > -goto unimplemented_cmd; > +if (sd->spi) { > +goto unimplemented_spi_cmd; > +} > switch (sd->state) { > case sd_transfer_state: > sd->state = sd_receivingdata_state; > @@ -1361,8 +1364,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, > SDRequest req) > > /* Lock card commands (Class 7) */ > case 42: /* CMD42: LOCK_UNLOCK */ > -if (sd->spi) > -goto unimplemented_cmd; > +if (sd->spi) { > +goto unimplemented_spi_cmd; > +} > switch (sd->state) { > case sd_transfer_state: > sd->state = sd_receivingdata_state; > @@ -1413,7 +1417,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, > SDRequest req) > qemu_log_mask(LOG_GUEST_ERROR, "SD: Unknown CMD%i\n", req.cmd); > return sd_illegal; > > -unimplemented_cmd: > +unimplemented_spi_cmd: > /* Commands that are recognised but not yet implemented in SPI mode. > */ > qemu_log_mask(LOG_UNIMP, "SD: CMD%i not implemented in SPI mode\n", >req.cmd); > -- > 2.16.1 > >
[Qemu-devel] [PATCH v4 20/20] sdcard: add an enum for the SD PHY Spec version
So far this device intends to model the Spec v1.10 Signed-off-by: Philippe Mathieu-DaudéReviewed-by: Alistair Francis --- hw/sd/sd.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index b9429b06ca..d4565626ce 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -47,6 +47,11 @@ //#define DEBUG_SD 1 +typedef enum { +SD_PHY_SPEC_VER_1_10 = 110, +SD_PHY_SPEC_VER_2_00 = 200, /* not yet supported */ +} sd_phy_spec_ver_t; + typedef enum { sd_r0 = 0,/* no response */ sd_r1,/* normal response command */ @@ -122,6 +127,7 @@ struct SDState { qemu_irq inserted_cb; QEMUTimer *ocr_power_timer; const char *proto_name; +int spec_version; bool enable; uint8_t dat_lines; bool cmd_line; @@ -2169,6 +2175,7 @@ static void sd_realize(DeviceState *dev, Error **errp) int ret; sd->proto_name = sd->spi ? "SPI" : "SD"; +sd->spec_version = SD_PHY_SPEC_VER_1_10; if (sd->blk && blk_is_read_only(sd->blk)) { error_setg(errp, "Cannot use read-only drive as SD card"); -- 2.16.1
Re: [Qemu-devel] [PATCH v4 12/20] sdcard: handles more commands in SPI mode
On Thu, Feb 15, 2018 at 2:13 PM, Philippe Mathieu-Daudéwrote: > Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Alistair > --- > hw/sd/sd.c | 29 ++--- > 1 file changed, 26 insertions(+), 3 deletions(-) > > diff --git a/hw/sd/sd.c b/hw/sd/sd.c > index 4f82638735..0ecb446fdb 100644 > --- a/hw/sd/sd.c > +++ b/hw/sd/sd.c > @@ -1390,9 +1390,11 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, > SDRequest req) > > /* Application specific commands (Class 8) */ > case 55: /* CMD55: APP_CMD */ > -if (sd->rca != rca) > -return sd_r0; > - > +if (!sd->spi) { > +if (sd->rca != rca) { > +return sd_r0; > +} > +} > sd->expecting_acmd = true; > sd->card_status |= APP_CMD; > return sd_r1; > @@ -1412,6 +1414,18 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, > SDRequest req) > } > break; > > +case 58:/* CMD58: READ_OCR (SPI) */ > +if (!sd->spi) { > +goto bad_cmd; > +} > +return sd_r3; > + > +case 59:/* CMD59: CRC_ON_OFF (SPI) */ > +if (!sd->spi) { > +goto bad_cmd; > +} > +goto unimplemented_spi_cmd; > + > default: > bad_cmd: > qemu_log_mask(LOG_GUEST_ERROR, "SD: Unknown CMD%i\n", req.cmd); > @@ -1436,6 +1450,9 @@ static sd_rsp_type_t sd_app_command(SDState *sd, > sd->card_status |= APP_CMD; > switch (req.cmd) { > case 6:/* ACMD6: SET_BUS_WIDTH */ > +if (sd->spi) { > +goto unimplemented_spi_cmd; > +} > switch (sd->state) { > case sd_transfer_state: > sd->sd_status[0] &= 0x3f; > @@ -1569,6 +1586,12 @@ static sd_rsp_type_t sd_app_command(SDState *sd, > default: > /* Fall back to standard commands. */ > return sd_normal_command(sd, req); > + > +unimplemented_spi_cmd: > +/* Commands that are recognised but not yet implemented in SPI mode. > */ > +qemu_log_mask(LOG_UNIMP, "SD: CMD%i not implemented in SPI mode\n", > + req.cmd); > +return sd_illegal; > } > > qemu_log_mask(LOG_GUEST_ERROR, "SD: ACMD%i in a wrong state\n", req.cmd); > -- > 2.16.1 > >
[Qemu-devel] [PATCH v4 19/20] sdcard: add a 'uhs' property, update the OCR register ACCEPT_SWITCH_1V8 bit
Signed-off-by: Philippe Mathieu-Daudé--- hw/sd/sd.c | 4 1 file changed, 4 insertions(+) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index ada96f5574..b9429b06ca 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -93,6 +93,7 @@ struct SDState { /* Configurable properties */ BlockBackend *blk; bool spi; +uint8_t uhs_supported; uint32_t mode;/* current card mode, one of SDCardModes */ int32_t state;/* current card state, one of SDCardStates */ @@ -292,6 +293,8 @@ static void sd_set_ocr(SDState *sd) { /* All voltages OK */ sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK; + +sd->ocr = FIELD_DP32(sd->ocr, OCR, ACCEPT_SWITCH_1V8, !!sd->uhs_supported); } static void sd_ocr_powerup(void *opaque) @@ -2189,6 +2192,7 @@ static Property sd_properties[] = { * board to ensure that ssi transfers only occur when the chip select * is asserted. */ DEFINE_PROP_BOOL("spi", SDState, spi, false), +DEFINE_PROP_UINT8("uhs", SDState, uhs_supported, UHS_NOT_SUPPORTED), DEFINE_PROP_END_OF_LIST() }; -- 2.16.1
Re: [Qemu-devel] [PATCH v13 30/30] sdhci: add Spec v4.2 register definitions
On Mon, Feb 12, 2018 at 8:08 PM, Philippe Mathieu-Daudéwrote: > Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Alistair > --- > hw/sd/sdhci-internal.h | 9 + > hw/sd/sdhci.c | 14 ++ > 2 files changed, 23 insertions(+) > > diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h > index 0092627076..e1bb733aed 100644 > --- a/hw/sd/sdhci-internal.h > +++ b/hw/sd/sdhci-internal.h > @@ -198,6 +198,10 @@ FIELD(SDHC_HOSTCTL2, V18_ENA, 3, 1); /* UHS-I > only */ > FIELD(SDHC_HOSTCTL2, DRIVER_STRENGTH, 4, 2); /* UHS-I only */ > FIELD(SDHC_HOSTCTL2, EXECUTE_TUNING, 6, 1); /* UHS-I only */ > FIELD(SDHC_HOSTCTL2, SAMPLING_CLKSEL, 7, 1); /* UHS-I only */ > +FIELD(SDHC_HOSTCTL2, UHS_II_ENA, 8, 1); /* since v4 */ > +FIELD(SDHC_HOSTCTL2, ADMA2_LENGTH,10, 1); /* since v4 */ > +FIELD(SDHC_HOSTCTL2, CMD23_ENA, 11, 1); /* since v4 */ > +FIELD(SDHC_HOSTCTL2, VERSION4,12, 1); /* since v4 */ > FIELD(SDHC_HOSTCTL2, ASYNC_INT, 14, 1); > FIELD(SDHC_HOSTCTL2, PRESET_ENA, 15, 1); > > @@ -216,10 +220,12 @@ FIELD(SDHC_CAPAB, SUSPRESUME, 23, 1); > FIELD(SDHC_CAPAB, V33,24, 1); > FIELD(SDHC_CAPAB, V30,25, 1); > FIELD(SDHC_CAPAB, V18,26, 1); > +FIELD(SDHC_CAPAB, BUS64BIT_V4,27, 1); /* since v4.10 */ > FIELD(SDHC_CAPAB, BUS64BIT, 28, 1); /* since v2 */ > FIELD(SDHC_CAPAB, ASYNC_INT, 29, 1); /* since v3 */ > FIELD(SDHC_CAPAB, SLOT_TYPE, 30, 2); /* since v3 */ > FIELD(SDHC_CAPAB, BUS_SPEED, 32, 3); /* since v3 */ > +FIELD(SDHC_CAPAB, UHS_II, 35, 8); /* since v4.20 */ > FIELD(SDHC_CAPAB, DRIVER_STRENGTH,36, 3); /* since v3 */ > FIELD(SDHC_CAPAB, DRIVER_TYPE_A, 36, 1); /* since v3 */ > FIELD(SDHC_CAPAB, DRIVER_TYPE_C, 37, 1); /* since v3 */ > @@ -228,12 +234,15 @@ FIELD(SDHC_CAPAB, TIMER_RETUNING, 40, 4); /* since > v3 */ > FIELD(SDHC_CAPAB, SDR50_TUNING, 45, 1); /* since v3 */ > FIELD(SDHC_CAPAB, RETUNING_MODE, 46, 2); /* since v3 */ > FIELD(SDHC_CAPAB, CLOCK_MULT, 48, 8); /* since v3 */ > +FIELD(SDHC_CAPAB, ADMA3, 59, 1); /* since v4.20 */ > +FIELD(SDHC_CAPAB, V18_VDD2, 60, 1); /* since v4.20 */ > > /* HWInit Maximum Current Capabilities Register 0x0 */ > #define SDHC_MAXCURR 0x48 > FIELD(SDHC_MAXCURR, V33_VDD1, 0, 8); > FIELD(SDHC_MAXCURR, V30_VDD1, 8, 8); > FIELD(SDHC_MAXCURR, V18_VDD1, 16, 8); > +FIELD(SDHC_MAXCURR, V18_VDD2, 32, 8); /* since v4.20 */ > > /* W Force Event Auto CMD12 Error Interrupt Register 0x */ > #define SDHC_FEAER 0x50 > diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c > index 0cd968fc6b..74b1802503 100644 > --- a/hw/sd/sdhci.c > +++ b/hw/sd/sdhci.c > @@ -91,6 +91,20 @@ static void sdhci_check_capareg(SDHCIState *s, Error > **errp) > bool unit_mhz; > > switch (s->sd_spec_version) { > +case 4: > +val = FIELD_EX64(s->capareg, SDHC_CAPAB, BUS64BIT_V4); > +msk = FIELD_DP64(msk, SDHC_CAPAB, BUS64BIT_V4, 0); > +trace_sdhci_capareg("64-bit system bus (v4)", val); > + > +val = FIELD_EX64(s->capareg, SDHC_CAPAB, UHS_II); > +msk = FIELD_DP64(msk, SDHC_CAPAB, UHS_II, 0); > +trace_sdhci_capareg("UHS-II", val); > + > +val = FIELD_EX64(s->capareg, SDHC_CAPAB, ADMA3); > +msk = FIELD_DP64(msk, SDHC_CAPAB, ADMA3, 0); > +trace_sdhci_capareg("ADMA3", val); > + > +/* fallback */ > case 3: > val = FIELD_EX64(s->capareg, SDHC_CAPAB, ASYNC_INT); > trace_sdhci_capareg("async interrupt", val); > -- > 2.16.1 > >
[Qemu-devel] [PATCH v4 16/20] sdcard: simplify SD_SEND_OP_COND (ACMD41)
replace switch(single case) -> if() Signed-off-by: Philippe Mathieu-DaudéReviewed-by: Alistair Francis --- hw/sd/sd.c | 56 ++-- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 942143ab3e..911aae6233 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -1517,45 +1517,41 @@ static sd_rsp_type_t sd_app_command(SDState *sd, sd->state = sd_transfer_state; return sd_r1; } -switch (sd->state) { -case sd_idle_state: -/* If it's the first ACMD41 since reset, we need to decide - * whether to power up. If this is not an enquiry ACMD41, - * we immediately report power on and proceed below to the - * ready state, but if it is, we set a timer to model a - * delay for power up. This works around a bug in EDK2 - * UEFI, which sends an initial enquiry ACMD41, but - * assumes that the card is in ready state as soon as it - * sees the power up bit set. */ -if (!FIELD_EX32(sd->ocr, OCR, CARD_POWER_UP)) { -if ((req.arg & ACMD41_ENQUIRY_MASK) != 0) { -timer_del(sd->ocr_power_timer); -sd_ocr_powerup(sd); -} else { -trace_sdcard_inquiry_cmd41(); -if (!timer_pending(sd->ocr_power_timer)) { -timer_mod_ns(sd->ocr_power_timer, - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - + OCR_POWER_DELAY_NS)); -} +if (sd->state != sd_idle_state) { +break; +} +/* If it's the first ACMD41 since reset, we need to decide + * whether to power up. If this is not an enquiry ACMD41, + * we immediately report power on and proceed below to the + * ready state, but if it is, we set a timer to model a + * delay for power up. This works around a bug in EDK2 + * UEFI, which sends an initial enquiry ACMD41, but + * assumes that the card is in ready state as soon as it + * sees the power up bit set. */ +if (!FIELD_EX32(sd->ocr, OCR, CARD_POWER_UP)) { +if ((req.arg & ACMD41_ENQUIRY_MASK) != 0) { +timer_del(sd->ocr_power_timer); +sd_ocr_powerup(sd); +} else { +trace_sdcard_inquiry_cmd41(); +if (!timer_pending(sd->ocr_power_timer)) { +timer_mod_ns(sd->ocr_power_timer, + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + OCR_POWER_DELAY_NS)); } } +} +if (FIELD_EX32(sd->ocr & req.arg, OCR, VDD_VOLTAGE_WINDOW)) { /* We accept any voltage. 1 V is nothing. * * Once we're powered up, we advance straight to ready state * unless it's an enquiry ACMD41 (bits 23:0 == 0). */ -if (req.arg & ACMD41_ENQUIRY_MASK) { -sd->state = sd_ready_state; -} - -return sd_r3; - -default: -break; +sd->state = sd_ready_state; } -break; + +return sd_r3; case 42: /* ACMD42: SET_CLR_CARD_DETECT */ switch (sd->state) { -- 2.16.1
[Qemu-devel] [PATCH] virtio-balloon: add huge page allocation statistics
qemu should read and report huge page allocation statistics exported in the following kernel patch: commit 01be4bb1aafeab73feba628c6dd120cd6647faae Author: Jonathan HelmanDate: Thu Feb 15 10:59:03 2018 -0800 virtio_balloon: export huge page allocation statistics Export statistics for successful and failed huge page allocations from the virtio balloon driver. These 2 stats come directly from the vm_events HTLB_BUDDY_PGALLOC and HTLB_BUDDY_PGALLOC_FAIL. Signed-off-by: Jonathan Helman --- docs/virtio-balloon-stats.txt | 2 ++ hw/virtio/virtio-balloon.c | 2 ++ include/standard-headers/linux/virtio_balloon.h | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/virtio-balloon-stats.txt b/docs/virtio-balloon-stats.txt index edff5f2..12d33a7 100644 --- a/docs/virtio-balloon-stats.txt +++ b/docs/virtio-balloon-stats.txt @@ -32,6 +32,8 @@ which will return a dictionary containing: - stat-minor-faults - stat-free-memory - stat-total-memory + - stat-htlb-pgalloc + - stat-htlb-pgfail o A key named last-update, which contains the last stats update timestamp in seconds. Since this timestamp is generated by the host, diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 4822449..f4f2b98 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -52,6 +52,8 @@ static const char *balloon_stat_names[] = { [VIRTIO_BALLOON_S_MEMTOT] = "stat-total-memory", [VIRTIO_BALLOON_S_AVAIL] = "stat-available-memory", [VIRTIO_BALLOON_S_CACHES] = "stat-disk-caches", + [VIRTIO_BALLOON_S_HTLB_PGALLOC] = "stat-htlb-pgalloc", + [VIRTIO_BALLOON_S_HTLB_PGFAIL] = "stat-htlb-pgfail", [VIRTIO_BALLOON_S_NR] = NULL }; diff --git a/include/standard-headers/linux/virtio_balloon.h b/include/standard-headers/linux/virtio_balloon.h index 7b0a41b..ed445b6 100644 --- a/include/standard-headers/linux/virtio_balloon.h +++ b/include/standard-headers/linux/virtio_balloon.h @@ -53,7 +53,9 @@ struct virtio_balloon_config { #define VIRTIO_BALLOON_S_MEMTOT 5 /* Total amount of memory */ #define VIRTIO_BALLOON_S_AVAIL6 /* Available memory as in /proc */ #define VIRTIO_BALLOON_S_CACHES 7 /* Disk caches */ -#define VIRTIO_BALLOON_S_NR 8 +#define VIRTIO_BALLOON_S_HTLB_PGALLOC 8 /* Number of htlb pgalloc successes */ +#define VIRTIO_BALLOON_S_HTLB_PGFAIL 9 /* Number of htlb pgalloc failures */ +#define VIRTIO_BALLOON_S_NR 10 /* * Memory statistics structure. -- 1.8.3.1
[Qemu-devel] [PATCH v4 11/20] sdcard: use a more descriptive label 'unimplemented_spi_cmd'
Suggested-by: Alistair FrancisSigned-off-by: Philippe Mathieu-Daudé --- hw/sd/sd.c | 22 +- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 0457f5214b..4f82638735 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -1183,8 +1183,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) /* Block write commands (Class 4) */ case 24: /* CMD24: WRITE_SINGLE_BLOCK */ -if (sd->spi) -goto unimplemented_cmd; +if (sd->spi) { +goto unimplemented_spi_cmd; +} switch (sd->state) { case sd_transfer_state: /* Writing in SPI mode not implemented. */ @@ -1209,8 +1210,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) break; case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */ -if (sd->spi) -goto unimplemented_cmd; +if (sd->spi) { +goto unimplemented_spi_cmd; +} switch (sd->state) { case sd_transfer_state: /* Writing in SPI mode not implemented. */ @@ -1250,8 +1252,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) break; case 27: /* CMD27: PROGRAM_CSD */ -if (sd->spi) -goto unimplemented_cmd; +if (sd->spi) { +goto unimplemented_spi_cmd; +} switch (sd->state) { case sd_transfer_state: sd->state = sd_receivingdata_state; @@ -1361,8 +1364,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) /* Lock card commands (Class 7) */ case 42: /* CMD42: LOCK_UNLOCK */ -if (sd->spi) -goto unimplemented_cmd; +if (sd->spi) { +goto unimplemented_spi_cmd; +} switch (sd->state) { case sd_transfer_state: sd->state = sd_receivingdata_state; @@ -1413,7 +1417,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) qemu_log_mask(LOG_GUEST_ERROR, "SD: Unknown CMD%i\n", req.cmd); return sd_illegal; -unimplemented_cmd: +unimplemented_spi_cmd: /* Commands that are recognised but not yet implemented in SPI mode. */ qemu_log_mask(LOG_UNIMP, "SD: CMD%i not implemented in SPI mode\n", req.cmd); -- 2.16.1
Re: [Qemu-devel] [PATCH v2] hw/char/stm32f2xx_usart: fix TXE/TC bit handling
On Tue, Feb 13, 2018 at 12:54 PM, Richard Braunwrote: > I/O currently being synchronous, there is no reason to ever clear the > SR_TXE bit. However the SR_TC bit may be cleared by software writing > to the SR register, so set it on each write. > > In addition, fix the reset value of the USART status register. > > Signed-off-by: Richard Braun Reviewed-by: Alistair Francis Alistair > --- > hw/char/stm32f2xx_usart.c | 12 > include/hw/char/stm32f2xx_usart.h | 7 ++- > 2 files changed, 14 insertions(+), 5 deletions(-) > > diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c > index 07b462d4b6..032b5fda13 100644 > --- a/hw/char/stm32f2xx_usart.c > +++ b/hw/char/stm32f2xx_usart.c > @@ -96,12 +96,10 @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr > addr, > switch (addr) { > case USART_SR: > retvalue = s->usart_sr; > -s->usart_sr &= ~USART_SR_TC; > qemu_chr_fe_accept_input(>chr); > return retvalue; > case USART_DR: > DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) > s->usart_dr); > -s->usart_sr |= USART_SR_TXE; > s->usart_sr &= ~USART_SR_RXNE; > qemu_chr_fe_accept_input(>chr); > qemu_set_irq(s->irq, 0); > @@ -137,7 +135,9 @@ static void stm32f2xx_usart_write(void *opaque, hwaddr > addr, > switch (addr) { > case USART_SR: > if (value <= 0x3FF) { > -s->usart_sr = value; > +/* I/O being synchronous, TXE is always set. In addition, it may > + only be set by hardware, so keep it set here. */ > +s->usart_sr = value | USART_SR_TXE; > } else { > s->usart_sr &= value; > } > @@ -151,8 +151,12 @@ static void stm32f2xx_usart_write(void *opaque, hwaddr > addr, > /* XXX this blocks entire thread. Rewrite to use > * qemu_chr_fe_write and background I/O callbacks */ > qemu_chr_fe_write_all(>chr, , 1); > +/* XXX I/O are currently synchronous, making it impossible for > + software to observe transient states where TXE or TC aren't > + set. Unlike TXE however, which is read-only, software may > + clear TC by writing 0 to the SR register, so set it again > + on each write. */ > s->usart_sr |= USART_SR_TC; > -s->usart_sr &= ~USART_SR_TXE; > } > return; > case USART_BRR: > diff --git a/include/hw/char/stm32f2xx_usart.h > b/include/hw/char/stm32f2xx_usart.h > index 9d03a7527c..7ea7448813 100644 > --- a/include/hw/char/stm32f2xx_usart.h > +++ b/include/hw/char/stm32f2xx_usart.h > @@ -37,7 +37,12 @@ > #define USART_CR3 0x14 > #define USART_GTPR 0x18 > > -#define USART_SR_RESET 0x00C0 > +/* > + * XXX The reset value mentioned in "24.6.1 Status register" seems bogus. > + * Looking at "Table 98 USART register map and reset values", it seems it > + * should be 0xc0, and that's how real hardware behaves. > + */ > +#define USART_SR_RESET (USART_SR_TXE | USART_SR_TC) > > #define USART_SR_TXE (1 << 7) > #define USART_SR_TC (1 << 6) > -- > 2.11.0 > >
[Qemu-devel] [PATCH v4 10/20] sdcard: handle the Security Specification commands
returning sd_illegal, since they are not implemented. Signed-off-by: Philippe Mathieu-Daudé--- hw/sd/sd.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 30acd04ad7..0457f5214b 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -1551,6 +1551,17 @@ static sd_rsp_type_t sd_app_command(SDState *sd, } break; +case 18:/* Reserved for SD security applications */ +case 25: +case 26: +case 38: +case 43 ... 49: +/* Refer to the "SD Specifications Part3 Security Specification" for + * information about the SD Security Features */ +qemu_log_mask(LOG_UNIMP, "SD: CMD%i Security not implemented\n", + req.cmd); +return sd_illegal; + default: /* Fall back to standard commands. */ return sd_normal_command(sd, req); -- 2.16.1
[Qemu-devel] [PATCH v4 09/20] sdcard: handle CMD54 (SDIO)
Linux uses it to poll the bus before polling for a card. Signed-off-by: Philippe Mathieu-DaudéReviewed-by: Alistair Francis --- hw/sd/sd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index b567c44da8..30acd04ad7 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -1375,9 +1375,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) } break; -case 52: -case 53: -/* CMD52, CMD53: reserved for SDIO cards +case 52 ... 54: +/* CMD52, CMD53, CMD54: reserved for SDIO cards * (see the SDIO Simplified Specification V2.0) * Handle as illegal command but do not complain * on stderr, as some OSes may use these in their -- 2.16.1
Re: [Qemu-devel] [PATCH 07/30] hw/arm: use the BYTE-based definitions
On Wed, Feb 14, 2018 at 8:28 PM, Philippe Mathieu-Daudéwrote: > It ease code review, unit is explicit. > > Signed-off-by: Philippe Mathieu-Daudé The logic looks good. Did you do this automatically? If so you should include the commands in the commit message. Reviewed-by: Alistair Francis Alistair > --- > include/hw/arm/stm32f205_soc.h | 4 ++-- > hw/arm/boot.c | 6 +++--- > hw/arm/collie.c| 4 ++-- > hw/arm/digic_boards.c | 6 +++--- > hw/arm/gumstix.c | 2 +- > hw/arm/integratorcp.c | 2 +- > hw/arm/mainstone.c | 2 +- > hw/arm/musicpal.c | 8 > hw/arm/omap_sx1.c | 8 > hw/arm/raspi.c | 2 +- > hw/arm/stellaris.c | 4 ++-- > hw/arm/versatilepb.c | 4 ++-- > hw/arm/vexpress.c | 6 +++--- > hw/arm/virt.c | 4 ++-- > hw/arm/xilinx_zynq.c | 4 ++-- > hw/misc/aspeed_sdmc.c | 8 > hw/misc/imx7_gpr.c | 2 +- > hw/misc/omap_gpmc.c| 4 ++-- > hw/ssi/aspeed_smc.c| 28 ++-- > 19 files changed, 54 insertions(+), 54 deletions(-) > > diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h > index 922a733f88..e30ae33c65 100644 > --- a/include/hw/arm/stm32f205_soc.h > +++ b/include/hw/arm/stm32f205_soc.h > @@ -43,9 +43,9 @@ > #define STM_NUM_SPIS 3 > > #define FLASH_BASE_ADDRESS 0x0800 > -#define FLASH_SIZE (1024 * 1024) > +#define FLASH_SIZE (1 * M_BYTE) > #define SRAM_BASE_ADDRESS 0x2000 > -#define SRAM_SIZE (128 * 1024) > +#define SRAM_SIZE (128 * K_BYTE) > > typedef struct STM32F205State { > /*< private >*/ > diff --git a/hw/arm/boot.c b/hw/arm/boot.c > index 05108bc42f..0552284d57 100644 > --- a/hw/arm/boot.c > +++ b/hw/arm/boot.c > @@ -984,7 +984,7 @@ static void arm_load_kernel_notify(Notifier *notifier, > void *data) > * the initrd at 128MB. > */ > info->initrd_start = info->loader_start + > -MIN(info->ram_size / 2, 128 * 1024 * 1024); > +MIN(info->ram_size / 2, 128 * M_BYTE); > > /* Assume that raw images are linux kernels, and ELF images are not. */ > kernel_size = arm_load_elf(info, _entry, _low_addr, > @@ -1069,13 +1069,13 @@ static void arm_load_kernel_notify(Notifier > *notifier, void *data) > * > * Let's play safe and prealign it to 2MB to give us some > space. > */ > -align = 2 * 1024 * 1024; > +align = 2 * M_BYTE; > } else { > /* > * Some 32bit kernels will trash anything in the 4K page the > * initrd ends in, so make sure the DTB isn't caught up in > that. > */ > -align = 4096; > +align = 4 * K_BYTE; > } > > /* Place the DTB after the initrd in memory with alignment. */ > diff --git a/hw/arm/collie.c b/hw/arm/collie.c > index f8c566e2e5..1695863629 100644 > --- a/hw/arm/collie.c > +++ b/hw/arm/collie.c > @@ -39,12 +39,12 @@ static void collie_init(MachineState *machine) > dinfo = drive_get(IF_PFLASH, 0, 0); > pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x0200, > dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, > -(64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0); > +64 * K_BYTE, 512, 4, 0x00, 0x00, 0x00, 0x00, 0); > > dinfo = drive_get(IF_PFLASH, 0, 1); > pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x0200, > dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, > -(64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0); > +64 * K_BYTE, 512, 4, 0x00, 0x00, 0x00, 0x00, 0); > > sysbus_create_simple("scoop", 0x4080, NULL); > > diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c > index 9f11dcd11f..04e52e776f 100644 > --- a/hw/arm/digic_boards.c > +++ b/hw/arm/digic_boards.c > @@ -126,8 +126,8 @@ static void digic_load_rom(DigicBoardState *s, hwaddr > addr, > static void digic4_add_k8p3215uqb_rom(DigicBoardState *s, hwaddr addr, >const char *def_filename) > { > -#define FLASH_K8P3215UQB_SIZE (4 * 1024 * 1024) > -#define FLASH_K8P3215UQB_SECTOR_SIZE (64 * 1024) > +#define FLASH_K8P3215UQB_SIZE (4 * M_BYTE) > +#define FLASH_K8P3215UQB_SECTOR_SIZE (64 * K_BYTE) > > pflash_cfi02_register(addr, NULL, "pflash", FLASH_K8P3215UQB_SIZE, >NULL, FLASH_K8P3215UQB_SECTOR_SIZE, > @@ -141,7 +141,7 @@ static void digic4_add_k8p3215uqb_rom(DigicBoardState *s, > hwaddr addr, > } > > static DigicBoard digic4_board_canon_a1100 = { > -.ram_size = 64 * 1024 * 1024, > +.ram_size = 64 * M_BYTE, > .add_rom1 =
[Qemu-devel] [PATCH v4 18/20] sdcard: implement the UHS-I SWITCH_FUNCTION entries (Spec v3)
[based on a patch from Alistair Francisfrom qemu/xilinx tag xilinx-v2015.2] Signed-off-by: Philippe Mathieu-Daudé --- hw/sd/sd.c | 148 + hw/sd/trace-events | 1 + 2 files changed, 127 insertions(+), 22 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 4b0bb7992d..ada96f5574 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -124,6 +124,7 @@ struct SDState { bool enable; uint8_t dat_lines; bool cmd_line; +bool uhs_enabled; }; static const char *sd_state_name(enum SDCardStates state) @@ -563,6 +564,7 @@ static void sd_reset(DeviceState *dev) sd->expecting_acmd = false; sd->dat_lines = 0xf; sd->cmd_line = true; +sd->uhs_enabled = false; sd->multi_blk_cnt = 0; } @@ -761,30 +763,132 @@ static uint32_t sd_wpbits(SDState *sd, uint64_t addr) return ret; } +/* Function Group */ +enum { +SD_FG_MIN = 1, +SD_FG_ACCESS_MODE = 1, +SD_FG_COMMAND_SYSTEM= 2, +SD_FG_DRIVER_STRENGTH = 3, +SD_FG_CURRENT_LIMIT = 4, +SD_FG_RSVD_5= 5, +SD_FG_RSVD_6= 6, +SD_FG_COUNT +}; + +/* Function name */ +#define SD_FN_COUNT 16 + +static const char *sd_fn_grp_name[SD_FG_COUNT] = { +[SD_FG_ACCESS_MODE] = "ACCESS_MODE", +[SD_FG_COMMAND_SYSTEM] = "COMMAND_SYSTEM", +[SD_FG_DRIVER_STRENGTH] = "DRIVER_STRENGTH", +[SD_FG_CURRENT_LIMIT] = "CURRENT_LIMIT", +[SD_FG_RSVD_5] = "RSVD5", +[SD_FG_RSVD_6] = "RSVD6", +}; + +typedef struct sd_fn_support { +const char *name; +bool uhs_only; +bool unimp; +} sd_fn_support; + +static const sd_fn_support *sd_fn_support_defs[SD_FG_COUNT] = { +[SD_FG_ACCESS_MODE] = (sd_fn_support [SD_FN_COUNT]) { +[0] = { .name = "default/SDR12" }, +[1] = { .name = "high-speed/SDR25" }, +[2] = { .name = "SDR50",.uhs_only = true }, +[3] = { .name = "SDR104", .uhs_only = true }, +[4] = { .name = "DDR50",.uhs_only = true }, +}, +[SD_FG_COMMAND_SYSTEM] = (sd_fn_support [SD_FN_COUNT]) { +[0] = { .name = "default" }, +[1] = { .name = "For eC" }, +[3] = { .name = "OTP", .unimp = true }, +[4] = { .name = "ASSD", .unimp = true }, +}, +[SD_FG_DRIVER_STRENGTH] = (sd_fn_support [SD_FN_COUNT]) { +[0] = { .name = "default/Type B" }, +[1] = { .name = "Type A", .uhs_only = true }, +[2] = { .name = "Type C", .uhs_only = true }, +[3] = { .name = "Type D", .uhs_only = true }, +}, +[SD_FG_CURRENT_LIMIT] = (sd_fn_support [SD_FN_COUNT]) { +[0] = { .name = "default/200mA" }, +[1] = { .name = "400mA",.uhs_only = true }, +[2] = { .name = "600mA",.uhs_only = true }, +[3] = { .name = "800mA",.uhs_only = true }, +}, +[SD_FG_RSVD_5] = (sd_fn_support [SD_FN_COUNT]) { +[0] = { .name = "default" }, +}, +[SD_FG_RSVD_6] = (sd_fn_support [SD_FN_COUNT]) { +[0] = { .name = "default" }, +}, +}; + +#define SD_FN_NO_INFLUENCE (1 << 15) + static void sd_function_switch(SDState *sd, uint32_t arg) { -int i, mode, new_func; -mode = !!(arg & 0x8000); - -sd->data[0] = 0x00;/* Maximum current consumption */ -sd->data[1] = 0x01; -sd->data[2] = 0x80;/* Supported group 6 functions */ -sd->data[3] = 0x01; -sd->data[4] = 0x80;/* Supported group 5 functions */ -sd->data[5] = 0x01; -sd->data[6] = 0x80;/* Supported group 4 functions */ -sd->data[7] = 0x01; -sd->data[8] = 0x80;/* Supported group 3 functions */ -sd->data[9] = 0x01; -sd->data[10] = 0x80; /* Supported group 2 functions */ -sd->data[11] = 0x43; -sd->data[12] = 0x80; /* Supported group 1 functions */ -sd->data[13] = 0x03; -for (i = 0; i < 6; i ++) { -new_func = (arg >> (i * 4)) & 0x0f; -if (mode && new_func != 0x0f) -sd->function_group[i] = new_func; -sd->data[14 + (i >> 1)] = new_func << ((i * 4) & 4); +int fn_grp, new_func, i; +uint8_t *data_p; +bool mode = extract32(arg, 31, 1); /* 0: check only, 1: do switch */ + +stw_be_p(sd->data + 0, 0x0001); /* Maximum current consumption */ + +data_p = >data[2]; +for (fn_grp = SD_FG_COUNT - 1; fn_grp >= SD_FG_MIN; fn_grp--) { +uint16_t supported_fns = SD_FN_NO_INFLUENCE; +for (i = 0; i < SD_FN_COUNT; ++i) { +const sd_fn_support *def = _fn_support_defs[fn_grp][i]; + +if (def->name && !def->unimp && +!(def->uhs_only && !sd->uhs_enabled)) { +supported_fns |= 1 << i; +} +} +stw_be_p(data_p, supported_fns); +data_p += 2; +} + +assert(data_p == >data[14]); +for (fn_grp = SD_FG_COUNT -
[Qemu-devel] [PATCH v4 03/20] sdcard: fix the 'maximum data transfer rate' to 25MHz
To comply with Spec v1.10 (and 2.00, 3.01): . TRAN_SPEED for current SD Memory Cards that field must be always 0_0110_010b (032h) which is equal to 25MHz - the mandatory maximum operating frequency of SD Memory Card. Signed-off-by: Philippe Mathieu-DaudéReviewed-by: Alistair Francis --- hw/sd/sd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index c1ba098d86..14c1cb1332 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -358,7 +358,7 @@ static void sd_set_csd(SDState *sd, uint64_t size) sd->csd[0] = 0x00; /* CSD structure */ sd->csd[1] = 0x26; /* Data read access-time-1 */ sd->csd[2] = 0x00; /* Data read access-time-2 */ -sd->csd[3] = 0x5a; /* Max. data transfer rate */ +sd->csd[3] = 0x32; /* Max. data transfer rate: 25 MHz */ sd->csd[4] = 0x5f; /* Card Command Classes */ sd->csd[5] = 0x50 |/* Max. read data block length */ HWBLOCK_SHIFT; -- 2.16.1
[Qemu-devel] [PATCH v4 17/20] sdcard: add SD SEND_TUNING_BLOCK (CMD19)
[based on a patch from Alistair Francisfrom qemu/xilinx tag xilinx-v2015.2] Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis --- hw/sd/sd.c | 24 1 file changed, 24 insertions(+) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 911aae6233..4b0bb7992d 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -1166,6 +1166,14 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) } break; +case 19:/* CMD19: SEND_TUNING_BLOCK (SD) */ +if (sd->state == sd_transfer_state) { +sd->state = sd_sendingdata_state; +sd->data_offset = 0; +return sd_r1; +} +break; + case 23:/* CMD23: SET_BLOCK_COUNT */ switch (sd->state) { case sd_transfer_state: @@ -1889,6 +1897,15 @@ void sd_write_data(SDState *sd, uint8_t value) } } +#define SD_TUNING_BLOCK_SIZE64 + +static const uint32_t sd_tunning_data[SD_TUNING_BLOCK_SIZE / 4] = { +0xFF0FFF00, 0x0FFCC3CC, 0xC33CCCFF, 0xFEFFFEEF, +0xFFDFFFDD, 0xFFFBFFFB, 0XBFFF7FFF, 0X77F7BDEF, +0XFFF0FFF0, 0X0FFCCC3C, 0XCC33CCCF, 0XFFEFFFEE, +0XFFFDFFFD, 0XDFFFBFFF, 0XBBFFF7FF, 0XF77F7BDE, +}; + uint8_t sd_read_data(SDState *sd) { /* TODO: Append CRCs */ @@ -1968,6 +1985,13 @@ uint8_t sd_read_data(SDState *sd) } break; +case 19:/* CMD19: SEND_TUNING_BLOCK (SD) */ +if (sd->data_offset >= SD_TUNING_BLOCK_SIZE - 1) { +sd->state = sd_transfer_state; +} +ret = ((uint8_t *)(_tunning_data))[sd->data_offset++]; +break; + case 22: /* ACMD22: SEND_NUM_WR_BLOCKS */ ret = sd->data[sd->data_offset ++]; -- 2.16.1
[Qemu-devel] [PATCH v4 00/20] SDCard: bugfixes, support UHS-I (part 5)
Some refactors, few bugfixes, better SD/SPI support. With this series apply, machines can use SD cards in UHS-I mode. (mostly imported from Alistair Francis work) MMC mode split out for another series, so UHS enabled MMC cards are still not usable: kernel: mmc0: SDHCI controller on PCI [:00:05.0] using ADMA kernel: sd 0:0:0:0: Attached scsi generic sg0 type 0 kernel: mmc0: Skipping voltage switch [mmc kthread looping] Since v3: - simpler SPI handling, improved descriptions (Alistair review) - inverted patches 16/17 order Since v2: - split again in 2... other part is cleanup/tracing Since v1: - rewrote mostly all patches to keep it simpler. $ git backport-diff 001/20:[] [-C] 'sdcard: Don't always set the high capacity bit' 002/20:[] [-C] 'sdcard: update the CSD CRC register regardless the CSD structure version' 003/20:[] [-C] 'sdcard: fix the 'maximum data transfer rate' to 25MHz' 004/20:[] [-C] 'sdcard: clean the SCR register and add few comments' 005/20:[] [--] 'sdcard: remove commands from unsupported old MMC specification' 006/20:[] [--] 'sdcard: simplify using the ldst API' 007/20:[0008] [FC] 'sdcard: use the correct masked OCR in the R3 reply' 008/20:[] [-C] 'sdcard: use the registerfields API for the CARD_STATUS register masks' 009/20:[] [--] 'sdcard: handle CMD54 (SDIO)' 010/20:[down] 'sdcard: handle the Security Specification commands' 011/20:[down] 'sdcard: use a more descriptive label 'unimplemented_spi_cmd'' 012/20:[0034] [FC] 'sdcard: handles more commands in SPI mode' 013/20:[] [--] 'sdcard: check the card is in correct state for APP CMD (CMD55)' 014/20:[] [--] 'sdcard: warn if host uses an incorrect address for APP CMD (CMD55)' 015/20:[] [--] 'sdcard: simplify SEND_IF_COND (CMD8)' 016/20:[] [--] 'sdcard: simplify SD_SEND_OP_COND (ACMD41)' 017/20:[] [--] 'sdcard: add SD SEND_TUNING_BLOCK (CMD19)' 018/20:[] [--] 'sdcard: implement the UHS-I SWITCH_FUNCTION entries (Spec v3)' 019/20:[] [-C] 'sdcard: add a 'uhs' property, update the OCR register ACCEPT_SWITCH_1V8 bit' 020/20:[] [--] 'sdcard: add an enum for the SD PHY Spec version' Based-on: 20180215220540.6556-12-f4...@amsat.org Philippe Mathieu-Daudé (20): sdcard: Don't always set the high capacity bit sdcard: update the CSD CRC register regardless the CSD structure version sdcard: fix the 'maximum data transfer rate' to 25MHz sdcard: clean the SCR register and add few comments sdcard: remove commands from unsupported old MMC specification sdcard: simplify using the ldst API sdcard: use the correct masked OCR in the R3 reply sdcard: use the registerfields API for the CARD_STATUS register masks sdcard: handle CMD54 (SDIO) sdcard: handle the Security Specification commands sdcard: use a more descriptive label 'unimplemented_spi_cmd' sdcard: handles more commands in SPI mode sdcard: check the card is in correct state for APP CMD (CMD55) sdcard: warn if host uses an incorrect address for APP CMD (CMD55) sdcard: simplify SEND_IF_COND (CMD8) sdcard: simplify SD_SEND_OP_COND (ACMD41) sdcard: add SD SEND_TUNING_BLOCK (CMD19) sdcard: implement the UHS-I SWITCH_FUNCTION entries (Spec v3) sdcard: add a 'uhs' property, update the OCR register ACCEPT_SWITCH_1V8 bit sdcard: add an enum for the SD PHY Spec version hw/sd/sd.c | 498 - hw/sd/trace-events | 1 + 2 files changed, 343 insertions(+), 156 deletions(-) -- 2.16.1
[Qemu-devel] [PATCH v4 14/20] sdcard: warn if host uses an incorrect address for APP CMD (CMD55)
Signed-off-by: Philippe Mathieu-DaudéReviewed-by: Alistair Francis --- hw/sd/sd.c | 5 + 1 file changed, 5 insertions(+) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index c2f01a5fa3..5827379d0f 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -1395,6 +1395,11 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) case sd_identification_state: case sd_inactive_state: return sd_illegal; +case sd_idle_state: +if (rca) { +qemu_log_mask(LOG_GUEST_ERROR, + "SD: illegal RCA 0x%04x for APP_CMD\n", req.cmd); +} default: break; } -- 2.16.1
[Qemu-devel] [PATCH v4 15/20] sdcard: simplify SEND_IF_COND (CMD8)
replace switch(single case) -> if() Signed-off-by: Philippe Mathieu-DaudéReviewed-by: Alistair Francis --- hw/sd/sd.c | 26 +++--- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 5827379d0f..942143ab3e 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -1012,23 +1012,19 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) case 8:/* CMD8: SEND_IF_COND */ /* Physical Layer Specification Version 2.00 command */ -switch (sd->state) { -case sd_idle_state: -sd->vhs = 0; - -/* No response if not exactly one VHS bit is set. */ -if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1))) { -return sd->spi ? sd_r7 : sd_r0; -} - -/* Accept. */ -sd->vhs = req.arg; -return sd_r7; - -default: +if (sd->state != sd_idle_state) { break; } -break; +sd->vhs = 0; + +/* No response if not exactly one VHS bit is set. */ +if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1))) { +return sd->spi ? sd_r7 : sd_r0; +} + +/* Accept. */ +sd->vhs = req.arg; +return sd_r7; case 9:/* CMD9: SEND_CSD */ switch (sd->state) { -- 2.16.1
[Qemu-devel] [PATCH v4 07/20] sdcard: use the correct masked OCR in the R3 reply
use the registerfields API to access the OCR register Signed-off-by: Philippe Mathieu-DaudéReviewed-by: Alistair Francis --- hw/sd/sd.c | 21 - 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index b43baa2edd..3970e590e6 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -47,8 +47,6 @@ //#define DEBUG_SD 1 -#define ACMD41_ENQUIRY_MASK 0x00ff - typedef enum { sd_r0 = 0,/* no response */ sd_r1,/* normal response command */ @@ -273,13 +271,26 @@ static uint16_t sd_crc16(void *message, size_t width) #define OCR_POWER_DELAY_NS 50 /* 0.5ms */ +FIELD(OCR, VDD_VOLTAGE_WINDOW, 0, 24) +FIELD(OCR, VDD_VOLTAGE_WIN_LO, 0, 8) +FIELD(OCR, DUAL_VOLTAGE_CARD, 7, 1) +FIELD(OCR, VDD_VOLTAGE_WIN_HI, 8, 16) +FIELD(OCR, ACCEPT_SWITCH_1V8, 24, 1) /* Only UHS-I */ +FIELD(OCR, UHS_II_CARD,29, 1) /* Only UHS-II */ FIELD(OCR, CARD_CAPACITY, 30, 1) /* 0:SDSC, 1:SDHC/SDXC */ FIELD(OCR, CARD_POWER_UP, 31, 1) +#define ACMD41_ENQUIRY_MASK 0x00ff +#define ACMD41_R3_MASK (R_OCR_VDD_VOLTAGE_WIN_HI_MASK \ + | R_OCR_ACCEPT_SWITCH_1V8_MASK \ + | R_OCR_UHS_II_CARD_MASK \ + | R_OCR_CARD_CAPACITY_MASK \ + | R_OCR_CARD_POWER_UP_MASK) + static void sd_set_ocr(SDState *sd) { -/* All voltages OK, Standard Capacity SD Memory Card, not yet powered up */ -sd->ocr = 0x0000; +/* All voltages OK */ +sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK; } static void sd_ocr_powerup(void *opaque) @@ -447,7 +458,7 @@ static void sd_response_r1_make(SDState *sd, uint8_t *response) static void sd_response_r3_make(SDState *sd, uint8_t *response) { -stl_be_p(response, sd->ocr); +stl_be_p(response, sd->ocr & ACMD41_R3_MASK); } static void sd_response_r6_make(SDState *sd, uint8_t *response) -- 2.16.1
[Qemu-devel] [PATCH v2 1/3] ppc4xx: Add device models found in PPC440 core SoCs
These devices are found in newer SoCs based on 440 core e.g. the 460EX (http://www.embeddeddeveloper.com/assets/processors/amcc/datasheets/ PP460EX_DS2063.pdf) Signed-off-by: BALATON Zoltan--- v2: - Rebased to latest changes on master - Removed printfs hw/ppc/ppc440.h| 26 + hw/ppc/ppc440_uc.c | 1159 include/hw/pci/pcie_host.h |2 +- 3 files changed, 1186 insertions(+), 1 deletion(-) create mode 100644 hw/ppc/ppc440.h create mode 100644 hw/ppc/ppc440_uc.c diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h new file mode 100644 index 000..ad27db1 --- /dev/null +++ b/hw/ppc/ppc440.h @@ -0,0 +1,26 @@ +/* + * QEMU PowerPC 440 shared definitions + * + * Copyright (c) 2012 François Revol + * Copyright (c) 2016-2018 BALATON Zoltan + * + * This work is licensed under the GNU GPL license version 2 or later. + * + */ + +#ifndef PPC440_H +#define PPC440_H + +#include "hw/ppc/ppc.h" + +void ppc4xx_l2sram_init(CPUPPCState *env); +void ppc4xx_cpr_init(CPUPPCState *env); +void ppc4xx_sdr_init(CPUPPCState *env); +void ppc440_sdram_init(CPUPPCState *env, int nbanks, + MemoryRegion *ram_memories, + hwaddr *ram_bases, hwaddr *ram_sizes, + int do_init); +void ppc4xx_ahb_init(CPUPPCState *env); +void ppc460ex_pcie_init(CPUPPCState *env); + +#endif /* PPC440_H */ diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c new file mode 100644 index 000..4e2523a --- /dev/null +++ b/hw/ppc/ppc440_uc.c @@ -0,0 +1,1159 @@ +/* + * QEMU PowerPC 440 embedded processors emulation + * + * Copyright (c) 2012 François Revol + * Copyright (c) 2016-2018 BALATON Zoltan + * + * This work is licensed under the GNU GPL license version 2 or later. + * + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qemu/cutils.h" +#include "qemu/error-report.h" +#include "qapi/error.h" +#include "cpu.h" +#include "hw/hw.h" +#include "exec/address-spaces.h" +#include "exec/memory.h" +#include "hw/ppc/ppc.h" +#include "hw/pci/pci.h" +#include "sysemu/block-backend.h" +#include "hw/ppc/ppc440.h" + +/*/ +/* L2 Cache as SRAM */ +/* FIXME:fix names */ +enum { +DCR_L2CACHE_BASE = 0x30, +DCR_L2CACHE_CFG = DCR_L2CACHE_BASE, +DCR_L2CACHE_CMD, +DCR_L2CACHE_ADDR, +DCR_L2CACHE_DATA, +DCR_L2CACHE_STAT, +DCR_L2CACHE_CVER, +DCR_L2CACHE_SNP0, +DCR_L2CACHE_SNP1, +DCR_L2CACHE_END = DCR_L2CACHE_SNP1, +}; + +/* base is 460ex-specific, cf. U-Boot, ppc4xx-isram.h */ +enum { +DCR_ISRAM0_BASE = 0x20, +DCR_ISRAM0_SB0CR = DCR_ISRAM0_BASE, +DCR_ISRAM0_SB1CR, +DCR_ISRAM0_SB2CR, +DCR_ISRAM0_SB3CR, +DCR_ISRAM0_BEAR, +DCR_ISRAM0_BESR0, +DCR_ISRAM0_BESR1, +DCR_ISRAM0_PMEG, +DCR_ISRAM0_CID, +DCR_ISRAM0_REVID, +DCR_ISRAM0_DPC, +DCR_ISRAM0_END= DCR_ISRAM0_DPC +}; + +enum { +DCR_ISRAM1_BASE = 0xb0, +DCR_ISRAM1_SB0CR = DCR_ISRAM1_BASE, +/* single bank */ +DCR_ISRAM1_BEAR = DCR_ISRAM1_BASE + 0x04, +DCR_ISRAM1_BESR0, +DCR_ISRAM1_BESR1, +DCR_ISRAM1_PMEG, +DCR_ISRAM1_CID, +DCR_ISRAM1_REVID, +DCR_ISRAM1_DPC, +DCR_ISRAM1_END= DCR_ISRAM1_DPC +}; + +typedef struct ppc4xx_l2sram_t { +MemoryRegion bank[4]; +uint32_t l2cache[8]; +uint32_t isram0[11]; +} ppc4xx_l2sram_t; + +#ifdef MAP_L2SRAM +static void l2sram_update_mappings(ppc4xx_l2sram_t *l2sram, + uint32_t isarc, uint32_t isacntl, + uint32_t dsarc, uint32_t dsacntl) +{ +if (l2sram->isarc != isarc || +(l2sram->isacntl & 0x8000) != (isacntl & 0x8000)) { +if (l2sram->isacntl & 0x8000) { +/* Unmap previously assigned memory region */ +memory_region_del_subregion(get_system_memory(), +>isarc_ram); +} +if (isacntl & 0x8000) { +/* Map new instruction memory region */ +memory_region_add_subregion(get_system_memory(), isarc, +>isarc_ram); +} +} +if (l2sram->dsarc != dsarc || +(l2sram->dsacntl & 0x8000) != (dsacntl & 0x8000)) { +if (l2sram->dsacntl & 0x8000) { +/* Beware not to unmap the region we just mapped */ +if (!(isacntl & 0x8000) || l2sram->dsarc != isarc) { +/* Unmap previously assigned memory region */ +memory_region_del_subregion(get_system_memory(), +>dsarc_ram); +} +} +if (dsacntl & 0x8000) { +/* Beware not to remap the region we just mapped */ +if (!(isacntl & 0x8000) || dsarc != isarc) { +/* Map new data memory region */ +
[Qemu-devel] [PATCH v4 13/20] sdcard: check the card is in correct state for APP CMD (CMD55)
Signed-off-by: Philippe Mathieu-DaudéReviewed-by: Alistair Francis --- hw/sd/sd.c | 8 1 file changed, 8 insertions(+) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 0ecb446fdb..c2f01a5fa3 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -1390,6 +1390,14 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) /* Application specific commands (Class 8) */ case 55: /* CMD55: APP_CMD */ +switch (sd->state) { +case sd_ready_state: +case sd_identification_state: +case sd_inactive_state: +return sd_illegal; +default: +break; +} if (!sd->spi) { if (sd->rca != rca) { return sd_r0; -- 2.16.1
[Qemu-devel] [PATCH v4 06/20] sdcard: simplify using the ldst API
the code is easier to review/refactor. Signed-off-by: Philippe Mathieu-DaudéReviewed-by: Alistair Francis --- hw/sd/sd.c | 38 +- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 4267919ce0..b43baa2edd 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -432,57 +432,39 @@ static int sd_req_crc_validate(SDRequest *req) { uint8_t buffer[5]; buffer[0] = 0x40 | req->cmd; -buffer[1] = (req->arg >> 24) & 0xff; -buffer[2] = (req->arg >> 16) & 0xff; -buffer[3] = (req->arg >> 8) & 0xff; -buffer[4] = (req->arg >> 0) & 0xff; +stl_be_p([1], req->arg); return 0; return sd_crc7(buffer, 5) != req->crc; /* TODO */ } static void sd_response_r1_make(SDState *sd, uint8_t *response) { -uint32_t status = sd->card_status; +stl_be_p(response, sd->card_status); + /* Clear the "clear on read" status bits */ sd->card_status &= ~CARD_STATUS_C; - -response[0] = (status >> 24) & 0xff; -response[1] = (status >> 16) & 0xff; -response[2] = (status >> 8) & 0xff; -response[3] = (status >> 0) & 0xff; } static void sd_response_r3_make(SDState *sd, uint8_t *response) { -response[0] = (sd->ocr >> 24) & 0xff; -response[1] = (sd->ocr >> 16) & 0xff; -response[2] = (sd->ocr >> 8) & 0xff; -response[3] = (sd->ocr >> 0) & 0xff; +stl_be_p(response, sd->ocr); } static void sd_response_r6_make(SDState *sd, uint8_t *response) { -uint16_t arg; uint16_t status; -arg = sd->rca; status = ((sd->card_status >> 8) & 0xc000) | ((sd->card_status >> 6) & 0x2000) | (sd->card_status & 0x1fff); sd->card_status &= ~(CARD_STATUS_C & 0xc81fff); - -response[0] = (arg >> 8) & 0xff; -response[1] = arg & 0xff; -response[2] = (status >> 8) & 0xff; -response[3] = status & 0xff; +stw_be_p(response + 0, sd->rca); +stw_be_p(response + 2, status); } static void sd_response_r7_make(SDState *sd, uint8_t *response) { -response[0] = (sd->vhs >> 24) & 0xff; -response[1] = (sd->vhs >> 16) & 0xff; -response[2] = (sd->vhs >> 8) & 0xff; -response[3] = (sd->vhs >> 0) & 0xff; +stl_be_p(response, sd->vhs); } static inline uint64_t sd_addr_to_wpnum(uint64_t addr) @@ -728,7 +710,7 @@ static uint32_t sd_wpbits(SDState *sd, uint64_t addr) static void sd_function_switch(SDState *sd, uint32_t arg) { -int i, mode, new_func, crc; +int i, mode, new_func; mode = !!(arg & 0x8000); sd->data[0] = 0x00;/* Maximum current consumption */ @@ -752,9 +734,7 @@ static void sd_function_switch(SDState *sd, uint32_t arg) sd->data[14 + (i >> 1)] = new_func << ((i * 4) & 4); } memset(>data[17], 0, 47); -crc = sd_crc16(sd->data, 64); -sd->data[65] = crc >> 8; -sd->data[66] = crc & 0xff; +stw_be_p(sd->data + 65, sd_crc16(sd->data, 64)); } static inline bool sd_wp_addr(SDState *sd, uint64_t addr) -- 2.16.1
[Qemu-devel] [PATCH v4 09/11] sdcard: display protocol used when tracing
put the function in sdmmc-common.c since we will reuse it in hw/sd/core.c Signed-off-by: Philippe Mathieu-Daudé--- hw/sd/sd.c | 14 ++ hw/sd/trace-events | 8 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 666ff3873f..6760815045 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -122,6 +122,7 @@ struct SDState { qemu_irq readonly_cb; qemu_irq inserted_cb; QEMUTimer *ocr_power_timer; +const char *proto_name; bool enable; uint8_t dat_lines; bool cmd_line; @@ -828,7 +829,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) uint64_t addr = (sd->ocr & (1 << 30)) ? (uint64_t) req.arg << 9 : req.arg; if (req.cmd != 55 || sd->expecting_acmd) { -trace_sdcard_normal_command(sd_cmd_name(req.cmd), req.cmd, +trace_sdcard_normal_command(sd->proto_name, +sd_cmd_name(req.cmd), req.cmd, req.arg, sd_state_name(sd->state)); } @@ -1400,7 +1402,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) static sd_rsp_type_t sd_app_command(SDState *sd, SDRequest req) { -trace_sdcard_app_command(sd_acmd_name(req.cmd), +trace_sdcard_app_command(sd->proto_name, sd_acmd_name(req.cmd), req.cmd, req.arg, sd_state_name(sd->state)); sd->card_status |= APP_CMD; switch (req.cmd) { @@ -1699,7 +1701,8 @@ void sd_write_data(SDState *sd, uint8_t value) if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION)) return; -trace_sdcard_write_data(sd_acmd_name(sd->current_cmd), +trace_sdcard_write_data(sd->proto_name, +sd_acmd_name(sd->current_cmd), sd->current_cmd, value); switch (sd->current_cmd) { case 24: /* CMD24: WRITE_SINGLE_BLOCK */ @@ -1838,7 +1841,8 @@ uint8_t sd_read_data(SDState *sd) io_len = (sd->ocr & (1 << 30)) ? 512 : sd->blk_len; -trace_sdcard_read_data(sd_acmd_name(sd->current_cmd), +trace_sdcard_read_data(sd->proto_name, + sd_acmd_name(sd->current_cmd), sd->current_cmd, io_len); switch (sd->current_cmd) { case 6:/* CMD6: SWITCH_FUNCTION */ @@ -1980,6 +1984,8 @@ static void sd_realize(DeviceState *dev, Error **errp) SDState *sd = SD_CARD(dev); int ret; +sd->proto_name = sd->spi ? "SPI" : "SD"; + if (sd->blk && blk_is_read_only(sd->blk)) { error_setg(errp, "Cannot use read-only drive as SD card"); return; diff --git a/hw/sd/trace-events b/hw/sd/trace-events index cdddca3dbf..2059ace61f 100644 --- a/hw/sd/trace-events +++ b/hw/sd/trace-events @@ -24,8 +24,8 @@ sdhci_write_dataport(uint16_t data_count) "write buffer filled with %u bytes of sdhci_capareg(const char *desc, uint16_t val) "%s: %u" # hw/sd/sd.c -sdcard_normal_command(const char *cmd_desc, uint8_t cmd, uint32_t arg, const char *state) "%20s/ CMD%02d arg 0x%08x (state %s)" -sdcard_app_command(const char *acmd_desc, uint8_t acmd, uint32_t arg, const char *state) "%23s/ACMD%02d arg 0x%08x (state %s)" +sdcard_normal_command(const char *proto, const char *cmd_desc, uint8_t cmd, uint32_t arg, const char *state) "%s %20s/ CMD%02d arg 0x%08x (state %s)" +sdcard_app_command(const char *proto, const char *acmd_desc, uint8_t acmd, uint32_t arg, const char *state) "%s %23s/ACMD%02d arg 0x%08x (state %s)" sdcard_response(const char *rspdesc, int rsplen) "%s (sz:%d)" sdcard_powerup(void) "" sdcard_inquiry_cmd41(void) "" @@ -39,8 +39,8 @@ sdcard_lock(void) "" sdcard_unlock(void) "" sdcard_read_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x" sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x" -sdcard_write_data(const char *cmd_desc, uint8_t cmd, uint8_t value) "%20s/ CMD%02d value 0x%02x" -sdcard_read_data(const char *cmd_desc, uint8_t cmd, int length) "%20s/ CMD%02d len %d" +sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint8_t value) "%s %20s/ CMD%02d value 0x%02x" +sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, int length) "%s %20s/ CMD%02d len %d" sdcard_set_voltage(uint16_t millivolts) "%u mV" # hw/sd/milkymist-memcard.c -- 2.16.1
[Qemu-devel] [PATCH v4 01/20] sdcard: Don't always set the high capacity bit
Don't set the high capacity bit by default as it will be set if required in the sd_set_csd() function. [based on a patch from Alistair Francisand Peter Ogden from qemu/xilinx tag xilinx-v2015.4] Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis --- hw/sd/sd.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index fbee87afef..9dfbd65ac8 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -291,6 +291,10 @@ static void sd_ocr_powerup(void *opaque) /* card power-up OK */ sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_POWER_UP, 1); + +if (sd->size > 1 * G_BYTE) { +sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_CAPACITY, 1); +} } static void sd_set_scr(SDState *sd) @@ -395,7 +399,6 @@ static void sd_set_csd(SDState *sd, uint64_t size) sd->csd[13] = 0x40; sd->csd[14] = 0x00; sd->csd[15] = 0x00; -sd->ocr |= 1 << 30; /* High Capacity SD Memory Card */ } } -- 2.16.1
[Qemu-devel] [PATCH v4 12/20] sdcard: handles more commands in SPI mode
Signed-off-by: Philippe Mathieu-Daudé--- hw/sd/sd.c | 29 ++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 4f82638735..0ecb446fdb 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -1390,9 +1390,11 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) /* Application specific commands (Class 8) */ case 55: /* CMD55: APP_CMD */ -if (sd->rca != rca) -return sd_r0; - +if (!sd->spi) { +if (sd->rca != rca) { +return sd_r0; +} +} sd->expecting_acmd = true; sd->card_status |= APP_CMD; return sd_r1; @@ -1412,6 +1414,18 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) } break; +case 58:/* CMD58: READ_OCR (SPI) */ +if (!sd->spi) { +goto bad_cmd; +} +return sd_r3; + +case 59:/* CMD59: CRC_ON_OFF (SPI) */ +if (!sd->spi) { +goto bad_cmd; +} +goto unimplemented_spi_cmd; + default: bad_cmd: qemu_log_mask(LOG_GUEST_ERROR, "SD: Unknown CMD%i\n", req.cmd); @@ -1436,6 +1450,9 @@ static sd_rsp_type_t sd_app_command(SDState *sd, sd->card_status |= APP_CMD; switch (req.cmd) { case 6:/* ACMD6: SET_BUS_WIDTH */ +if (sd->spi) { +goto unimplemented_spi_cmd; +} switch (sd->state) { case sd_transfer_state: sd->sd_status[0] &= 0x3f; @@ -1569,6 +1586,12 @@ static sd_rsp_type_t sd_app_command(SDState *sd, default: /* Fall back to standard commands. */ return sd_normal_command(sd, req); + +unimplemented_spi_cmd: +/* Commands that are recognised but not yet implemented in SPI mode. */ +qemu_log_mask(LOG_UNIMP, "SD: CMD%i not implemented in SPI mode\n", + req.cmd); +return sd_illegal; } qemu_log_mask(LOG_GUEST_ERROR, "SD: ACMD%i in a wrong state\n", req.cmd); -- 2.16.1
[Qemu-devel] [PATCH v4 05/20] sdcard: remove commands from unsupported old MMC specification
This device does not model MMCA Specification previous to v4.2 Signed-off-by: Philippe Mathieu-DaudéReviewed-by: Alistair Francis --- hw/sd/sd.c | 33 - 1 file changed, 33 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 41fac9a4aa..4267919ce0 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -1041,24 +1041,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) } break; -case 11: /* CMD11: READ_DAT_UNTIL_STOP */ -if (sd->spi) -goto bad_cmd; -switch (sd->state) { -case sd_transfer_state: -sd->state = sd_sendingdata_state; -sd->data_start = req.arg; -sd->data_offset = 0; - -if (sd->data_start + sd->blk_len > sd->size) -sd->card_status |= ADDRESS_ERROR; -return sd_r0; - -default: -break; -} -break; - case 12: /* CMD12: STOP_TRANSMISSION */ switch (sd->state) { case sd_sendingdata_state: @@ -1871,21 +1853,6 @@ uint8_t sd_read_data(SDState *sd) sd->state = sd_transfer_state; break; -case 11: /* CMD11: READ_DAT_UNTIL_STOP */ -if (sd->data_offset == 0) -BLK_READ_BLOCK(sd->data_start, io_len); -ret = sd->data[sd->data_offset ++]; - -if (sd->data_offset >= io_len) { -sd->data_start += io_len; -sd->data_offset = 0; -if (sd->data_start + io_len > sd->size) { -sd->card_status |= ADDRESS_ERROR; -break; -} -} -break; - case 13: /* ACMD13: SD_STATUS */ ret = sd->sd_status[sd->data_offset ++]; -- 2.16.1
[Qemu-devel] [PATCH v4 08/11] sdcard: display command name when tracing CMD/ACMD
put the function in sdmmc-common.c since we will reuse it in hw/sd/core.c Signed-off-by: Philippe Mathieu-Daudé--- hw/sd/sdmmc-internal.h | 3 +++ hw/sd/sd.c | 13 + hw/sd/sdmmc-common.c | 72 ++ hw/sd/Makefile.objs| 2 +- hw/sd/trace-events | 8 +++--- 5 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 hw/sd/sdmmc-common.c diff --git a/hw/sd/sdmmc-internal.h b/hw/sd/sdmmc-internal.h index 0e96cb0081..02b730089b 100644 --- a/hw/sd/sdmmc-internal.h +++ b/hw/sd/sdmmc-internal.h @@ -12,4 +12,7 @@ #define SDMMC_CMD_MAX 64 +const char *sd_cmd_name(uint8_t cmd); +const char *sd_acmd_name(uint8_t cmd); + #endif diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 6acd6b3c5c..666ff3873f 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -828,8 +828,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) uint64_t addr = (sd->ocr & (1 << 30)) ? (uint64_t) req.arg << 9 : req.arg; if (req.cmd != 55 || sd->expecting_acmd) { -trace_sdcard_normal_command(req.cmd, req.arg, -sd_state_name(sd->state)); +trace_sdcard_normal_command(sd_cmd_name(req.cmd), req.cmd, +req.arg, sd_state_name(sd->state)); } /* Not interpreting this as an app command */ @@ -1400,7 +1400,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) static sd_rsp_type_t sd_app_command(SDState *sd, SDRequest req) { -trace_sdcard_app_command(req.cmd, req.arg); +trace_sdcard_app_command(sd_acmd_name(req.cmd), + req.cmd, req.arg, sd_state_name(sd->state)); sd->card_status |= APP_CMD; switch (req.cmd) { case 6:/* ACMD6: SET_BUS_WIDTH */ @@ -1698,7 +1699,8 @@ void sd_write_data(SDState *sd, uint8_t value) if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION)) return; -trace_sdcard_write_data(sd->current_cmd, value); +trace_sdcard_write_data(sd_acmd_name(sd->current_cmd), +sd->current_cmd, value); switch (sd->current_cmd) { case 24: /* CMD24: WRITE_SINGLE_BLOCK */ sd->data[sd->data_offset ++] = value; @@ -1836,7 +1838,8 @@ uint8_t sd_read_data(SDState *sd) io_len = (sd->ocr & (1 << 30)) ? 512 : sd->blk_len; -trace_sdcard_read_data(sd->current_cmd, io_len); +trace_sdcard_read_data(sd_acmd_name(sd->current_cmd), + sd->current_cmd, io_len); switch (sd->current_cmd) { case 6:/* CMD6: SWITCH_FUNCTION */ ret = sd->data[sd->data_offset ++]; diff --git a/hw/sd/sdmmc-common.c b/hw/sd/sdmmc-common.c new file mode 100644 index 00..1d0198b1ad --- /dev/null +++ b/hw/sd/sdmmc-common.c @@ -0,0 +1,72 @@ +/* + * SD/MMC cards common helpers + * + * Copyright (c) 2018 Philippe Mathieu-Daudé + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "sdmmc-internal.h" + +const char *sd_cmd_name(uint8_t cmd) +{ +static const char *cmd_abbrev[SDMMC_CMD_MAX] = { + [0]= "GO_IDLE_STATE", + [2]= "ALL_SEND_CID",[3]= "SEND_RELATIVE_ADDR", + [4]= "SET_DSR", [5]= "IO_SEND_OP_COND", + [6]= "SWITCH_FUNC", [7]= "SELECT/DESELECT_CARD", + [8]= "SEND_IF_COND",[9]= "SEND_CSD", +[10]= "SEND_CID", [11]= "VOLTAGE_SWITCH", +[12]= "STOP_TRANSMISSION", [13]= "SEND_STATUS", +[15]= "GO_INACTIVE_STATE", +[16]= "SET_BLOCKLEN", [17]= "READ_SINGLE_BLOCK", +[18]= "READ_MULTIPLE_BLOCK",[19]= "SEND_TUNING_BLOCK", +[20]= "SPEED_CLASS_CONTROL",[21]= "DPS_spec", +[23]= "SET_BLOCK_COUNT", +[24]= "WRITE_BLOCK",[25]= "WRITE_MULTIPLE_BLOCK", +[26]= "MANUF_RSVD", [27]= "PROGRAM_CSD", +[28]= "SET_WRITE_PROT", [29]= "CLR_WRITE_PROT", +[30]= "SEND_WRITE_PROT", +[32]= "ERASE_WR_BLK_START", [33]= "ERASE_WR_BLK_END", +[34]= "SW_FUNC_RSVD", [35]= "SW_FUNC_RSVD", +[36]= "SW_FUNC_RSVD", [37]= "SW_FUNC_RSVD", +[38]= "ERASE", +[40]= "DPS_spec", +[42]= "LOCK_UNLOCK",[43]= "Q_MANAGEMENT", +[44]= "Q_TASK_INFO_A", [45]= "Q_TASK_INFO_B", +[46]= "Q_RD_TASK", [47]= "Q_WR_TASK", +[48]= "READ_EXTR_SINGLE", [49]= "WRITE_EXTR_SINGLE", +
[Qemu-devel] [PATCH v2 0/3] Sam460ex emulation
Remaining patches for Sam460ex emulation. The original cover letter with more details is here: http://lists.nongnu.org/archive/html/qemu-ppc/2017-08/msg00112.html We'll need to also add binaries for firmware (customised u-boot version) and dtb but I'm not sure how to submit those. Current status for OSes I've tried: - AROS boots (after I've fixed some bugs in it which are now upstream so the nightly iso should work) but keyboard doesn't work (could be a bug in AROS's HID driver) and time is going slow (this can be seen in time prefs). This may be a QEMU bug and possibly causes the hang seen in other OSes but I don't know what causes it or how to fix it. Maybe related to some internal timing registers of the SoC because setting multipliers to real values causes U-Boot to become slow. Anyone with more knowledge of this hardware has any idea? - Linux: kernel boots but hangs during user space (again could be the above timing problem or maybe missing emac network interface emulation but I don't really know). - AmigaOS 4 seems to boot but display is not working so not usable (either related to timing problem or could be SM502 emulation). - MorphOS does not boot (it seems to either deliberately do stuff to prevent it from running on QEMU or it has bugs but developers are not communicative about it) Regards, BALATON Zoltan BALATON Zoltan (3): ppc4xx: Add device models found in PPC440 core SoCs ppc440: Add emulation of plb-pcix controller found in some 440 SoCs ppc: Add aCube Sam460ex board default-configs/ppc-softmmu.mak|2 + default-configs/ppcemb-softmmu.mak |1 + hw/ppc/Makefile.objs |3 +- hw/ppc/ppc440.h| 26 + hw/ppc/ppc440_pcix.c | 528 hw/ppc/ppc440_uc.c | 1159 hw/ppc/sam460ex.c | 603 +++ hw/ppc/trace-events|8 + include/hw/pci/pcie_host.h |2 +- 9 files changed, 2330 insertions(+), 2 deletions(-) create mode 100644 hw/ppc/ppc440.h create mode 100644 hw/ppc/ppc440_pcix.c create mode 100644 hw/ppc/ppc440_uc.c create mode 100644 hw/ppc/sam460ex.c -- 2.7.6