Re: [PATCH v2 00/12] linux-user sparc fixes

2019-10-26 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20191025113921.9412-1-richard.hender...@linaro.org/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Subject: [PATCH v2 00/12] linux-user sparc fixes
Type: series
Message-id: 20191025113921.9412-1-richard.hender...@linaro.org

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Switched to a new branch 'test'
10a58e6 linux-user/alpha: Set r20 secondary return value
5eb8e13 linux-user/sparc: Fix cpu_clone_regs_*
1fe4085 linux-user: Introduce cpu_clone_regs_parent
c6bf6f2 linux-user: Rename cpu_clone_regs to cpu_clone_regs_child
1e0a916 linux-user/sparc64: Fix target_signal_frame
b250d74 linux-user/sparc: Fix WREG usage in setup_frame
a8508ed linux-user/sparc: Use WREG_SP constant in sparc/signal.c
9b12e1c linux-user/sparc: Begin using WREG constants in sparc/signal.c
0da4e3e linux-user/sparc: Use WREG constants in sparc/target_cpu.h
2bab940 target/sparc: Define an enumeration for accessing env->regwptr
dfc8869 tests/tcg/multiarch/linux-test: Fix error check for shmat
32ef6cd scripts/qemu-binfmt-conf: Update for sparc64

=== OUTPUT BEGIN ===
1/12 Checking commit 32ef6cd7742f (scripts/qemu-binfmt-conf: Update for sparc64)
WARNING: line over 80 characters
#34: FILE: scripts/qemu-binfmt-conf.sh:41:
+sparc64_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2b'

ERROR: line over 90 characters
#35: FILE: scripts/qemu-binfmt-conf.sh:42:
+sparc64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'

total: 1 errors, 1 warnings, 20 lines checked

Patch 1/12 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

2/12 Checking commit dfc8869ba150 (tests/tcg/multiarch/linux-test: Fix error 
check for shmat)
3/12 Checking commit 2bab94043648 (target/sparc: Define an enumeration for 
accessing env->regwptr)
4/12 Checking commit 0da4e3e1f98e (linux-user/sparc: Use WREG constants in 
sparc/target_cpu.h)
5/12 Checking commit 9b12e1c8e388 (linux-user/sparc: Begin using WREG constants 
in sparc/signal.c)
ERROR: spaces required around that '+' (ctx:VxV)
#49: FILE: linux-user/sparc/signal.c:151:
+__put_user(env->regwptr[WREG_O0 + i], &si->si_regs.u_regs[i+8]);
^

ERROR: spaces required around that '+' (ctx:VxV)
#121: FILE: linux-user/sparc/signal.c:290:
+__get_user(env->regwptr[i + WREG_O0], &sf->info.si_regs.u_regs[i+8]);
 ^

ERROR: spaces required around that '+' (ctx:VxV)
#168: FILE: linux-user/sparc/signal.c:460:
+w_addr = TARGET_STACK_BIAS+env->regwptr[WREG_O6];
   ^

ERROR: spaces required around that '+' (ctx:VxV)
#203: FILE: linux-user/sparc/signal.c:563:
+w_addr = TARGET_STACK_BIAS+env->regwptr[WREG_O6];
   ^

total: 4 errors, 0 warnings, 175 lines checked

Patch 5/12 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

6/12 Checking commit a8508ed3e8ff (linux-user/sparc: Use WREG_SP constant in 
sparc/signal.c)
7/12 Checking commit b250d74fed90 (linux-user/sparc: Fix WREG usage in 
setup_frame)
8/12 Checking commit 1e0a916d1fca (linux-user/sparc64: Fix target_signal_frame)
ERROR: space prohibited between function name and open parenthesis '('
#21: FILE: linux-user/sparc/signal.c:90:
+uint32_tinsns[2] __attribute__ ((aligned (8)));

total: 1 errors, 0 warnings, 16 lines checked

Patch 8/12 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

9/12 Checking commit c6bf6f2ab73f (linux-user: Rename cpu_clone_regs to 
cpu_clone_regs_child)
10/12 Checking commit 1fe40851fad6 (linux-user: Introduce cpu_clone_regs_parent)
11/12 Checking commit 5eb8e1397a6b (linux-user/sparc: Fix cpu_clone_regs_*)
12/12 Checking commit 10a58e689746 (linux-user/alpha: Set r20 secondary return 
value)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20191025113921.9412-1-richard.hender...@linaro.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: USB-audio sound issues with qemu-system-ppc in Linux and Windows.

2019-10-26 Thread Howard Spoelstra
Hi,

I'd like to add to the previous report that similar issues are present in
OSX (Sierra) builds of qemu-system-ppc.

In Mac OS 9.2 and OS X 10.3 guests, sound through the usb-audio device is
unrecognisable.
After forcibly shutting down Mac OS 9.2 after it becomes unresponsive, qemu
crashes. The OS X crash reporter says this:
Thread 2 Crashed:
0   qemu-system-ppc   0x00010999c4bd timer_del + 13
(qemu-timer.c:429)
1   qemu-system-ppc   0x0001096d543f audio_reset_timer +
319 (audio.c:811)
2   qemu-system-ppc   0x0001096ca2a6 vm_state_notify + 262
(vl.c:1433)
3   qemu-system-ppc   0x00010953642f do_vm_stop + 47
(cpus.c:1104)
4   qemu-system-ppc   0x0001096ceed7 qemu_main + 17239
(vl.c:4477)
5   qemu-system-ppc   0x00010988a526 call_qemu_main + 38
(cocoa.m:1769)
6   qemu-system-ppc   0x0001099a11ee qemu_thread_start +
126 (qemu-thread-posix.c:519)
7   libsystem_pthread.dylib   0x7fffb864a93b _pthread_body + 180
8   libsystem_pthread.dylib   0x7fffb864a887 _pthread_start + 286
9   libsystem_pthread.dylib   0x7fffb864a08d thread_start + 13

Best,
Howard


Re: [PATCH v1 1/1] opensbi: Upgrade from v0.4 to v0.5

2019-10-26 Thread Philippe Mathieu-Daudé

Hi Alistair,

On 10/26/19 1:15 AM, Alistair Francis wrote:

This release has:
 Lot of critical fixes
 Hypervisor extension support
 SBI v0.2 base extension support
 Debug prints support
 Handle traps when doing unpriv load/store
 Allow compiling without FP support
 Use git describe to generate boot-time banner
 Andes AE350 platform support


Do you mind amending the output of 'git shortlog v0.4..v0.5'?



Signed-off-by: Alistair Francis 
---
You can get the branch from here if the binaries are causing issues:
https://github.com/alistair23/qemu/tree/mainline/alistair/opensbi.next


You can use 'git format-patch --no-binary'.



  pc-bios/opensbi-riscv32-virt-fw_jump.bin | Bin 36888 -> 40984 bytes
  pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin | Bin 45064 -> 49160 bytes
  pc-bios/opensbi-riscv64-virt-fw_jump.bin | Bin 40968 -> 45064 bytes
  roms/opensbi |   2 +-
  4 files changed, 1 insertion(+), 1 deletion(-)

[...]

diff --git a/roms/opensbi b/roms/opensbi
index ce228ee091..be92da280d 16
--- a/roms/opensbi
+++ b/roms/opensbi
@@ -1 +1 @@
-Subproject commit ce228ee0919deb9957192d723eecc8aaae2697c6
+Subproject commit be92da280d87c38a2e0adc5d3f43bab7b5468f09






Re: [PATCH v1 1/1] opensbi: Upgrade from v0.4 to v0.5

2019-10-26 Thread Philippe Mathieu-Daudé
On Sat, Oct 26, 2019 at 10:45 AM Philippe Mathieu-Daudé
 wrote:
>
> Hi Alistair,
>
> On 10/26/19 1:15 AM, Alistair Francis wrote:
> > This release has:
> >  Lot of critical fixes
> >  Hypervisor extension support
> >  SBI v0.2 base extension support
> >  Debug prints support
> >  Handle traps when doing unpriv load/store
> >  Allow compiling without FP support
> >  Use git describe to generate boot-time banner
> >  Andes AE350 platform support
>
> Do you mind amending the output of 'git shortlog v0.4..v0.5'?

Err this comment is for Palmer, if Alistair agree (no need to repost).

> >
> > Signed-off-by: Alistair Francis 
> > ---
> > You can get the branch from here if the binaries are causing issues:
> > https://github.com/alistair23/qemu/tree/mainline/alistair/opensbi.next
>
> You can use 'git format-patch --no-binary'.
>
> >
> >   pc-bios/opensbi-riscv32-virt-fw_jump.bin | Bin 36888 -> 40984 bytes
> >   pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin | Bin 45064 -> 49160 bytes
> >   pc-bios/opensbi-riscv64-virt-fw_jump.bin | Bin 40968 -> 45064 bytes
> >   roms/opensbi |   2 +-
> >   4 files changed, 1 insertion(+), 1 deletion(-)
> [...]
> > diff --git a/roms/opensbi b/roms/opensbi
> > index ce228ee091..be92da280d 16
> > --- a/roms/opensbi
> > +++ b/roms/opensbi
> > @@ -1 +1 @@
> > -Subproject commit ce228ee0919deb9957192d723eecc8aaae2697c6
> > +Subproject commit be92da280d87c38a2e0adc5d3f43bab7b5468f09
> >




Re: [PULL 0/2] Block patches

2019-10-26 Thread Peter Maydell
On Fri, 25 Oct 2019 at 20:18, Stefan Hajnoczi  wrote:
>
> The following changes since commit 58560ad254fbda71d4daa6622d71683190070ee2:
>
>   Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.2-20191024' 
> into staging (2019-10-24 16:22:58 +0100)
>
> are available in the Git repository at:
>
>   https://github.com/stefanha/qemu.git tags/block-pull-request
>
> for you to fetch changes up to d154ef37ff885918fa3e512fd7a8e42870291667:
>
>   yield_until_fd_readable: make it work with any AioContect (2019-10-25 
> 14:38:29 +0200)
>
> 
> Pull request
>
> 
>
> Dietmar Maurer (1):
>   yield_until_fd_readable: make it work with any AioContect
>
> Julia Suvorova (1):
>   virtio-blk: Add blk_drain() to virtio_blk_device_unrealize()


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/4.2
for any user-visible changes.

-- PMM



Re: USB-audio sound issues with qemu-system-ppc in Linux and Windows.

2019-10-26 Thread BALATON Zoltan

Hello,

On Sat, 26 Oct 2019, Howard Spoelstra wrote:

I'd like to add to the previous report that similar issues are present in
OSX (Sierra) builds of qemu-system-ppc.


I think the problem is not specific to host OS so instead of giving 
debugging info for all hosts which would just confuse anyone trying to 
reproduce it, it may be better to just concentrate on Linux (as that's 
what most developers would have) and ignore Windows and OSX hosts for now.


It's probably also not specific to MacOS guests because I get similar 
crackling sound on sam460ex with the ES1370 device with AmigaOS4 and can 
reproduce the usb-audio shows up but does not make sound problem on 
mac99,via=pmu with MorphOS so maybe either it's something with the sound 
backend (like a buffer underflow in case of crackling that may be improved 
by tweaking some parameters but I don't know what parameters are available 
or how to set them) or maybe a problem with irqs (in case of no sound or 
crashing MacOS guest but I don't know how to debug that either). Or I may 
be completely wrong with my guesses so any advice from people knowing 
sound and USB emulation in QEMU better is very welcome. (Also likely there 
are more than one problem here so reporting them at once is also 
confusing, these may need to be debugged separately.)


So to most likely get useful feedback you should find a simple way to 
reproduce it with Linux host and guest and describe that in the shortest 
way to make it easy for interested developers to reproduce it then also cc 
your Gerd who is the audio and USB maintainer. Otherwise it's likely these 
will get ignored because nobody can reproduce it who would able to attempt 
debugging it.


Regards,
BALATON Zoltan



Re: [PATCH v3 5/6] hppa: Add emulation of Artist graphics

2019-10-26 Thread Mark Cave-Ayland
On 25/10/2019 10:31, Sven Schnelle wrote:

> Hi Mark,
> 
> On Thu, Oct 24, 2019 at 09:51:31PM +0100, Mark Cave-Ayland wrote:
> 
>> On 22/10/2019 21:59, Sven Schnelle wrote:
>>
>>> This adds emulation of Artist graphics good enough
>>> to get a Text console on both Linux and HP-UX. The
>>> X11 server from HP-UX also works.
>>>
>>> Signed-off-by: Sven Schnelle 
>>> ---
>>>  hw/display/Kconfig   |3 +
>>>  hw/display/Makefile.objs |1 +
>>>  hw/display/artist.c  | 1336 ++
>>>  hw/display/trace-events  |9 +
>>>  hw/hppa/Kconfig  |1 +
>>>  hw/hppa/hppa_hardware.h  |1 +
>>>  hw/hppa/machine.c|   10 +
>>>  7 files changed, 1361 insertions(+)
>>>  create mode 100644 hw/display/artist.c
>>>
>>> diff --git a/hw/display/Kconfig b/hw/display/Kconfig
>>> index cbdf7b1a67..953631afb6 100644
>>> --- a/hw/display/Kconfig
>>> +++ b/hw/display/Kconfig
>>> @@ -91,6 +91,9 @@ config TCX
>>>  config CG3
>>>  bool
>>>  
>>> +config ARTIST
>>> +bool
>>> +
>>>  config VGA
>>>  bool
>>>  
>>> diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
>>> index 5a4066383b..5f63294149 100644
>>> --- a/hw/display/Makefile.objs
>>> +++ b/hw/display/Makefile.objs
>>> @@ -39,6 +39,7 @@ common-obj-$(CONFIG_SM501) += sm501.o
>>>  common-obj-$(CONFIG_TCX) += tcx.o
>>>  common-obj-$(CONFIG_CG3) += cg3.o
>>>  common-obj-$(CONFIG_NEXTCUBE) += next-fb.o
>>> +common-obj-$(CONFIG_ARTIST) += artist.o
>>>  
>>>  obj-$(CONFIG_VGA) += vga.o
>>>  
>>> diff --git a/hw/display/artist.c b/hw/display/artist.c
>>> new file mode 100644
>>> index 00..9b285b3993
>>> --- /dev/null
>>> +++ b/hw/display/artist.c
>>> @@ -0,0 +1,1336 @@
>>> +/*
>>> + * QEMU HP Artist Emulation
>>> + *
>>> + * Copyright (c) 2019 Sven Schnelle 
>>> + *
>>> + * This work is licensed under the terms of the GNU GPL, version 2 or 
>>> later.
>>> + */
>>> +
>>> +#include "qemu/osdep.h"
>>> +#include "qemu-common.h"
>>> +#include "qemu/error-report.h"
>>> +#include "qemu/typedefs.h"
>>> +#include "qemu/log.h"
>>> +#include "qemu/module.h"
>>> +#include "qapi/error.h"
>>> +#include "hw/sysbus.h"
>>> +#include "hw/loader.h"
>>> +#include "hw/qdev-core.h"
>>> +#include "hw/qdev-properties.h"
>>> +#include "migration/vmstate.h"
>>> +#include "ui/console.h"
>>> +#include "trace.h"
>>> +
>>> +#define TYPE_ARTIST "artist"
>>> +#define ARTIST(obj) OBJECT_CHECK(ARTISTState, (obj), TYPE_ARTIST)
>>> +
>>> +struct vram_buffer {
>>> +uint8_t *data;
>>> +int size;
>>> +int width;
>>> +int height;
>>> +};
>>> +
>>> +typedef struct ARTISTState {
>>> +SysBusDevice parent_obj;
>>> +
>>> +QemuConsole *con;
>>> +MemoryRegion vram_mem;
>>> +MemoryRegion reg;
>>> +uint8_t *vram;
>>> +
>>> +struct vram_buffer vram_buffer[16];
>>> +
>>> +uint16_t width;
>>> +uint16_t height;
>>> +uint16_t depth;
>>> +
>>> +uint32_t fg_color;
>>> +uint32_t bg_color;
>>> +
>>> +uint32_t vram_char_y;
>>> +uint32_t vram_bitmask;
>>> +
>>> +uint32_t vram_start;
>>> +uint32_t vram_pos;
>>> +
>>> +uint32_t vram_size;
>>> +
>>> +uint32_t blockmove_source;
>>> +uint32_t blockmove_dest;
>>> +uint32_t blockmove_size;
>>> +
>>> +uint32_t line_size;
>>> +uint32_t line_end;
>>> +uint32_t line_xy;
>>> +uint32_t line_pattern_start;
>>> +uint32_t line_pattern_skip;
>>> +
>>> +uint32_t cursor_pos;
>>> +
>>> +uint32_t cursor_height;
>>> +uint32_t cursor_width;
>>> +
>>> +uint32_t plane_mask;
>>> +
>>> +uint32_t reg_100080;
>>> +uint32_t reg_300200;
>>> +uint32_t reg_300208;
>>> +uint32_t reg_300218;
>>> +
>>> +uint32_t cmap_bm_access;
>>> +uint32_t dst_bm_access;
>>> +uint32_t src_bm_access;
>>> +uint32_t control_plane;
>>> +uint32_t transfer_data;
>>> +uint32_t image_bitmap_op;
>>> +
>>> +uint32_t font_write1;
>>> +uint32_t font_write2;
>>> +uint32_t font_write_pos_y;
>>> +
>>> +int draw_line_pattern;
>>> +} ARTISTState;
>>> +
>>> +typedef enum {
>>> +ARTIST_BUFFER_AP = 1,
>>> +ARTIST_BUFFER_OVERLAY = 2,
>>> +ARTIST_BUFFER_CURSOR1 = 6,
>>> +ARTIST_BUFFER_CURSOR2 = 7,
>>> +ARTIST_BUFFER_ATTRIBUTE = 13,
>>> +ARTIST_BUFFER_CMAP = 15,
>>> +} artist_buffer_t;
>>> +
>>> +typedef enum {
>>> +VRAM_IDX = 0x1004a0,
>>> +VRAM_BITMASK = 0x1005a0,
>>> +VRAM_WRITE_INCR_X = 0x100600,
>>> +VRAM_WRITE_INCR_X2 = 0x100604,
>>> +VRAM_WRITE_INCR_Y = 0x100620,
>>> +VRAM_START = 0x100800,
>>> +BLOCK_MOVE_SIZE = 0x100804,
>>> +BLOCK_MOVE_SOURCE = 0x100808,
>>> +TRANSFER_DATA = 0x100820,
>>> +FONT_WRITE_INCR_Y = 0x1008a0,
>>> +VRAM_START_TRIGGER = 0x100a00,
>>> +VRAM_SIZE_TRIGGER = 0x100a04,
>>> +FONT_WRITE_START = 0x100aa0,
>>> +BLOCK_MOVE_DEST_TRIGGER = 0x100b00,
>>> +BLOCK_MOVE_SIZE_TRIGGER = 0x100b04,
>>> +LINE_XY = 0x100ccc,
>>> +PATTERN_LINE_START = 0x100ecc,
>>> +LINE_SIZE = 0x100e04,
>>

Re: USB-audio sound issues with qemu-system-ppc in Linux and Windows.

2019-10-26 Thread BALATON Zoltan

On Sat, 26 Oct 2019, BALATON Zoltan wrote:

On Sat, 26 Oct 2019, Howard Spoelstra wrote:

I'd like to add to the previous report that similar issues are present in
OSX (Sierra) builds of qemu-system-ppc.


I think the problem is not specific to host OS so instead of giving debugging 
info for all hosts which would just confuse anyone trying to reproduce it, it 
may be better to just concentrate on Linux (as that's what most developers 
would have) and ignore Windows and OSX hosts for now.


It's probably also not specific to MacOS guests because I get similar 
crackling sound on sam460ex with the ES1370 device with AmigaOS4 and can 
reproduce the usb-audio shows up but does not make sound problem on 
mac99,via=pmu with MorphOS so maybe either it's something with the sound 
backend (like a buffer underflow in case of crackling that may be improved by 
tweaking some parameters but I don't know what parameters are available or 
how to set them) or maybe a problem with irqs (in case of no sound or 
crashing MacOS guest but I don't know how to debug that either). Or I may be 
completely wrong with my guesses so any advice from people knowing sound and 
USB emulation in QEMU better is very welcome. (Also likely there are more 
than one problem here so reporting them at once is also confusing, these may 
need to be debugged separately.)


So to most likely get useful feedback you should find a simple way to 
reproduce it with Linux host and guest and describe that in the shortest way 
to make it easy for interested developers to reproduce it then also cc your 
Gerd who is the audio and USB maintainer. Otherwise it's likely these will


correction: cc your message to Gerd

get ignored because nobody can reproduce it who would able to attempt 
debugging it.


Regards,
BALATON Zoltan






[PATCH] qemu-iotests/iotests.py: improve assert_qmp message

2019-10-26 Thread Vladimir Sementsov-Ogievskiy
Make it obvious, from the two values which is found at path and which
is expected.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---

It's a pain, I can never remember it, and checking each time in source
code who is who is boring.

 tests/qemu-iotests/iotests.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 709def4d5d..e805b9ab14 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -729,8 +729,8 @@ class QMPTestCase(unittest.TestCase):
 self.fail('no match for "%s" in %s' % (str(result), str(value)))
 else:
 self.assertEqual(result, value,
- 'values not equal "%s" and "%s"'
- % (str(result), str(value)))
+ '"%s" is "%s", expected "%s"'
+ % (path, str(result), str(value)))
 
 def assert_no_active_block_jobs(self):
 result = self.vm.qmp('query-block-jobs')
-- 
2.21.0




Re: [PULL 00/12] tcg patch queue

2019-10-26 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20191025142159.12459-1-richard.hender...@linaro.org/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Subject: [PULL 00/12] tcg patch queue
Type: series
Message-id: 20191025142159.12459-1-richard.hender...@linaro.org

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
   ee70fc2..856bd2c  master -> master
 * [new tag] patchew/20191026101221.5506-1-vsement...@virtuozzo.com -> 
patchew/20191026101221.5506-1-vsement...@virtuozzo.com
Switched to a new branch 'test'
c6bcef1 translate-all: Remove tb_alloc
338d348 translate-all: fix uninitialized tb->orig_tb
0ecc6ef cputlb: Fix tlb_vaddr_to_host
ac5a22e exec: Cache TARGET_PAGE_MASK for TARGET_PAGE_BITS_VARY
cbe6f3c exec: Promote TARGET_PAGE_MASK to target_long
193d2f1 exec: Restrict TARGET_PAGE_BITS_VARY assert to CONFIG_DEBUG_TCG
f455681 exec: Use const alias for TARGET_PAGE_BITS_VARY
72299c7 configure: Detect compiler support for __attribute__((alias))
878dbed exec: Split out variable page size support to exec-vary.c
2a0f4d3 cpu: use ROUND_UP() to define xxx_PAGE_ALIGN
0ba8f67 cputlb: ensure _cmmu helper functions follow the naming standard
db4e121 tci: Add implementation for INDEX_op_ld16u_i64

=== OUTPUT BEGIN ===
1/12 Checking commit db4e1218f5b1 (tci: Add implementation for 
INDEX_op_ld16u_i64)
2/12 Checking commit 0ba8f676473c (cputlb: ensure _cmmu helper functions follow 
the naming standard)
3/12 Checking commit 2a0f4d3df675 (cpu: use ROUND_UP() to define xxx_PAGE_ALIGN)
4/12 Checking commit 878dbed6b17c (exec: Split out variable page size support 
to exec-vary.c)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#34: 
new file mode 100644

total: 0 errors, 1 warnings, 125 lines checked

Patch 4/12 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
5/12 Checking commit 72299c761114 (configure: Detect compiler support for 
__attribute__((alias)))
6/12 Checking commit f455681930d9 (exec: Use const alias for 
TARGET_PAGE_BITS_VARY)
ERROR: externs should be avoided in .c files
#66: FILE: exec-vary.c:57:
+extern const TargetPageBits target_page

total: 1 errors, 0 warnings, 103 lines checked

Patch 6/12 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

7/12 Checking commit 193d2f196d18 (exec: Restrict TARGET_PAGE_BITS_VARY assert 
to CONFIG_DEBUG_TCG)
8/12 Checking commit cbe6f3c25e7c (exec: Promote TARGET_PAGE_MASK to 
target_long)
9/12 Checking commit ac5a22e1e5fc (exec: Cache TARGET_PAGE_MASK for 
TARGET_PAGE_BITS_VARY)
10/12 Checking commit 0ecc6ef8ebd8 (cputlb: Fix tlb_vaddr_to_host)
11/12 Checking commit 338d348e2de5 (translate-all: fix uninitialized 
tb->orig_tb)
12/12 Checking commit c6bcef1f1970 (translate-all: Remove tb_alloc)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20191025142159.12459-1-richard.hender...@linaro.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH] qemu-iotests/iotests.py: improve assert_qmp message

2019-10-26 Thread Philippe Mathieu-Daudé

On 10/26/19 12:12 PM, Vladimir Sementsov-Ogievskiy wrote:

Make it obvious, from the two values which is found at path and which
is expected.


Maybe:

"From the two values compared, make it obvious which is found at path, 
and which is expected."


Reviewed-by: Philippe Mathieu-Daudé 



Signed-off-by: Vladimir Sementsov-Ogievskiy 
---

It's a pain, I can never remember it, and checking each time in source
code who is who is boring.

  tests/qemu-iotests/iotests.py | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 709def4d5d..e805b9ab14 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -729,8 +729,8 @@ class QMPTestCase(unittest.TestCase):
  self.fail('no match for "%s" in %s' % (str(result), str(value)))
  else:
  self.assertEqual(result, value,
- 'values not equal "%s" and "%s"'
- % (str(result), str(value)))
+ '"%s" is "%s", expected "%s"'
+ % (path, str(result), str(value)))
  
  def assert_no_active_block_jobs(self):

  result = self.vm.qmp('query-block-jobs')





Re: [PATCH v3 5/6] hppa: Add emulation of Artist graphics

2019-10-26 Thread Philippe Mathieu-Daudé

Hi Sven,

On 10/22/19 10:59 PM, Sven Schnelle wrote:

This adds emulation of Artist graphics good enough
to get a Text console on both Linux and HP-UX. The
X11 server from HP-UX also works.

Signed-off-by: Sven Schnelle 
---
  hw/display/Kconfig   |3 +
  hw/display/Makefile.objs |1 +
  hw/display/artist.c  | 1336 ++
  hw/display/trace-events  |9 +
  hw/hppa/Kconfig  |1 +
  hw/hppa/hppa_hardware.h  |1 +
  hw/hppa/machine.c|   10 +
  7 files changed, 1361 insertions(+)
  create mode 100644 hw/display/artist.c


[...]

+static void fill_window(ARTISTState *s, int startx, int starty,
+int width, int height)
+{
+uint32_t offset;
+uint8_t color = artist_get_color(s);
+uint8_t *buf;
+int x, y;
+
+trace_artist_fill_window(startx, starty, width, height,
+s->image_bitmap_op, s->control_plane);
+
+if (s->control_plane != 0) {
+qemu_log_mask(LOG_UNIMP, "%s: CONTROL_PLANE: %08x\n", __func__,
+s->control_plane);
+return;
+}
+
+if (s->reg_100080 == 0x7d) {


What is checked here? Can you add a comment about it?


+height = artist_get_y(s->blockmove_size);
+s->vram_start += height;
+}
+
+buf = s->vram_buffer[ARTIST_BUFFER_AP].data;
+
+for (y = starty; y < starty + height; y++) {
+offset = y * s->width;
+
+for (x = startx; x < startx + width; x++) {
+artist_rop8(s, buf + offset + x, color);
+}
+}
+}
+

[...]

+static void artist_initfn(Object *obj)
+{
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+ARTISTState *s = ARTIST(obj);
+
+memory_region_init_io(&s->reg, obj, &artist_reg_ops, s, "artist.reg",
+0x40);


Easier to read as: 4 * MiB


+memory_region_init_io(&s->vram_mem, obj, &artist_vram_ops, s, 
"artist.vram",
+0x80);


And 8 * MiB.


+sysbus_init_mmio(sbd, &s->reg);
+sysbus_init_mmio(sbd, &s->vram_mem);
+}
+
+static void artist_set_buffer(ARTISTState *s, uint8_t **vram, unsigned int idx,
+  int width, int height)
+{
+struct vram_buffer *buf = s->vram_buffer + idx;
+
+buf->data = *vram;
+buf->size = height * width;
+buf->width = width;
+buf->height = height;
+*vram = *vram + buf->size;
+}
+
+static void artist_realizefn(DeviceState *dev, Error **errp)
+{
+uint8_t *vram;
+
+ARTISTState *s = ARTIST(dev);
+
+vram = g_malloc0(4 * 1048576);


Here you can simply use g_malloc(4 * MiB). If you really need
to bzero the VRAM, that should be done in the reset() handler.


+s->vram = vram;
+artist_set_buffer(s, &vram, ARTIST_BUFFER_CMAP, 2048, 4);
+artist_set_buffer(s, &vram, ARTIST_BUFFER_AP, s->width, s->height);
+artist_set_buffer(s, &vram, ARTIST_BUFFER_CURSOR1, 64, 64);
+artist_set_buffer(s, &vram, ARTIST_BUFFER_CURSOR2, 64, 64);
+artist_set_buffer(s, &vram, ARTIST_BUFFER_ATTRIBUTE, 64, 64);


Shouldn't this be done by firmware code? If no firmware, this seems to
belong to reset() too, isn't it?


+
+/*
+ * no idea whether the cursor is fixed size or not, so assume 32x32 which
+ * seems sufficient for HP-UX X11.
+ */
+s->cursor_height = 32;
+s->cursor_width = 32;
+
+s->con = graphic_console_init(DEVICE(dev), 0, &artist_ops, s);
+qemu_console_resize(s->con, s->width, s->height);
+}

[...]




Re: [PATCH 00/20] hw: Clean up hw/i386 headers (and few alpha/hppa)

2019-10-26 Thread Philippe Mathieu-Daudé

Hi,

On 10/14/19 4:22 PM, Philippe Mathieu-Daudé wrote:

This is a follow-up of Markus's cleanup series:
Tame a few "touch this, recompile the world"
https://www.mail-archive.com/qemu-devel@nongnu.org/msg635748.html

This part is mostly restricted to X86, but since some file from the
Alpha/PA-RISC machines include "hw/i386/pc.h" I had to fix them
too.

Eventually I'll succeed at removing hw/i386/ dependency on non-X86
platforms (Quest I started 2 years ago...).

Regards,

Phil.

Philippe Mathieu-Daudé (20):
   vl: Add missing "hw/boards.h" include
   hw/southbridge/ich9: Removed unused headers
   hw/input/pckbd: Remove unused "hw/i386/pc.h" header
   hw/i386/ioapic_internal: Remove unused "hw/i386/ioapic.h" header
   hw/timer: Remove unused "ui/console.h" header
   hw/usb/dev-storage: Remove unused "ui/console.h" header
   hw/i386/intel_iommu: Remove unused includes
   hw/xen/xen_pt_load_rom: Remove unused includes
   hw/alpha/alpha_sys: Remove unused "hw/ide.h" header
   hw/alpha/dp264: Include "net/net.h"
   hw/hppa/machine: Include "net/net.h"
   hw/acpi/cpu_hotplug: Include "hw/pci/pci.h"
   hw/timer/hpet: Include "exec/address-spaces.h"
   hw/pci-host/q35: Include "qemu/range.h"
   hw/i2c/smbus_ich9: Include "qemu/range.h"
   hw/pci-host/piix: Include "qemu/range.h"
   hw/acpi: Include "hw/mem/nvdimm.h"
   hw/i386: Include "hw/mem/nvdimm.h"
   hw/pci-host/q35: Remove unused includes
   hw/i386/pc: Clean up includes

Laurent, since this series is fully reviewed, can it go via
your qemu-trivial tree?

Thanks,

Phil.



Re: [PULL 00/39] Misc (mostly x86) patches for 2019-10-24

2019-10-26 Thread Philippe Mathieu-Daudé

On 10/25/19 1:17 PM, Paolo Bonzini wrote:

On 25/10/19 12:46, Peter Maydell wrote:


x86_register_ferr_irq() is defined in target/i386/fpu_helper.c,
which is only built if CONFIG_TCG, but the callers don't
seem to be similarly guarded and there's no stub fallback.


Indeed, thanks.  I'll add an "if (tcg_enabled())" since this feature is
not supported by accelerators other than TCG.


Paolo, since the "Split timer <-> rtc" series got merged via
the trivial tree, you need to squash this fix to patch #33
("mc146818rtc: Include mc146818rtc_regs.h directly in
 mc146818rtc.c") to avoid build failure:

-- >8 --
diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
index bbe6783898..9f5dd47fb6 100644
--- a/hw/rtc/mc146818rtc.c
+++ b/hw/rtc/mc146818rtc.c
@@ -42,7 +42,7 @@
 #include "qapi/qapi-events-misc-target.h"
 #include "qapi/visitor.h"
 #include "exec/address-spaces.h"
-#include "hw/timer/mc146818rtc_regs.h"
+#include "hw/rtc/mc146818rtc_regs.h"

 #ifdef TARGET_I386
 #include "hw/i386/apic.h"
---

Regards,

Phil.



[PATCH] qcow2-bitmap: Fix uint64_t left-shift overflow

2019-10-26 Thread Tuguoyi
In check_constraints_on_bitmap(), the sanity check on the
granularity will cause uint64_t integer left-shift overflow
when cluster_size is 2M and the granularity is bigger than
32K which is even smaller than the default value for a qcow2
disk with cluster_size set to 64k or bigger. This patch fix
the issue by right-shift @len instead.

Signed-off-by: Guoyi Tu 
---
 block/qcow2-bitmap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index 98294a7..2a1d789 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -172,8 +172,8 @@ static int check_constraints_on_bitmap(BlockDriverState *bs,
 }

 if ((len > (uint64_t)BME_MAX_PHYS_SIZE << granularity_bits) ||
-(len > (uint64_t)BME_MAX_TABLE_SIZE * s->cluster_size <<
-   granularity_bits))
+((len >> granularity_bits) > (uint64_t)BME_MAX_TABLE_SIZE *
+s->cluster_size))
 {
 error_setg(errp, "Too much space will be occupied by the bitmap. "
"Use larger granularity");
--
2.7.4
-
本邮件及其附件含有新华三集团的保密信息,仅限于发送给上面地址中列出
的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制、
或散发)本邮件中的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本
邮件!
This e-mail and its attachments contain confidential information from New H3C, 
which is
intended only for the person or entity whose address is listed above. Any use 
of the
information contained herein in any way (including, but not limited to, total 
or partial
disclosure, reproduction, or dissemination) by persons other than the intended
recipient(s) is prohibited. If you receive this e-mail in error, please notify 
the sender
by phone or email immediately and delete it!


Re: [PATCH 00/20] hw: Clean up hw/i386 headers (and few alpha/hppa)

2019-10-26 Thread Laurent Vivier
Le 26/10/2019 à 14:20, Philippe Mathieu-Daudé a écrit :
> Hi,
> 
> On 10/14/19 4:22 PM, Philippe Mathieu-Daudé wrote:
>> This is a follow-up of Markus's cleanup series:
>> Tame a few "touch this, recompile the world"
>> https://www.mail-archive.com/qemu-devel@nongnu.org/msg635748.html
>>
>> This part is mostly restricted to X86, but since some file from the
>> Alpha/PA-RISC machines include "hw/i386/pc.h" I had to fix them
>> too.
>>
>> Eventually I'll succeed at removing hw/i386/ dependency on non-X86
>> platforms (Quest I started 2 years ago...).
>>
>> Regards,
>>
>> Phil.
>>
>> Philippe Mathieu-Daudé (20):
>>    vl: Add missing "hw/boards.h" include
>>    hw/southbridge/ich9: Removed unused headers
>>    hw/input/pckbd: Remove unused "hw/i386/pc.h" header
>>    hw/i386/ioapic_internal: Remove unused "hw/i386/ioapic.h" header
>>    hw/timer: Remove unused "ui/console.h" header
>>    hw/usb/dev-storage: Remove unused "ui/console.h" header
>>    hw/i386/intel_iommu: Remove unused includes
>>    hw/xen/xen_pt_load_rom: Remove unused includes
>>    hw/alpha/alpha_sys: Remove unused "hw/ide.h" header
>>    hw/alpha/dp264: Include "net/net.h"
>>    hw/hppa/machine: Include "net/net.h"
>>    hw/acpi/cpu_hotplug: Include "hw/pci/pci.h"
>>    hw/timer/hpet: Include "exec/address-spaces.h"
>>    hw/pci-host/q35: Include "qemu/range.h"
>>    hw/i2c/smbus_ich9: Include "qemu/range.h"
>>    hw/pci-host/piix: Include "qemu/range.h"
>>    hw/acpi: Include "hw/mem/nvdimm.h"
>>    hw/i386: Include "hw/mem/nvdimm.h"
>>    hw/pci-host/q35: Remove unused includes
>>    hw/i386/pc: Clean up includes
> Laurent, since this series is fully reviewed, can it go via
> your qemu-trivial tree?

I'll try but I'm not sure to have the time to do that before the softfreeze.

Thanks,
Laurent



Re: [PULL 00/39] Misc (mostly x86) patches for 2019-10-24

2019-10-26 Thread Paolo Bonzini
On 26/10/19 15:20, Philippe Mathieu-Daudé wrote:
> On 10/25/19 1:17 PM, Paolo Bonzini wrote:
>> On 25/10/19 12:46, Peter Maydell wrote:
>>>
>>> x86_register_ferr_irq() is defined in target/i386/fpu_helper.c,
>>> which is only built if CONFIG_TCG, but the callers don't
>>> seem to be similarly guarded and there's no stub fallback.
>>
>> Indeed, thanks.  I'll add an "if (tcg_enabled())" since this feature is
>> not supported by accelerators other than TCG.
> 
> Paolo, since the "Split timer <-> rtc" series got merged via
> the trivial tree, you need to squash this fix to patch #33
> ("mc146818rtc: Include mc146818rtc_regs.h directly in
>  mc146818rtc.c") to avoid build failure:

There are a couple other semantic conflicts, so I pushed again the tag.

Paolo



[PULL v2 00/39] Misc (mostly x86) patches for 2019-10-24

2019-10-26 Thread Paolo Bonzini
The following changes since commit e9d42461920f6f40f4d847a5ba18e90d095ed0b9:

  Merge remote-tracking branch 
'remotes/kraxel/tags/audio-20191018-pull-request' into staging (2019-10-18 
14:13:11 +0100)

are available in the git repository at:


  git://github.com/bonzini/qemu.git tags/for-upstream

for you to fetch changes up to bf13bfab0840d34a74938ddf567d52e9010dbdc6:

  i386: implement IGNNE (2019-10-25 13:18:21 +0200)


* Bulgarian translation update (Alexander)
* RTC and PC refactorings (Hervé, Philippe, Sergio)
* RTC fix (Marcelo)
* More comprehensive MCE logging (Mario)
* x86 IGNNE implementation (Paolo)
* Microvm machine type (Sergio)
* Support for UMONITOR/UMWAIT/TPAUSE (Tao)
* Do not use %m in common code (Thomas)
* NoNonArchitecturalCoreSharing Hyper-V enlightenment (Vitaly)
* getpagesize cleanups (Wei)


Alexander Shopov (1):
  Updated Bulgarian translation (19) - 4.1.0

Hervé Poussineau (2):
  mc146818rtc: move structure to header file
  mc146818rtc: always register rtc to rtc list

Laurent Vivier (1):
  runstate: ignore exit request in finish migrate state

Marcelo Tosatti (1):
  mc146818rtc: fix timer interrupt reinjection

Mario Smarduch (1):
  target/i386: log MCE guest and host addresses

Paolo Bonzini (6):
  memory-device: simplify Makefile.objs conditions
  hw/i386: split PCMachineState deriving X86MachineState from it
  audio: fix missing break
  target/i386: move FERR handling to target/i386
  target/i386: introduce cpu_set_fpus
  i386: implement IGNNE

Philippe Mathieu-Daudé (7):
  hw/timer/mc146818rtc: Only include qapi-commands-misc on I386
  hw/i386/pc: Extract pc_gsi_create()
  hw/i386/pc: Move gsi_state creation code
  hw/i386/pc: Extract pc_i8259_create()
  hw/i386/pc: Remove kvm_i386.h include
  mc146818rtc: Move RTC_ISA_IRQ definition
  mc146818rtc: Include mc146818rtc_regs.h directly in mc146818rtc.c

Sergio Lopez (14):
  hw/virtio: Factorize virtio-mmio headers
  hw/i386/pc: rename functions shared with non-PC machines
  hw/i386/pc: fix code style issues on functions that will be moved out
  hw/i386/pc: replace use of strtol with qemu_strtoui in x86_load_linux()
  hw/i386/pc: avoid an assignment in if condition in x86_load_linux()
  hw/i386/pc: remove commented out code from x86_load_linux()
  hw/i386/pc: move shared x86 functions to x86.c and export them
  hw/i386: make x86.c independent from PCMachineState
  fw_cfg: add "modify" functions for all types
  hw/intc/apic: reject pic ints if isa_pic == NULL
  roms: add microvm-bios (qboot) as binary and git submodule
  docs/microvm.rst: document the new microvm machine type
  hw/i386: Introduce the microvm machine type
  MAINTAINERS: add microvm related files

Tao Xu (2):
  x86/cpu: Add support for UMONITOR/UMWAIT/TPAUSE
  target/i386: Add support for save/load IA32_UMWAIT_CONTROL MSR

Thomas Huth (1):
  Do not use %m in common code to print error messages

Vitaly Kuznetsov (1):
  i386/kvm: add NoNonArchitecturalCoreSharing Hyper-V enlightenment

Wei Yang (2):
  checkpatch: suggest qemu_real_host_page_size instead of getpagesize() or 
sysconf(_SC_PAGESIZE)
  core: replace getpagesize() with qemu_real_host_page_size

 .gitmodules |   3 +
 MAINTAINERS |   9 +
 accel/kvm/kvm-all.c |   6 +-
 audio/paaudio.c |   1 +
 backends/hostmem.c  |   2 +-
 block.c |   4 +-
 block/file-posix.c  |   9 +-
 block/io.c  |   2 +-
 block/parallels.c   |   2 +-
 block/qcow2-cache.c |   2 +-
 contrib/vhost-user-gpu/vugbm.c  |   2 +-
 default-configs/i386-softmmu.mak|   1 +
 docs/hyperv.txt |  13 +
 docs/microvm.rst| 108 +
 exec.c  |   6 +-
 hw/acpi/cpu_hotplug.c   |  10 +-
 hw/i386/Kconfig |  10 +
 hw/i386/Makefile.objs   |   2 +
 hw/i386/acpi-build.c|  29 +-
 hw/i386/amd_iommu.c |   3 +-
 hw/i386/intel_iommu.c   |   3 +-
 hw/i386/microvm.c   | 572 +
 hw/i386/pc.c| 832 +---
 hw/i386/pc_piix.c   |  67 ++-
 hw/i386/pc_q35.c|  64 ++-
 hw/i386/pc_sysfw.c  |  60 +--
 hw/i386/x86.c   | 795 ++
 hw/i386/xen/xen-hvm.c   |  28 +-
 hw/intc/apic.c  |   2 +-
 hw/intc/ioapic.c|   2 +-
 hw/intc/s390_flic_kvm.c |   2 +-
 hw/mem/Makefile.objs|   2 +-
 h

[PULL v2 37/39] target/i386: move FERR handling to target/i386

2019-10-26 Thread Paolo Bonzini
Move it out of pc.c since it is strictly tied to TCG.  This is
almost exclusively code movement, the next patch will implement
IGNNE.

Signed-off-by: Paolo Bonzini 
---
 hw/i386/pc.c | 17 +++--
 hw/i386/pc_piix.c|  4 +++-
 hw/i386/pc_q35.c |  4 +++-
 include/hw/i386/pc.h |  1 -
 target/i386/cpu.h|  3 ++-
 target/i386/fpu_helper.c | 26 +-
 6 files changed, 36 insertions(+), 19 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 5fce60c..66d865b 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -381,23 +381,12 @@ static uint64_t ioport80_read(void *opaque, hwaddr addr, 
unsigned size)
 }
 
 /* MSDOS compatibility mode FPU exception support */
-static qemu_irq ferr_irq;
-
-void pc_register_ferr_irq(qemu_irq irq)
-{
-ferr_irq = irq;
-}
-
-/* XXX: add IGNNE support */
-void cpu_set_ferr(CPUX86State *s)
-{
-qemu_irq_raise(ferr_irq);
-}
-
 static void ioportF0_write(void *opaque, hwaddr addr, uint64_t data,
unsigned size)
 {
-qemu_irq_lower(ferr_irq);
+if (tcg_enabled()) {
+cpu_clear_ferr();
+}
 }
 
 static uint64_t ioportF0_read(void *opaque, hwaddr addr, unsigned size)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 3a4a64a..c15929a 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -213,7 +213,9 @@ static void pc_init1(MachineState *machine,
 ioapic_init_gsi(gsi_state, "i440fx");
 }
 
-pc_register_ferr_irq(x86ms->gsi[13]);
+if (tcg_enabled()) {
+x86_register_ferr_irq(x86ms->gsi[13]);
+}
 
 pc_vga_init(isa_bus, pcmc->pci_enabled ? pci_bus : NULL);
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index def3bc2..b9c3e18 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -261,7 +261,9 @@ static void pc_q35_init(MachineState *machine)
 ioapic_init_gsi(gsi_state, "q35");
 }
 
-pc_register_ferr_irq(x86ms->gsi[13]);
+if (tcg_enabled()) {
+x86_register_ferr_irq(x86ms->gsi[13]);
+}
 
 assert(pcms->vmport != ON_OFF_AUTO__MAX);
 if (pcms->vmport == ON_OFF_AUTO_AUTO) {
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 5923318..f040a72 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -176,7 +176,6 @@ void vmmouse_set_data(const uint32_t *data);
 extern int fd_bootchk;
 
 bool pc_machine_is_smm_enabled(PCMachineState *pcms);
-void pc_register_ferr_irq(qemu_irq irq);
 void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
 
 void pc_hot_add_cpu(MachineState *ms, const int64_t id, Error **errp);
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index b772e82..01e052b 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1761,7 +1761,8 @@ int cpu_x86_support_mca_broadcast(CPUX86State *env);
 
 int cpu_get_pic_interrupt(CPUX86State *s);
 /* MSDOS compatibility mode FPU exception support */
-void cpu_set_ferr(CPUX86State *s);
+void x86_register_ferr_irq(qemu_irq irq);
+void cpu_clear_ferr(void);
 /* mpx_helper.c */
 void cpu_sync_bndcs_hflags(CPUX86State *env);
 
diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c
index 005f1f6..4db0059 100644
--- a/target/i386/fpu_helper.c
+++ b/target/i386/fpu_helper.c
@@ -26,6 +26,10 @@
 #include "exec/cpu_ldst.h"
 #include "fpu/softfloat.h"
 
+#ifdef CONFIG_SOFTMMU
+#include "hw/irq.h"
+#endif
+
 #define FPU_RC_MASK 0xc00
 #define FPU_RC_NEAR 0x000
 #define FPU_RC_DOWN 0x400
@@ -58,6 +62,26 @@
 #define floatx80_l2e make_floatx80(0x3fff, 0xb8aa3b295c17f0bcLL)
 #define floatx80_l2t make_floatx80(0x4000, 0xd49a784bcd1b8afeLL)
 
+#if !defined(CONFIG_USER_ONLY)
+static qemu_irq ferr_irq;
+
+void x86_register_ferr_irq(qemu_irq irq)
+{
+ferr_irq = irq;
+}
+
+void cpu_clear_ferr(void)
+{
+qemu_irq_lower(ferr_irq);
+}
+
+static void cpu_set_ferr(void)
+{
+qemu_irq_raise(ferr_irq);
+}
+#endif
+
+
 static inline void fpush(CPUX86State *env)
 {
 env->fpstt = (env->fpstt - 1) & 7;
@@ -137,7 +161,7 @@ static void fpu_raise_exception(CPUX86State *env, uintptr_t 
retaddr)
 }
 #if !defined(CONFIG_USER_ONLY)
 else {
-cpu_set_ferr(env);
+cpu_set_ferr();
 }
 #endif
 }
-- 
1.8.3.1



Re: [PATCH v2 03/20] piix4: Add a i8259 Interrupt Controller as specified in datasheet

2019-10-26 Thread Philippe Mathieu-Daudé

Hi Li,

On 10/21/19 4:59 PM, Li Qiang wrote:
Philippe Mathieu-Daudé mailto:phi...@redhat.com>> 于 
2019年10月18日周五 下午9:52写道:


From: Hervé Poussineau mailto:hpous...@reactos.org>>

Add ISA irqs as piix4 gpio in, and CPU interrupt request as piix4
gpio out.
Remove i8259 instanciated in malta board, to not have it twice.

We can also remove the now unused piix4_init() function.

Acked-by: Michael S. Tsirkin mailto:m...@redhat.com>>
Acked-by: Paolo Bonzini mailto:pbonz...@redhat.com>>
Signed-off-by: Hervé Poussineau mailto:hpous...@reactos.org>>
Message-Id: <20171216090228.28505-8-hpous...@reactos.org
>
Reviewed-by: Aleksandar Markovic mailto:amarko...@wavecomp.com>>
[PMD: rebased, updated includes, use ISA_NUM_IRQS in for loop]
Signed-off-by: Philippe Mathieu-Daudé mailto:phi...@redhat.com>>
---
  hw/isa/piix4.c       | 43 ---
  hw/mips/mips_malta.c | 32 +---
  include/hw/i386/pc.h |  1 -
  3 files changed, 45 insertions(+), 31 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index d0b18e0586..9c37c85ae2 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -24,6 +24,7 @@
   */

  #include "qemu/osdep.h"
+#include "hw/irq.h"
  #include "hw/i386/pc.h"
  #include "hw/pci/pci.h"
  #include "hw/isa/isa.h"
@@ -36,6 +37,8 @@ PCIDevice *piix4_dev;

  typedef struct PIIX4State {
      PCIDevice dev;
+    qemu_irq cpu_intr;
+    qemu_irq *isa;

      /* Reset Control Register */
      MemoryRegion rcr_mem;
@@ -94,6 +97,18 @@ static const VMStateDescription vmstate_piix4 = {
      }
  };

+static void piix4_request_i8259_irq(void *opaque, int irq, int level)
+{
+    PIIX4State *s = opaque;
+    qemu_set_irq(s->cpu_intr, level);
+}
+
+static void piix4_set_i8259_irq(void *opaque, int irq, int level)
+{
+    PIIX4State *s = opaque;
+    qemu_set_irq(s->isa[irq], level);
+}
+
  static void piix4_rcr_write(void *opaque, hwaddr addr, uint64_t val,
                              unsigned int len)
  {
@@ -127,29 +142,35 @@ static const MemoryRegionOps piix4_rcr_ops = {
  static void piix4_realize(PCIDevice *dev, Error **errp)
  {
      PIIX4State *s = PIIX4_PCI_DEVICE(dev);
+    ISABus *isa_bus;
+    qemu_irq *i8259_out_irq;

-    if (!isa_bus_new(DEVICE(dev), pci_address_space(dev),
-                     pci_address_space_io(dev), errp)) {
+    isa_bus = isa_bus_new(DEVICE(dev), pci_address_space(dev),
+                          pci_address_space_io(dev), errp);
+    if (!isa_bus) {
          return;
      }

+    qdev_init_gpio_in_named(DEVICE(dev), piix4_set_i8259_irq,
+                            "isa", ISA_NUM_IRQS);
+    qdev_init_gpio_out_named(DEVICE(dev), &s->cpu_intr,
+                             "intr", 1);
+



Does the piix4 hardware has the GPIO for interrupt? Seems not.


Yes it does, you can check in the datasheet:
https://www.intel.com/Assets/PDF/datasheet/290562.pdf

Page 3 is the 'Simplified Block Diagram' you see the INTR pin.

Page 24 table "2.1.5. INTERRUPT CONTROLLER/APIC SIGNALS"

  INTR: INTERRUPT. See CPU Interface Signals.

Page 26 "2.1.6. CPU INTERFACE SIGNALS"


  CPU INTERRUPT. INTR is driven by PIIX4 to signal the CPU that
  an interrupt request is pending and needs to be serviced. It
  is asynchronous with respect to SYSCLK or PCICLK and is always
  an output. The interrupt controller must be programmed following
  PCIRST# to ensure that INTR is at a known state.



      memory_region_init_io(&s->rcr_mem, OBJECT(dev), &piix4_rcr_ops, s,
                            "reset-control", 1);
      memory_region_add_subregion_overlap(pci_address_space_io(dev),
0xcf9,
                                          &s->rcr_mem, 1);

+    /* initialize i8259 pic */
+    i8259_out_irq = qemu_allocate_irqs(piix4_request_i8259_irq, s, 1);
+    s->isa = i8259_init(isa_bus, *i8259_out_irq);


In i8259_init, we also allocate 16 input line and 1 output line.
Seems it is duplicated with the GPIO allocation in previous.


No, this is different, here we don't allocate the 16 i8259
INPUT lines, we allocate 1 input IRQ and pass it to the
i8259_init function which uses it as its OUTPUT line.

IOW:

* i8259
  - 16 INPUT (from ISA devices)
  - 1 OUTPUT (to PIIX)

* PIIX
  - 1 INPUT (from i8259)
  - 1 OUTPUT (to CPU, on the Malta board: CPU IRQ2)


Also
Maybe here can uses
i8259(isa_bus, qemu_allocate_irq(piix4_request_i8259_irq, s, 0));

+
+    /* initialize ISA irqs */
+    isa_bus_irqs(isa_bus, s->isa);
+
      piix4_dev = dev;
  }

-int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn)
-{
-    PCIDevice *d;
-
-    d = pci_create_simple_

Re: [PATCH v2 00/20] hw/i386/pc: Split PIIX3 southbridge from i440FX northbridge

2019-10-26 Thread Philippe Mathieu-Daudé

Hi Aleksandar,

On 10/25/19 12:51 PM, Aleksandar Markovic wrote:
On Thursday, October 24, 2019, Aleksandar Markovic 
mailto:aleksandar.m.m...@gmail.com>> wrote:




On Friday, October 18, 2019, Philippe Mathieu-Daudé
mailto:phi...@redhat.com>> wrote:

Changes since v1 [0]:
- Removed patch reintroducing DO_UPCAST() use (thuth)
- Took various patches out to reduce series (thuth)
- Added review tags (thanks all for reviewing!)


Philippe,

Do you intend to submit v3? The softfreeze is close.

A.


Philippe,

It looks you are very busy these days. Do you mind my integrating this 
series in next Mips queue, in its present v2 state? (You can certainly 
do further refinements later on.)


I addressed the review comments from this version, however it can not
be merged yet ...



Aleksandar

$ git backport-diff -u pc_split_i440fx_piix-v1 -r mc146818rtc_init..
Key:
[] : patches are identical
[] : number of functional differences between
upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual
differences, respectively

001/20:[] [--] 'MAINTAINERS: Keep PIIX4 South Bridge
separate from PC Chipsets'
002/20:[0011] [FC] 'piix4: add Reset Control Register'
003/20:[0014] [FC] 'piix4: add a i8259 interrupt controller as
specified in datasheet'
004/20:[] [--] 'Revert "irq: introduce qemu_irq_proxy()"'
005/20:[] [--] 'piix4: rename PIIX4 object to piix4-isa'
006/20:[] [-C] 'piix4: add a i8257 dma controller as
specified in datasheet'
007/20:[] [-C] 'piix4: add a i8254 pit controller as
specified in datasheet'
008/20:[] [-C] 'piix4: add a mc146818rtc controller as
specified in datasheet'
009/20:[] [--] 'hw/mips/mips_malta: Create IDE hard drive
array dynamically'
010/20:[] [--] 'hw/mips/mips_malta: Extract the PIIX4
creation code as piix4_create()'
011/20:[] [--] 'hw/isa/piix4: Move piix4_create() to
hw/isa/piix4.c'
012/20:[] [--] 'hw/i386: Remove obsolete
LoadStateHandler::load_state_old handlers'
013/20:[] [--] 'hw/pci-host/piix: Extract piix3_create()'
014/20:[0010] [FC] 'hw/pci-host/piix: Move RCR_IOPORT register
definition'
015/20:[] [--] 'hw/pci-host/piix: Define and use the PIIX
IRQ Route Control Registers'
016/20:[] [--] 'hw/pci-host/piix: Move i440FX declarations
to hw/pci-host/i440fx.h'
017/20:[] [--] 'hw/pci-host/piix: Fix code style issues'
018/20:[0012] [FC] 'hw/pci-host/piix: Extract PIIX3 functions to
hw/isa/piix3.c'
019/20:[] [--] 'hw/pci-host: Rename incorrectly named 'piix'
as 'i440fx''
020/20:[] [-C] 'hw/pci-host/i440fx: Remove the last PIIX3
traces'

Previous cover:

This series is a rework of "piix4: cleanup and improvements" [1]
from Hervé, and my "remove i386/pc dependency: PIIX cleanup" [2].

Still trying to remove the strong X86/PC dependency 2 years later,
one step at a time.
Here we split the PIIX3 southbridge from i440FX northbridge.
The i440FX northbridge is only used by the PC machine, while the
PIIX southbridge is also used by the Malta MIPS machine.

This is also a step forward using KConfig with the Malta board.
Without this split, it was impossible to compile the Malta without
pulling various X86 pieces of code.

The overall design cleanup is not yet perfect, but enough to post
as a series.

Now that the PIIX3 code is extracted, the code duplication with the
PIIX4 chipset is obvious. Not worth improving for now because it
isn't broken.

[0]
https://lists.gnu.org/archive/html/qemu-devel/2019-10/msg03685.html

[1]
https://www.mail-archive.com/qemu-devel@nongnu.org/msg500737.html 

[2]
https://www.mail-archive.com/qemu-devel@nongnu.org/msg504081.html 


Based-on: <20191018133547.10936-1-phi...@redhat.com
>
mc146818rtc: Allow call object_initialize(MC146818_RTC) instead
of rtc_init()


... because it depends on this series which has been queued by Paolo but 
is not yet merged.



20191018133547.10936-1-philmd@redhat.com">https://mid.mail-archive.com/20191018133547.10936-1-philmd@redhat.com
<20191018133547.10936-1-philmd@redhat.com">https://mid.mail-archive.com/20191018133547.10936-1-philmd@redhat.com>

   

Re: [PATCH 0/5] hw/i386/pc: Extract pc_gsi_create() and pc_i8259_create()

2019-10-26 Thread Philippe Mathieu-Daudé

Hi Paolo,

On 10/22/19 7:32 PM, Philippe Mathieu-Daudé wrote:

On 10/22/19 6:55 PM, Paolo Bonzini wrote:

On 18/10/19 15:59, Philippe Mathieu-Daudé wrote:

These are few patches extracted from the previous too big series:
hw/i386/pc: Split PIIX3 southbridge from i440FX northbridge
https://lists.gnu.org/archive/html/qemu-devel/2019-10/msg03685.html

Dropped "Move kvm_i8259_init() declaration to sysemu/kvm.h" (thuth),
no logical changes:


I queued this, but neither I nor patchew got patch 5.  I just got it
from the PIIX3/i440FX series.


In the patch 'hw/i386: Introduce the microvm machine type'
Sergio uses gsi_handler(), so you need to drop 'hw/i386/pc:
Reduce gsi_handler scope' to keep microvm building.


Odd... Yes this is the same patch resent with no change. Thanks for
noticing this and carrying about finding it!



paolo


$ git backport-diff -u pc_split_i440fx_piix-v1
Key:
[] : patches are identical
[] : number of functional differences between upstream/downstream 
patch

[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, 
respectively


001/5:[] [-C] 'hw/i386/pc: Extract pc_gsi_create()'
002/5:[] [--] 'hw/i386/pc: Reduce gsi_handler scope'
003/5:[] [--] 'hw/i386/pc: Move gsi_state creation code'
004/5:[] [--] 'hw/i386/pc: Extract pc_i8259_create()'
005/5:[] [--] 'hw/i386/pc: Remove kvm_i386.h include'

Based-on: <20191018134754.16362-1-phi...@redhat.com>
hw/i386/pc: Split PIIX3 southbridge from i440FX northbridge [v2]
20191018134754.16362-1-philmd@redhat.com">https://mid.mail-archive.com/20191018134754.16362-1-philmd@redhat.com

Philippe Mathieu-Daudé (5):
   hw/i386/pc: Extract pc_gsi_create()
   hw/i386/pc: Reduce gsi_handler scope
   hw/i386/pc: Move gsi_state creation code
   hw/i386/pc: Extract pc_i8259_create()
   hw/i386/pc: Remove kvm_i386.h include

  hw/i386/pc.c | 36 +++-
  hw/i386/pc_piix.c    | 23 ++-
  hw/i386/pc_q35.c | 28 
  include/hw/i386/pc.h |  3 ++-
  4 files changed, 43 insertions(+), 47 deletions(-)







Re: [PATCH v2 00/20] hw/i386/pc: Split PIIX3 southbridge from i440FX northbridge

2019-10-26 Thread Aleksandar Markovic
On Saturday, October 26, 2019, Philippe Mathieu-Daudé 
wrote:

> Hi Aleksandar,
>
> On 10/25/19 12:51 PM, Aleksandar Markovic wrote:
>
>> On Thursday, October 24, 2019, Aleksandar Markovic <
>> aleksandar.m.m...@gmail.com > wrote:
>>
>>
>>
>> On Friday, October 18, 2019, Philippe Mathieu-Daudé
>> mailto:phi...@redhat.com>> wrote:
>>
>> Changes since v1 [0]:
>> - Removed patch reintroducing DO_UPCAST() use (thuth)
>> - Took various patches out to reduce series (thuth)
>> - Added review tags (thanks all for reviewing!)
>>
>>
>> Philippe,
>>
>> Do you intend to submit v3? The softfreeze is close.
>>
>> A.
>>
>>
>> Philippe,
>>
>> It looks you are very busy these days. Do you mind my integrating this
>> series in next Mips queue, in its present v2 state? (You can certainly do
>> further refinements later on.)
>>
>
> I addressed the review comments from this version, however it can not
> be merged yet ...


OK. Let's not rush. Let me know if I can help in any way.

A.




>
>
>> Aleksandar
>>
>> $ git backport-diff -u pc_split_i440fx_piix-v1 -r
>> mc146818rtc_init..
>> Key:
>> [] : patches are identical
>> [] : number of functional differences between
>> upstream/downstream patch
>> [down] : patch is downstream-only
>> The flags [FC] indicate (F)unctional and (C)ontextual
>> differences, respectively
>>
>> 001/20:[] [--] 'MAINTAINERS: Keep PIIX4 South Bridge
>> separate from PC Chipsets'
>> 002/20:[0011] [FC] 'piix4: add Reset Control Register'
>> 003/20:[0014] [FC] 'piix4: add a i8259 interrupt controller as
>> specified in datasheet'
>> 004/20:[] [--] 'Revert "irq: introduce qemu_irq_proxy()"'
>> 005/20:[] [--] 'piix4: rename PIIX4 object to piix4-isa'
>> 006/20:[] [-C] 'piix4: add a i8257 dma controller as
>> specified in datasheet'
>> 007/20:[] [-C] 'piix4: add a i8254 pit controller as
>> specified in datasheet'
>> 008/20:[] [-C] 'piix4: add a mc146818rtc controller as
>> specified in datasheet'
>> 009/20:[] [--] 'hw/mips/mips_malta: Create IDE hard drive
>> array dynamically'
>> 010/20:[] [--] 'hw/mips/mips_malta: Extract the PIIX4
>> creation code as piix4_create()'
>> 011/20:[] [--] 'hw/isa/piix4: Move piix4_create() to
>> hw/isa/piix4.c'
>> 012/20:[] [--] 'hw/i386: Remove obsolete
>> LoadStateHandler::load_state_old handlers'
>> 013/20:[] [--] 'hw/pci-host/piix: Extract piix3_create()'
>> 014/20:[0010] [FC] 'hw/pci-host/piix: Move RCR_IOPORT register
>> definition'
>> 015/20:[] [--] 'hw/pci-host/piix: Define and use the PIIX
>> IRQ Route Control Registers'
>> 016/20:[] [--] 'hw/pci-host/piix: Move i440FX declarations
>> to hw/pci-host/i440fx.h'
>> 017/20:[] [--] 'hw/pci-host/piix: Fix code style issues'
>> 018/20:[0012] [FC] 'hw/pci-host/piix: Extract PIIX3 functions to
>> hw/isa/piix3.c'
>> 019/20:[] [--] 'hw/pci-host: Rename incorrectly named 'piix'
>> as 'i440fx''
>> 020/20:[] [-C] 'hw/pci-host/i440fx: Remove the last PIIX3
>> traces'
>>
>> Previous cover:
>>
>> This series is a rework of "piix4: cleanup and improvements" [1]
>> from Hervé, and my "remove i386/pc dependency: PIIX cleanup" [2].
>>
>> Still trying to remove the strong X86/PC dependency 2 years later,
>> one step at a time.
>> Here we split the PIIX3 southbridge from i440FX northbridge.
>> The i440FX northbridge is only used by the PC machine, while the
>> PIIX southbridge is also used by the Malta MIPS machine.
>>
>> This is also a step forward using KConfig with the Malta board.
>> Without this split, it was impossible to compile the Malta without
>> pulling various X86 pieces of code.
>>
>> The overall design cleanup is not yet perfect, but enough to post
>> as a series.
>>
>> Now that the PIIX3 code is extracted, the code duplication with
>> the
>> PIIX4 chipset is obvious. Not worth improving for now because it
>> isn't broken.
>>
>> [0]
>> https://lists.gnu.org/archive/html/qemu-devel/2019-10/msg036
>> 85.html
>> > msg03685.html>
>> [1]
>> https://www.mail-archive.com/qemu-devel@nongnu.org/msg500737.html
>> 
>> [2]
>> https://www.mail-archive.com/qemu-devel@nongnu.org/msg504081.html
>> 
>>
>> Based-on: <20191018133547.10936-1-phi...@redhat.com
>> 

Re: Long term approaches to mitigate device reset issue in vhost-user-scsi

2019-10-26 Thread Michael S. Tsirkin
On Fri, Oct 25, 2019 at 06:40:41AM -0700, Raphael Norwitz wrote:
> Hi MST,
> 
> We are trying to develop a long term fix to the following issue with
> vhost-user-scsi:
> 
> When a live migration starts, Qemu sends a SET_VRING_ADDR message to
> update the VQ's flags (turning log on). We can't distinguish that
> message from the first SET_VRING_ADDR message sent after a device
> reset (given that vhost-user backends are not notified about resets).
> That distinction is important because we need to know whether to
> refetch the used ring from guest memory.


Could you clarify a bit more please?

According to the spec the trigger for starting/stopping
the rings is supposed to be VHOST_USER_SET_VRING_KICK,
not SET_VRING_ADDR.

What is this fetching you are talking about?


> A while back we sent a patch [1] (which we still use internally) to introduce 
> a
> message which tells vhost-user backends about device resets. No one
> ever responded to that patch. They are getting clunky to maintain
> and we would prefer to converge on a solution which is inline with
> upstream.
> 
> [1] https://lists.gnu.org/archive/html/qemu-devel/2018-03/msg05077.html
> 
> Vhost seems to support the concept of a reset through the reset_device
> callback in the VhostOps struct. Currently, the vhost-user VhostOps
> reset callback sends RESET_OWNER message.
> 
> The docs currently state, though, that this message is obsolete. Looking
> at the history, I see change d1f8b30ec8dde0318fd1b98d24a64926feae9625
> actually changed the message name to RESET_DEVICE, although it was
> subsequently changed back to RESET_OWNER.
> 
> With this in mind, we think the code should be improved by:
> 
> 1) Stopping qemu from sending the RESET_OWNER message on the
> vhost-user device_reset callback.
> 2) Amending the docs to better align with the code.
> 3) If you agree with 1), adding a separate DEVICE_RESET message.
> 
> If you agree with 1) and 3) would you reconsider patch [1]? If so, I will
> have to update the patch because the message/features numbers
> are now taken. Should I update the patch and resend?
> 
> If you don't plan on stopping Qemu from sending RESET_OWNER,
> I'd like to post a patch allowing vhost-user-scsi benefit from
> the RESET_OWNER message (as it currently don't offer a device
> reset callback).
> 
> Thanks,
> Raphael




Re: [PATCH v14 1/9] esp: add pseudo-DMA as used by Macintosh

2019-10-26 Thread Laurent Vivier
Le 22/10/2019 à 14:21, Philippe Mathieu-Daudé a écrit :
> Hi Laurent,
> 
> On 10/22/19 1:17 PM, Laurent Vivier wrote:
>> There is no DMA in Quadra 800, so the CPU reads/writes the data from the
>> PDMA register (offset 0x100, ESP_PDMA in hw/m68k/q800.c) and copies them
>> to/from the memory.
>>
>> There is a nice assembly loop in the kernel to do that, see
>> linux/drivers/scsi/mac_esp.c:MAC_ESP_PDMA_LOOP().
>>
>> The start of the transfer is triggered by the DREQ interrupt (see linux
>> mac_esp_send_pdma_cmd()), the CPU polls on the IRQ flag to start the
>> transfer after a SCSI command has been sent (in Quadra 800 it goes
>> through the VIA2, the via2-irq line and the vIFR register)
>>
>> The Macintosh hardware includes hardware handshaking to prevent the CPU
>> from reading invalid data or writing data faster than the peripheral
>> device can accept it.
>>
>> This is the "blind mode", and from the doc:
>> "Approximate maximum SCSI transfer rates within a blocks are 1.4 MB per
>> second for blind transfers in the Macintosh II"
>>
>> Some references can be found in:
>>    Apple Macintosh Family Hardware Reference, ISBN 0-201-19255-1
>>    Guide to the Macintosh Family Hardware, ISBN-0-201-52405-8
>>
>> Acked-by: Dr. David Alan Gilbert 
>> Co-developed-by: Mark Cave-Ayland 
>> Signed-off-by: Mark Cave-Ayland 
>> Signed-off-by: Laurent Vivier 
>> ---
>>   include/hw/scsi/esp.h |  15 ++
>>   hw/scsi/esp.c | 338 ++
>>   2 files changed, 324 insertions(+), 29 deletions(-)
>>
>> diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
>> index adab63d1c9..6ba47dac41 100644
>> --- a/include/hw/scsi/esp.h
>> +++ b/include/hw/scsi/esp.h
>> @@ -14,10 +14,18 @@ typedef void (*ESPDMAMemoryReadWriteFunc)(void
>> *opaque, uint8_t *buf, int len);
>>     typedef struct ESPState ESPState;
>>   +enum pdma_origin_id {
>> +    PDMA,
>> +    TI,
>> +    CMD,
>> +    ASYNC,
>> +};
>> +
>>   struct ESPState {
>>   uint8_t rregs[ESP_REGS];
>>   uint8_t wregs[ESP_REGS];
>>   qemu_irq irq;
>> +    qemu_irq irq_data;
>>   uint8_t chip_id;
>>   bool tchi_written;
>>   int32_t ti_size;
>> @@ -48,6 +56,12 @@ struct ESPState {
>>   ESPDMAMemoryReadWriteFunc dma_memory_write;
>>   void *dma_opaque;
>>   void (*dma_cb)(ESPState *s);
>> +    uint8_t pdma_buf[32];
>> +    int pdma_origin;
>> +    uint32_t pdma_len;
>> +    uint32_t pdma_start;
>> +    uint32_t pdma_cur;
>> +    void (*pdma_cb)(ESPState *s);
>>   };
>>     #define TYPE_ESP "esp"
>> @@ -59,6 +73,7 @@ typedef struct {
>>   /*< public >*/
>>     MemoryRegion iomem;
>> +    MemoryRegion pdma;
>>   uint32_t it_shift;
>>   ESPState esp;
>>   } SysBusESPState;
>> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
>> index 841d79b60e..90b40c4cb5 100644
>> --- a/hw/scsi/esp.c
>> +++ b/hw/scsi/esp.c
>> @@ -38,6 +38,8 @@
>>    *
>> http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
>>
>>    * and
>>    *
>> http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
>>
>> + *
>> + * On Macintosh Quadra it is a NCR53C96.
>>    */
>>     static void esp_raise_irq(ESPState *s)
>> @@ -58,6 +60,16 @@ static void esp_lower_irq(ESPState *s)
>>   }
>>   }
>>   +static void esp_raise_drq(ESPState *s)
>> +{
>> +    qemu_irq_raise(s->irq_data);
>> +}
>> +
>> +static void esp_lower_drq(ESPState *s)
>> +{
>> +    qemu_irq_lower(s->irq_data);
>> +}
>> +
>>   void esp_dma_enable(ESPState *s, int irq, int level)
>>   {
>>   if (level) {
>> @@ -84,29 +96,35 @@ void esp_request_cancelled(SCSIRequest *req)
>>   }
>>   }
>>   -static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
>> +static void set_pdma(ESPState *s, enum pdma_origin_id origin,
>> + uint32_t index, uint32_t len)
>> +{
>> +    s->pdma_origin = origin;
>> +    s->pdma_start = index;
>> +    s->pdma_cur = index;
>> +    s->pdma_len = len;
> 
> Can you pass the pdma_cb to this function, and:
> 
>    s->pdma_cb = pdma_cb;
> 
>> +}
>> +
>> +static uint8_t *get_pdma_buf(ESPState *s)
>> +{
>> +    switch (s->pdma_origin) {
>> +    case PDMA:
>> +    return s->pdma_buf;
>> +    case TI:
>> +    return s->ti_buf;
>> +    case CMD:
>> +    return s->cmdbuf;
>> +    case ASYNC:
>> +    return s->async_buf;
>> +    }
>> +    return NULL;
>> +}
>> +
>> +static int get_cmd_cb(ESPState *s)
>>   {
>> -    uint32_t dmalen;
>>   int target;
>>     target = s->wregs[ESP_WBUSID] & BUSID_DID;
>> -    if (s->dma) {
>> -    dmalen = s->rregs[ESP_TCLO];
>> -    dmalen |= s->rregs[ESP_TCMID] << 8;
>> -    dmalen |= s->rregs[ESP_TCHI] << 16;
>> -    if (dmalen > buflen) {
>> -    return 0;
>> -    }
>> -    s->dma_memory_read(s->dma_opaque, buf, dmalen);
>> -    } else {
>> -    dmalen = s->ti_size;
>> -    if (dmalen > TI_BUFSZ) {
>> -    return 0;
>> -    }
>> -    memcpy(buf, s->ti_buf, dmalen);
>> 

[PATCH v15 00/11] hw/m68k: add Apple Machintosh Quadra 800 machine

2019-10-26 Thread Laurent Vivier
I'm rebasing some of these patches for seven years now,
too many years...

if you want to test the machine, I'm sorry, it doesn't boot
a MacROM, but you can boot a linux kernel from the command line.

You can install your own disk using debian-installer, with:

...
-M q800 \
-serial none -serial mon:stdio \
-m 1000M \
-net nic,model=dp83932,addr=09:00:07:12:34:57 \
-append "console=ttyS0 vga=off" \
-kernel vmlinux-4.16.0-1-m68k \
-initrd initrd.gz \
-drive file=debian-10.0-m68k-NETINST-1.iso,media=cdrom \
-drive file=m68k.qcow2,format=qcow2 \
-nographic

If you use a graphic adapter instead of "-nographic", you can use "-g" to set 
the
size of the display (I use "-g 1600x800x24").

You can get the ISO from:

https://cdimage.debian.org/cdimage/ports/10.0/m68k/iso-cd/debian-10.0-m68k-NETINST-1.iso

and extract the kernel and initrd.gz:

guestfish --add debian-10.0-m68k-NETINST-1.iso --ro \
  --mount /dev/sda:/ <<_EOF_
copy-out /install/cdrom/initrd.gz .
copy-out /install/kernels/vmlinux-4.16.0-1-m68k .
_EOF_

The mirror to use is: http://ftp.ports.debian.org/debian-ports/
when it fails, continue without boot loader.

In the same way, you can extract the kernel and the initramfs from the qcow2
image to use it with "-kernel" and "-initrd":

guestfish --add m68k.qcow2 --mount /dev/sda2:/ <<_EOF_
copy-out /boot/vmlinux-4.16.0-1-m68k .
copy-out /boot/initrd.img-4.16.0-1-m68k .
_EOF_

and boot with:

   ...
   -append "root=/dev/sda2 rw console=ttyS0 console=tty \
   -kernel vmlinux-4.16.0-1-m68k \
   -initrd initrd.img-4.16.0-1-m68k

NOTE: DHCP doesn't work but you can assign a static IP address.
  We need some patches for dp8393x that are not ready to be merged.
  See http://patchwork.ozlabs.org/patch/927020/
  http://patchwork.ozlabs.org/patch/927030/
  http://patchwork.ozlabs.org/patch/927026/

v15: limit the memory to 1GiB (max RAM address on Q800 is 0x4000)
 (but kernel crashes for values beyond 1015 MiB, I don't know why,
 perhaps because specs of real Q800 say maximum memory is 136 MiB...)
 split ESP patch to ease review, remove one useless change.

v14: rebase
 update VBL and SECOND IFR flags even if the timer is stopped
 updated swim.c header

v13: rebase
 Stop 1-second and VBL timers when the interrupt is disabled
 (fix some performance regressions on PowerMac G5, and 100% CPU
  usage on x86_64)

v12: Merge macfb and nubus macfb patches
 Add some commit messages
 replace DEFINE_MACHINE() by type_init()
 Add BootLinuxConsoleTest from Philippe
 rebase

v11: Add VMState to migrate ESP PDMA

 The new VMState structures cannot be tested because m68k is not
 migratable and then Q800 is not either.
 I've tested the ESP VMState is not broken by the change
 with 'migrate "exec:cat > mig"' with qemu-system-sparc and
 I have compared the result with/without the patch with
 scripts/analyze-migrate.py: files desc.json are identical.

v10: Add SWIM VMState and reset function
 Add MacVIA VMState
 rework Kconfig

v9: Fix comments format
rebase on top of NeXTcube

v8: rebase (new blk_new(), add "qemu-common.h")
update bootinfo information and license
add some braces
Rename Q800IRQState to GLUEState:
it's more like a Logic Unit than an IRQ controller,
and Apple calls it "GLUE" (Mark: I prefer to keep it
like this for the moment, in the future this part
need to be reworked, we have to review the IRQ levels
and to wire NUBUS IRQ. The implementation is really trivial
for the moment and we will move it to QOM in the future)

v7: rebase and port to Kconfig
move IRQ controller back to q800.c (we don't need an object for this)
update log message for ESP changes and add some g_assert()
re-order patches: put esp, escc and dp8393x first

v6: Rebase onto git master (this now includes the m68k EXCP_ILLEGAL fix required
  for this patchset to boot)
Add Hervé's R-B tags
Drop ASC (Apple Sound Chip) device since the Linux driver is broken and
  it is not required for a successful boot
Remove extra esp_raise_irq() from ESP pseudo-DMA patch (Hervé)
Remove "return" from unimplemented write functions and instead add a
  "read only" comment (Hervé)
Rename MAX_FD to SWIM_MAX_FD in SWIM floppy controller patch to prevent
  potential conflicts with other files (Hervé)

v5: Rebase onto git master
Add Philippe's R-B to patch 10
Include the command line to boot a Linux kernel under the q800 machine in 
the
commit message for patch 11 (Philippe)
Fix up comments in hw/misc/mac_via.c (Thomas)
Add asserts to VIA ADB support to prevent potential buffer overflows 
(Thomas)
Move macfb surface/resolution checks to realise and remove hw_error (Thomas)
Move macfb draw_line functions inline and remove macfb-template.h (Mark)
Use guest address rather than source pointer in draw_line f

[PATCH v15 01/11] esp: move handle_ti_cmd() cleanup code to esp_do_dma().

2019-10-26 Thread Laurent Vivier
To prepare following patches move do_cmd and DMA special case
from handle_ti() to esp_do_dma().

This part of the code must be only executed with real DMA, not with
pseudo-DMA. And PDMA is detected in esp_do_dma(), so move this part
of the code in esp_do_dma(). We keep the code in handle_ti_cmd()
in the case no DMA is done.

Signed-off-by: Laurent Vivier 
---
 hw/scsi/esp.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 841d79b60e..09b28cba17 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -249,10 +249,19 @@ static void esp_do_dma(ESPState *s)
 
 len = s->dma_left;
 if (s->do_cmd) {
+/*
+ * handle_ti_cmd() case: esp_do_dma() is called only from
+ * handle_ti_cmd() with do_cmd != NULL (see the assert())
+ */
 trace_esp_do_dma(s->cmdlen, len);
 assert (s->cmdlen <= sizeof(s->cmdbuf) &&
 len <= sizeof(s->cmdbuf) - s->cmdlen);
 s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
+trace_esp_handle_ti_cmd(s->cmdlen);
+s->ti_size = 0;
+s->cmdlen = 0;
+s->do_cmd = 0;
+do_cmd(s, s->cmdbuf);
 return;
 }
 if (s->async_len == 0) {
@@ -373,8 +382,7 @@ static void handle_ti(ESPState *s)
 s->dma_left = minlen;
 s->rregs[ESP_RSTAT] &= ~STAT_TC;
 esp_do_dma(s);
-}
-if (s->do_cmd) {
+} else if (s->do_cmd) {
 trace_esp_handle_ti_cmd(s->cmdlen);
 s->ti_size = 0;
 s->cmdlen = 0;
-- 
2.21.0




[PATCH v15 02/11] esp: move get_cmd() post-DMA code to get_cmd_cb()

2019-10-26 Thread Laurent Vivier
This will be needed to implement pseudo-DMA

Signed-off-by: Laurent Vivier 
---
 hw/scsi/esp.c | 46 +-
 1 file changed, 29 insertions(+), 17 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 09b28cba17..0230ede21d 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -84,6 +84,34 @@ void esp_request_cancelled(SCSIRequest *req)
 }
 }
 
+static int get_cmd_cb(ESPState *s)
+{
+int target;
+
+target = s->wregs[ESP_WBUSID] & BUSID_DID;
+
+s->ti_size = 0;
+s->ti_rptr = 0;
+s->ti_wptr = 0;
+
+if (s->current_req) {
+/* Started a new command before the old one finished.  Cancel it.  */
+scsi_req_cancel(s->current_req);
+s->async_len = 0;
+}
+
+s->current_dev = scsi_device_find(&s->bus, 0, target, 0);
+if (!s->current_dev) {
+/* No such drive */
+s->rregs[ESP_RSTAT] = 0;
+s->rregs[ESP_RINTR] = INTR_DC;
+s->rregs[ESP_RSEQ] = SEQ_0;
+esp_raise_irq(s);
+return -1;
+}
+return 0;
+}
+
 static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
 {
 uint32_t dmalen;
@@ -108,23 +136,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t 
buflen)
 }
 trace_esp_get_cmd(dmalen, target);
 
-s->ti_size = 0;
-s->ti_rptr = 0;
-s->ti_wptr = 0;
-
-if (s->current_req) {
-/* Started a new command before the old one finished.  Cancel it.  */
-scsi_req_cancel(s->current_req);
-s->async_len = 0;
-}
-
-s->current_dev = scsi_device_find(&s->bus, 0, target, 0);
-if (!s->current_dev) {
-// No such drive
-s->rregs[ESP_RSTAT] = 0;
-s->rregs[ESP_RINTR] = INTR_DC;
-s->rregs[ESP_RSEQ] = SEQ_0;
-esp_raise_irq(s);
+if (get_cmd_cb(s) < 0) {
 return 0;
 }
 return dmalen;
-- 
2.21.0




[PATCH v15 04/11] dp8393x: manage big endian bus

2019-10-26 Thread Laurent Vivier
This is needed by Quadra 800, this card can run on little-endian
or big-endian bus.

Signed-off-by: Laurent Vivier 
Tested-by: Hervé Poussineau 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Hervé Poussineau 
---
 hw/net/dp8393x.c | 88 +++-
 1 file changed, 57 insertions(+), 31 deletions(-)

diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index a5678e11fa..693e244ce6 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -153,6 +153,7 @@ typedef struct dp8393xState {
 
 /* Hardware */
 uint8_t it_shift;
+bool big_endian;
 qemu_irq irq;
 #ifdef DEBUG_SONIC
 int irq_level;
@@ -223,6 +224,29 @@ static uint32_t dp8393x_wt(dp8393xState *s)
 return s->regs[SONIC_WT1] << 16 | s->regs[SONIC_WT0];
 }
 
+static uint16_t dp8393x_get(dp8393xState *s, int width, uint16_t *base,
+int offset)
+{
+uint16_t val;
+
+if (s->big_endian) {
+val = be16_to_cpu(base[offset * width + width - 1]);
+} else {
+val = le16_to_cpu(base[offset * width]);
+}
+return val;
+}
+
+static void dp8393x_put(dp8393xState *s, int width, uint16_t *base, int offset,
+uint16_t val)
+{
+if (s->big_endian) {
+base[offset * width + width - 1] = cpu_to_be16(val);
+} else {
+base[offset * width] = cpu_to_le16(val);
+}
+}
+
 static void dp8393x_update_irq(dp8393xState *s)
 {
 int level = (s->regs[SONIC_IMR] & s->regs[SONIC_ISR]) ? 1 : 0;
@@ -254,12 +278,12 @@ static void dp8393x_do_load_cam(dp8393xState *s)
 /* Fill current entry */
 address_space_rw(&s->as, dp8393x_cdp(s),
 MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0);
-s->cam[index][0] = data[1 * width] & 0xff;
-s->cam[index][1] = data[1 * width] >> 8;
-s->cam[index][2] = data[2 * width] & 0xff;
-s->cam[index][3] = data[2 * width] >> 8;
-s->cam[index][4] = data[3 * width] & 0xff;
-s->cam[index][5] = data[3 * width] >> 8;
+s->cam[index][0] = dp8393x_get(s, width, data, 1) & 0xff;
+s->cam[index][1] = dp8393x_get(s, width, data, 1) >> 8;
+s->cam[index][2] = dp8393x_get(s, width, data, 2) & 0xff;
+s->cam[index][3] = dp8393x_get(s, width, data, 2) >> 8;
+s->cam[index][4] = dp8393x_get(s, width, data, 3) & 0xff;
+s->cam[index][5] = dp8393x_get(s, width, data, 3) >> 8;
 DPRINTF("load cam[%d] with %02x%02x%02x%02x%02x%02x\n", index,
 s->cam[index][0], s->cam[index][1], s->cam[index][2],
 s->cam[index][3], s->cam[index][4], s->cam[index][5]);
@@ -272,7 +296,7 @@ static void dp8393x_do_load_cam(dp8393xState *s)
 /* Read CAM enable */
 address_space_rw(&s->as, dp8393x_cdp(s),
 MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0);
-s->regs[SONIC_CE] = data[0 * width];
+s->regs[SONIC_CE] = dp8393x_get(s, width, data, 0);
 DPRINTF("load cam done. cam enable mask 0x%04x\n", s->regs[SONIC_CE]);
 
 /* Done */
@@ -293,10 +317,10 @@ static void dp8393x_do_read_rra(dp8393xState *s)
 MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0);
 
 /* Update SONIC registers */
-s->regs[SONIC_CRBA0] = data[0 * width];
-s->regs[SONIC_CRBA1] = data[1 * width];
-s->regs[SONIC_RBWC0] = data[2 * width];
-s->regs[SONIC_RBWC1] = data[3 * width];
+s->regs[SONIC_CRBA0] = dp8393x_get(s, width, data, 0);
+s->regs[SONIC_CRBA1] = dp8393x_get(s, width, data, 1);
+s->regs[SONIC_RBWC0] = dp8393x_get(s, width, data, 2);
+s->regs[SONIC_RBWC1] = dp8393x_get(s, width, data, 3);
 DPRINTF("CRBA0/1: 0x%04x/0x%04x, RBWC0/1: 0x%04x/0x%04x\n",
 s->regs[SONIC_CRBA0], s->regs[SONIC_CRBA1],
 s->regs[SONIC_RBWC0], s->regs[SONIC_RBWC1]);
@@ -411,12 +435,12 @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
 tx_len = 0;
 
 /* Update registers */
-s->regs[SONIC_TCR] = data[0 * width] & 0xf000;
-s->regs[SONIC_TPS] = data[1 * width];
-s->regs[SONIC_TFC] = data[2 * width];
-s->regs[SONIC_TSA0] = data[3 * width];
-s->regs[SONIC_TSA1] = data[4 * width];
-s->regs[SONIC_TFS] = data[5 * width];
+s->regs[SONIC_TCR] = dp8393x_get(s, width, data, 0) & 0xf000;
+s->regs[SONIC_TPS] = dp8393x_get(s, width, data, 1);
+s->regs[SONIC_TFC] = dp8393x_get(s, width, data, 2);
+s->regs[SONIC_TSA0] = dp8393x_get(s, width, data, 3);
+s->regs[SONIC_TSA1] = dp8393x_get(s, width, data, 4);
+s->regs[SONIC_TFS] = dp8393x_get(s, width, data, 5);
 
 /* Handle programmable interrupt */
 if (s->regs[SONIC_TCR] & SONIC_TCR_PINT) {
@@ -442,9 +466,9 @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
 address_space_rw(&s->as,
 dp8393x_ttda(s) + sizeof(uint16_t) * (4 + 3 * i) * width,
 MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 0);
-s->regs[SONIC_TSA0

[PATCH v15 08/11] hw/m68k: add Nubus macfb video card

2019-10-26 Thread Laurent Vivier
This patch adds support for a graphic framebuffer device.
This device can be added as a sysbus device or as a NuBus device.

It is accessed as a framebuffer but the color palette can be set.

Co-developed-by: Mark Cave-Ayland 
Signed-off-by: Mark Cave-Ayland 
Signed-off-by: Laurent Vivier 
Reviewed-by: Hervé Poussineau 
Reviewed-by: Thomas Huth 
---
 include/hw/display/macfb.h |  64 +
 arch_init.c|   4 +
 hw/display/macfb.c | 477 +
 vl.c   |   3 +-
 MAINTAINERS|   2 +
 hw/display/Kconfig |   5 +
 hw/display/Makefile.objs   |   1 +
 hw/m68k/Kconfig|   1 +
 qemu-options.hx|   2 +-
 9 files changed, 557 insertions(+), 2 deletions(-)
 create mode 100644 include/hw/display/macfb.h
 create mode 100644 hw/display/macfb.c

diff --git a/include/hw/display/macfb.h b/include/hw/display/macfb.h
new file mode 100644
index 00..26367ae2c4
--- /dev/null
+++ b/include/hw/display/macfb.h
@@ -0,0 +1,64 @@
+/*
+ * QEMU Motorola 680x0 Macintosh Video Card Emulation
+ * Copyright (c) 2012-2018 Laurent Vivier
+ *
+ * some parts from QEMU G364 framebuffer Emulator.
+ * Copyright (c) 2007-2011 Herve Poussineau
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef MACFB_H
+#define MACFB_H
+
+#include "qemu/osdep.h"
+#include "exec/memory.h"
+#include "ui/console.h"
+
+typedef struct MacfbState {
+MemoryRegion mem_vram;
+MemoryRegion mem_ctrl;
+QemuConsole *con;
+
+uint8_t *vram;
+uint32_t vram_bit_mask;
+uint32_t palette_current;
+uint8_t color_palette[256 * 3];
+uint32_t width, height; /* in pixels */
+uint8_t depth;
+} MacfbState;
+
+#define TYPE_MACFB "sysbus-macfb"
+#define MACFB(obj) \
+OBJECT_CHECK(MacfbSysBusState, (obj), TYPE_MACFB)
+
+typedef struct {
+SysBusDevice busdev;
+
+MacfbState macfb;
+} MacfbSysBusState;
+
+#define MACFB_NUBUS_DEVICE_CLASS(class) \
+OBJECT_CLASS_CHECK(MacfbNubusDeviceClass, (class), TYPE_NUBUS_MACFB)
+#define MACFB_NUBUS_GET_CLASS(obj) \
+OBJECT_GET_CLASS(MacfbNubusDeviceClass, (obj), TYPE_NUBUS_MACFB)
+
+typedef struct MacfbNubusDeviceClass {
+DeviceClass parent_class;
+
+DeviceRealize parent_realize;
+} MacfbNubusDeviceClass;
+
+#define TYPE_NUBUS_MACFB "nubus-macfb"
+#define NUBUS_MACFB(obj) \
+OBJECT_CHECK(MacfbNubusState, (obj), TYPE_NUBUS_MACFB)
+
+typedef struct {
+NubusDevice busdev;
+
+MacfbState macfb;
+} MacfbNubusState;
+
+#endif
diff --git a/arch_init.c b/arch_init.c
index 0a1531124c..705d0b94ad 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -38,6 +38,10 @@
 int graphic_width = 1024;
 int graphic_height = 768;
 int graphic_depth = 8;
+#elif defined(TARGET_M68K)
+int graphic_width = 800;
+int graphic_height = 600;
+int graphic_depth = 8;
 #else
 int graphic_width = 800;
 int graphic_height = 600;
diff --git a/hw/display/macfb.c b/hw/display/macfb.c
new file mode 100644
index 00..f4fa8e3206
--- /dev/null
+++ b/hw/display/macfb.c
@@ -0,0 +1,477 @@
+/*
+ * QEMU Motorola 680x0 Macintosh Video Card Emulation
+ * Copyright (c) 2012-2018 Laurent Vivier
+ *
+ * some parts from QEMU G364 framebuffer Emulator.
+ * Copyright (c) 2007-2011 Herve Poussineau
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "hw/sysbus.h"
+#include "ui/console.h"
+#include "ui/pixel_ops.h"
+#include "hw/nubus/nubus.h"
+#include "hw/display/macfb.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+
+#define VIDEO_BASE 0x1000
+#define DAFB_BASE  0x0080
+
+#define MACFB_PAGE_SIZE 4096
+#define MACFB_VRAM_SIZE (4 * MiB)
+
+#define DAFB_RESET  0x200
+#define DAFB_LUT0x213
+
+
+typedef void macfb_draw_line_func(MacfbState *s, uint8_t *d, uint32_t addr,
+  int width);
+
+static inline uint8_t macfb_read_byte(MacfbState *s, uint32_t addr)
+{
+return s->vram[addr & s->vram_bit_mask];
+}
+
+/* 1-bit color */
+static void macfb_draw_line1(MacfbState *s, uint8_t *d, uint32_t addr,
+ int width)
+{
+uint8_t r, g, b;
+int x;
+
+for (x = 0; x < width; x++) {
+int bit = x & 7;
+int idx = (macfb_read_byte(s, addr) >> (7 - bit)) & 1;
+r = g = b  = ((1 - idx) << 7);
+addr += (bit == 7);
+
+*(uint32_t *)d = rgb_to_pixel32(r, g, b);
+d += 4;
+}
+}
+
+/* 2-bit color */
+static void macfb_draw_line2(MacfbState *s, uint8_t *d, uint32_t addr,
+ int width)
+{
+uint8_t r, g, b;
+int x;
+
+for (x = 0; x < width; x++) {
+int bit = (x & 3);
+int idx = (macfb_read_byte(s, 

[PATCH v15 06/11] hw/m68k: implement ADB bus support for via

2019-10-26 Thread Laurent Vivier
VIA needs to be able to poll the ADB interface and to read/write data
from/to the bus.

This patch adds functions allowing that.

Co-developed-by: Mark Cave-Ayland 
Signed-off-by: Mark Cave-Ayland 
Signed-off-by: Laurent Vivier 
Reviewed-by: Hervé Poussineau 
Reviewed-by: Thomas Huth 
---
 include/hw/misc/mac_via.h |   7 ++
 hw/misc/mac_via.c | 197 ++
 hw/misc/Kconfig   |   1 +
 3 files changed, 205 insertions(+)

diff --git a/include/hw/misc/mac_via.h b/include/hw/misc/mac_via.h
index efc8ef3ce3..3f86fcb7e1 100644
--- a/include/hw/misc/mac_via.h
+++ b/include/hw/misc/mac_via.h
@@ -103,6 +103,13 @@ typedef struct MacVIAState {
 
 /* ADB */
 ADBBusState adb_bus;
+QEMUTimer *adb_poll_timer;
+qemu_irq adb_data_ready;
+int adb_data_in_size;
+int adb_data_in_index;
+int adb_data_out_index;
+uint8_t adb_data_in[128];
+uint8_t adb_data_out[16];
 } MacVIAState;
 
 #endif
diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index d2da8b8e60..f3f130ad96 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -264,10 +264,16 @@
  * Table 19-10 ADB transaction states
  */
 
+#define ADB_STATE_NEW   0
+#define ADB_STATE_EVEN  1
+#define ADB_STATE_ODD   2
+#define ADB_STATE_IDLE  3
+
 #define VIA1B_vADB_StateMask(VIA1B_vADBS1 | VIA1B_vADBS2)
 #define VIA1B_vADB_StateShift   4
 
 #define VIA_TIMER_FREQ (783360)
+#define VIA_ADB_POLL_FREQ 50 /* XXX: not real */
 
 /* VIA returns time offset from Jan 1, 1904, not 1970 */
 #define RTC_OFFSET 2082844800
@@ -472,6 +478,181 @@ static void via1_rtc_update(MacVIAState *m)
 }
 }
 
+static int adb_via_poll(MacVIAState *s, int state, uint8_t *data)
+{
+if (state != ADB_STATE_IDLE) {
+return 0;
+}
+
+if (s->adb_data_in_size < s->adb_data_in_index) {
+return 0;
+}
+
+if (s->adb_data_out_index != 0) {
+return 0;
+}
+
+s->adb_data_in_index = 0;
+s->adb_data_out_index = 0;
+s->adb_data_in_size = adb_poll(&s->adb_bus, s->adb_data_in, 0x);
+
+if (s->adb_data_in_size) {
+*data = s->adb_data_in[s->adb_data_in_index++];
+qemu_irq_raise(s->adb_data_ready);
+}
+
+return s->adb_data_in_size;
+}
+
+static int adb_via_send(MacVIAState *s, int state, uint8_t data)
+{
+switch (state) {
+case ADB_STATE_NEW:
+s->adb_data_out_index = 0;
+break;
+case ADB_STATE_EVEN:
+if ((s->adb_data_out_index & 1) == 0) {
+return 0;
+}
+break;
+case ADB_STATE_ODD:
+if (s->adb_data_out_index & 1) {
+return 0;
+}
+break;
+case ADB_STATE_IDLE:
+return 0;
+}
+
+assert(s->adb_data_out_index < sizeof(s->adb_data_out) - 1);
+
+s->adb_data_out[s->adb_data_out_index++] = data;
+qemu_irq_raise(s->adb_data_ready);
+return 1;
+}
+
+static int adb_via_receive(MacVIAState *s, int state, uint8_t *data)
+{
+switch (state) {
+case ADB_STATE_NEW:
+return 0;
+
+case ADB_STATE_EVEN:
+if (s->adb_data_in_size <= 0) {
+qemu_irq_raise(s->adb_data_ready);
+return 0;
+}
+
+if (s->adb_data_in_index >= s->adb_data_in_size) {
+*data = 0;
+qemu_irq_raise(s->adb_data_ready);
+return 1;
+}
+
+if ((s->adb_data_in_index & 1) == 0) {
+return 0;
+}
+
+break;
+
+case ADB_STATE_ODD:
+if (s->adb_data_in_size <= 0) {
+qemu_irq_raise(s->adb_data_ready);
+return 0;
+}
+
+if (s->adb_data_in_index >= s->adb_data_in_size) {
+*data = 0;
+qemu_irq_raise(s->adb_data_ready);
+return 1;
+}
+
+if (s->adb_data_in_index & 1) {
+return 0;
+}
+
+break;
+
+case ADB_STATE_IDLE:
+if (s->adb_data_out_index == 0) {
+return 0;
+}
+
+s->adb_data_in_size = adb_request(&s->adb_bus, s->adb_data_in,
+  s->adb_data_out,
+  s->adb_data_out_index);
+s->adb_data_out_index = 0;
+s->adb_data_in_index = 0;
+if (s->adb_data_in_size < 0) {
+*data = 0xff;
+qemu_irq_raise(s->adb_data_ready);
+return -1;
+}
+
+if (s->adb_data_in_size == 0) {
+return 0;
+}
+
+break;
+}
+
+assert(s->adb_data_in_index < sizeof(s->adb_data_in) - 1);
+
+*data = s->adb_data_in[s->adb_data_in_index++];
+qemu_irq_raise(s->adb_data_ready);
+if (*data == 0xff || *data == 0) {
+return 0;
+}
+return 1;
+}
+
+static void via1_adb_update(MacVIAState *m)
+{
+MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
+MOS6522State *s = MOS6522(v1s);
+int state;
+int ret;
+
+state = (s->b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift;

[PATCH v15 11/11] BootLinuxConsoleTest: Test the Quadra 800

2019-10-26 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

This test boots a Linux kernel on a Quadra 800 board
and verify the serial is working.

Example:

  $ avocado --show=app,console run -t machine:q800 
tests/acceptance/boot_linux_console.py
  console: ABCFGHIJK
  console: Linux version 5.2.0-2-m68k (debian-ker...@lists.debian.org) (gcc 
version 8.3.0 (Debian 8.3.0-21)) #1 Debian 5.2.9-2 (2019-08-21)
  console: Detected Macintosh model: 35
  console: Apple Macintosh Quadra 800
  console: Built 1 zonelists, mobility grouping on.  Total pages: 32448
  console: Kernel command line: printk.time=0 console=ttyS0 vga=off
  [...]
  console: Calibrating delay loop... 1236.99 BogoMIPS (lpj=6184960)
  [...]
  console: NuBus: Scanning NuBus slots.
  console: Slot 9: Board resource not found!
  console: SCSI subsystem initialized
  console: clocksource: Switched to clocksource via1
  [...]
  console: macfb: framebuffer at 0xf9001000, mapped to 0x(ptrval), size 468k
  console: macfb: mode is 800x600x8, linelength=800
  console: Console: switching to colour frame buffer device 100x37
  console: fb0: DAFB frame buffer device
  console: pmac_zilog: 0.6 (Benjamin Herrenschmidt )
  console: scc.0: ttyS0 at MMIO 0x50f0c022 (irq = 4, base_baud = 230400) is a 
Z85c30 ESCC - Serial port
  console: scc.1: ttyS1 at MMIO 0x50f0c020 (irq = 4, base_baud = 230400) is a 
Z85c30 ESCC - Serial port
  console: Non-volatile memory driver v1.3
  console: adb: Mac II ADB Driver v1.0 for Unified ADB
  console: mousedev: PS/2 mouse device common for all mice
  console: random: fast init done
  console: Detected ADB keyboard, type .
  console: input: ADB keyboard as /devices/virtual/input/input0
  console: input: ADB mouse as /devices/virtual/input/input1
  console: rtc-generic rtc-generic: registered as rtc0
  console: ledtrig-cpu: registered to indicate activity on CPUs
  [...]
  console: rtc-generic rtc-generic: setting system clock to 2019-09-10T16:20:25 
UTC (1568132425)
  console: List of all partitions:
  console: No filesystem could mount root, tried:
  JOB TIME   : 2.91 s

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Laurent Vivier 
Tested-by: Cleber Rosa 
Reviewed-by: Cleber Rosa 
Message-Id: <20190910163430.11326-1-f4...@amsat.org>
Signed-off-by: Laurent Vivier 
---
 tests/acceptance/boot_linux_console.py | 24 
 1 file changed, 24 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 8a9a314ab4..df27813c78 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -378,3 +378,27 @@ class BootLinuxConsole(Test):
 self.vm.launch()
 console_pattern = 'Kernel command line: %s' % kernel_command_line
 self.wait_for_console_pattern(console_pattern)
+
+def test_m68k_q800(self):
+"""
+:avocado: tags=arch:m68k
+:avocado: tags=machine:q800
+"""
+deb_url = ('http://ftp.ports.debian.org/debian-ports/pool-m68k/main'
+   '/l/linux/kernel-image-5.2.0-2-m68k-di_5.2.9-2_m68k.udeb')
+deb_hash = '0797e05129595f22f3c0142db5e199769a723bf9'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+kernel_path = self.extract_from_deb(deb_path,
+'/boot/vmlinux-5.2.0-2-m68k')
+
+self.vm.set_machine('q800')
+self.vm.set_console()
+kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+   'console=ttyS0 vga=off')
+self.vm.add_args('-kernel', kernel_path,
+ '-append', kernel_command_line)
+self.vm.launch()
+console_pattern = 'Kernel command line: %s' % kernel_command_line
+self.wait_for_console_pattern(console_pattern)
+console_pattern = 'No filesystem could mount root'
+self.wait_for_console_pattern(console_pattern)
-- 
2.21.0




[PATCH v15 10/11] hw/m68k: define Macintosh Quadra 800

2019-10-26 Thread Laurent Vivier
If you want to test the machine, it doesn't yet boot a MacROM, but you can
boot a linux kernel from the command line.

You can install your own disk using debian-installer with:

./qemu-system-m68k \
-M q800 \
-serial none -serial mon:stdio \
-m 1000M -drive file=m68k.qcow2,format=qcow2 \
-net nic,model=dp83932,addr=09:00:07:12:34:57 \
-append "console=ttyS0 vga=off" \
-kernel vmlinux-4.15.0-2-m68k \
-initrd initrd.gz \
-drive file=debian-9.0-m68k-NETINST-1.iso \
-drive file=m68k.qcow2,format=qcow2 \
-nographic

If you use a graphic adapter instead of "-nographic", you can use "-g"
to set the size of the display (I use "-g 1600x800x24").

Tested-by: Philippe Mathieu-Daudé 
Co-developed-by: Mark Cave-Ayland 
Signed-off-by: Mark Cave-Ayland 
Signed-off-by: Laurent Vivier 
---
 hw/m68k/bootinfo.h| 114 
 hw/m68k/q800.c| 401 ++
 MAINTAINERS   |   2 +
 hw/m68k/Kconfig   |   3 +
 hw/m68k/Makefile.objs |   1 +
 5 files changed, 521 insertions(+)
 create mode 100644 hw/m68k/bootinfo.h
 create mode 100644 hw/m68k/q800.c

diff --git a/hw/m68k/bootinfo.h b/hw/m68k/bootinfo.h
new file mode 100644
index 00..5f8ded2686
--- /dev/null
+++ b/hw/m68k/bootinfo.h
@@ -0,0 +1,114 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+ *
+ * Bootinfo tags from linux bootinfo.h and bootinfo-mac.h:
+ * This is an easily parsable and extendable structure containing all
+ * information to be passed from the bootstrap to the kernel
+ *
+ * This structure is copied right after the kernel by the bootstrap
+ * routine.
+ */
+
+#ifndef HW_M68K_BOOTINFO_H
+#define HW_M68K_BOOTINFO_H
+struct bi_record {
+uint16_t tag;/* tag ID */
+uint16_t size;   /* size of record */
+uint32_t data[0];/* data */
+};
+
+/* machine independent tags */
+
+#define BI_LAST 0x /* last record */
+#define BI_MACHTYPE 0x0001 /* machine type (u_long) */
+#define BI_CPUTYPE  0x0002 /* cpu type (u_long) */
+#define BI_FPUTYPE  0x0003 /* fpu type (u_long) */
+#define BI_MMUTYPE  0x0004 /* mmu type (u_long) */
+#define BI_MEMCHUNK 0x0005 /* memory chunk address and size */
+   /* (struct mem_info) */
+#define BI_RAMDISK  0x0006 /* ramdisk address and size */
+   /* (struct mem_info) */
+#define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */
+   /* (string) */
+
+/*  Macintosh-specific tags (all u_long) */
+
+#define BI_MAC_MODEL0x8000  /* Mac Gestalt ID (model type) */
+#define BI_MAC_VADDR0x8001  /* Mac video base address */
+#define BI_MAC_VDEPTH   0x8002  /* Mac video depth */
+#define BI_MAC_VROW 0x8003  /* Mac video rowbytes */
+#define BI_MAC_VDIM 0x8004  /* Mac video dimensions */
+#define BI_MAC_VLOGICAL 0x8005  /* Mac video logical base */
+#define BI_MAC_SCCBASE  0x8006  /* Mac SCC base address */
+#define BI_MAC_BTIME0x8007  /* Mac boot time */
+#define BI_MAC_GMTBIAS  0x8008  /* Mac GMT timezone offset */
+#define BI_MAC_MEMSIZE  0x8009  /* Mac RAM size (sanity check) */
+#define BI_MAC_CPUID0x800a  /* Mac CPU type (sanity check) */
+#define BI_MAC_ROMBASE  0x800b  /* Mac system ROM base address */
+
+/*  Macintosh hardware profile data */
+
+#define BI_MAC_VIA1BASE 0x8010  /* Mac VIA1 base address (always present) */
+#define BI_MAC_VIA2BASE 0x8011  /* Mac VIA2 base address (type varies) */
+#define BI_MAC_VIA2TYPE 0x8012  /* Mac VIA2 type (VIA, RBV, OSS) */
+#define BI_MAC_ADBTYPE  0x8013  /* Mac ADB interface type */
+#define BI_MAC_ASCBASE  0x8014  /* Mac Apple Sound Chip base address */
+#define BI_MAC_SCSI5380 0x8015  /* Mac NCR 5380 SCSI (base address, multi) */
+#define BI_MAC_SCSIDMA  0x8016  /* Mac SCSI DMA (base address) */
+#define BI_MAC_SCSI5396 0x8017  /* Mac NCR 53C96 SCSI (base address, multi) */
+#define BI_MAC_IDETYPE  0x8018  /* Mac IDE interface type */
+#define BI_MAC_IDEBASE  0x8019  /* Mac IDE interface base address */
+#define BI_MAC_NUBUS0x801a  /* Mac Nubus type (none, regular, pseudo) */
+#define BI_MAC_SLOTMASK 0x801b  /* Mac Nubus slots present */
+#define BI_MAC_SCCTYPE  0x801c  /* Mac SCC serial type (normal, IOP) */
+#define BI_MAC_ETHTYPE  0x801d  /* Mac builtin ethernet type (Sonic, MACE */
+#define BI_MAC_ETHBASE  0x801e  /* Mac builtin ethernet base address */
+#define BI_MAC_PMU  0x801f  /* Mac power management / poweroff hardware */
+#define BI_MAC_IOP_SWIM 0x8020  /* Mac SWIM floppy IOP */
+#define BI_MAC_IOP_ADB  0x8021  /* Mac ADB IOP */
+
+#define BOOTINFO0(as, base, id) \
+do { \
+stw_phys(as, base, id); \
+base += 2; \
+stw_phys(as, base, sizeof(struct bi_record)); \
+base += 2; \
+} while (0)
+
+#define BOOTINFO1(as, base, id, value) \
+do { \
+stw_phys(as, base, id); \
+base += 2; \
+stw_phys(as, base, sizeof(struct 

[PATCH v15 03/11] esp: add pseudo-DMA as used by Macintosh

2019-10-26 Thread Laurent Vivier
There is no DMA in Quadra 800, so the CPU reads/writes the data from the
PDMA register (offset 0x100, ESP_PDMA in hw/m68k/q800.c) and copies them
to/from the memory.

There is a nice assembly loop in the kernel to do that, see
linux/drivers/scsi/mac_esp.c:MAC_ESP_PDMA_LOOP().

The start of the transfer is triggered by the DREQ interrupt (see linux
mac_esp_send_pdma_cmd()), the CPU polls on the IRQ flag to start the
transfer after a SCSI command has been sent (in Quadra 800 it goes
through the VIA2, the via2-irq line and the vIFR register)

The Macintosh hardware includes hardware handshaking to prevent the CPU
from reading invalid data or writing data faster than the peripheral
device can accept it.

This is the "blind mode", and from the doc:
"Approximate maximum SCSI transfer rates within a blocks are 1.4 MB per
second for blind transfers in the Macintosh II"

Some references can be found in:
  Apple Macintosh Family Hardware Reference, ISBN 0-201-19255-1
  Guide to the Macintosh Family Hardware, ISBN-0-201-52405-8

Acked-by: Dr. David Alan Gilbert 
Co-developed-by: Mark Cave-Ayland 
Signed-off-by: Mark Cave-Ayland 
Signed-off-by: Laurent Vivier 
---
 include/hw/scsi/esp.h |  15 +++
 hw/scsi/esp.c | 278 --
 2 files changed, 284 insertions(+), 9 deletions(-)

diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index adab63d1c9..6ba47dac41 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -14,10 +14,18 @@ typedef void (*ESPDMAMemoryReadWriteFunc)(void *opaque, 
uint8_t *buf, int len);
 
 typedef struct ESPState ESPState;
 
+enum pdma_origin_id {
+PDMA,
+TI,
+CMD,
+ASYNC,
+};
+
 struct ESPState {
 uint8_t rregs[ESP_REGS];
 uint8_t wregs[ESP_REGS];
 qemu_irq irq;
+qemu_irq irq_data;
 uint8_t chip_id;
 bool tchi_written;
 int32_t ti_size;
@@ -48,6 +56,12 @@ struct ESPState {
 ESPDMAMemoryReadWriteFunc dma_memory_write;
 void *dma_opaque;
 void (*dma_cb)(ESPState *s);
+uint8_t pdma_buf[32];
+int pdma_origin;
+uint32_t pdma_len;
+uint32_t pdma_start;
+uint32_t pdma_cur;
+void (*pdma_cb)(ESPState *s);
 };
 
 #define TYPE_ESP "esp"
@@ -59,6 +73,7 @@ typedef struct {
 /*< public >*/
 
 MemoryRegion iomem;
+MemoryRegion pdma;
 uint32_t it_shift;
 ESPState esp;
 } SysBusESPState;
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 0230ede21d..f8fc30cccb 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -38,6 +38,8 @@
  * 
http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
  * and
  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
+ *
+ * On Macintosh Quadra it is a NCR53C96.
  */
 
 static void esp_raise_irq(ESPState *s)
@@ -58,6 +60,16 @@ static void esp_lower_irq(ESPState *s)
 }
 }
 
+static void esp_raise_drq(ESPState *s)
+{
+qemu_irq_raise(s->irq_data);
+}
+
+static void esp_lower_drq(ESPState *s)
+{
+qemu_irq_lower(s->irq_data);
+}
+
 void esp_dma_enable(ESPState *s, int irq, int level)
 {
 if (level) {
@@ -84,6 +96,30 @@ void esp_request_cancelled(SCSIRequest *req)
 }
 }
 
+static void set_pdma(ESPState *s, enum pdma_origin_id origin,
+ uint32_t index, uint32_t len)
+{
+s->pdma_origin = origin;
+s->pdma_start = index;
+s->pdma_cur = index;
+s->pdma_len = len;
+}
+
+static uint8_t *get_pdma_buf(ESPState *s)
+{
+switch (s->pdma_origin) {
+case PDMA:
+return s->pdma_buf;
+case TI:
+return s->ti_buf;
+case CMD:
+return s->cmdbuf;
+case ASYNC:
+return s->async_buf;
+}
+return NULL;
+}
+
 static int get_cmd_cb(ESPState *s)
 {
 int target;
@@ -125,7 +161,14 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t 
buflen)
 if (dmalen > buflen) {
 return 0;
 }
-s->dma_memory_read(s->dma_opaque, buf, dmalen);
+if (s->dma_memory_read) {
+s->dma_memory_read(s->dma_opaque, buf, dmalen);
+} else {
+memcpy(s->pdma_buf, buf, dmalen);
+set_pdma(s, PDMA, 0, dmalen);
+esp_raise_drq(s);
+return 0;
+}
 } else {
 dmalen = s->ti_size;
 if (dmalen > TI_BUFSZ) {
@@ -177,6 +220,16 @@ static void do_cmd(ESPState *s, uint8_t *buf)
 do_busid_cmd(s, &buf[1], busid);
 }
 
+static void satn_pdma_cb(ESPState *s)
+{
+if (get_cmd_cb(s) < 0) {
+return;
+}
+if (s->pdma_cur != s->pdma_start) {
+do_cmd(s, get_pdma_buf(s) + s->pdma_start);
+}
+}
+
 static void handle_satn(ESPState *s)
 {
 uint8_t buf[32];
@@ -186,11 +239,22 @@ static void handle_satn(ESPState *s)
 s->dma_cb = handle_satn;
 return;
 }
+s->pdma_cb = satn_pdma_cb;
 len = get_cmd(s, buf, sizeof(buf));
 if (len)
 do_cmd(s, buf);
 }
 
+static void s_without_satn_pdma_cb(ESPState *s)
+{
+if (get_cmd_cb(s) < 0) {
+retu

[PATCH v15 09/11] hw/m68k: add a dummy SWIM floppy controller

2019-10-26 Thread Laurent Vivier
SWIM (Sander-Wozniak Integrated Machine) is the floppy controller of
the 680x0 Macintosh.

This patch introduces only the basic support: it allows to switch from
IWM (Integrated WOZ Machine) mode to the SWIM mode and makes the linux
driver happy.

It cannot read any floppy image.

Co-developed-by: Mark Cave-Ayland 
Signed-off-by: Mark Cave-Ayland 
Signed-off-by: Laurent Vivier 
Reviewed-by: Hervé Poussineau 
---
 include/hw/block/swim.h |  76 +++
 hw/block/swim.c | 489 
 MAINTAINERS |   2 +
 hw/block/Kconfig|   3 +
 hw/block/Makefile.objs  |   1 +
 hw/m68k/Kconfig |   1 +
 6 files changed, 572 insertions(+)
 create mode 100644 include/hw/block/swim.h
 create mode 100644 hw/block/swim.c

diff --git a/include/hw/block/swim.h b/include/hw/block/swim.h
new file mode 100644
index 00..6add3499d0
--- /dev/null
+++ b/include/hw/block/swim.h
@@ -0,0 +1,76 @@
+/*
+ * QEMU Macintosh floppy disk controller emulator (SWIM)
+ *
+ * Copyright (c) 2014-2018 Laurent Vivier 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef SWIM_H
+#define SWIM_H
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+
+#define SWIM_MAX_FD2
+
+typedef struct SWIMDrive SWIMDrive;
+typedef struct SWIMBus SWIMBus;
+typedef struct SWIMCtrl SWIMCtrl;
+
+#define TYPE_SWIM_DRIVE "swim-drive"
+#define SWIM_DRIVE(obj) OBJECT_CHECK(SWIMDrive, (obj), TYPE_SWIM_DRIVE)
+
+struct SWIMDrive {
+DeviceState qdev;
+int32_t unit;
+BlockConf   conf;
+};
+
+#define TYPE_SWIM_BUS "swim-bus"
+#define SWIM_BUS(obj) OBJECT_CHECK(SWIMBus, (obj), TYPE_SWIM_BUS)
+
+struct SWIMBus {
+BusState bus;
+struct SWIMCtrl *ctrl;
+};
+
+typedef struct FDrive {
+SWIMCtrl *swimctrl;
+BlockBackend *blk;
+BlockConf *conf;
+} FDrive;
+
+struct SWIMCtrl {
+MemoryRegion iomem;
+FDrive drives[SWIM_MAX_FD];
+int mode;
+/* IWM mode */
+int iwm_switch;
+uint16_t regs[8];
+#define IWM_PH0   0
+#define IWM_PH1   1
+#define IWM_PH2   2
+#define IWM_PH3   3
+#define IWM_MTR   4
+#define IWM_DRIVE 5
+#define IWM_Q66
+#define IWM_Q77
+uint8_t iwm_data;
+uint8_t iwm_mode;
+/* SWIM mode */
+uint8_t swim_phase;
+uint8_t swim_mode;
+SWIMBus bus;
+};
+
+#define TYPE_SWIM "swim"
+#define SWIM(obj) OBJECT_CHECK(SWIM, (obj), TYPE_SWIM)
+
+typedef struct SWIM {
+SysBusDevice parent_obj;
+SWIMCtrl ctrl;
+} SWIM;
+#endif
diff --git a/hw/block/swim.c b/hw/block/swim.c
new file mode 100644
index 00..c6d117e89b
--- /dev/null
+++ b/hw/block/swim.c
@@ -0,0 +1,489 @@
+/*
+ * QEMU Macintosh floppy disk controller emulator (SWIM)
+ *
+ * Copyright (c) 2014-2018 Laurent Vivier 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Only the basic support: it allows to switch from IWM (Integrated WOZ
+ * Machine) mode to the SWIM mode and makes the linux driver happy.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "qapi/error.h"
+#include "sysemu/block-backend.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "hw/block/block.h"
+#include "hw/block/swim.h"
+#include "hw/qdev-properties.h"
+
+/* IWM registers */
+
+#define IWM_PH0L0
+#define IWM_PH0H1
+#define IWM_PH1L2
+#define IWM_PH1H3
+#define IWM_PH2L4
+#define IWM_PH2H5
+#define IWM_PH3L6
+#define IWM_PH3H7
+#define IWM_MTROFF  8
+#define IWM_MTRON   9
+#define IWM_INTDRIVE10
+#define IWM_EXTDRIVE11
+#define IWM_Q6L 12
+#define IWM_Q6H 13
+#define IWM_Q7L 14
+#define IWM_Q7H 15
+
+/* SWIM registers */
+
+#define SWIM_WRITE_DATA 0
+#define SWIM_WRITE_MARK 1
+#define SWIM_WRITE_CRC  2
+#define SWIM_WRITE_PARAMETER3
+#define SWIM_WRITE_PHASE4
+#define SWIM_WRITE_SETUP5
+#define SWIM_WRITE_MODE06
+#define SWIM_WRITE_MODE17
+
+#define SWIM_READ_DATA  8
+#define SWIM_READ_MARK  9
+#define SWIM_READ_ERROR 10
+#define SWIM_READ_PARAMETER 11
+#define SWIM_READ_PHASE 12
+#define SWIM_READ_SETUP 13
+#define SWIM_READ_STATUS14
+#define SWIM_READ_HANDSHAKE 15
+
+#define REG_SHIFT   9
+
+#define SWIM_MODE_IWM  0
+#define SWIM_MODE_SWIM 1
+
+/* bits in phase register */
+
+#define SWIM_SEEK_NEGATIVE   0x074
+#define SWIM_STEP0x071
+#define SWIM_MOTOR_ON0x072
+#define SWIM_MOTOR_OFF   0x076
+#define SWIM_INDEX   0x073
+#define SWIM_EJECT   0x077
+#define SWIM_SETMFM  0x171
+#define SWIM_SETGCR  0x175
+#define SWIM_RELAX   0x033
+#def

[PATCH v15 05/11] hw/m68k: add VIA support

2019-10-26 Thread Laurent Vivier
Inside the 680x0 Macintosh, VIA (Versatile Interface Adapter) is used
to interface the keyboard, Mouse, and real-time clock. It also provides
control line for the floppy disk driver, video interface, sound circuitry
and serial interface.

This implementation is based on the MOS6522 object.

Co-developed-by: Mark Cave-Ayland 
Signed-off-by: Mark Cave-Ayland 
Signed-off-by: Laurent Vivier 
Reviewed-by: Hervé Poussineau 
---
 default-configs/m68k-softmmu.mak |   1 +
 include/hw/misc/mac_via.h| 108 +
 hw/misc/mac_via.c| 767 +++
 MAINTAINERS  |   6 +
 hw/m68k/Kconfig  |   4 +
 hw/misc/Kconfig  |   4 +
 hw/misc/Makefile.objs|   1 +
 7 files changed, 891 insertions(+)
 create mode 100644 include/hw/misc/mac_via.h
 create mode 100644 hw/misc/mac_via.c

diff --git a/default-configs/m68k-softmmu.mak b/default-configs/m68k-softmmu.mak
index d67ab8b96d..6629fd2aa3 100644
--- a/default-configs/m68k-softmmu.mak
+++ b/default-configs/m68k-softmmu.mak
@@ -7,3 +7,4 @@ CONFIG_SEMIHOSTING=y
 CONFIG_AN5206=y
 CONFIG_MCF5208=y
 CONFIG_NEXTCUBE=y
+CONFIG_Q800=y
diff --git a/include/hw/misc/mac_via.h b/include/hw/misc/mac_via.h
new file mode 100644
index 00..efc8ef3ce3
--- /dev/null
+++ b/include/hw/misc/mac_via.h
@@ -0,0 +1,108 @@
+/*
+ *
+ * Copyright (c) 2011-2018 Laurent Vivier
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_MISC_MAC_VIA_H
+#define HW_MISC_MAC_VIA_H
+
+#include "exec/memory.h"
+#include "hw/sysbus.h"
+#include "hw/misc/mos6522.h"
+
+
+/* VIA 1 */
+#define VIA1_IRQ_ONE_SECOND_BIT 0
+#define VIA1_IRQ_VBLANK_BIT 1
+#define VIA1_IRQ_ADB_READY_BIT  2
+#define VIA1_IRQ_ADB_DATA_BIT   3
+#define VIA1_IRQ_ADB_CLOCK_BIT  4
+
+#define VIA1_IRQ_NB 8
+
+#define VIA1_IRQ_ONE_SECOND (1 << VIA1_IRQ_ONE_SECOND_BIT)
+#define VIA1_IRQ_VBLANK (1 << VIA1_IRQ_VBLANK_BIT)
+#define VIA1_IRQ_ADB_READY  (1 << VIA1_IRQ_ADB_READY_BIT)
+#define VIA1_IRQ_ADB_DATA   (1 << VIA1_IRQ_ADB_DATA_BIT)
+#define VIA1_IRQ_ADB_CLOCK  (1 << VIA1_IRQ_ADB_CLOCK_BIT)
+
+
+#define TYPE_MOS6522_Q800_VIA1 "mos6522-q800-via1"
+#define MOS6522_Q800_VIA1(obj)  OBJECT_CHECK(MOS6522Q800VIA1State, (obj), \
+TYPE_MOS6522_Q800_VIA1)
+
+typedef struct MOS6522Q800VIA1State {
+/*< private >*/
+MOS6522State parent_obj;
+
+qemu_irq irqs[VIA1_IRQ_NB];
+uint8_t last_b;
+uint8_t PRAM[256];
+
+/* external timers */
+QEMUTimer *one_second_timer;
+int64_t next_second;
+QEMUTimer *VBL_timer;
+int64_t next_VBL;
+} MOS6522Q800VIA1State;
+
+
+/* VIA 2 */
+#define VIA2_IRQ_SCSI_DATA_BIT  0
+#define VIA2_IRQ_SLOT_BIT   1
+#define VIA2_IRQ_UNUSED_BIT 2
+#define VIA2_IRQ_SCSI_BIT   3
+#define VIA2_IRQ_ASC_BIT4
+
+#define VIA2_IRQ_NB 8
+
+#define VIA2_IRQ_SCSI_DATA  (1 << VIA2_IRQ_SCSI_DATA_BIT)
+#define VIA2_IRQ_SLOT   (1 << VIA2_IRQ_SLOT_BIT)
+#define VIA2_IRQ_UNUSED (1 << VIA2_IRQ_SCSI_BIT)
+#define VIA2_IRQ_SCSI   (1 << VIA2_IRQ_UNUSED_BIT)
+#define VIA2_IRQ_ASC(1 << VIA2_IRQ_ASC_BIT)
+
+#define TYPE_MOS6522_Q800_VIA2 "mos6522-q800-via2"
+#define MOS6522_Q800_VIA2(obj)  OBJECT_CHECK(MOS6522Q800VIA2State, (obj), \
+TYPE_MOS6522_Q800_VIA2)
+
+typedef struct MOS6522Q800VIA2State {
+/*< private >*/
+MOS6522State parent_obj;
+} MOS6522Q800VIA2State;
+
+
+#define TYPE_MAC_VIA "mac_via"
+#define MAC_VIA(obj)   OBJECT_CHECK(MacVIAState, (obj), TYPE_MAC_VIA)
+
+typedef struct MacVIAState {
+SysBusDevice busdev;
+
+/* MMIO */
+MemoryRegion mmio;
+MemoryRegion via1mem;
+MemoryRegion via2mem;
+
+/* VIAs */
+MOS6522Q800VIA1State mos6522_via1;
+MOS6522Q800VIA2State mos6522_via2;
+
+/* RTC */
+uint32_t tick_offset;
+
+uint8_t data_out;
+int data_out_cnt;
+uint8_t data_in;
+uint8_t data_in_cnt;
+uint8_t cmd;
+int wprotect;
+int alt;
+
+/* ADB */
+ADBBusState adb_bus;
+} MacVIAState;
+
+#endif
diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
new file mode 100644
index 00..d2da8b8e60
--- /dev/null
+++ b/hw/misc/mac_via.c
@@ -0,0 +1,767 @@
+/*
+ * QEMU m68k Macintosh VIA device support
+ *
+ * Copyright (c) 2011-2018 Laurent Vivier
+ * Copyright (c) 2018 Mark Cave-Ayland
+ *
+ * Some parts from hw/misc/macio/cuda.c
+ *
+ * Copyright (c) 2004-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * some parts from linux-2.6.29, arch/m68k/include/asm/mac_via.h
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "migration/vmstate.h"
+#include "hw/sysbus.h"
+#include "hw/irq.h"
+#include "qemu/timer.h"
+#include "hw/misc/mac_via.h"
+#include

[PATCH v15 07/11] hw/m68k: add Nubus support

2019-10-26 Thread Laurent Vivier
This patch adds basic support for the NuBus bus. This is used by 680x0
Macintosh.

Co-developed-by: Mark Cave-Ayland 
Signed-off-by: Mark Cave-Ayland 
Signed-off-by: Laurent Vivier 
Reviewed-by: Thomas Huth 
---
 include/hw/nubus/mac-nubus-bridge.h |  24 
 include/hw/nubus/nubus.h|  69 +
 hw/nubus/mac-nubus-bridge.c |  45 ++
 hw/nubus/nubus-bridge.c |  34 +
 hw/nubus/nubus-bus.c| 111 ++
 hw/nubus/nubus-device.c | 215 
 MAINTAINERS |   2 +
 hw/Kconfig  |   1 +
 hw/Makefile.objs|   1 +
 hw/m68k/Kconfig |   1 +
 hw/nubus/Kconfig|   2 +
 hw/nubus/Makefile.objs  |   4 +
 12 files changed, 509 insertions(+)
 create mode 100644 include/hw/nubus/mac-nubus-bridge.h
 create mode 100644 include/hw/nubus/nubus.h
 create mode 100644 hw/nubus/mac-nubus-bridge.c
 create mode 100644 hw/nubus/nubus-bridge.c
 create mode 100644 hw/nubus/nubus-bus.c
 create mode 100644 hw/nubus/nubus-device.c
 create mode 100644 hw/nubus/Kconfig
 create mode 100644 hw/nubus/Makefile.objs

diff --git a/include/hw/nubus/mac-nubus-bridge.h 
b/include/hw/nubus/mac-nubus-bridge.h
new file mode 100644
index 00..ce9c789d99
--- /dev/null
+++ b/include/hw/nubus/mac-nubus-bridge.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013-2018 Laurent Vivier 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef HW_NUBUS_MAC_H
+#define HW_NUBUS_MAC_H
+
+#include "hw/nubus/nubus.h"
+
+#define TYPE_MAC_NUBUS_BRIDGE "mac-nubus-bridge"
+#define MAC_NUBUS_BRIDGE(obj) OBJECT_CHECK(MacNubusState, (obj), \
+   TYPE_MAC_NUBUS_BRIDGE)
+
+typedef struct MacNubusState {
+SysBusDevice sysbus_dev;
+
+NubusBus *bus;
+} MacNubusState;
+
+#endif
diff --git a/include/hw/nubus/nubus.h b/include/hw/nubus/nubus.h
new file mode 100644
index 00..a8634e54c5
--- /dev/null
+++ b/include/hw/nubus/nubus.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2013-2018 Laurent Vivier 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef HW_NUBUS_NUBUS_H
+#define HW_NUBUS_NUBUS_H
+
+#include "hw/qdev-properties.h"
+#include "exec/address-spaces.h"
+
+#define NUBUS_SUPER_SLOT_SIZE 0x1000U
+#define NUBUS_SUPER_SLOT_NB   0x9
+
+#define NUBUS_SLOT_SIZE   0x0100
+#define NUBUS_SLOT_NB 0xF
+
+#define NUBUS_FIRST_SLOT  0x9
+#define NUBUS_LAST_SLOT   0xF
+
+#define TYPE_NUBUS_DEVICE "nubus-device"
+#define NUBUS_DEVICE(obj) \
+ OBJECT_CHECK(NubusDevice, (obj), TYPE_NUBUS_DEVICE)
+
+#define TYPE_NUBUS_BUS "nubus-bus"
+#define NUBUS_BUS(obj) OBJECT_CHECK(NubusBus, (obj), TYPE_NUBUS_BUS)
+
+#define TYPE_NUBUS_BRIDGE "nubus-bridge"
+#define NUBUS_BRIDGE(obj) OBJECT_CHECK(NubusBridge, (obj), TYPE_NUBUS_BRIDGE)
+
+typedef struct NubusBus {
+BusState qbus;
+
+MemoryRegion super_slot_io;
+MemoryRegion slot_io;
+
+int current_slot;
+} NubusBus;
+
+typedef struct NubusDevice {
+DeviceState qdev;
+
+int slot_nb;
+MemoryRegion slot_mem;
+
+/* Format Block */
+
+MemoryRegion fblock_io;
+
+uint32_t rom_length;
+uint32_t rom_crc;
+uint8_t rom_rev;
+uint8_t rom_format;
+uint8_t byte_lanes;
+int32_t directory_offset;
+
+/* ROM */
+
+MemoryRegion rom_io;
+const uint8_t *rom;
+} NubusDevice;
+
+void nubus_register_rom(NubusDevice *dev, const uint8_t *rom, uint32_t size,
+int revision, int format, uint8_t byte_lanes);
+
+#endif
diff --git a/hw/nubus/mac-nubus-bridge.c b/hw/nubus/mac-nubus-bridge.c
new file mode 100644
index 00..7c329300b8
--- /dev/null
+++ b/hw/nubus/mac-nubus-bridge.c
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (c) 2013-2018 Laurent Vivier 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/nubus/mac-nubus-bridge.h"
+
+
+static void mac_nubus_bridge_init(Object *obj)
+{
+MacNubusState *s = MAC_NUBUS_BRIDGE(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+s->bus = NUBUS_BUS(qbus_create(TYPE_NUBUS_BUS, DEVICE(s), NULL));
+
+sysbus_init_mmio(sbd, &s->bus->super_slot_io);
+sysbus_init_mmio(sbd, &s->bus->slot_io);
+}
+
+static void mac_nubus_bridge_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->desc = "Nubus bridge";
+}
+
+static const TypeInfo mac_nubus_bridge_info = {
+.name  = TYPE_MAC_NUBUS_BRIDGE,
+.parent= TYPE_NUBUS_BRIDGE,
+.instance_init = mac_nubus_bridge_init,
+.instance_size = sizeof(MacNubusState),
+.class_init= mac_nubu

Re: [PATCH v14 1/9] esp: add pseudo-DMA as used by Macintosh

2019-10-26 Thread Laurent Vivier
Le 25/10/2019 à 16:01, Paolo Bonzini a écrit :
> On 22/10/19 13:17, Laurent Vivier wrote:
>> +if (s->dma_memory_read) {
>> +s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
>> +} else {
>> +set_pdma(s, CMD, s->cmdlen, len);
>> +s->pdma_cb = do_dma_pdma_cb;
>> +esp_raise_drq(s);
>> +return;
>> +}
>> +trace_esp_handle_ti_cmd(s->cmdlen);
>> +s->ti_size = 0;
>> +s->cmdlen = 0;
>> +s->do_cmd = 0;
>> +do_cmd(s, s->cmdbuf);
>>  return;
> 
> Can you explain these lines after s->dma_memory_read?  I suppose they
> are related to
> 
>> -}
>> -if (s->do_cmd) {
>> +} else if (s->do_cmd) {
> 
> If so, it would be nice to make those a separate patch.  Otherwise seems
> okay.

Sent a new series with separate patches for ESP.

Could you have a look?

Thanks,
Laurent




Re: [PATCH] qemu-iotests/iotests.py: improve assert_qmp message

2019-10-26 Thread Vladimir Sementsov-Ogievskiy
26.10.2019 14:29, Philippe Mathieu-Daudé wrote:
> On 10/26/19 12:12 PM, Vladimir Sementsov-Ogievskiy wrote:
>> Make it obvious, from the two values which is found at path and which
>> is expected.
> 
> Maybe:
> 
> "From the two values compared, make it obvious which is found at path, and 
> which is expected."
> 
> Reviewed-by: Philippe Mathieu-Daudé 

Thanks for review and better wording!

> 
>>
>> Signed-off-by: Vladimir Sementsov-Ogievskiy 
>> ---
>>
>> It's a pain, I can never remember it, and checking each time in source
>> code who is who is boring.
>>
>>   tests/qemu-iotests/iotests.py | 4 ++--
>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
>> index 709def4d5d..e805b9ab14 100644
>> --- a/tests/qemu-iotests/iotests.py
>> +++ b/tests/qemu-iotests/iotests.py
>> @@ -729,8 +729,8 @@ class QMPTestCase(unittest.TestCase):
>>   self.fail('no match for "%s" in %s' % (str(result), 
>> str(value)))
>>   else:
>>   self.assertEqual(result, value,
>> - 'values not equal "%s" and "%s"'
>> - % (str(result), str(value)))
>> + '"%s" is "%s", expected "%s"'
>> + % (path, str(result), str(value)))
>>   def assert_no_active_block_jobs(self):
>>   result = self.vm.qmp('query-block-jobs')
>>


-- 
Best regards,
Vladimir


Re: [PATCH] qcow2-bitmap: Fix uint64_t left-shift overflow

2019-10-26 Thread Vladimir Sementsov-Ogievskiy
26.10.2019 12:19, Tuguoyi wrote:
> In check_constraints_on_bitmap(), the sanity check on the
> granularity will cause uint64_t integer left-shift overflow
> when cluster_size is 2M and the granularity is bigger than
> 32K which is even smaller than the default value for a qcow2
> disk with cluster_size set to 64k or bigger. This patch fix
> the issue by right-shift @len instead.
> 
> Signed-off-by: Guoyi Tu 
> ---
>   block/qcow2-bitmap.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
> index 98294a7..2a1d789 100644
> --- a/block/qcow2-bitmap.c
> +++ b/block/qcow2-bitmap.c
> @@ -172,8 +172,8 @@ static int check_constraints_on_bitmap(BlockDriverState 
> *bs,
>   }
> 
>   if ((len > (uint64_t)BME_MAX_PHYS_SIZE << granularity_bits) ||
> -(len > (uint64_t)BME_MAX_TABLE_SIZE * s->cluster_size <<
> -   granularity_bits))

Hmm.
BME_MAX_TABLE_SIZE = 0x800

0x800 * 1024 * 1024 * 2 << 16 = 2 ** 64, so for 64k granularity it 
owerflows..
But for 32k doesn't. Or am I wrong?

Anyway, thanks for fixing!

> +((len >> granularity_bits) > (uint64_t)BME_MAX_TABLE_SIZE *
> +s->cluster_size))

It's a bit incorrect, as len may be unaligned, we need ((len + granularity - 1) 
>> granularity_bits) on the left,
or better DIV_ROUNTD_UP(len, granularity).

>   {
>   error_setg(errp, "Too much space will be occupied by the bitmap. "
>  "Use larger granularity");
> --
> 2.7.4
> -
> 本邮件及其附件含有新华三集团的保密信息,仅限于发送给上面地址中列出
> 的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制、
> 或散发)本邮件中的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本
> 邮件!
> This e-mail and its attachments contain confidential information from New 
> H3C, which is
> intended only for the person or entity whose address is listed above. Any use 
> of the
> information contained herein in any way (including, but not limited to, total 
> or partial
> disclosure, reproduction, or dissemination) by persons other than the intended
> recipient(s) is prohibited. If you receive this e-mail in error, please 
> notify the sender
> by phone or email immediately and delete it!
> 

Not sure that this is possible, as it's automatically available here:
https://lists.gnu.org/archive/html/qemu-devel/2019-10/msg07336.html


-- 
Best regards,
Vladimir


[PATCH] MAINTAINERS: add more bitmap-related to Dirty Bitmaps section

2019-10-26 Thread Vladimir Sementsov-Ogievskiy
Let's add bitmaps persistence qcow2 feature and postcopy bitmaps
migration to Dirty Bitmaps section.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 556ce0bfe3..51f31b4011 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1829,6 +1829,8 @@ F: util/hbitmap.c
 F: block/dirty-bitmap.c
 F: include/qemu/hbitmap.h
 F: include/block/dirty-bitmap.h
+F: qcow2-bitmap.c
+F: migration/block-dirty-bitmap.c
 F: tests/test-hbitmap.c
 F: docs/interop/bitmaps.rst
 T: git https://github.com/jnsnow/qemu.git bitmaps
-- 
2.21.0




Re: [PATCH v15 02/11] esp: move get_cmd() post-DMA code to get_cmd_cb()

2019-10-26 Thread Philippe Mathieu-Daudé

On 10/26/19 6:45 PM, Laurent Vivier wrote:

This will be needed to implement pseudo-DMA

Signed-off-by: Laurent Vivier 


:)

Reviewed-by: Philippe Mathieu-Daudé 


---
  hw/scsi/esp.c | 46 +-
  1 file changed, 29 insertions(+), 17 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 09b28cba17..0230ede21d 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -84,6 +84,34 @@ void esp_request_cancelled(SCSIRequest *req)
  }
  }
  
+static int get_cmd_cb(ESPState *s)

+{
+int target;
+
+target = s->wregs[ESP_WBUSID] & BUSID_DID;
+
+s->ti_size = 0;
+s->ti_rptr = 0;
+s->ti_wptr = 0;
+
+if (s->current_req) {
+/* Started a new command before the old one finished.  Cancel it.  */
+scsi_req_cancel(s->current_req);
+s->async_len = 0;
+}
+
+s->current_dev = scsi_device_find(&s->bus, 0, target, 0);
+if (!s->current_dev) {
+/* No such drive */
+s->rregs[ESP_RSTAT] = 0;
+s->rregs[ESP_RINTR] = INTR_DC;
+s->rregs[ESP_RSEQ] = SEQ_0;
+esp_raise_irq(s);
+return -1;
+}
+return 0;
+}
+
  static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
  {
  uint32_t dmalen;
@@ -108,23 +136,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t 
buflen)
  }
  trace_esp_get_cmd(dmalen, target);
  
-s->ti_size = 0;

-s->ti_rptr = 0;
-s->ti_wptr = 0;
-
-if (s->current_req) {
-/* Started a new command before the old one finished.  Cancel it.  */
-scsi_req_cancel(s->current_req);
-s->async_len = 0;
-}
-
-s->current_dev = scsi_device_find(&s->bus, 0, target, 0);
-if (!s->current_dev) {
-// No such drive
-s->rregs[ESP_RSTAT] = 0;
-s->rregs[ESP_RINTR] = INTR_DC;
-s->rregs[ESP_RSEQ] = SEQ_0;
-esp_raise_irq(s);
+if (get_cmd_cb(s) < 0) {
  return 0;
  }
  return dmalen;





Re: [RFC 2/3] block/file-posix: Detect XFS with CONFIG_FALLOCATE

2019-10-26 Thread Nir Soffer
On Fri, Oct 25, 2019 at 1:22 PM Max Reitz  wrote:
>
> We will need this for the next patch.
>
> Signed-off-by: Max Reitz 
> ---
>  block/file-posix.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 695fcf740d..5cd54c8bff 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -149,7 +149,7 @@ typedef struct BDRVRawState {
>  int perm_change_flags;
>  BDRVReopenState *reopen_state;
>
> -#ifdef CONFIG_XFS
> +#if defined(CONFIG_XFS) || defined(CONFIG_FALLOCATE)
>  bool is_xfs:1;
>  #endif
>  bool has_discard:1;
> @@ -667,7 +667,7 @@ static int raw_open_common(BlockDriverState *bs, QDict 
> *options,
>  }
>  #endif
>
> -#ifdef CONFIG_XFS
> +#if defined(CONFIG_XFS) || defined(CONFIG_FALLOCATE)
>  if (platform_test_xfs_fd(s->fd)) {
>  s->is_xfs = true;

What about remote xfs filesystem, e.g. glusterfs over xfs mounted using fuse?
(how oVirt uses glusterfs)

The buggy behavior with concurrent fallocate/pwrite can affect this, and
platform_test_xfs_fd() will probably fail to detect xfs.

Nir

>  }
> --
> 2.21.0
>
>



Re: [RFC 3/3] block/file-posix: Let post-EOF fallocate serialize

2019-10-26 Thread Nir Soffer
On Fri, Oct 25, 2019 at 1:24 PM Max Reitz  wrote:
>
> The XFS kernel driver has a bug that may cause data corruption for qcow2
> images as of qemu commit c8bb23cbdbe32f.  We can work around it by
> treating post-EOF fallocates as serializing up until infinity (INT64_MAX
> in practice).
>
> Signed-off-by: Max Reitz 
> ---
>  block/file-posix.c | 42 ++
>  1 file changed, 42 insertions(+)
>
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 5cd54c8bff..1f5a01df70 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -2713,6 +2713,48 @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t 
> offset, int bytes,
>  RawPosixAIOData acb;
>  ThreadPoolFunc *handler;
>
> +#ifdef CONFIG_FALLOCATE
> +if (s->is_xfs && s->use_linux_aio &&

This limit the fix to local xfs filesystem, but the fix may be needed
to remote filesystem such
as gluster over xfs.

> +offset + bytes > bs->total_sectors * BDRV_SECTOR_SIZE)
> +{
> +BdrvTrackedRequest *req;
> +uint64_t end;
> +
> +/*
> + * The Linux XFS driver has a bug where it will discard writes
> + * submitted through the AIO interface if they happen beyond a
> + * concurrently running fallocate() that increases the file
> + * length (i.e., both the write and the fallocate() happen
> + * beyond the EOF).
> + *
> + * To work around it, we look for the tracked request for this
> + * zero write, extend it until INT64_MAX (effectively
> + * infinity), and mark it as serializing.
> + *
> + * TODO: Detect whether this has been fixed in the XFS driver.
> + */
> +
> +QLIST_FOREACH(req, &bs->tracked_requests, list) {
> +if (req->co == qemu_coroutine_self() &&
> +req->type == BDRV_TRACKED_WRITE)
> +{
> +break;
> +}
> +}
> +
> +assert(req);
> +assert(req->offset <= offset);
> +assert(req->offset + req->bytes >= offset + bytes);
> +
> +end = INT64_MAX & -(uint64_t)bs->bl.request_alignment;
> +req->bytes = end - req->offset;
> +req->overlap_bytes = req->bytes;
> +
> +bdrv_mark_request_serialising(req, bs->bl.request_alignment);
> +bdrv_wait_serialising_requests(req);
> +}
> +#endif
> +
>  acb = (RawPosixAIOData) {
>  .bs = bs,
>  .aio_fildes = s->fd,
> --
> 2.21.0
>
>



Re: [RFC 0/3] block/file-posix: Work around XFS bug

2019-10-26 Thread Nir Soffer
On Fri, Oct 25, 2019 at 1:11 PM Max Reitz  wrote:
>
> Hi,
>
> It seems to me that there is a bug in Linux’s XFS kernel driver, as
> I’ve explained here:
>
> https://lists.nongnu.org/archive/html/qemu-block/2019-10/msg01429.html
>
> In combination with our commit c8bb23cbdbe32f, this may lead to guest
> data corruption when using qcow2 images on XFS with aio=native.
>
> We can’t wait until the XFS kernel driver is fixed, we should work
> around the problem ourselves.
>
> This is an RFC for two reasons:
> (1) I don’t know whether this is the right way to address the issue,
> (2) Ideally, we should detect whether the XFS kernel driver is fixed and
> if so stop applying the workaround.
> I don’t know how we would go about this, so this series doesn’t do
> it.  (Hence it’s an RFC.)
> (3) Perhaps it’s a bit of a layering violation to let the file-posix
> driver access and modify a BdrvTrackedRequest object.
>
> As for how we can address the issue, I see three ways:
> (1) The one presented in this series: On XFS with aio=native, we extend
> tracked requests for post-EOF fallocate() calls (i.e., write-zero
> operations) to reach until infinity (INT64_MAX in practice), mark
> them serializing and wait for other conflicting requests.
>
> Advantages:
> + Limits the impact to very specific cases
>   (And that means it wouldn’t hurt too much to keep this workaround
>   even when the XFS driver has been fixed)
> + Works around the bug where it happens, namely in file-posix
>
> Disadvantages:
> - A bit complex
> - A bit of a layering violation (should file-posix have access to
>   tracked requests?)
>
> (2) Always skip qcow2’s handle_alloc_space() on XFS.  The XFS bug only
> becomes visible due to that function: I don’t think qcow2 writes
> zeroes in any other I/O path, and raw images are fixed in size so
> post-EOF writes won’t happen.
>
> Advantages:
> + Maybe simpler, depending on how difficult it is to handle the
>   layering violation
> + Also fixes the performance problem of handle_alloc_space() being
>   slow on ppc64+XFS.
>
> Disadvantages:
> - Huge layering violation because qcow2 would need to know whether
>   the image is stored on XFS or not.
> - We’d definitely want to skip this workaround when the XFS driver
>   has been fixed, so we need some method to find out whether it has
>
> (3) Drop handle_alloc_space(), i.e. revert c8bb23cbdbe32f.
> To my knowledge I’m the only one who has provided any benchmarks for
> this commit, and even then I was a bit skeptical because it performs
> well in some cases and bad in others.  I concluded that it’s
> probably worth it because the “some cases” are more likely to occur.
>
> Now we have this problem of corruption here (granted due to a bug in
> the XFS driver), and another report of massively degraded
> performance on ppc64
> (https://bugzilla.redhat.com/show_bug.cgi?id=1745823 – sorry, a
> private BZ; I hate that :-/  The report is about 40 % worse
> performance for an in-guest fio write benchmark.)
>
> So I have to ask the question about what the justification for
> keeping c8bb23cbdbe32f is.  How much does performance increase with
> it actually?  (On non-(ppc64+XFS) machines, obviously)
>
> Advantages:
> + Trivial
> + No layering violations
> + We wouldn’t need to keep track of whether the kernel bug has been
>   fixed or not
> + Fixes the ppc64+XFS performance problem
>
> Disadvantages:
> - Reverts cluster allocation performance to pre-c8bb23cbdbe32f
>   levels, whatever that means

Correctness is more important than performance, so this is my
preference as a user.

Nir

> So this is the main reason this is an RFC: What should we do?  Is (1)
> really the best choice?
>
>
> In any case, I’ve ran the test case I showed in
> https://lists.nongnu.org/archive/html/qemu-block/2019-10/msg01282.html
> more than ten times with this series applied and the installation
> succeeded every time.  (Without this series, it fails like every other
> time.)
>
>
> Max Reitz (3):
>   block: Make wait/mark serialising requests public
>   block/file-posix: Detect XFS with CONFIG_FALLOCATE
>   block/file-posix: Let post-EOF fallocate serialize
>
>  include/block/block_int.h |  3 +++
>  block/file-posix.c| 46 +--
>  block/io.c| 24 ++--
>  3 files changed, 59 insertions(+), 14 deletions(-)
>
> --
> 2.21.0
>
>



Re: [RFC 0/3] block/file-posix: Work around XFS bug

2019-10-26 Thread Vladimir Sementsov-Ogievskiy
26.10.2019 20:37, Nir Soffer wrote:
> On Fri, Oct 25, 2019 at 1:11 PM Max Reitz  wrote:
>>
>> Hi,
>>
>> It seems to me that there is a bug in Linux’s XFS kernel driver, as
>> I’ve explained here:
>>
>> https://lists.nongnu.org/archive/html/qemu-block/2019-10/msg01429.html
>>
>> In combination with our commit c8bb23cbdbe32f, this may lead to guest
>> data corruption when using qcow2 images on XFS with aio=native.
>>
>> We can’t wait until the XFS kernel driver is fixed, we should work
>> around the problem ourselves.
>>
>> This is an RFC for two reasons:
>> (1) I don’t know whether this is the right way to address the issue,
>> (2) Ideally, we should detect whether the XFS kernel driver is fixed and
>>  if so stop applying the workaround.
>>  I don’t know how we would go about this, so this series doesn’t do
>>  it.  (Hence it’s an RFC.)
>> (3) Perhaps it’s a bit of a layering violation to let the file-posix
>>  driver access and modify a BdrvTrackedRequest object.
>>
>> As for how we can address the issue, I see three ways:
>> (1) The one presented in this series: On XFS with aio=native, we extend
>>  tracked requests for post-EOF fallocate() calls (i.e., write-zero
>>  operations) to reach until infinity (INT64_MAX in practice), mark
>>  them serializing and wait for other conflicting requests.
>>
>>  Advantages:
>>  + Limits the impact to very specific cases
>>(And that means it wouldn’t hurt too much to keep this workaround
>>even when the XFS driver has been fixed)
>>  + Works around the bug where it happens, namely in file-posix
>>
>>  Disadvantages:
>>  - A bit complex
>>  - A bit of a layering violation (should file-posix have access to
>>tracked requests?)
>>
>> (2) Always skip qcow2’s handle_alloc_space() on XFS.  The XFS bug only
>>  becomes visible due to that function: I don’t think qcow2 writes
>>  zeroes in any other I/O path, and raw images are fixed in size so
>>  post-EOF writes won’t happen.
>>
>>  Advantages:
>>  + Maybe simpler, depending on how difficult it is to handle the
>>layering violation
>>  + Also fixes the performance problem of handle_alloc_space() being
>>slow on ppc64+XFS.
>>
>>  Disadvantages:
>>  - Huge layering violation because qcow2 would need to know whether
>>the image is stored on XFS or not.
>>  - We’d definitely want to skip this workaround when the XFS driver
>>has been fixed, so we need some method to find out whether it has
>>
>> (3) Drop handle_alloc_space(), i.e. revert c8bb23cbdbe32f.
>>  To my knowledge I’m the only one who has provided any benchmarks for
>>  this commit, and even then I was a bit skeptical because it performs
>>  well in some cases and bad in others.  I concluded that it’s
>>  probably worth it because the “some cases” are more likely to occur.
>>
>>  Now we have this problem of corruption here (granted due to a bug in
>>  the XFS driver), and another report of massively degraded
>>  performance on ppc64
>>  (https://bugzilla.redhat.com/show_bug.cgi?id=1745823 – sorry, a
>>  private BZ; I hate that :-/  The report is about 40 % worse
>>  performance for an in-guest fio write benchmark.)
>>
>>  So I have to ask the question about what the justification for
>>  keeping c8bb23cbdbe32f is.  How much does performance increase with
>>  it actually?  (On non-(ppc64+XFS) machines, obviously)
>>
>>  Advantages:
>>  + Trivial
>>  + No layering violations
>>  + We wouldn’t need to keep track of whether the kernel bug has been
>>fixed or not
>>  + Fixes the ppc64+XFS performance problem
>>
>>  Disadvantages:
>>  - Reverts cluster allocation performance to pre-c8bb23cbdbe32f
>>levels, whatever that means
> 
> Correctness is more important than performance, so this is my
> preference as a user.
> 

Hmm, still, incorrect is XFS, not Qemu. This bug may be triggered by another
software, or may be another scenario in Qemu (not sure).

> 
>> So this is the main reason this is an RFC: What should we do?  Is (1)
>> really the best choice?
>>
>>
>> In any case, I’ve ran the test case I showed in
>> https://lists.nongnu.org/archive/html/qemu-block/2019-10/msg01282.html
>> more than ten times with this series applied and the installation
>> succeeded every time.  (Without this series, it fails like every other
>> time.)
>>
>>
>> Max Reitz (3):
>>block: Make wait/mark serialising requests public
>>block/file-posix: Detect XFS with CONFIG_FALLOCATE
>>block/file-posix: Let post-EOF fallocate serialize
>>
>>   include/block/block_int.h |  3 +++
>>   block/file-posix.c| 46 +--
>>   block/io.c| 24 ++--
>>   3 files changed, 59 insertions(+), 14 deletions(-)
>>
>> --
>> 2.21.0
>>
>>


-- 
Best regards,
Vladimir


Re: [PATCH v3 5/6] hppa: Add emulation of Artist graphics

2019-10-26 Thread Sven Schnelle
Hi Mark,

On Sat, Oct 26, 2019 at 10:35:20AM +0100, Mark Cave-Ayland wrote:

> > However, the VRAM in Artist is not really exposed to the Host. Instead,
> > there's the Chipset inbetween that can do byte swapping (Colormap is LE,
> > VRAM is BE) and Bit-to-Byte/Word/Dword conversion. For example you could
> > write 0x55 into that VRAM region, and the chipset would expand that to
> > VRAM Bytes: 00 01 00 01 00 01 00 01. And to make it even worse emulation
> > wise it can also do different encodings for Read or Write accesses, and
> > mask out certain bits of the data. So after trying to convert it to the
> > "dirty bitmap" API i decided to just leave it as it is. The CPU load
> > used by the display update code is usually < 1%, so it's ok for me.
> 
> Wow that sounds that some interesting hardware(!). Does it make sense to 
> model the
> behaviour of the chipset separately using a proxy MemoryRegion similar to 
> virtio i.e.
> introduce an intermediate IO MemoryRegion that does the swapping and then 
> forward it
> onto the VRAM MemoryRegion?

Thanks for the pointer, i'll check whether that would work. For now i
think i'll remove the Artist patch from the series, so we can apply the
other patches, and i'll re-submit Artist when it's done. I guess the
rewrite to use a MemRegion is a bit bigger. But i would to get the other
patches in especially the LASI Stuff as both Helge and i have a lot of
stuff depending on that.

Regards
Sven



[PATCH v3 01/20] MAINTAINERS: Keep PIIX4 South Bridge separate from PC Chipsets

2019-10-26 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

The PIIX4 Southbridge is not used by the PC machine,
but by the Malta board (MIPS). Add a new section to
keep it covered.

Suggested-by: Michael S. Tsirkin 
Reviewed-by: Aleksandar Markovic 
Reviewed-by: Li Qiang 
Signed-off-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 42e702f346..1f04502fac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1230,7 +1230,6 @@ F: hw/pci-host/q35.c
 F: hw/pci-host/pam.c
 F: include/hw/pci-host/q35.h
 F: include/hw/pci-host/pam.h
-F: hw/isa/piix4.c
 F: hw/isa/lpc_ich9.c
 F: hw/i2c/smbus_ich9.c
 F: hw/acpi/piix4.c
@@ -1730,6 +1729,12 @@ F: hw/display/edid*
 F: include/hw/display/edid.h
 F: qemu-edid.c
 
+PIIX4 South Bridge (i82371AB)
+M: Hervé Poussineau 
+M: Philippe Mathieu-Daudé 
+S: Maintained
+F: hw/isa/piix4.c
+
 Firmware configuration (fw_cfg)
 M: Philippe Mathieu-Daudé 
 R: Laszlo Ersek 
-- 
2.21.0




[PATCH v3 04/20] Revert "irq: introduce qemu_irq_proxy()"

2019-10-26 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

This function isn't used anymore.

This reverts commit 22ec3283efba9ba0792790da786d6776d83f2a92.

Reviewed-by: Thomas Huth 
Reviewed-by: Li Qiang 
Reviewed-by: Esteban Bosse 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/core/irq.c| 14 --
 include/hw/irq.h |  5 -
 2 files changed, 19 deletions(-)

diff --git a/hw/core/irq.c b/hw/core/irq.c
index 7cc0295d0e..fb3045b912 100644
--- a/hw/core/irq.c
+++ b/hw/core/irq.c
@@ -120,20 +120,6 @@ qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2)
 return qemu_allocate_irq(qemu_splitirq, s, 0);
 }
 
-static void proxy_irq_handler(void *opaque, int n, int level)
-{
-qemu_irq **target = opaque;
-
-if (*target) {
-qemu_set_irq((*target)[n], level);
-}
-}
-
-qemu_irq *qemu_irq_proxy(qemu_irq **target, int n)
-{
-return qemu_allocate_irqs(proxy_irq_handler, target, n);
-}
-
 void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
 {
 int i;
diff --git a/include/hw/irq.h b/include/hw/irq.h
index fe527f6f51..24ba0ece11 100644
--- a/include/hw/irq.h
+++ b/include/hw/irq.h
@@ -51,11 +51,6 @@ qemu_irq qemu_irq_invert(qemu_irq irq);
  */
 qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
 
-/* Returns a new IRQ set which connects 1:1 to another IRQ set, which
- * may be set later.
- */
-qemu_irq *qemu_irq_proxy(qemu_irq **target, int n);
-
 /* For internal use in qtest.  Similar to qemu_irq_split, but operating
on an existing vector of qemu_irq.  */
 void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
-- 
2.21.0




[PATCH v3 00/20] hw/i386/pc: Split PIIX3 southbridge from i440FX northbridge

2019-10-26 Thread Philippe Mathieu-Daudé
Changes since v2 [0]:
- Use a #define
- Reword one description
- Added review tags (thanks all for reviewing!)

Changes since v1 [1]:
- Removed patch reintroducing DO_UPCAST() use (thuth)
- Took various patches out to reduce series (thuth)
- Added review tags (thanks all for reviewing!)

$ git backport-diff -u pc_split_i440fx_piix-v2
Key:
[] : patches are identical
[] : number of functional differences between upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively

001/20:[] [--] 'MAINTAINERS: Keep PIIX4 South Bridge separate from PC 
Chipsets'
002/20:[0004] [FC] 'piix4: Add the Reset Control Register'
003/20:[0002] [FC] 'piix4: Add an i8259 Interrupt Controller as specified in 
datasheet'
004/20:[] [--] 'Revert "irq: introduce qemu_irq_proxy()"'
005/20:[] [--] 'piix4: Rename PIIX4 object to piix4-isa'
006/20:[] [--] 'piix4: Add an i8257 DMA Controller as specified in 
datasheet'
007/20:[] [-C] 'piix4: Add an i8254 PIT Controller as specified in 
datasheet'
008/20:[0004] [FC] 'piix4: Add a MC146818 RTC Controller as specified in 
datasheet'
009/20:[] [--] 'hw/mips/mips_malta: Create IDE hard drive array dynamically'
010/20:[] [--] 'hw/mips/mips_malta: Extract the PIIX4 creation code as 
piix4_create()'
011/20:[] [-C] 'hw/isa/piix4: Move piix4_create() to hw/isa/piix4.c'
012/20:[] [--] 'hw/i386: Remove obsolete LoadStateHandler::load_state_old 
handlers'
013/20:[] [--] 'hw/pci-host/piix: Extract piix3_create()'
014/20:[0002] [FC] 'hw/pci-host/piix: Move RCR_IOPORT register definition'
015/20:[] [--] 'hw/pci-host/piix: Define and use the PIIX IRQ Route Control 
Registers'
016/20:[] [-C] 'hw/pci-host/piix: Move i440FX declarations to 
hw/pci-host/i440fx.h'
017/20:[] [--] 'hw/pci-host/piix: Fix code style issues'
018/20:[] [--] 'hw/pci-host/piix: Extract PIIX3 functions to hw/isa/piix3.c'
019/20:[] [--] 'hw/pci-host: Rename incorrectly named 'piix' as 'i440fx''
020/20:[0004] [FC] 'hw/pci-host/i440fx: Remove the last PIIX3 traces'

Previous cover:

This series is a rework of "piix4: cleanup and improvements" [2]
from Hervé, and my "remove i386/pc dependency: PIIX cleanup" [3].

Still trying to remove the strong X86/PC dependency 2 years later,
one step at a time.
Here we split the PIIX3 southbridge from i440FX northbridge.
The i440FX northbridge is only used by the PC machine, while the
PIIX southbridge is also used by the Malta MIPS machine.

This is also a step forward using KConfig with the Malta board.
Without this split, it was impossible to compile the Malta without
pulling various X86 pieces of code.

The overall design cleanup is not yet perfect, but enough to post
as a series.

Now that the PIIX3 code is extracted, the code duplication with the
PIIX4 chipset is obvious. Not worth improving for now because it
isn't broken.

Based-on: <1572097538-18898-1-git-send-email-pbonz...@redhat.com>
to include:
mc146818rtc: Allow call object_initialize(MC146818_RTC) instead of rtc_init()
20191018133547.10936-1-philmd@redhat.com">https://mid.mail-archive.com/20191018133547.10936-1-philmd@redhat.com

Since Aleksandar offered me to send the pull request [4] I plan to do
it once Paolo's pull [5] is merged.

Thanks,

Phil.

CI results:
https://travis-ci.org/philmd/qemu/builds/603253987
https://app.shippable.com/github/philmd/qemu/runs/550/summary/console

[0] https://lists.gnu.org/archive/html/qemu-devel/2019-10/msg04662.html
[1] https://lists.gnu.org/archive/html/qemu-devel/2019-10/msg03685.html
[2] https://www.mail-archive.com/qemu-devel@nongnu.org/msg500737.html
[3] https://www.mail-archive.com/qemu-devel@nongnu.org/msg504081.html
[4] https://lists.gnu.org/archive/html/qemu-devel/2019-10/msg04959.html
[5] https://lists.gnu.org/archive/html/qemu-devel/2019-10/msg07339.html

Hervé Poussineau (5):
  piix4: Add the Reset Control Register
  piix4: Add an i8259 Interrupt Controller as specified in datasheet
  piix4: Rename PIIX4 object to piix4-isa
  piix4: Add an i8257 DMA Controller as specified in datasheet
  piix4: Add an i8254 PIT Controller as specified in datasheet

Philippe Mathieu-Daudé (15):
  MAINTAINERS: Keep PIIX4 South Bridge separate from PC Chipsets
  Revert "irq: introduce qemu_irq_proxy()"
  piix4: Add a MC146818 RTC Controller as specified in datasheet
  hw/mips/mips_malta: Create IDE hard drive array dynamically
  hw/mips/mips_malta: Extract the PIIX4 creation code as piix4_create()
  hw/isa/piix4: Move piix4_create() to hw/isa/piix4.c
  hw/i386: Remove obsolete LoadStateHandler::load_state_old handlers
  hw/pci-host/piix: Extract piix3_create()
  hw/pci-host/piix: Move RCR_IOPORT register definition
  hw/pci-host/piix: Define and use the PIIX IRQ Route Control Registers
  hw/pci-host/piix: Move i440FX declarations to hw/pci-host/i440fx.h
  hw/pci-host/piix: Fix code style issues
  hw/pci-host/piix: Extract PIIX3 functions to hw/isa/piix3.c
  hw/pci-ho

[PATCH v3 11/20] hw/isa/piix4: Move piix4_create() to hw/isa/piix4.c

2019-10-26 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Now that we properly refactored the piix4_create() function, let's
move it to hw/isa/piix4.c where it belongs, so it can be reused
on other places.

Reviewed-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix4.c| 30 ++
 hw/mips/gt64xxx_pci.c |  1 +
 hw/mips/mips_malta.c  | 28 
 include/hw/i386/pc.h  |  2 --
 include/hw/southbridge/piix.h |  6 ++
 5 files changed, 37 insertions(+), 30 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 6bf6f0c5d9..f3e21ea76d 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -27,12 +27,14 @@
 #include "qapi/error.h"
 #include "hw/irq.h"
 #include "hw/i386/pc.h"
+#include "hw/southbridge/piix.h"
 #include "hw/pci/pci.h"
 #include "hw/isa/isa.h"
 #include "hw/sysbus.h"
 #include "hw/dma/i8257.h"
 #include "hw/timer/i8254.h"
 #include "hw/rtc/mc146818rtc.h"
+#include "hw/ide.h"
 #include "migration/vmstate.h"
 #include "sysemu/reset.h"
 #include "sysemu/runstate.h"
@@ -237,3 +239,31 @@ static void piix4_register_types(void)
 }
 
 type_init(piix4_register_types)
+
+DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus,
+  I2CBus **smbus, size_t ide_buses)
+{
+size_t ide_drives = ide_buses * MAX_IDE_DEVS;
+DriveInfo **hd;
+PCIDevice *pci;
+DeviceState *dev;
+
+pci = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0),
+  true, TYPE_PIIX4_PCI_DEVICE);
+dev = DEVICE(pci);
+if (isa_bus) {
+*isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
+}
+
+hd = g_new(DriveInfo *, ide_drives);
+ide_drive_get(hd, ide_drives);
+pci_piix4_ide_init(pci_bus, hd, pci->devfn + 1);
+g_free(hd);
+pci_create_simple(pci_bus, pci->devfn + 2, "piix4-usb-uhci");
+if (smbus) {
+*smbus = piix4_pm_init(pci_bus, pci->devfn + 3, 0x1100,
+   isa_get_irq(NULL, 9), NULL, 0, NULL);
+   }
+
+return dev;
+}
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index f325bd6c1c..c277398c0d 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -28,6 +28,7 @@
 #include "hw/mips/mips.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_host.h"
+#include "hw/southbridge/piix.h"
 #include "migration/vmstate.h"
 #include "hw/i386/pc.h"
 #include "hw/irq.h"
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 9014d77b7a..92e9ca5bfa 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1210,34 +1210,6 @@ static void mips_create_cpu(MachineState *ms, MaltaState 
*s,
 }
 }
 
-static DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus,
- I2CBus **smbus, size_t ide_buses)
-{
-const size_t ide_drives = ide_buses * MAX_IDE_DEVS;
-DriveInfo **hd;
-PCIDevice *pci;
-DeviceState *dev;
-
-pci = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0),
-  true, TYPE_PIIX4_PCI_DEVICE);
-dev = DEVICE(pci);
-if (isa_bus) {
-*isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
-}
-
-hd = g_new(DriveInfo *, ide_drives);
-ide_drive_get(hd, ide_drives);
-pci_piix4_ide_init(pci_bus, hd, pci->devfn + 1);
-g_free(hd);
-pci_create_simple(pci_bus, pci->devfn + 2, "piix4-usb-uhci");
-if (smbus) {
-*smbus = piix4_pm_init(pci_bus, pci->devfn + 3, 0x1100,
-   isa_get_irq(NULL, 9), NULL, 0, NULL);
-   }
-
-return dev;
-}
-
 static
 void mips_malta_init(MachineState *machine)
 {
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index c933c0d3a1..2fd40ceebe 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -258,8 +258,6 @@ PCIBus *i440fx_init(const char *host_type, const char 
*pci_type,
 MemoryRegion *ram_memory);
 
 PCIBus *find_i440fx(void);
-/* piix4.c */
-extern PCIDevice *piix4_dev;
 
 /* pc_sysfw.c */
 void pc_system_flash_create(PCMachineState *pcms);
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index b8ce26fec4..add352456b 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -2,6 +2,7 @@
  * QEMU PIIX South Bridge Emulation
  *
  * Copyright (c) 2006 Fabrice Bellard
+ * Copyright (c) 2018 Hervé Poussineau
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -17,4 +18,9 @@ I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t 
smb_io_base,
   qemu_irq sci_irq, qemu_irq smi_irq,
   int smm_enabled, DeviceState **piix4_pm);
 
+extern PCIDevice *piix4_dev;
+
+DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus,
+  I2CBus **smbus, size_t ide_buses);
+
 #endif
-- 
2.21.0




[PATCH v3 05/20] piix4: Rename PIIX4 object to piix4-isa

2019-10-26 Thread Philippe Mathieu-Daudé
From: Hervé Poussineau 

Other piix4 parts are already named piix4-ide and piix4-usb-uhci.

Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: Michael S. Tsirkin 
Acked-by: Paolo Bonzini 
Signed-off-by: Hervé Poussineau 
Message-Id: <20171216090228.28505-15-hpous...@reactos.org>
Reviewed-by: Aleksandar Markovic 
Reviewed-by: Li Qiang 
Reviewed-by: Esteban Bosse 
[PMD: rebased]
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix4.c   | 1 -
 hw/mips/mips_malta.c | 2 +-
 include/hw/isa/isa.h | 2 ++
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 7cf72e3118..fa387919b5 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -45,7 +45,6 @@ typedef struct PIIX4State {
 uint8_t rcr;
 } PIIX4State;
 
-#define TYPE_PIIX4_PCI_DEVICE "PIIX4"
 #define PIIX4_PCI_DEVICE(obj) \
 OBJECT_CHECK(PIIX4State, (obj), TYPE_PIIX4_PCI_DEVICE)
 
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 6d9b230322..5086024821 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1414,7 +1414,7 @@ void mips_malta_init(MachineState *machine)
 ide_drive_get(hd, ARRAY_SIZE(hd));
 
 pci = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0),
-  true, "PIIX4");
+  true, TYPE_PIIX4_PCI_DEVICE);
 dev = DEVICE(pci);
 isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
 piix4_devfn = pci->devfn;
diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index 018ada4f6f..79f703fd6c 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -147,4 +147,6 @@ static inline ISABus *isa_bus_from_device(ISADevice *d)
 return ISA_BUS(qdev_get_parent_bus(DEVICE(d)));
 }
 
+#define TYPE_PIIX4_PCI_DEVICE "piix4-isa"
+
 #endif
-- 
2.21.0




[PATCH v3 02/20] piix4: Add the Reset Control Register

2019-10-26 Thread Philippe Mathieu-Daudé
From: Hervé Poussineau 

The RCR I/O port (0xcf9) is used to generate a hard reset or a soft reset.

Acked-by: Michael S. Tsirkin 
Acked-by: Paolo Bonzini 
Signed-off-by: Hervé Poussineau 
Message-Id: <20171216090228.28505-7-hpous...@reactos.org>
Reviewed-by: Aleksandar Markovic 
Reviewed-by: Li Qiang 
[PMD: rebased, updated includes]
Signed-off-by: Philippe Mathieu-Daudé 
---
v3: Use RCR_IOPORT (Li Qiang)
---
 hw/isa/piix4.c | 49 ++---
 1 file changed, 46 insertions(+), 3 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 890d999abf..7a1361a9dd 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -2,6 +2,7 @@
  * QEMU PIIX4 PCI Bridge Emulation
  *
  * Copyright (c) 2006 Fabrice Bellard
+ * Copyright (c) 2018 Hervé Poussineau
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to 
deal
@@ -28,11 +29,17 @@
 #include "hw/isa/isa.h"
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
 
 PCIDevice *piix4_dev;
 
 typedef struct PIIX4State {
 PCIDevice dev;
+
+/* Reset Control Register */
+MemoryRegion rcr_mem;
+uint8_t rcr;
 } PIIX4State;
 
 #define TYPE_PIIX4_PCI_DEVICE "PIIX4"
@@ -87,15 +94,51 @@ static const VMStateDescription vmstate_piix4 = {
 }
 };
 
+static void piix4_rcr_write(void *opaque, hwaddr addr, uint64_t val,
+unsigned int len)
+{
+PIIX4State *s = opaque;
+
+if (val & 4) {
+qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+return;
+}
+
+s->rcr = val & 2; /* keep System Reset type only */
+}
+
+static uint64_t piix4_rcr_read(void *opaque, hwaddr addr, unsigned int len)
+{
+PIIX4State *s = opaque;
+
+return s->rcr;
+}
+
+static const MemoryRegionOps piix4_rcr_ops = {
+.read = piix4_rcr_read,
+.write = piix4_rcr_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.impl = {
+.min_access_size = 1,
+.max_access_size = 1,
+},
+};
+
 static void piix4_realize(PCIDevice *dev, Error **errp)
 {
-PIIX4State *d = PIIX4_PCI_DEVICE(dev);
+PIIX4State *s = PIIX4_PCI_DEVICE(dev);
 
-if (!isa_bus_new(DEVICE(d), pci_address_space(dev),
+if (!isa_bus_new(DEVICE(dev), pci_address_space(dev),
  pci_address_space_io(dev), errp)) {
 return;
 }
-piix4_dev = &d->dev;
+
+memory_region_init_io(&s->rcr_mem, OBJECT(dev), &piix4_rcr_ops, s,
+  "reset-control", 1);
+memory_region_add_subregion_overlap(pci_address_space_io(dev),
+RCR_IOPORT, &s->rcr_mem, 1);
+
+piix4_dev = dev;
 }
 
 int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn)
-- 
2.21.0




[PATCH v3 09/20] hw/mips/mips_malta: Create IDE hard drive array dynamically

2019-10-26 Thread Philippe Mathieu-Daudé
In the next commit we'll refactor the PIIX4 code out of
mips_malta_init(). As a preliminary step, add the 'ide_drives'
variable and create the drive array dynamically.

Reviewed-by: Aleksandar Markovic 
Reviewed-by: Li Qiang 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/mips/mips_malta.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 645c223edb..239ea98ef8 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1235,7 +1235,8 @@ void mips_malta_init(MachineState *machine)
 int piix4_devfn;
 I2CBus *smbus;
 DriveInfo *dinfo;
-DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
+const size_t ide_drives = MAX_IDE_BUS * MAX_IDE_DEVS;
+DriveInfo **hd;
 int fl_idx = 0;
 int be;
 
@@ -1406,7 +1407,8 @@ void mips_malta_init(MachineState *machine)
 pci_bus = gt64120_register(s->i8259);
 
 /* Southbridge */
-ide_drive_get(hd, ARRAY_SIZE(hd));
+hd = g_new(DriveInfo *, ide_drives);
+ide_drive_get(hd, ide_drives);
 
 pci = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0),
   true, TYPE_PIIX4_PCI_DEVICE);
@@ -1421,6 +1423,7 @@ void mips_malta_init(MachineState *machine)
 }
 
 pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
+g_free(hd);
 pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci");
 smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
   isa_get_irq(NULL, 9), NULL, 0, NULL);
-- 
2.21.0




[PATCH v3 12/20] hw/i386: Remove obsolete LoadStateHandler::load_state_old handlers

2019-10-26 Thread Philippe Mathieu-Daudé
These devices implemented their load_state_old() handler 10 years
ago, previous to QEMU v0.12.
Since commit cc425b5ddf removed the pc-0.10 and pc-0.11 machines,
we can drop this code.

Note: the mips_r4k machine started to use the i8254 device just
after QEMU v0.5.0, but the MIPS machine types are not versioned,
so there is no migration compatibility issue removing this handler.

Suggested-by: Peter Maydell 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/acpi/piix4.c | 40 -
 hw/intc/apic_common.c   | 49 -
 hw/pci-host/piix.c  | 25 -
 hw/timer/i8254_common.c | 40 -
 4 files changed, 154 deletions(-)

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 2efd1605b8..93aec2dd2c 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -41,7 +41,6 @@
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/xen/xen.h"
-#include "migration/qemu-file-types.h"
 #include "migration/vmstate.h"
 #include "hw/core/cpu.h"
 #include "trace.h"
@@ -204,43 +203,6 @@ static const VMStateDescription vmstate_pci_status = {
 }
 };
 
-static int acpi_load_old(QEMUFile *f, void *opaque, int version_id)
-{
-PIIX4PMState *s = opaque;
-int ret, i;
-uint16_t temp;
-
-ret = pci_device_load(PCI_DEVICE(s), f);
-if (ret < 0) {
-return ret;
-}
-qemu_get_be16s(f, &s->ar.pm1.evt.sts);
-qemu_get_be16s(f, &s->ar.pm1.evt.en);
-qemu_get_be16s(f, &s->ar.pm1.cnt.cnt);
-
-ret = vmstate_load_state(f, &vmstate_apm, &s->apm, 1);
-if (ret) {
-return ret;
-}
-
-timer_get(f, s->ar.tmr.timer);
-qemu_get_sbe64s(f, &s->ar.tmr.overflow_time);
-
-qemu_get_be16s(f, (uint16_t *)s->ar.gpe.sts);
-for (i = 0; i < 3; i++) {
-qemu_get_be16s(f, &temp);
-}
-
-qemu_get_be16s(f, (uint16_t *)s->ar.gpe.en);
-for (i = 0; i < 3; i++) {
-qemu_get_be16s(f, &temp);
-}
-
-ret = vmstate_load_state(f, &vmstate_pci_status,
-&s->acpi_pci_hotplug.acpi_pcihp_pci_status[ACPI_PCIHP_BSEL_DEFAULT], 
1);
-return ret;
-}
-
 static bool vmstate_test_use_acpi_pci_hotplug(void *opaque, int version_id)
 {
 PIIX4PMState *s = opaque;
@@ -312,8 +274,6 @@ static const VMStateDescription vmstate_acpi = {
 .name = "piix4_pm",
 .version_id = 3,
 .minimum_version_id = 3,
-.minimum_version_id_old = 1,
-.load_state_old = acpi_load_old,
 .post_load = vmstate_acpi_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState),
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index aafd8e0e33..375cb6abe9 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -31,7 +31,6 @@
 #include "sysemu/kvm.h"
 #include "hw/qdev-properties.h"
 #include "hw/sysbus.h"
-#include "migration/qemu-file-types.h"
 #include "migration/vmstate.h"
 
 static int apic_irq_delivered;
@@ -262,52 +261,6 @@ static void apic_reset_common(DeviceState *dev)
 apic_init_reset(dev);
 }
 
-/* This function is only used for old state version 1 and 2 */
-static int apic_load_old(QEMUFile *f, void *opaque, int version_id)
-{
-APICCommonState *s = opaque;
-APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
-int i;
-
-if (version_id > 2) {
-return -EINVAL;
-}
-
-/* XXX: what if the base changes? (registered memory regions) */
-qemu_get_be32s(f, &s->apicbase);
-qemu_get_8s(f, &s->id);
-qemu_get_8s(f, &s->arb_id);
-qemu_get_8s(f, &s->tpr);
-qemu_get_be32s(f, &s->spurious_vec);
-qemu_get_8s(f, &s->log_dest);
-qemu_get_8s(f, &s->dest_mode);
-for (i = 0; i < 8; i++) {
-qemu_get_be32s(f, &s->isr[i]);
-qemu_get_be32s(f, &s->tmr[i]);
-qemu_get_be32s(f, &s->irr[i]);
-}
-for (i = 0; i < APIC_LVT_NB; i++) {
-qemu_get_be32s(f, &s->lvt[i]);
-}
-qemu_get_be32s(f, &s->esr);
-qemu_get_be32s(f, &s->icr[0]);
-qemu_get_be32s(f, &s->icr[1]);
-qemu_get_be32s(f, &s->divide_conf);
-s->count_shift = qemu_get_be32(f);
-qemu_get_be32s(f, &s->initial_count);
-s->initial_count_load_time = qemu_get_be64(f);
-s->next_time = qemu_get_be64(f);
-
-if (version_id >= 2) {
-s->timer_expiry = qemu_get_be64(f);
-}
-
-if (info->post_load) {
-info->post_load(s);
-}
-return 0;
-}
-
 static const VMStateDescription vmstate_apic_common;
 
 static void apic_common_realize(DeviceState *dev, Error **errp)
@@ -408,8 +361,6 @@ static const VMStateDescription vmstate_apic_common = {
 .name = "apic",
 .version_id = 3,
 .minimum_version_id = 3,
-.minimum_version_id_old = 1,
-.load_state_old = apic_load_old,
 .pre_load = apic_pre_load,
 .pre_save = apic_dispatch_pre_save,
 .post_load = apic_dispatch_post_load,
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 135c645535..

[PATCH v3 03/20] piix4: Add an i8259 Interrupt Controller as specified in datasheet

2019-10-26 Thread Philippe Mathieu-Daudé
From: Hervé Poussineau 

Add ISA irqs as piix4 gpio in, and CPU interrupt request as piix4 gpio out.
Remove i8259 instanciated in malta board, to not have it twice.

We can also remove the now unused piix4_init() function.

Acked-by: Michael S. Tsirkin 
Acked-by: Paolo Bonzini 
Signed-off-by: Hervé Poussineau 
Message-Id: <20171216090228.28505-8-hpous...@reactos.org>
Reviewed-by: Aleksandar Markovic 
[PMD: rebased, updated includes, use ISA_NUM_IRQS in for loop]
Signed-off-by: Philippe Mathieu-Daudé 
---
v3:
- "Add a i8259 -> Add an i8259" in title (Aleksandar)
- Changed 16 -> ISA_NUM_IRQS
---
 hw/isa/piix4.c   | 43 ---
 hw/mips/mips_malta.c | 32 +---
 include/hw/i386/pc.h |  1 -
 3 files changed, 45 insertions(+), 31 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 7a1361a9dd..7cf72e3118 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -24,6 +24,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "hw/irq.h"
 #include "hw/i386/pc.h"
 #include "hw/pci/pci.h"
 #include "hw/isa/isa.h"
@@ -36,6 +37,8 @@ PCIDevice *piix4_dev;
 
 typedef struct PIIX4State {
 PCIDevice dev;
+qemu_irq cpu_intr;
+qemu_irq *isa;
 
 /* Reset Control Register */
 MemoryRegion rcr_mem;
@@ -94,6 +97,18 @@ static const VMStateDescription vmstate_piix4 = {
 }
 };
 
+static void piix4_request_i8259_irq(void *opaque, int irq, int level)
+{
+PIIX4State *s = opaque;
+qemu_set_irq(s->cpu_intr, level);
+}
+
+static void piix4_set_i8259_irq(void *opaque, int irq, int level)
+{
+PIIX4State *s = opaque;
+qemu_set_irq(s->isa[irq], level);
+}
+
 static void piix4_rcr_write(void *opaque, hwaddr addr, uint64_t val,
 unsigned int len)
 {
@@ -127,29 +142,35 @@ static const MemoryRegionOps piix4_rcr_ops = {
 static void piix4_realize(PCIDevice *dev, Error **errp)
 {
 PIIX4State *s = PIIX4_PCI_DEVICE(dev);
+ISABus *isa_bus;
+qemu_irq *i8259_out_irq;
 
-if (!isa_bus_new(DEVICE(dev), pci_address_space(dev),
- pci_address_space_io(dev), errp)) {
+isa_bus = isa_bus_new(DEVICE(dev), pci_address_space(dev),
+  pci_address_space_io(dev), errp);
+if (!isa_bus) {
 return;
 }
 
+qdev_init_gpio_in_named(DEVICE(dev), piix4_set_i8259_irq,
+"isa", ISA_NUM_IRQS);
+qdev_init_gpio_out_named(DEVICE(dev), &s->cpu_intr,
+ "intr", 1);
+
 memory_region_init_io(&s->rcr_mem, OBJECT(dev), &piix4_rcr_ops, s,
   "reset-control", 1);
 memory_region_add_subregion_overlap(pci_address_space_io(dev),
 RCR_IOPORT, &s->rcr_mem, 1);
 
+/* initialize i8259 pic */
+i8259_out_irq = qemu_allocate_irqs(piix4_request_i8259_irq, s, 1);
+s->isa = i8259_init(isa_bus, *i8259_out_irq);
+
+/* initialize ISA irqs */
+isa_bus_irqs(isa_bus, s->isa);
+
 piix4_dev = dev;
 }
 
-int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn)
-{
-PCIDevice *d;
-
-d = pci_create_simple_multifunction(bus, devfn, true, "PIIX4");
-*isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(d), "isa.0"));
-return d->devfn;
-}
-
 static void piix4_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index c1c8810e71..6d9b230322 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -97,7 +97,7 @@ typedef struct {
 SysBusDevice parent_obj;
 
 MIPSCPSState cps;
-qemu_irq *i8259;
+qemu_irq i8259[ISA_NUM_IRQS];
 } MaltaState;
 
 static ISADevice *pit;
@@ -1235,8 +1235,8 @@ void mips_malta_init(MachineState *machine)
 int64_t kernel_entry, bootloader_run_addr;
 PCIBus *pci_bus;
 ISABus *isa_bus;
-qemu_irq *isa_irq;
 qemu_irq cbus_irq, i8259_irq;
+PCIDevice *pci;
 int piix4_devfn;
 I2CBus *smbus;
 DriveInfo *dinfo;
@@ -1407,30 +1407,24 @@ void mips_malta_init(MachineState *machine)
 /* Board ID = 0x420 (Malta Board with CoreLV) */
 stl_p(memory_region_get_ram_ptr(bios_copy) + 0x10, 0x0420);
 
-/*
- * We have a circular dependency problem: pci_bus depends on isa_irq,
- * isa_irq is provided by i8259, i8259 depends on ISA, ISA depends
- * on piix4, and piix4 depends on pci_bus.  To stop the cycle we have
- * qemu_irq_proxy() adds an extra bit of indirection, allowing us
- * to resolve the isa_irq -> i8259 dependency after i8259 is initialized.
- */
-isa_irq = qemu_irq_proxy(&s->i8259, 16);
-
 /* Northbridge */
-pci_bus = gt64120_register(isa_irq);
+pci_bus = gt64120_register(s->i8259);
 
 /* Southbridge */
 ide_drive_get(hd, ARRAY_SIZE(hd));
 
-piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);
+pci = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0),
+  true, "PIIX4");
+   

[PATCH v3 06/20] piix4: Add an i8257 DMA Controller as specified in datasheet

2019-10-26 Thread Philippe Mathieu-Daudé
From: Hervé Poussineau 

The i8257 is not a chipset on the Malta board, but is part of
the PIIX4 chipset.
Create the i8257 in the PIIX4 code, remove the one instantiated
in malta board, to not have it twice.

Acked-by: Michael S. Tsirkin 
Acked-by: Paolo Bonzini 
Signed-off-by: Hervé Poussineau 
Message-Id: <20171216090228.28505-9-hpous...@reactos.org>
Reviewed-by: Aleksandar Markovic 
Reviewed-by: Esteban Bosse 
[PMD: rebased, reworded description]
Signed-off-by: Philippe Mathieu-Daudé 
---
v3: Reworded commit description (Li Qiang)
---
 hw/isa/piix4.c   | 4 
 hw/mips/mips_malta.c | 2 --
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index fa387919b5..9ebe98bdc3 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -29,6 +29,7 @@
 #include "hw/pci/pci.h"
 #include "hw/isa/isa.h"
 #include "hw/sysbus.h"
+#include "hw/dma/i8257.h"
 #include "migration/vmstate.h"
 #include "sysemu/reset.h"
 #include "sysemu/runstate.h"
@@ -167,6 +168,9 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 /* initialize ISA irqs */
 isa_bus_irqs(isa_bus, s->isa);
 
+/* DMA */
+i8257_dma_init(isa_bus, 0);
+
 piix4_dev = dev;
 }
 
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 5086024821..44e5f8b26b 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -28,7 +28,6 @@
 #include "cpu.h"
 #include "hw/i386/pc.h"
 #include "hw/isa/superio.h"
-#include "hw/dma/i8257.h"
 #include "hw/char/serial.h"
 #include "net/net.h"
 #include "hw/boards.h"
@@ -1430,7 +1429,6 @@ void mips_malta_init(MachineState *machine)
 smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
   isa_get_irq(NULL, 9), NULL, 0, NULL);
 pit = i8254_pit_init(isa_bus, 0x40, 0, NULL);
-i8257_dma_init(isa_bus, 0);
 mc146818_rtc_init(isa_bus, 2000, NULL);
 
 /* generate SPD EEPROM data */
-- 
2.21.0




[PATCH v3 19/20] hw/pci-host: Rename incorrectly named 'piix' as 'i440fx'

2019-10-26 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

We moved all the PIIX3 southbridge code out of hw/pci-host/piix.c,
it now only contains i440FX northbridge code.
Rename it to match the chipset modelled.

Reviewed-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS  | 2 +-
 hw/i386/Kconfig  | 2 +-
 hw/pci-host/Kconfig  | 2 +-
 hw/pci-host/Makefile.objs| 2 +-
 hw/pci-host/{piix.c => i440fx.c} | 0
 5 files changed, 4 insertions(+), 4 deletions(-)
 rename hw/pci-host/{piix.c => i440fx.c} (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index e7e7bfc890..87e7fb1a65 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1225,7 +1225,7 @@ M: Marcel Apfelbaum 
 S: Supported
 F: include/hw/i386/
 F: hw/i386/
-F: hw/pci-host/piix.c
+F: hw/pci-host/i440fx.c
 F: hw/pci-host/q35.c
 F: hw/pci-host/pam.c
 F: include/hw/pci-host/i440fx.h
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index d420b35548..5a494342ea 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -60,7 +60,7 @@ config I440FX
 select PC_PCI
 select PC_ACPI
 select ACPI_SMBUS
-select PCI_PIIX
+select PCI_I440FX
 select PIIX3
 select IDE_PIIX
 select DIMM
diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index 397043b289..b0aa8351c4 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -28,7 +28,7 @@ config PCI_SABRE
 select PCI
 bool
 
-config PCI_PIIX
+config PCI_I440FX
 bool
 select PCI
 select PAM
diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
index a9cd3e022d..efd752b766 100644
--- a/hw/pci-host/Makefile.objs
+++ b/hw/pci-host/Makefile.objs
@@ -13,7 +13,7 @@ common-obj-$(CONFIG_VERSATILE_PCI) += versatile.o
 
 common-obj-$(CONFIG_PCI_SABRE) += sabre.o
 common-obj-$(CONFIG_FULONG) += bonito.o
-common-obj-$(CONFIG_PCI_PIIX) += piix.o
+common-obj-$(CONFIG_PCI_I440FX) += i440fx.o
 common-obj-$(CONFIG_PCI_EXPRESS_Q35) += q35.o
 common-obj-$(CONFIG_PCI_EXPRESS_GENERIC_BRIDGE) += gpex.o
 common-obj-$(CONFIG_PCI_EXPRESS_XILINX) += xilinx-pcie.o
diff --git a/hw/pci-host/piix.c b/hw/pci-host/i440fx.c
similarity index 100%
rename from hw/pci-host/piix.c
rename to hw/pci-host/i440fx.c
-- 
2.21.0




[PATCH v3 16/20] hw/pci-host/piix: Move i440FX declarations to hw/pci-host/i440fx.h

2019-10-26 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

The hw/pci-host/piix.c contains a mix of PIIX3 and i440FX chipsets
functions. To be able to split it, we need to export some
declarations first.

Reviewed-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS  |  1 +
 hw/acpi/pcihp.c  |  2 +-
 hw/i386/pc_piix.c|  1 +
 hw/pci-host/piix.c   |  1 +
 include/hw/i386/pc.h | 22 -
 include/hw/pci-host/i440fx.h | 37 
 stubs/pci-host-piix.c|  3 ++-
 7 files changed, 43 insertions(+), 24 deletions(-)
 create mode 100644 include/hw/pci-host/i440fx.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 90c5ece04b..a48daf0615 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1228,6 +1228,7 @@ F: hw/i386/
 F: hw/pci-host/piix.c
 F: hw/pci-host/q35.c
 F: hw/pci-host/pam.c
+F: include/hw/pci-host/i440fx.h
 F: include/hw/pci-host/q35.h
 F: include/hw/pci-host/pam.h
 F: hw/isa/lpc_ich9.c
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 82d295b6e8..8413348a33 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -27,7 +27,7 @@
 #include "qemu/osdep.h"
 #include "hw/acpi/pcihp.h"
 
-#include "hw/i386/pc.h"
+#include "hw/pci-host/i440fx.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_bridge.h"
 #include "hw/acpi/acpi.h"
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index a96ede19b2..ba35d5685e 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -30,6 +30,7 @@
 #include "hw/i386/x86.h"
 #include "hw/i386/pc.h"
 #include "hw/i386/apic.h"
+#include "hw/pci-host/i440fx.h"
 #include "hw/southbridge/piix.h"
 #include "hw/display/ramfb.h"
 #include "hw/firmware/smbios.h"
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 390fb9ceba..95b04122fa 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -27,6 +27,7 @@
 #include "hw/irq.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_host.h"
+#include "hw/pci-host/i440fx.h"
 #include "hw/southbridge/piix.h"
 #include "hw/qdev-properties.h"
 #include "hw/isa/isa.h"
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index d6ff95e047..e6fa8418ca 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -231,28 +231,6 @@ int cmos_get_fd_drive_type(FloppyDriveType fd0);
 /* hpet.c */
 extern int no_hpet;
 
-/* piix_pci.c */
-struct PCII440FXState;
-typedef struct PCII440FXState PCII440FXState;
-
-#define TYPE_I440FX_PCI_HOST_BRIDGE "i440FX-pcihost"
-#define TYPE_I440FX_PCI_DEVICE "i440FX"
-
-#define TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE "igd-passthrough-i440FX"
-
-PCIBus *i440fx_init(const char *host_type, const char *pci_type,
-PCII440FXState **pi440fx_state, int *piix_devfn,
-ISABus **isa_bus, qemu_irq *pic,
-MemoryRegion *address_space_mem,
-MemoryRegion *address_space_io,
-ram_addr_t ram_size,
-ram_addr_t below_4g_mem_size,
-ram_addr_t above_4g_mem_size,
-MemoryRegion *pci_memory,
-MemoryRegion *ram_memory);
-
-PCIBus *find_i440fx(void);
-
 /* pc_sysfw.c */
 void pc_system_flash_create(PCMachineState *pcms);
 void pc_system_firmware_init(PCMachineState *pcms, MemoryRegion *rom_memory);
diff --git a/include/hw/pci-host/i440fx.h b/include/hw/pci-host/i440fx.h
new file mode 100644
index 00..e327f9bf87
--- /dev/null
+++ b/include/hw/pci-host/i440fx.h
@@ -0,0 +1,37 @@
+/*
+ * QEMU i440FX North Bridge Emulation
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef HW_PCI_I440FX_H
+#define HW_PCI_I440FX_H
+
+#include "hw/hw.h"
+#include "hw/pci/pci_bus.h"
+
+typedef struct PCII440FXState PCII440FXState;
+
+#define TYPE_I440FX_PCI_HOST_BRIDGE "i440FX-pcihost"
+#define TYPE_I440FX_PCI_DEVICE "i440FX"
+
+#define TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE "igd-passthrough-i440FX"
+
+PCIBus *i440fx_init(const char *host_type, const char *pci_type,
+PCII440FXState **pi440fx_state, int *piix_devfn,
+ISABus **isa_bus, qemu_irq *pic,
+MemoryRegion *address_space_mem,
+MemoryRegion *address_space_io,
+ram_addr_t ram_size,
+ram_addr_t below_4g_mem_size,
+ram_addr_t above_4g_mem_size,
+MemoryRegion *pci_memory,
+MemoryRegion *ram_memory);
+
+PCIBus *find_i440fx(void);
+
+#endif
diff --git a/stubs/pci-host-piix.c b/stubs/pci-host-piix.c
index 6ed81b1f21..93975adbfe 100644
--- a/stubs/pci-host-piix.c
+++ b/stubs/pci-host-piix.c
@@ -1,5 +1,6 @@
 #include "qemu/osdep.h"
-#include "hw/i386/pc.h"
+#include "hw/pci-host/i440fx.h"
+
 PCIBus *find_i440fx(void)
 {
 return NULL;
-- 
2.21.0




[PATCH v3 07/20] piix4: Add an i8254 PIT Controller as specified in datasheet

2019-10-26 Thread Philippe Mathieu-Daudé
From: Hervé Poussineau 

Remove i8254 instanciated in malta board, to not have it twice.

Acked-by: Michael S. Tsirkin 
Acked-by: Paolo Bonzini 
Signed-off-by: Hervé Poussineau 
Message-Id: <20171216090228.28505-10-hpous...@reactos.org>
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
---
v2: Fixed typo (thuth)
---
 hw/isa/piix4.c   | 4 
 hw/mips/mips_malta.c | 4 
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 9ebe98bdc3..c07a1e14a8 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -30,6 +30,7 @@
 #include "hw/isa/isa.h"
 #include "hw/sysbus.h"
 #include "hw/dma/i8257.h"
+#include "hw/timer/i8254.h"
 #include "migration/vmstate.h"
 #include "sysemu/reset.h"
 #include "sysemu/runstate.h"
@@ -168,6 +169,9 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 /* initialize ISA irqs */
 isa_bus_irqs(isa_bus, s->isa);
 
+/* initialize pit */
+i8254_pit_init(isa_bus, 0x40, 0, NULL);
+
 /* DMA */
 i8257_dma_init(isa_bus, 0);
 
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 44e5f8b26b..9af486c77c 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -45,7 +45,6 @@
 #include "hw/loader.h"
 #include "elf.h"
 #include "hw/rtc/mc146818rtc.h"
-#include "hw/timer/i8254.h"
 #include "exec/address-spaces.h"
 #include "hw/sysbus.h" /* SysBusDevice */
 #include "qemu/host-utils.h"
@@ -99,8 +98,6 @@ typedef struct {
 qemu_irq i8259[ISA_NUM_IRQS];
 } MaltaState;
 
-static ISADevice *pit;
-
 static struct _loaderparams {
 int ram_size, ram_low_size;
 const char *kernel_filename;
@@ -1428,7 +1425,6 @@ void mips_malta_init(MachineState *machine)
 pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci");
 smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
   isa_get_irq(NULL, 9), NULL, 0, NULL);
-pit = i8254_pit_init(isa_bus, 0x40, 0, NULL);
 mc146818_rtc_init(isa_bus, 2000, NULL);
 
 /* generate SPD EEPROM data */
-- 
2.21.0




[PATCH v3 08/20] piix4: Add a MC146818 RTC Controller as specified in datasheet

2019-10-26 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Remove mc146818rtc instanciated in malta board, to not have it twice.

Acked-by: Michael S. Tsirkin 
Acked-by: Paolo Bonzini 
Signed-off-by: Hervé Poussineau 
Message-Id: <20171216090228.28505-13-hpous...@reactos.org>
[PMD: rebased, set RTC base_year to 2000]
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS   |  3 ++-
 hw/acpi/piix4.c   |  2 +-
 hw/i386/acpi-build.c  |  3 +--
 hw/i386/pc_piix.c |  1 +
 hw/isa/piix4.c| 22 ++
 hw/mips/mips_malta.c  |  4 +---
 include/hw/acpi/piix4.h   |  6 --
 include/hw/i386/pc.h  |  6 --
 include/hw/southbridge/piix.h | 20 
 9 files changed, 48 insertions(+), 19 deletions(-)
 delete mode 100644 include/hw/acpi/piix4.h
 create mode 100644 include/hw/southbridge/piix.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 1f04502fac..90c5ece04b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1235,7 +1235,7 @@ F: hw/i2c/smbus_ich9.c
 F: hw/acpi/piix4.c
 F: hw/acpi/ich9.c
 F: include/hw/acpi/ich9.h
-F: include/hw/acpi/piix4.h
+F: include/hw/southbridge/piix.h
 F: hw/misc/sga.c
 F: hw/isa/apm.c
 F: include/hw/isa/apm.h
@@ -1734,6 +1734,7 @@ M: Hervé Poussineau 
 M: Philippe Mathieu-Daudé 
 S: Maintained
 F: hw/isa/piix4.c
+F: include/hw/southbridge/piix.h
 
 Firmware configuration (fw_cfg)
 M: Philippe Mathieu-Daudé 
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 4e079b39bd..2efd1605b8 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -21,6 +21,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/i386/pc.h"
+#include "hw/southbridge/piix.h"
 #include "hw/irq.h"
 #include "hw/isa/apm.h"
 #include "hw/i2c/pm_smbus.h"
@@ -32,7 +33,6 @@
 #include "qapi/error.h"
 #include "qemu/range.h"
 #include "exec/address-spaces.h"
-#include "hw/acpi/piix4.h"
 #include "hw/acpi/pcihp.h"
 #include "hw/acpi/cpu_hotplug.h"
 #include "hw/acpi/cpu.h"
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 9dd3dbb16c..b1b050d8e2 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -34,7 +34,6 @@
 #include "hw/acpi/acpi-defs.h"
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/cpu.h"
-#include "hw/acpi/piix4.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/acpi/bios-linker-loader.h"
 #include "hw/isa/isa.h"
@@ -52,7 +51,7 @@
 #include "sysemu/reset.h"
 
 /* Supported chipsets: */
-#include "hw/acpi/piix4.h"
+#include "hw/southbridge/piix.h"
 #include "hw/acpi/pcihp.h"
 #include "hw/i386/ich9.h"
 #include "hw/pci/pci_bus.h"
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index c15929a1f5..a96ede19b2 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -30,6 +30,7 @@
 #include "hw/i386/x86.h"
 #include "hw/i386/pc.h"
 #include "hw/i386/apic.h"
+#include "hw/southbridge/piix.h"
 #include "hw/display/ramfb.h"
 #include "hw/firmware/smbios.h"
 #include "hw/pci/pci.h"
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index c07a1e14a8..6bf6f0c5d9 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -24,6 +24,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qapi/error.h"
 #include "hw/irq.h"
 #include "hw/i386/pc.h"
 #include "hw/pci/pci.h"
@@ -31,6 +32,7 @@
 #include "hw/sysbus.h"
 #include "hw/dma/i8257.h"
 #include "hw/timer/i8254.h"
+#include "hw/rtc/mc146818rtc.h"
 #include "migration/vmstate.h"
 #include "sysemu/reset.h"
 #include "sysemu/runstate.h"
@@ -42,6 +44,7 @@ typedef struct PIIX4State {
 qemu_irq cpu_intr;
 qemu_irq *isa;
 
+RTCState rtc;
 /* Reset Control Register */
 MemoryRegion rcr_mem;
 uint8_t rcr;
@@ -145,6 +148,7 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 PIIX4State *s = PIIX4_PCI_DEVICE(dev);
 ISABus *isa_bus;
 qemu_irq *i8259_out_irq;
+Error *err = NULL;
 
 isa_bus = isa_bus_new(DEVICE(dev), pci_address_space(dev),
   pci_address_space_io(dev), errp);
@@ -175,9 +179,26 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 /* DMA */
 i8257_dma_init(isa_bus, 0);
 
+/* RTC */
+qdev_set_parent_bus(DEVICE(&s->rtc), BUS(isa_bus));
+qdev_prop_set_int32(DEVICE(&s->rtc), "base_year", 2000);
+object_property_set_bool(OBJECT(&s->rtc), true, "realized", &err);
+if (err) {
+error_propagate(errp, err);
+return;
+}
+isa_init_irq(ISA_DEVICE(&s->rtc), &s->rtc.irq, RTC_ISA_IRQ);
+
 piix4_dev = dev;
 }
 
+static void piix4_init(Object *obj)
+{
+PIIX4State *s = PIIX4_PCI_DEVICE(obj);
+
+object_initialize(&s->rtc, sizeof(s->rtc), TYPE_MC146818_RTC);
+}
+
 static void piix4_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -202,6 +223,7 @@ static const TypeInfo piix4_info = {
 .name  = TYPE_PIIX4_PCI_DEVICE,
 .parent= TYPE_PCI_DEVICE,
 .instance_size = sizeof(PIIX4State),
+.instance_init = piix4_init,
 .class_init= piix4_class_init,
 .interfaces = (InterfaceInfo

[PATCH v3 17/20] hw/pci-host/piix: Fix code style issues

2019-10-26 Thread Philippe Mathieu-Daudé
We will move this code, fix its style first.

Reviewed-by: Aleksandar Markovic 
Reviewed-by: Esteban Bosse 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/piix.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 95b04122fa..1544c4726b 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -133,9 +133,10 @@ static PCIINTxRoute piix3_route_intx_pin_to_irq(void 
*opaque, int pci_intx);
 static void piix3_write_config_xen(PCIDevice *dev,
uint32_t address, uint32_t val, int len);
 
-/* return the global irq number corresponding to a given device irq
-   pin. We could also use the bus number to have a more precise
-   mapping. */
+/*
+ * Return the global irq number corresponding to a given device irq
+ * pin. We could also use the bus number to have a more precise mapping.
+ */
 static int pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx)
 {
 int slot_addend;
-- 
2.21.0




[PATCH v3 10/20] hw/mips/mips_malta: Extract the PIIX4 creation code as piix4_create()

2019-10-26 Thread Philippe Mathieu-Daudé
The Malta board instantiate a PIIX4 chipset doing various
calls. Refactor all those related calls into a single
function: piix4_create().

Reviewed-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/mips/mips_malta.c | 47 +++-
 1 file changed, 29 insertions(+), 18 deletions(-)

diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 239ea98ef8..9014d77b7a 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1210,6 +1210,34 @@ static void mips_create_cpu(MachineState *ms, MaltaState 
*s,
 }
 }
 
+static DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus,
+ I2CBus **smbus, size_t ide_buses)
+{
+const size_t ide_drives = ide_buses * MAX_IDE_DEVS;
+DriveInfo **hd;
+PCIDevice *pci;
+DeviceState *dev;
+
+pci = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0),
+  true, TYPE_PIIX4_PCI_DEVICE);
+dev = DEVICE(pci);
+if (isa_bus) {
+*isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
+}
+
+hd = g_new(DriveInfo *, ide_drives);
+ide_drive_get(hd, ide_drives);
+pci_piix4_ide_init(pci_bus, hd, pci->devfn + 1);
+g_free(hd);
+pci_create_simple(pci_bus, pci->devfn + 2, "piix4-usb-uhci");
+if (smbus) {
+*smbus = piix4_pm_init(pci_bus, pci->devfn + 3, 0x1100,
+   isa_get_irq(NULL, 9), NULL, 0, NULL);
+   }
+
+return dev;
+}
+
 static
 void mips_malta_init(MachineState *machine)
 {
@@ -1231,12 +1259,8 @@ void mips_malta_init(MachineState *machine)
 PCIBus *pci_bus;
 ISABus *isa_bus;
 qemu_irq cbus_irq, i8259_irq;
-PCIDevice *pci;
-int piix4_devfn;
 I2CBus *smbus;
 DriveInfo *dinfo;
-const size_t ide_drives = MAX_IDE_BUS * MAX_IDE_DEVS;
-DriveInfo **hd;
 int fl_idx = 0;
 int be;
 
@@ -1407,14 +1431,7 @@ void mips_malta_init(MachineState *machine)
 pci_bus = gt64120_register(s->i8259);
 
 /* Southbridge */
-hd = g_new(DriveInfo *, ide_drives);
-ide_drive_get(hd, ide_drives);
-
-pci = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0),
-  true, TYPE_PIIX4_PCI_DEVICE);
-dev = DEVICE(pci);
-isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
-piix4_devfn = pci->devfn;
+dev = piix4_create(pci_bus, &isa_bus, &smbus, MAX_IDE_BUS);
 
 /* Interrupt controller */
 qdev_connect_gpio_out_named(dev, "intr", 0, i8259_irq);
@@ -1422,12 +1439,6 @@ void mips_malta_init(MachineState *machine)
 s->i8259[i] = qdev_get_gpio_in_named(dev, "isa", i);
 }
 
-pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
-g_free(hd);
-pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci");
-smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
-  isa_get_irq(NULL, 9), NULL, 0, NULL);
-
 /* generate SPD EEPROM data */
 generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size);
 generate_eeprom_serial(&smbus_eeprom_buf[6 * 256]);
-- 
2.21.0




[PATCH v3 15/20] hw/pci-host/piix: Define and use the PIIX IRQ Route Control Registers

2019-10-26 Thread Philippe Mathieu-Daudé
The IRQ Route Control registers definitions belong to the PIIX
chipset. We were only defining the 'A' register. Define the other
B, C and D registers, and use them.

Acked-by: Paul Durrant 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/xen/xen-hvm.c | 5 +++--
 hw/mips/gt64xxx_pci.c | 4 ++--
 hw/pci-host/piix.c| 9 -
 include/hw/southbridge/piix.h | 6 ++
 4 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index 95f23a263c..82ece6b9e7 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -14,6 +14,7 @@
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_host.h"
 #include "hw/i386/pc.h"
+#include "hw/southbridge/piix.h"
 #include "hw/irq.h"
 #include "hw/hw.h"
 #include "hw/i386/apic-msidef.h"
@@ -156,8 +157,8 @@ void xen_piix_pci_write_config_client(uint32_t address, 
uint32_t val, int len)
 v = 0;
 }
 v &= 0xf;
-if (((address + i) >= 0x60) && ((address + i) <= 0x63)) {
-xen_set_pci_link_route(xen_domid, address + i - 0x60, v);
+if (((address + i) >= PIIX_PIRQCA) && ((address + i) <= PIIX_PIRQCD)) {
+xen_set_pci_link_route(xen_domid, address + i - PIIX_PIRQCA, v);
 }
 }
 }
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index c277398c0d..5cab9c1ee1 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -1013,12 +1013,12 @@ static void gt64120_pci_set_irq(void *opaque, int 
irq_num, int level)
 
 /* now we change the pic irq level according to the piix irq mappings */
 /* XXX: optimize */
-pic_irq = piix4_dev->config[0x60 + irq_num];
+pic_irq = piix4_dev->config[PIIX_PIRQCA + irq_num];
 if (pic_irq < 16) {
 /* The pic level is the logical OR of all the PCI irqs mapped to it. */
 pic_level = 0;
 for (i = 0; i < 4; i++) {
-if (pic_irq == piix4_dev->config[0x60 + i]) {
+if (pic_irq == piix4_dev->config[PIIX_PIRQCA + i]) {
 pic_level |= pci_irq_levels[i];
 }
 }
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 6548d9a4b5..390fb9ceba 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -61,7 +61,6 @@ typedef struct I440FXState {
 #define PIIX_NUM_PIC_IRQS   16  /* i8259 * 2 */
 #define PIIX_NUM_PIRQS  4ULL/* PIRQ[A-D] */
 #define XEN_PIIX_NUM_PIRQS  128ULL
-#define PIIX_PIRQC  0x60
 
 typedef struct PIIX3State {
 PCIDevice dev;
@@ -468,7 +467,7 @@ static void piix3_set_irq_level_internal(PIIX3State *piix3, 
int pirq, int level)
 int pic_irq;
 uint64_t mask;
 
-pic_irq = piix3->dev.config[PIIX_PIRQC + pirq];
+pic_irq = piix3->dev.config[PIIX_PIRQCA + pirq];
 if (pic_irq >= PIIX_NUM_PIC_IRQS) {
 return;
 }
@@ -482,7 +481,7 @@ static void piix3_set_irq_level(PIIX3State *piix3, int 
pirq, int level)
 {
 int pic_irq;
 
-pic_irq = piix3->dev.config[PIIX_PIRQC + pirq];
+pic_irq = piix3->dev.config[PIIX_PIRQCA + pirq];
 if (pic_irq >= PIIX_NUM_PIC_IRQS) {
 return;
 }
@@ -501,7 +500,7 @@ static void piix3_set_irq(void *opaque, int pirq, int level)
 static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pin)
 {
 PIIX3State *piix3 = opaque;
-int irq = piix3->dev.config[PIIX_PIRQC + pin];
+int irq = piix3->dev.config[PIIX_PIRQCA + pin];
 PCIINTxRoute route;
 
 if (irq < PIIX_NUM_PIC_IRQS) {
@@ -530,7 +529,7 @@ static void piix3_write_config(PCIDevice *dev,
uint32_t address, uint32_t val, int len)
 {
 pci_default_write_config(dev, address, val, len);
-if (ranges_overlap(address, len, PIIX_PIRQC, 4)) {
+if (ranges_overlap(address, len, PIIX_PIRQCA, 4)) {
 PIIX3State *piix3 = PIIX3_PCI_DEVICE(dev);
 int pic_irq;
 
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index e49d4a6bbe..094508b928 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -18,6 +18,12 @@ I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t 
smb_io_base,
   qemu_irq sci_irq, qemu_irq smi_irq,
   int smm_enabled, DeviceState **piix4_pm);
 
+/* PIRQRC[A:D]: PIRQx Route Control Registers */
+#define PIIX_PIRQCA 0x60
+#define PIIX_PIRQCB 0x61
+#define PIIX_PIRQCC 0x62
+#define PIIX_PIRQCD 0x63
+
 /*
  * Reset Control Register: PCI-accessible ISA-Compatible Register at address
  * 0xcf9, provided by the PCI/ISA bridge (PIIX3 PCI function 0, 8086:7000).
-- 
2.21.0




[PATCH v3 18/20] hw/pci-host/piix: Extract PIIX3 functions to hw/isa/piix3.c

2019-10-26 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Move all the PIIX3 functions to a new file: hw/isa/piix3.c.

Reviewed-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
---
Checkpatch warning:

 ERROR: spaces required around that '*' (ctx:VxV)
 #312: FILE: hw/isa/piix3.c:248:
 +.subsections = (const VMStateDescription*[]) {
  ^
---
 MAINTAINERS   |   1 +
 hw/i386/Kconfig   |   1 +
 hw/isa/Kconfig|   4 +
 hw/isa/Makefile.objs  |   1 +
 hw/isa/piix3.c| 399 +
 hw/pci-host/Kconfig   |   1 -
 hw/pci-host/piix.c| 402 --
 include/hw/southbridge/piix.h |  36 +++
 8 files changed, 442 insertions(+), 403 deletions(-)
 create mode 100644 hw/isa/piix3.c

diff --git a/MAINTAINERS b/MAINTAINERS
index a48daf0615..e7e7bfc890 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1231,6 +1231,7 @@ F: hw/pci-host/pam.c
 F: include/hw/pci-host/i440fx.h
 F: include/hw/pci-host/q35.h
 F: include/hw/pci-host/pam.h
+F: hw/isa/piix3.c
 F: hw/isa/lpc_ich9.c
 F: hw/i2c/smbus_ich9.c
 F: hw/acpi/piix4.c
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index b25bb6d78a..d420b35548 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -61,6 +61,7 @@ config I440FX
 select PC_ACPI
 select ACPI_SMBUS
 select PCI_PIIX
+select PIIX3
 select IDE_PIIX
 select DIMM
 select SMBIOS
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index 98a289957e..8a38813cc1 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -29,6 +29,10 @@ config PC87312
 select FDC
 select IDE_ISA
 
+config PIIX3
+bool
+select ISA_BUS
+
 config PIIX4
 bool
 # For historical reasons, SuperIO devices are created in the board
diff --git a/hw/isa/Makefile.objs b/hw/isa/Makefile.objs
index ff97485504..8e73960a75 100644
--- a/hw/isa/Makefile.objs
+++ b/hw/isa/Makefile.objs
@@ -3,6 +3,7 @@ common-obj-$(CONFIG_ISA_SUPERIO) += isa-superio.o
 common-obj-$(CONFIG_APM) += apm.o
 common-obj-$(CONFIG_I82378) += i82378.o
 common-obj-$(CONFIG_PC87312) += pc87312.o
+common-obj-$(CONFIG_PIIX3) += piix3.o
 common-obj-$(CONFIG_PIIX4) += piix4.o
 common-obj-$(CONFIG_VT82C686) += vt82c686.o
 common-obj-$(CONFIG_SMC37C669) += smc37c669-superio.o
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
new file mode 100644
index 00..fd1c78879f
--- /dev/null
+++ b/hw/isa/piix3.c
@@ -0,0 +1,399 @@
+/*
+ * QEMU PIIX PCI ISA Bridge Emulation
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/range.h"
+#include "hw/southbridge/piix.h"
+#include "hw/irq.h"
+#include "hw/isa/isa.h"
+#include "hw/xen/xen.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
+#include "migration/vmstate.h"
+
+#define XEN_PIIX_NUM_PIRQS  128ULL
+
+#define TYPE_PIIX3_PCI_DEVICE "pci-piix3"
+#define PIIX3_PCI_DEVICE(obj) \
+OBJECT_CHECK(PIIX3State, (obj), TYPE_PIIX3_PCI_DEVICE)
+
+#define TYPE_PIIX3_DEVICE "PIIX3"
+#define TYPE_PIIX3_XEN_DEVICE "PIIX3-xen"
+
+static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq)
+{
+qemu_set_irq(piix3->pic[pic_irq],
+ !!(piix3->pic_levels &
+(((1ULL << PIIX_NUM_PIRQS) - 1) <<
+ (pic_irq * PIIX_NUM_PIRQS;
+}
+
+static void piix3_set_irq_level_internal(PIIX3State *piix3, int pirq, int 
level)
+{
+int pic_irq;
+uint64_t mask;
+
+pic_irq = piix3->dev.config[PIIX_PIRQCA + pirq];
+if (pic_irq >= PIIX_NUM_PIC_IRQS) {
+return;
+}
+
+mask = 1ULL << ((pic_irq * PIIX_NUM_PIRQS) + pirq);
+piix3->pic_levels &= ~mask;
+piix3->pic_levels |= mask * !!level;
+}
+
+static void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level)
+{
+int pic_irq;
+
+pic_irq = piix3->dev.config[PIIX_PIRQCA + pirq];
+if (pi

[PATCH v3 14/20] hw/pci-host/piix: Move RCR_IOPORT register definition

2019-10-26 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

The RCR_IOPORT register belongs to the PIIX chipset.
Move the definition to "piix.h", and prepend the PIIX prefix.

Reviewed-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
---
v2: prepend PIIX prefix (Aleksandar)
---
 hw/i386/acpi-build.c  | 2 +-
 hw/isa/piix4.c| 2 +-
 hw/pci-host/piix.c| 7 ---
 include/hw/i386/pc.h  | 6 --
 include/hw/southbridge/piix.h | 6 ++
 5 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index b1b050d8e2..266d9b534b 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -209,7 +209,7 @@ static void acpi_get_pm_info(MachineState *machine, 
AcpiPmInfo *pm)
 
 /* The above need not be conditional on machine type because the reset port
  * happens to be the same on PIIX (pc) and ICH9 (q35). */
-QEMU_BUILD_BUG_ON(ICH9_RST_CNT_IOPORT != RCR_IOPORT);
+QEMU_BUILD_BUG_ON(ICH9_RST_CNT_IOPORT != PIIX_RCR_IOPORT);
 
 /* Fill in optional s3/s4 related properties */
 o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL);
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index f3e21ea76d..86678e6829 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -166,7 +166,7 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 memory_region_init_io(&s->rcr_mem, OBJECT(dev), &piix4_rcr_ops, s,
   "reset-control", 1);
 memory_region_add_subregion_overlap(pci_address_space_io(dev),
-RCR_IOPORT, &s->rcr_mem, 1);
+PIIX_RCR_IOPORT, &s->rcr_mem, 1);
 
 /* initialize i8259 pic */
 i8259_out_irq = qemu_allocate_irqs(piix4_request_i8259_irq, s, 1);
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 3292703de7..6548d9a4b5 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -27,6 +27,7 @@
 #include "hw/irq.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_host.h"
+#include "hw/southbridge/piix.h"
 #include "hw/qdev-properties.h"
 #include "hw/isa/isa.h"
 #include "hw/sysbus.h"
@@ -87,7 +88,7 @@ typedef struct PIIX3State {
 /* Reset Control Register contents */
 uint8_t rcr;
 
-/* IO memory region for Reset Control Register (RCR_IOPORT) */
+/* IO memory region for Reset Control Register (PIIX_RCR_IOPORT) */
 MemoryRegion rcr_mem;
 } PIIX3State;
 
@@ -695,8 +696,8 @@ static void piix3_realize(PCIDevice *dev, Error **errp)
 
 memory_region_init_io(&d->rcr_mem, OBJECT(dev), &rcr_ops, d,
   "piix3-reset-control", 1);
-memory_region_add_subregion_overlap(pci_address_space_io(dev), RCR_IOPORT,
-&d->rcr_mem, 1);
+memory_region_add_subregion_overlap(pci_address_space_io(dev),
+PIIX_RCR_IOPORT, &d->rcr_mem, 1);
 
 qemu_register_reset(piix3_reset, d);
 }
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 2fd40ceebe..d6ff95e047 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -240,12 +240,6 @@ typedef struct PCII440FXState PCII440FXState;
 
 #define TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE "igd-passthrough-i440FX"
 
-/*
- * Reset Control Register: PCI-accessible ISA-Compatible Register at address
- * 0xcf9, provided by the PCI/ISA bridge (PIIX3 PCI function 0, 8086:7000).
- */
-#define RCR_IOPORT 0xcf9
-
 PCIBus *i440fx_init(const char *host_type, const char *pci_type,
 PCII440FXState **pi440fx_state, int *piix_devfn,
 ISABus **isa_bus, qemu_irq *pic,
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index add352456b..e49d4a6bbe 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -18,6 +18,12 @@ I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t 
smb_io_base,
   qemu_irq sci_irq, qemu_irq smi_irq,
   int smm_enabled, DeviceState **piix4_pm);
 
+/*
+ * Reset Control Register: PCI-accessible ISA-Compatible Register at address
+ * 0xcf9, provided by the PCI/ISA bridge (PIIX3 PCI function 0, 8086:7000).
+ */
+#define PIIX_RCR_IOPORT 0xcf9
+
 extern PCIDevice *piix4_dev;
 
 DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus,
-- 
2.21.0




[PATCH v3 13/20] hw/pci-host/piix: Extract piix3_create()

2019-10-26 Thread Philippe Mathieu-Daudé
Extract the PIIX3 creation code from the i440fx_init() function.

Reviewed-by: Aleksandar Markovic 
Reviewed-by: Esteban Bosse 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/piix.c | 51 --
 1 file changed, 31 insertions(+), 20 deletions(-)

diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 2f4cbcbfe9..3292703de7 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -331,6 +331,36 @@ static void i440fx_realize(PCIDevice *dev, Error **errp)
 }
 }
 
+static PIIX3State *piix3_create(PCIBus *pci_bus, ISABus **isa_bus)
+{
+PIIX3State *piix3;
+PCIDevice *pci_dev;
+
+/*
+ * Xen supports additional interrupt routes from the PCI devices to
+ * the IOAPIC: the four pins of each PCI device on the bus are also
+ * connected to the IOAPIC directly.
+ * These additional routes can be discovered through ACPI.
+ */
+if (xen_enabled()) {
+pci_dev = pci_create_simple_multifunction(pci_bus, -1, true,
+  TYPE_PIIX3_XEN_DEVICE);
+piix3 = PIIX3_PCI_DEVICE(pci_dev);
+pci_bus_irqs(pci_bus, xen_piix3_set_irq, xen_pci_slot_get_pirq,
+ piix3, XEN_PIIX_NUM_PIRQS);
+} else {
+pci_dev = pci_create_simple_multifunction(pci_bus, -1, true,
+  TYPE_PIIX3_DEVICE);
+piix3 = PIIX3_PCI_DEVICE(pci_dev);
+pci_bus_irqs(pci_bus, piix3_set_irq, pci_slot_get_pirq,
+ piix3, PIIX_NUM_PIRQS);
+pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq);
+}
+*isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix3), "isa.0"));
+
+return piix3;
+}
+
 PCIBus *i440fx_init(const char *host_type, const char *pci_type,
 PCII440FXState **pi440fx_state,
 int *piix3_devfn,
@@ -400,27 +430,8 @@ PCIBus *i440fx_init(const char *host_type, const char 
*pci_type,
  PAM_EXPAN_SIZE);
 }
 
-/* Xen supports additional interrupt routes from the PCI devices to
- * the IOAPIC: the four pins of each PCI device on the bus are also
- * connected to the IOAPIC directly.
- * These additional routes can be discovered through ACPI. */
-if (xen_enabled()) {
-PCIDevice *pci_dev = pci_create_simple_multifunction(b,
- -1, true, TYPE_PIIX3_XEN_DEVICE);
-piix3 = PIIX3_PCI_DEVICE(pci_dev);
-pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq,
-piix3, XEN_PIIX_NUM_PIRQS);
-} else {
-PCIDevice *pci_dev = pci_create_simple_multifunction(b,
- -1, true, TYPE_PIIX3_DEVICE);
-piix3 = PIIX3_PCI_DEVICE(pci_dev);
-pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
-PIIX_NUM_PIRQS);
-pci_bus_set_route_irq_fn(b, piix3_route_intx_pin_to_irq);
-}
+piix3 = piix3_create(b, isa_bus);
 piix3->pic = pic;
-*isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix3), "isa.0"));
-
 *piix3_devfn = piix3->dev.devfn;
 
 ram_size = ram_size / 8 / 1024 / 1024;
-- 
2.21.0




[PATCH v3 20/20] hw/pci-host/i440fx: Remove the last PIIX3 traces

2019-10-26 Thread Philippe Mathieu-Daudé
The PIIX3 is not tied to the i440FX and can even be used without it.
Move its creation to the machine code (pc_piix.c).
We have now removed the last trace of southbridge code in the i440FX
northbridge.

Reviewed-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc_piix.c| 8 +++-
 hw/pci-host/i440fx.c | 8 
 include/hw/pci-host/i440fx.h | 3 +--
 3 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index ba35d5685e..2aefa3b8df 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -192,14 +192,20 @@ static void pc_init1(MachineState *machine,
 gsi_state = pc_gsi_create(&x86ms->gsi, pcmc->pci_enabled);
 
 if (pcmc->pci_enabled) {
+PIIX3State *piix3;
+
 pci_bus = i440fx_init(host_type,
   pci_type,
-  &i440fx_state, &piix3_devfn, &isa_bus, 
x86ms->gsi,
+  &i440fx_state,
   system_memory, system_io, machine->ram_size,
   x86ms->below_4g_mem_size,
   x86ms->above_4g_mem_size,
   pci_memory, ram_memory);
 pcms->bus = pci_bus;
+
+piix3 = piix3_create(pci_bus, &isa_bus);
+piix3->pic = x86ms->gsi;
+piix3_devfn = piix3->dev.devfn;
 } else {
 pci_bus = NULL;
 i440fx_state = NULL;
diff --git a/hw/pci-host/i440fx.c b/hw/pci-host/i440fx.c
index 79ecd58a2b..f27131102d 100644
--- a/hw/pci-host/i440fx.c
+++ b/hw/pci-host/i440fx.c
@@ -27,7 +27,6 @@
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_host.h"
 #include "hw/pci-host/i440fx.h"
-#include "hw/southbridge/piix.h"
 #include "hw/qdev-properties.h"
 #include "hw/sysbus.h"
 #include "qapi/error.h"
@@ -272,8 +271,6 @@ static void i440fx_realize(PCIDevice *dev, Error **errp)
 
 PCIBus *i440fx_init(const char *host_type, const char *pci_type,
 PCII440FXState **pi440fx_state,
-int *piix3_devfn,
-ISABus **isa_bus, qemu_irq *pic,
 MemoryRegion *address_space_mem,
 MemoryRegion *address_space_io,
 ram_addr_t ram_size,
@@ -286,7 +283,6 @@ PCIBus *i440fx_init(const char *host_type, const char 
*pci_type,
 PCIBus *b;
 PCIDevice *d;
 PCIHostState *s;
-PIIX3State *piix3;
 PCII440FXState *f;
 unsigned i;
 I440FXState *i440fx;
@@ -339,10 +335,6 @@ PCIBus *i440fx_init(const char *host_type, const char 
*pci_type,
  PAM_EXPAN_SIZE);
 }
 
-piix3 = piix3_create(b, isa_bus);
-piix3->pic = pic;
-*piix3_devfn = piix3->dev.devfn;
-
 ram_size = ram_size / 8 / 1024 / 1024;
 if (ram_size > 255) {
 ram_size = 255;
diff --git a/include/hw/pci-host/i440fx.h b/include/hw/pci-host/i440fx.h
index e327f9bf87..f54e6466e4 100644
--- a/include/hw/pci-host/i440fx.h
+++ b/include/hw/pci-host/i440fx.h
@@ -22,8 +22,7 @@ typedef struct PCII440FXState PCII440FXState;
 #define TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE "igd-passthrough-i440FX"
 
 PCIBus *i440fx_init(const char *host_type, const char *pci_type,
-PCII440FXState **pi440fx_state, int *piix_devfn,
-ISABus **isa_bus, qemu_irq *pic,
+PCII440FXState **pi440fx_state,
 MemoryRegion *address_space_mem,
 MemoryRegion *address_space_io,
 ram_addr_t ram_size,
-- 
2.21.0




[PULL 01/25] virtio: basic structure for packed ring

2019-10-26 Thread Michael S. Tsirkin
From: Wei Xu 

Define packed ring structure according to Qemu nomenclature,
field data(wrap counter, etc) are also included.

Signed-off-by: Wei Xu 
Signed-off-by: Jason Wang 
Signed-off-by: Eugenio Pérez 
Reviewed-by: Jens Freimann 
Message-Id: <20191025083527.30803-2-epere...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/virtio.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 527df03bfd..fdac203cdf 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -43,6 +43,13 @@ typedef struct VRingDesc
 uint16_t next;
 } VRingDesc;
 
+typedef struct VRingPackedDesc {
+uint64_t addr;
+uint32_t len;
+uint16_t id;
+uint16_t flags;
+} VRingPackedDesc;
+
 typedef struct VRingAvail
 {
 uint16_t flags;
@@ -81,17 +88,25 @@ typedef struct VRing
 VRingMemoryRegionCaches *caches;
 } VRing;
 
+typedef struct VRingPackedDescEvent {
+uint16_t off_wrap;
+uint16_t flags;
+} VRingPackedDescEvent ;
+
 struct VirtQueue
 {
 VRing vring;
 
 /* Next head to pop */
 uint16_t last_avail_idx;
+bool last_avail_wrap_counter;
 
 /* Last avail_idx read from VQ. */
 uint16_t shadow_avail_idx;
+bool shadow_avail_wrap_counter;
 
 uint16_t used_idx;
+bool used_wrap_counter;
 
 /* Last used index value we have signalled on */
 uint16_t signalled_used;
-- 
MST




[PULL 03/25] virtio: Free blk virqueues at unrealize()

2019-10-26 Thread Michael S. Tsirkin
From: Eugenio Pérez 

The function virtio_del_queue was not called at unrealize() callback.

This was detected due to add an allocated element on the vq introduce
in future commits (used_elems) and running address sanitizer memory
leak detector.

Signed-off-by: Eugenio Pérez 
Message-Id: <20191025083527.30803-4-epere...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/block/virtio-blk.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index ed2ddebd2b..ba846fe9dc 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -1206,9 +1206,14 @@ static void virtio_blk_device_unrealize(DeviceState 
*dev, Error **errp)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
 VirtIOBlock *s = VIRTIO_BLK(dev);
+VirtIOBlkConf *conf = &s->conf;
+unsigned i;
 
 virtio_blk_data_plane_destroy(s->dataplane);
 s->dataplane = NULL;
+for (i = 0; i < conf->num_queues; i++) {
+virtio_del_queue(vdev, i);
+}
 qemu_del_vm_change_state_handler(s->change);
 blockdev_mark_auto_del(s->blk);
 virtio_cleanup(vdev);
-- 
MST




[PULL 04/25] virtio: Free rnd virqueue at unrealize()

2019-10-26 Thread Michael S. Tsirkin
From: Eugenio Pérez 

The function virtio_del_queue was not called at unrealize() callback.

This was detected due to add an allocated element on the vq introduce
in future commits (used_elems) and running address sanitizer memory
leak detector.

Signed-off-by: Eugenio Pérez 
Message-Id: <20191025083527.30803-5-epere...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/virtio-rng.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index e93bed020f..b498a20332 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -238,6 +238,7 @@ static void virtio_rng_device_unrealize(DeviceState *dev, 
Error **errp)
 qemu_del_vm_change_state_handler(vrng->vmstate);
 timer_del(vrng->rate_limit_timer);
 timer_free(vrng->rate_limit_timer);
+virtio_del_queue(vdev, 0);
 virtio_cleanup(vdev);
 }
 
-- 
MST




[PULL 00/25] virtio: features, tests

2019-10-26 Thread Michael S. Tsirkin
The following changes since commit 58560ad254fbda71d4daa6622d71683190070ee2:

  Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.2-20191024' into 
staging (2019-10-24 16:22:58 +0100)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream

for you to fetch changes up to 909c548c539b4136e3abf2377980dad6274c4c2e:

  virtio: drop unused virtio_device_stop_ioeventfd() function (2019-10-25 
07:46:22 -0400)


virtio: features, tests

libqos update with support for virtio 1.
Packed ring support for virtio.

Signed-off-by: Michael S. Tsirkin 


Eugenio Pérez (2):
  virtio: Free blk virqueues at unrealize()
  virtio: Free rnd virqueue at unrealize()

Jason Wang (4):
  virtio: basic packed virtqueue support
  virtio: event suppression support for packed ring
  vhost_net: enable packed ring support
  virtio: add property to enable packed virtqueue

Stefan Hajnoczi (17):
  tests/virtio-blk-test: read config space after feature negotiation
  libqos: read QVIRTIO_MMIO_VERSION register
  libqos: extend feature bits to 64-bit
  virtio-scsi-test: add missing feature negotiation
  tests/virtio-blk-test: set up virtqueue after feature negotiation
  libqos: add missing virtio-9p feature negotiation
  libqos: enforce Device Initialization order
  libqos: implement VIRTIO 1.0 FEATURES_OK step
  libqos: access VIRTIO 1.0 vring in little-endian
  libqos: add iteration support to qpci_find_capability()
  libqos: pass full QVirtQueue to set_queue_address()
  libqos: add MSI-X callbacks to QVirtioPCIDevice
  libqos: expose common virtqueue setup/cleanup functions
  libqos: make the virtio-pci BAR index configurable
  libqos: extract Legacy virtio-pci.c code
  libqos: add VIRTIO PCI 1.0 support
  virtio: drop unused virtio_device_stop_ioeventfd() function

Wei Xu (2):
  virtio: basic structure for packed ring
  virtio: device/driver area size calculation refactor for split ring

 include/hw/virtio/virtio.h   |   15 +-
 tests/libqos/pci.h   |2 +-
 tests/libqos/virtio-mmio.h   |1 +
 tests/libqos/virtio-pci-modern.h |   17 +
 tests/libqos/virtio-pci.h|   34 +-
 tests/libqos/virtio.h|   19 +-
 hw/block/virtio-blk.c|7 +-
 hw/char/virtio-serial-bus.c  |2 +-
 hw/net/vhost_net.c   |2 +
 hw/scsi/virtio-scsi.c|3 +-
 hw/virtio/virtio-rng.c   |1 +
 hw/virtio/virtio.c   | 1074 ++
 tests/libqos/pci.c   |   30 +-
 tests/libqos/virtio-9p.c |6 +
 tests/libqos/virtio-mmio.c   |   38 +-
 tests/libqos/virtio-net.c|6 +-
 tests/libqos/virtio-pci-modern.c |  443 
 tests/libqos/virtio-pci.c|  105 ++--
 tests/libqos/virtio.c|  160 --
 tests/virtio-blk-test.c  |   66 ++-
 tests/virtio-scsi-test.c |8 +
 tests/Makefile.include   |1 +
 22 files changed, 1803 insertions(+), 237 deletions(-)
 create mode 100644 tests/libqos/virtio-pci-modern.h
 create mode 100644 tests/libqos/virtio-pci-modern.c




[PULL 02/25] virtio: device/driver area size calculation refactor for split ring

2019-10-26 Thread Michael S. Tsirkin
From: Wei Xu 

There is slight size difference between split/packed rings.

This is the refactor of split ring as well as a helper to expanding
device and driver area size calculation for packed ring.

Signed-off-by: Wei Xu 
Signed-off-by: Jason Wang 
Signed-off-by: Eugenio Pérez 
Reviewed-by: Jens Freimann 
Message-Id: <20191025083527.30803-3-epere...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/virtio.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index fdac203cdf..74cc10fad9 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -159,10 +159,8 @@ static void virtio_init_region_cache(VirtIODevice *vdev, 
int n)
 VRingMemoryRegionCaches *old = vq->vring.caches;
 VRingMemoryRegionCaches *new = NULL;
 hwaddr addr, size;
-int event_size;
 int64_t len;
 
-event_size = virtio_vdev_has_feature(vq->vdev, VIRTIO_RING_F_EVENT_IDX) ? 
2 : 0;
 
 addr = vq->vring.desc;
 if (!addr) {
@@ -177,7 +175,7 @@ static void virtio_init_region_cache(VirtIODevice *vdev, 
int n)
 goto err_desc;
 }
 
-size = virtio_queue_get_used_size(vdev, n) + event_size;
+size = virtio_queue_get_used_size(vdev, n);
 len = address_space_cache_init(&new->used, vdev->dma_as,
vq->vring.used, size, true);
 if (len < size) {
@@ -185,7 +183,7 @@ static void virtio_init_region_cache(VirtIODevice *vdev, 
int n)
 goto err_used;
 }
 
-size = virtio_queue_get_avail_size(vdev, n) + event_size;
+size = virtio_queue_get_avail_size(vdev, n);
 len = address_space_cache_init(&new->avail, vdev->dma_as,
vq->vring.avail, size, false);
 if (len < size) {
@@ -2414,14 +2412,20 @@ hwaddr virtio_queue_get_desc_size(VirtIODevice *vdev, 
int n)
 
 hwaddr virtio_queue_get_avail_size(VirtIODevice *vdev, int n)
 {
+int s;
+
+s = virtio_vdev_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0;
 return offsetof(VRingAvail, ring) +
-sizeof(uint16_t) * vdev->vq[n].vring.num;
+sizeof(uint16_t) * vdev->vq[n].vring.num + s;
 }
 
 hwaddr virtio_queue_get_used_size(VirtIODevice *vdev, int n)
 {
+int s;
+
+s = virtio_vdev_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0;
 return offsetof(VRingUsed, ring) +
-sizeof(VRingUsedElem) * vdev->vq[n].vring.num;
+sizeof(VRingUsedElem) * vdev->vq[n].vring.num + s;
 }
 
 uint16_t virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n)
-- 
MST




[PULL 07/25] vhost_net: enable packed ring support

2019-10-26 Thread Michael S. Tsirkin
From: Jason Wang 

Signed-off-by: Jason Wang 
Signed-off-by: Eugenio Pérez 
Reviewed-by: Jens Freimann 
Message-Id: <20191025083527.30803-8-epere...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/net/vhost_net.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index e975700f95..6b82803fa7 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -49,6 +49,7 @@ static const int kernel_feature_bits[] = {
 VIRTIO_F_VERSION_1,
 VIRTIO_NET_F_MTU,
 VIRTIO_F_IOMMU_PLATFORM,
+VIRTIO_F_RING_PACKED,
 VHOST_INVALID_FEATURE_BIT
 };
 
@@ -74,6 +75,7 @@ static const int user_feature_bits[] = {
 VIRTIO_NET_F_MRG_RXBUF,
 VIRTIO_NET_F_MTU,
 VIRTIO_F_IOMMU_PLATFORM,
+VIRTIO_F_RING_PACKED,
 
 /* This bit implies RARP isn't sent by QEMU out of band */
 VIRTIO_NET_F_GUEST_ANNOUNCE,
-- 
MST




[PULL 06/25] virtio: event suppression support for packed ring

2019-10-26 Thread Michael S. Tsirkin
From: Jason Wang 

This patch implements event suppression through device/driver
area. Please refer virtio specification for more information.

Signed-off-by: Wei Xu 
Signed-off-by: Jason Wang 
Signed-off-by: Eugenio Pérez 
Message-Id: <20191025083527.30803-7-epere...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/virtio.c | 142 ++---
 1 file changed, 133 insertions(+), 9 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index a694b4ab50..828c27de1f 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -240,6 +240,44 @@ static void vring_split_desc_read(VirtIODevice *vdev, 
VRingDesc *desc,
 virtio_tswap16s(vdev, &desc->next);
 }
 
+static void vring_packed_event_read(VirtIODevice *vdev,
+MemoryRegionCache *cache,
+VRingPackedDescEvent *e)
+{
+hwaddr off_off = offsetof(VRingPackedDescEvent, off_wrap);
+hwaddr off_flags = offsetof(VRingPackedDescEvent, flags);
+
+address_space_read_cached(cache, off_flags, &e->flags,
+  sizeof(e->flags));
+/* Make sure flags is seen before off_wrap */
+smp_rmb();
+address_space_read_cached(cache, off_off, &e->off_wrap,
+  sizeof(e->off_wrap));
+virtio_tswap16s(vdev, &e->off_wrap);
+virtio_tswap16s(vdev, &e->flags);
+}
+
+static void vring_packed_off_wrap_write(VirtIODevice *vdev,
+MemoryRegionCache *cache,
+uint16_t off_wrap)
+{
+hwaddr off = offsetof(VRingPackedDescEvent, off_wrap);
+
+virtio_tswap16s(vdev, &off_wrap);
+address_space_write_cached(cache, off, &off_wrap, sizeof(off_wrap));
+address_space_cache_invalidate(cache, off, sizeof(off_wrap));
+}
+
+static void vring_packed_flags_write(VirtIODevice *vdev,
+ MemoryRegionCache *cache, uint16_t flags)
+{
+hwaddr off = offsetof(VRingPackedDescEvent, flags);
+
+virtio_tswap16s(vdev, &flags);
+address_space_write_cached(cache, off, &flags, sizeof(flags));
+address_space_cache_invalidate(cache, off, sizeof(flags));
+}
+
 /* Called within rcu_read_lock().  */
 static VRingMemoryRegionCaches *vring_get_region_caches(struct VirtQueue *vq)
 {
@@ -347,14 +385,8 @@ static inline void vring_set_avail_event(VirtQueue *vq, 
uint16_t val)
 address_space_cache_invalidate(&caches->used, pa, sizeof(val));
 }
 
-void virtio_queue_set_notification(VirtQueue *vq, int enable)
+static void virtio_queue_split_set_notification(VirtQueue *vq, int enable)
 {
-vq->notification = enable;
-
-if (!vq->vring.desc) {
-return;
-}
-
 rcu_read_lock();
 if (virtio_vdev_has_feature(vq->vdev, VIRTIO_RING_F_EVENT_IDX)) {
 vring_set_avail_event(vq, vring_avail_idx(vq));
@@ -370,6 +402,51 @@ void virtio_queue_set_notification(VirtQueue *vq, int 
enable)
 rcu_read_unlock();
 }
 
+static void virtio_queue_packed_set_notification(VirtQueue *vq, int enable)
+{
+uint16_t off_wrap;
+VRingPackedDescEvent e;
+VRingMemoryRegionCaches *caches;
+
+rcu_read_lock();
+caches  = vring_get_region_caches(vq);
+vring_packed_event_read(vq->vdev, &caches->used, &e);
+
+if (!enable) {
+e.flags = VRING_PACKED_EVENT_FLAG_DISABLE;
+} else if (virtio_vdev_has_feature(vq->vdev, VIRTIO_RING_F_EVENT_IDX)) {
+off_wrap = vq->shadow_avail_idx | vq->shadow_avail_wrap_counter << 15;
+vring_packed_off_wrap_write(vq->vdev, &caches->used, off_wrap);
+/* Make sure off_wrap is wrote before flags */
+smp_wmb();
+e.flags = VRING_PACKED_EVENT_FLAG_DESC;
+} else {
+e.flags = VRING_PACKED_EVENT_FLAG_ENABLE;
+}
+
+vring_packed_flags_write(vq->vdev, &caches->used, e.flags);
+if (enable) {
+/* Expose avail event/used flags before caller checks the avail idx. */
+smp_mb();
+}
+rcu_read_unlock();
+}
+
+void virtio_queue_set_notification(VirtQueue *vq, int enable)
+{
+vq->notification = enable;
+
+if (!vq->vring.desc) {
+return;
+}
+
+if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) {
+virtio_queue_packed_set_notification(vq, enable);
+} else {
+virtio_queue_split_set_notification(vq, enable);
+}
+}
+
 int virtio_queue_ready(VirtQueue *vq)
 {
 return vq->vring.avail != 0;
@@ -2287,8 +2364,7 @@ static void virtio_set_isr(VirtIODevice *vdev, int value)
 }
 }
 
-/* Called within rcu_read_lock().  */
-static bool virtio_should_notify(VirtIODevice *vdev, VirtQueue *vq)
+static bool virtio_split_should_notify(VirtIODevice *vdev, VirtQueue *vq)
 {
 uint16_t old, new;
 bool v;
@@ -2311,6 +2387,54 @@ static bool virtio_should_notify(VirtIODevice *vdev, 
VirtQueue *vq)
 return !v || vring_need_event(vring_get_used_event(vq), new, old);
 }
 
+static bool vr

[PULL 08/25] virtio: add property to enable packed virtqueue

2019-10-26 Thread Michael S. Tsirkin
From: Jason Wang 

Signed-off-by: Jason Wang 
Signed-off-by: Eugenio Pérez 
Reviewed-by: Jens Freimann 
Message-Id: <20191025083527.30803-9-epere...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 include/hw/virtio/virtio.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index d123d5b181..40ddeafadb 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -285,7 +285,9 @@ typedef struct VirtIORNGConf VirtIORNGConf;
 DEFINE_PROP_BIT64("any_layout", _state, _field, \
   VIRTIO_F_ANY_LAYOUT, true), \
 DEFINE_PROP_BIT64("iommu_platform", _state, _field, \
-  VIRTIO_F_IOMMU_PLATFORM, false)
+  VIRTIO_F_IOMMU_PLATFORM, false), \
+DEFINE_PROP_BIT64("packed", _state, _field, \
+  VIRTIO_F_RING_PACKED, false)
 
 hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
 bool virtio_queue_enabled(VirtIODevice *vdev, int n);
-- 
MST




[PULL 05/25] virtio: basic packed virtqueue support

2019-10-26 Thread Michael S. Tsirkin
From: Jason Wang 

This patch implements basic support for the packed virtqueue. Compare
the split virtqueue which has three rings, packed virtqueue only have
one which is supposed to have better cache utilization and more
hardware friendly.

Please refer virtio specification for more information.

Signed-off-by: Wei Xu 
Signed-off-by: Jason Wang 
Signed-off-by: Eugenio Pérez 
Message-Id: <20191025083527.30803-6-epere...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/block/virtio-blk.c   |   2 +-
 hw/char/virtio-serial-bus.c |   2 +-
 hw/scsi/virtio-scsi.c   |   3 +-
 hw/virtio/virtio.c  | 901 +---
 include/hw/virtio/virtio.h  |  10 +-
 5 files changed, 836 insertions(+), 82 deletions(-)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index ba846fe9dc..7dbdeaaab9 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -1052,7 +1052,7 @@ static void virtio_blk_save_device(VirtIODevice *vdev, 
QEMUFile *f)
 qemu_put_be32(f, virtio_get_queue_index(req->vq));
 }
 
-qemu_put_virtqueue_element(f, &req->elem);
+qemu_put_virtqueue_element(vdev, f, &req->elem);
 req = req->next;
 }
 qemu_put_sbyte(f, 0);
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 4e0ed829ae..33259042a9 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -708,7 +708,7 @@ static void virtio_serial_save_device(VirtIODevice *vdev, 
QEMUFile *f)
 if (elem_popped) {
 qemu_put_be32s(f, &port->iov_idx);
 qemu_put_be64s(f, &port->iov_offset);
-qemu_put_virtqueue_element(f, port->elem);
+qemu_put_virtqueue_element(vdev, f, port->elem);
 }
 }
 }
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index ee52aa7d17..e8b2b64d09 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -190,11 +190,12 @@ static void virtio_scsi_save_request(QEMUFile *f, 
SCSIRequest *sreq)
 {
 VirtIOSCSIReq *req = sreq->hba_private;
 VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(req->dev);
+VirtIODevice *vdev = VIRTIO_DEVICE(req->dev);
 uint32_t n = virtio_get_queue_index(req->vq) - 2;
 
 assert(n < vs->conf.num_queues);
 qemu_put_be32s(f, &n);
-qemu_put_virtqueue_element(f, &req->elem);
+qemu_put_virtqueue_element(vdev, f, &req->elem);
 }
 
 static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 74cc10fad9..a694b4ab50 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -96,6 +96,7 @@ typedef struct VRingPackedDescEvent {
 struct VirtQueue
 {
 VRing vring;
+VirtQueueElement *used_elems;
 
 /* Next head to pop */
 uint16_t last_avail_idx;
@@ -160,6 +161,7 @@ static void virtio_init_region_cache(VirtIODevice *vdev, 
int n)
 VRingMemoryRegionCaches *new = NULL;
 hwaddr addr, size;
 int64_t len;
+bool packed;
 
 
 addr = vq->vring.desc;
@@ -168,8 +170,10 @@ static void virtio_init_region_cache(VirtIODevice *vdev, 
int n)
 }
 new = g_new0(VRingMemoryRegionCaches, 1);
 size = virtio_queue_get_desc_size(vdev, n);
+packed = virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED) ?
+   true : false;
 len = address_space_cache_init(&new->desc, vdev->dma_as,
-   addr, size, false);
+   addr, size, packed);
 if (len < size) {
 virtio_error(vdev, "Cannot map desc");
 goto err_desc;
@@ -225,8 +229,8 @@ void virtio_queue_update_rings(VirtIODevice *vdev, int n)
 }
 
 /* Called within rcu_read_lock().  */
-static void vring_desc_read(VirtIODevice *vdev, VRingDesc *desc,
-MemoryRegionCache *cache, int i)
+static void vring_split_desc_read(VirtIODevice *vdev, VRingDesc *desc,
+  MemoryRegionCache *cache, int i)
 {
 address_space_read_cached(cache, i * sizeof(VRingDesc),
   desc, sizeof(VRingDesc));
@@ -236,6 +240,7 @@ static void vring_desc_read(VirtIODevice *vdev, VRingDesc 
*desc,
 virtio_tswap16s(vdev, &desc->next);
 }
 
+/* Called within rcu_read_lock().  */
 static VRingMemoryRegionCaches *vring_get_region_caches(struct VirtQueue *vq)
 {
 VRingMemoryRegionCaches *caches = atomic_rcu_read(&vq->vring.caches);
@@ -370,6 +375,95 @@ int virtio_queue_ready(VirtQueue *vq)
 return vq->vring.avail != 0;
 }
 
+static void vring_packed_desc_read_flags(VirtIODevice *vdev,
+ uint16_t *flags,
+ MemoryRegionCache *cache,
+ int i)
+{
+address_space_read_cached(cache,
+  i * sizeof(VRingPackedDesc) +
+  offsetof(VRingPackedDesc, flags),
+ 

[PULL 09/25] tests/virtio-blk-test: read config space after feature negotiation

2019-10-26 Thread Michael S. Tsirkin
From: Stefan Hajnoczi 

The VIRTIO Configuration Space cannot be accessed before device feature
bits have been read because a driver doesn't know the endianness until
it has checked VIRTIO_F_VERSION_1.

Fix this problem in preparation for VIRTIO 1.0 support.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Thomas Huth 
Message-Id: <20191023100425.12168-2-stefa...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 tests/virtio-blk-test.c | 33 -
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index ed13167392..f6674fb233 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -125,10 +125,6 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator 
*alloc,
 char *data;
 QTestState *qts = global_qtest;
 
-capacity = qvirtio_config_readq(dev, 0);
-
-g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
-
 features = qvirtio_get_features(dev);
 features = features & ~(QVIRTIO_F_BAD_FEATURE |
 (1u << VIRTIO_RING_F_INDIRECT_DESC) |
@@ -136,6 +132,9 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator 
*alloc,
 (1u << VIRTIO_BLK_F_SCSI));
 qvirtio_set_features(dev, features);
 
+capacity = qvirtio_config_readq(dev, 0);
+g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
+
 qvirtio_set_driver_ok(dev);
 
 /* Write and read with 3 descriptor layout */
@@ -359,9 +358,6 @@ static void indirect(void *obj, void *u_data, 
QGuestAllocator *t_alloc)
 char *data;
 QTestState *qts = global_qtest;
 
-capacity = qvirtio_config_readq(dev, 0);
-g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
-
 features = qvirtio_get_features(dev);
 g_assert_cmphex(features & (1u << VIRTIO_RING_F_INDIRECT_DESC), !=, 0);
 features = features & ~(QVIRTIO_F_BAD_FEATURE |
@@ -369,6 +365,9 @@ static void indirect(void *obj, void *u_data, 
QGuestAllocator *t_alloc)
 (1u << VIRTIO_BLK_F_SCSI));
 qvirtio_set_features(dev, features);
 
+capacity = qvirtio_config_readq(dev, 0);
+g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
+
 vq = qvirtqueue_setup(dev, t_alloc, 0);
 qvirtio_set_driver_ok(dev);
 
@@ -434,8 +433,16 @@ static void config(void *obj, void *data, QGuestAllocator 
*t_alloc)
 QVirtioBlk *blk_if = obj;
 QVirtioDevice *dev = blk_if->vdev;
 int n_size = TEST_IMAGE_SIZE / 2;
+uint64_t features;
 uint64_t capacity;
 
+features = qvirtio_get_features(dev);
+features = features & ~(QVIRTIO_F_BAD_FEATURE |
+(1u << VIRTIO_RING_F_INDIRECT_DESC) |
+(1u << VIRTIO_RING_F_EVENT_IDX) |
+(1u << VIRTIO_BLK_F_SCSI));
+qvirtio_set_features(dev, features);
+
 capacity = qvirtio_config_readq(dev, 0);
 g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
@@ -475,9 +482,6 @@ static void msix(void *obj, void *u_data, QGuestAllocator 
*t_alloc)
 qpci_msix_enable(pdev->pdev);
 qvirtio_pci_set_msix_configuration_vector(pdev, t_alloc, 0);
 
-capacity = qvirtio_config_readq(dev, 0);
-g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
-
 features = qvirtio_get_features(dev);
 features = features & ~(QVIRTIO_F_BAD_FEATURE |
 (1u << VIRTIO_RING_F_INDIRECT_DESC) |
@@ -485,6 +489,9 @@ static void msix(void *obj, void *u_data, QGuestAllocator 
*t_alloc)
 (1u << VIRTIO_BLK_F_SCSI));
 qvirtio_set_features(dev, features);
 
+capacity = qvirtio_config_readq(dev, 0);
+g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
+
 vq = qvirtqueue_setup(dev, t_alloc, 0);
 qvirtqueue_pci_msix_setup(pdev, (QVirtQueuePCI *)vq, t_alloc, 1);
 
@@ -584,9 +591,6 @@ static void idx(void *obj, void *u_data, QGuestAllocator 
*t_alloc)
 qpci_msix_enable(pdev->pdev);
 qvirtio_pci_set_msix_configuration_vector(pdev, t_alloc, 0);
 
-capacity = qvirtio_config_readq(dev, 0);
-g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
-
 features = qvirtio_get_features(dev);
 features = features & ~(QVIRTIO_F_BAD_FEATURE |
 (1u << VIRTIO_RING_F_INDIRECT_DESC) |
@@ -594,6 +598,9 @@ static void idx(void *obj, void *u_data, QGuestAllocator 
*t_alloc)
 (1u << VIRTIO_BLK_F_SCSI));
 qvirtio_set_features(dev, features);
 
+capacity = qvirtio_config_readq(dev, 0);
+g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
+
 vq = qvirtqueue_setup(dev, t_alloc, 0);
 qvirtqueue_pci_msix_setup(pdev, (QVirtQueuePCI *)vq, t_alloc, 1);
 
-- 
MST




[PULL 10/25] libqos: read QVIRTIO_MMIO_VERSION register

2019-10-26 Thread Michael S. Tsirkin
From: Stefan Hajnoczi 

There was no real virtio-mmio ABI change between Legacy and VIRTIO 1.0
except that the Version field was incremented from 1 to 2.

However, QEMU does not allow Legacy drivers to perform VIRTIO 1.0
operations like accessing 64-bit feature bits.  Since we will introduce
64-bit feature bit support we need a way to differentiate between
virtio-mmio Version 1 and 2 to avoid upsetting QEMU when we operate in
Legacy mode.

Stash away the Version field so later patches can change behavior
depending on the version.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Thomas Huth 
Message-Id: <20191023100425.12168-3-stefa...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 tests/libqos/virtio-mmio.c | 3 +++
 tests/libqos/virtio-mmio.h | 1 +
 2 files changed, 4 insertions(+)

diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c
index d0047876a8..7154b03c1d 100644
--- a/tests/libqos/virtio-mmio.c
+++ b/tests/libqos/virtio-mmio.c
@@ -223,6 +223,9 @@ void qvirtio_mmio_init_device(QVirtioMMIODevice *dev, 
QTestState *qts,
 magic = qtest_readl(qts, addr + QVIRTIO_MMIO_MAGIC_VALUE);
 g_assert(magic == ('v' | 'i' << 8 | 'r' << 16 | 't' << 24));
 
+dev->version = qtest_readl(qts, addr + QVIRTIO_MMIO_VERSION);
+g_assert(dev->version == 1 || dev->version == 2);
+
 dev->qts = qts;
 dev->addr = addr;
 dev->page_size = page_size;
diff --git a/tests/libqos/virtio-mmio.h b/tests/libqos/virtio-mmio.h
index 17a17141c3..0e45778b07 100644
--- a/tests/libqos/virtio-mmio.h
+++ b/tests/libqos/virtio-mmio.h
@@ -40,6 +40,7 @@ typedef struct QVirtioMMIODevice {
 uint64_t addr;
 uint32_t page_size;
 uint32_t features; /* As it cannot be read later, save it */
+uint32_t version;
 } QVirtioMMIODevice;
 
 extern const QVirtioBus qvirtio_mmio;
-- 
MST




[PULL 11/25] libqos: extend feature bits to 64-bit

2019-10-26 Thread Michael S. Tsirkin
From: Stefan Hajnoczi 

In VIRTIO 1.0 feature bits changed from 32-bit to 64-bit.  (In fact, the
transports allow even more feature bits but nothing uses more than 64
bits today.)

Add 64-bit feature bit support to virtio-mmio and virtio-pci.  This will
be necessary for VIRTIO 1.0 support.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Thomas Huth 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20191023100425.12168-4-stefa...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 tests/libqos/virtio-mmio.c | 28 ++--
 tests/libqos/virtio-net.c  |  6 +++---
 tests/libqos/virtio-pci.c  | 12 ++--
 tests/libqos/virtio.c  |  4 ++--
 tests/libqos/virtio.h  | 12 ++--
 tests/virtio-blk-test.c|  8 
 6 files changed, 43 insertions(+), 27 deletions(-)

diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c
index 7154b03c1d..78066e6e05 100644
--- a/tests/libqos/virtio-mmio.c
+++ b/tests/libqos/virtio-mmio.c
@@ -40,22 +40,38 @@ static uint64_t qvirtio_mmio_config_readq(QVirtioDevice *d, 
uint64_t off)
 return qtest_readq(dev->qts, dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + 
off);
 }
 
-static uint32_t qvirtio_mmio_get_features(QVirtioDevice *d)
+static uint64_t qvirtio_mmio_get_features(QVirtioDevice *d)
 {
 QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+uint64_t lo;
+uint64_t hi = 0;
+
 qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES_SEL, 0);
-return qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES);
+lo = qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES);
+
+if (dev->version >= 2) {
+qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES_SEL, 1);
+hi = qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES);
+}
+
+return (hi << 32) | lo;
 }
 
-static void qvirtio_mmio_set_features(QVirtioDevice *d, uint32_t features)
+static void qvirtio_mmio_set_features(QVirtioDevice *d, uint64_t features)
 {
 QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
 dev->features = features;
 qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES_SEL, 0);
 qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES, features);
+
+if (dev->version >= 2) {
+qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES_SEL, 1);
+qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES,
+ features >> 32);
+}
 }
 
-static uint32_t qvirtio_mmio_get_guest_features(QVirtioDevice *d)
+static uint64_t qvirtio_mmio_get_guest_features(QVirtioDevice *d)
 {
 QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
 return dev->features;
@@ -149,8 +165,8 @@ static QVirtQueue 
*qvirtio_mmio_virtqueue_setup(QVirtioDevice *d,
 vq->free_head = 0;
 vq->num_free = vq->size;
 vq->align = dev->page_size;
-vq->indirect = (dev->features & (1u << VIRTIO_RING_F_INDIRECT_DESC)) != 0;
-vq->event = (dev->features & (1u << VIRTIO_RING_F_EVENT_IDX)) != 0;
+vq->indirect = dev->features & (1ull << VIRTIO_RING_F_INDIRECT_DESC);
+vq->event = dev->features & (1ull << VIRTIO_RING_F_EVENT_IDX);
 
 qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_NUM, vq->size);
 
diff --git a/tests/libqos/virtio-net.c b/tests/libqos/virtio-net.c
index 6567beb553..710d440c3d 100644
--- a/tests/libqos/virtio-net.c
+++ b/tests/libqos/virtio-net.c
@@ -44,11 +44,11 @@ static void virtio_net_setup(QVirtioNet *interface)
 
 features = qvirtio_get_features(vdev);
 features &= ~(QVIRTIO_F_BAD_FEATURE |
-  (1u << VIRTIO_RING_F_INDIRECT_DESC) |
-  (1u << VIRTIO_RING_F_EVENT_IDX));
+  (1ull << VIRTIO_RING_F_INDIRECT_DESC) |
+  (1ull << VIRTIO_RING_F_EVENT_IDX));
 qvirtio_set_features(vdev, features);
 
-if (features & (1u << VIRTIO_NET_F_MQ)) {
+if (features & (1ull << VIRTIO_NET_F_MQ)) {
 interface->n_queues = qvirtio_config_readw(vdev, 8) * 2;
 } else {
 interface->n_queues = 2;
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 50499e75ef..1b6b760fc6 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -96,19 +96,19 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, 
uint64_t off)
 return val;
 }
 
-static uint32_t qvirtio_pci_get_features(QVirtioDevice *d)
+static uint64_t qvirtio_pci_get_features(QVirtioDevice *d)
 {
 QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
 return qpci_io_readl(dev->pdev, dev->bar, VIRTIO_PCI_HOST_FEATURES);
 }
 
-static void qvirtio_pci_set_features(QVirtioDevice *d, uint32_t features)
+static void qvirtio_pci_set_features(QVirtioDevice *d, uint64_t features)
 {
 QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
 qpci_io_writel(dev->pdev, dev->bar, VIRTIO_PCI_GUEST_FEATURES, features);
 }
 

[RFC PATCH v2 16/26] qcow2: Add subcluster support to discard_in_l2_slice()

2019-10-26 Thread Alberto Garcia
Setting the QCOW_OFLAG_ZERO bit of the L2 entry is forbidden if an
image has subclusters. Instead, the individual 'all zeroes' bits must
be used.

Signed-off-by: Alberto Garcia 
---
 block/qcow2-cluster.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 3e4ba8d448..aa3eb727a5 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1772,7 +1772,11 @@ static int discard_in_l2_slice(BlockDriverState *bs, 
uint64_t offset,
 
 /* First remove L2 entries */
 qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_slice);
-if (!full_discard && s->qcow_version >= 3) {
+if (has_subclusters(s)) {
+set_l2_entry(s, l2_slice, l2_index + i, 0);
+set_l2_bitmap(s, l2_slice, l2_index + i,
+  full_discard ? 0 : QCOW_L2_BITMAP_ALL_ZEROES);
+} else if (!full_discard && s->qcow_version >= 3) {
 set_l2_entry(s, l2_slice, l2_index + i, QCOW_OFLAG_ZERO);
 } else {
 set_l2_entry(s, l2_slice, l2_index + i, 0);
-- 
2.20.1




[RFC PATCH v2 25/26] qcow2: Allow preallocation and backing files if extended_l2 is set

2019-10-26 Thread Alberto Garcia
Traditional qcow2 images don't allow preallocation if a backing file
is set. This is because once a cluster is allocated there is no way to
tell that its data should be read from the backing file.

Extended L2 entries have individual allocation bits for each
subcluster, and therefore it is perfectly possible to have an
allocated cluster with all its subclusters unallocated.

Signed-off-by: Alberto Garcia 
---
 block/qcow2.c  | 7 ---
 tests/qemu-iotests/206.out | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index b1fa7ab5da..8cf51c5d64 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3307,10 +3307,11 @@ qcow2_co_create(BlockdevCreateOptions *create_options, 
Error **errp)
 qcow2_opts->preallocation = PREALLOC_MODE_OFF;
 }
 if (qcow2_opts->has_backing_file &&
-qcow2_opts->preallocation != PREALLOC_MODE_OFF)
+qcow2_opts->preallocation != PREALLOC_MODE_OFF &&
+!qcow2_opts->extended_l2)
 {
-error_setg(errp, "Backing file and preallocation cannot be used at "
-   "the same time");
+error_setg(errp, "Backing file and preallocation can only be used at "
+   "the same time if extended_l2 is on");
 ret = -EINVAL;
 goto out;
 }
diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out
index d2efc0394a..cfddfbfaa4 100644
--- a/tests/qemu-iotests/206.out
+++ b/tests/qemu-iotests/206.out
@@ -198,7 +198,7 @@ Job failed: Different refcount widths than 16 bits require 
compatibility level 1
 === Invalid backing file options ===
 {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": 
{"backing-file": "/dev/null", "driver": "qcow2", "file": "node0", 
"preallocation": "full", "size": 67108864}}}
 {"return": {}}
-Job failed: Backing file and preallocation cannot be used at the same time
+Job failed: Backing file and preallocation can only be used at the same time 
if extended_l2 is on
 {"execute": "job-dismiss", "arguments": {"id": "job0"}}
 {"return": {}}
 
-- 
2.20.1




[RFC PATCH v2 13/26] qcow2: Add subcluster support to calculate_l2_meta()

2019-10-26 Thread Alberto Garcia
If an image has subclusters then there are more copy-on-write
scenarios that we need to consider. Let's say we have a write request
from the middle of subcluster #3 until the end of the cluster:

   - If the cluster is new, then subclusters #0 to #3 from the old
 cluster must be copied into the new one.

   - If the cluster is new but the old cluster was unallocated, then
 only subcluster #3 needs copy-on-write. #0 to #2 are marked as
 unallocated in the bitmap of the new L2 entry.

   - If we are overwriting an old cluster and subcluster #3 is
 unallocated or has the all-zeroes bit set then we need
 copy-on-write on subcluster #3.

   - If we are overwriting an old cluster and subcluster #3 was
 allocated then there is no need to copy-on-write.

Signed-off-by: Alberto Garcia 
---
 block/qcow2-cluster.c | 136 +-
 1 file changed, 108 insertions(+), 28 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 1f509bda15..990bc070af 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1034,14 +1034,16 @@ void qcow2_alloc_cluster_abort(BlockDriverState *bs, 
QCowL2Meta *m)
  * If @keep_old is true it means that the clusters were already
  * allocated and will be overwritten. If false then the clusters are
  * new and we have to decrease the reference count of the old ones.
+ *
+ * Returns 1 on success, -errno on failure.
  */
-static void calculate_l2_meta(BlockDriverState *bs, uint64_t host_offset,
-  uint64_t guest_offset, uint64_t bytes,
-  uint64_t *l2_slice, QCowL2Meta **m, bool 
keep_old)
+static int calculate_l2_meta(BlockDriverState *bs, uint64_t host_offset,
+ uint64_t guest_offset, uint64_t bytes,
+ uint64_t *l2_slice, QCowL2Meta **m, bool keep_old)
 {
 BDRVQcow2State *s = bs->opaque;
-int l2_index = offset_to_l2_slice_index(s, guest_offset);
-uint64_t l2_entry;
+int sc_index, l2_index = offset_to_l2_slice_index(s, guest_offset);
+uint64_t l2_entry, l2_bitmap;
 unsigned cow_start_from, cow_end_to;
 unsigned cow_start_to = offset_into_cluster(s, guest_offset);
 unsigned cow_end_from = cow_start_to + bytes;
@@ -1049,38 +1051,108 @@ static void calculate_l2_meta(BlockDriverState *bs, 
uint64_t host_offset,
 QCowL2Meta *old_m = *m;
 QCow2ClusterType type;
 
-/* Return if there's no COW (all clusters are normal and we keep them) */
+/* Return if there's no COW (all subclusters are normal and we are
+ * keeping the clusters) */
 if (keep_old) {
+unsigned first_sc = cow_start_to / s->subcluster_size;
+unsigned last_sc = (cow_end_from - 1) / s->subcluster_size;
 int i;
-for (i = 0; i < nb_clusters; i++) {
-l2_entry = get_l2_entry(s, l2_slice, l2_index + i);
-if (qcow2_get_cluster_type(bs, l2_entry) != QCOW2_CLUSTER_NORMAL) {
+for (i = first_sc; i <= last_sc; i++) {
+unsigned c = i / s->subclusters_per_cluster;
+unsigned sc = i % s->subclusters_per_cluster;
+l2_entry = get_l2_entry(s, l2_slice, l2_index + c);
+l2_bitmap = get_l2_bitmap(s, l2_slice, l2_index + c);
+type = qcow2_get_subcluster_type(bs, l2_entry, l2_bitmap, sc);
+if (type == QCOW2_CLUSTER_INVALID) {
+l2_index += c; /* Point to the invalid entry */
+goto fail;
+}
+if (type != QCOW2_CLUSTER_NORMAL) {
 break;
 }
 }
-if (i == nb_clusters) {
-return;
+if (i == last_sc + 1) {
+return 1;
 }
 }
 
 /* Get the L2 entry from the first cluster */
 l2_entry = get_l2_entry(s, l2_slice, l2_index);
-type = qcow2_get_cluster_type(bs, l2_entry);
+l2_bitmap = get_l2_bitmap(s, l2_slice, l2_index);
+sc_index = offset_to_sc_index(s, guest_offset);
+type = qcow2_get_subcluster_type(bs, l2_entry, l2_bitmap, sc_index);
 
-if (type == QCOW2_CLUSTER_NORMAL && keep_old) {
-cow_start_from = cow_start_to;
+if (type == QCOW2_CLUSTER_INVALID) {
+goto fail;
+}
+
+if (!keep_old) {
+switch (type) {
+case QCOW2_CLUSTER_NORMAL:
+case QCOW2_CLUSTER_COMPRESSED:
+case QCOW2_CLUSTER_ZERO_ALLOC:
+case QCOW2_CLUSTER_UNALLOCATED_SUBCLUSTER:
+cow_start_from = 0;
+break;
+case QCOW2_CLUSTER_ZERO_PLAIN:
+case QCOW2_CLUSTER_UNALLOCATED:
+cow_start_from = sc_index << s->subcluster_bits;
+break;
+default:
+g_assert_not_reached();
+}
 } else {
-cow_start_from = 0;
+switch (type) {
+case QCOW2_CLUSTER_NORMAL:
+cow_start_from = cow_start_to;
+break;
+case QCOW2_CLUSTER_ZERO_ALLOC:
+case QCOW2_CLUSTER_UNALLOCAT

[RFC PATCH v2 21/26] qcow2: Clear the L2 bitmap when allocating a compressed cluster

2019-10-26 Thread Alberto Garcia
Compressed clusters always have the bitmap part of the extended L2
entry set to 0.

Signed-off-by: Alberto Garcia 
---
 block/qcow2-cluster.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index acb7226e03..3ba8a98073 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -783,6 +783,7 @@ int qcow2_alloc_compressed_cluster_offset(BlockDriverState 
*bs,
 BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);
 qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_slice);
 set_l2_entry(s, l2_slice, l2_index, cluster_offset);
+set_l2_bitmap(s, l2_slice, l2_index, 0);
 qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);
 
 *host_offset = cluster_offset & s->cluster_offset_mask;
-- 
2.20.1




[RFC PATCH v2 20/26] qcow2: Update L2 bitmap in qcow2_alloc_cluster_link_l2()

2019-10-26 Thread Alberto Garcia
The L2 bitmap needs to be updated after each write to indicate what
new subclusters are now allocated.

This needs to happen even if the cluster was already allocated and the
L2 entry was otherwise valid.

Signed-off-by: Alberto Garcia 
---
 block/qcow2-cluster.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index fb6cf8df17..acb7226e03 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -980,6 +980,22 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, 
QCowL2Meta *m)
 
 set_l2_entry(s, l2_slice, l2_index + i, QCOW_OFLAG_COPIED |
  (cluster_offset + (i << s->cluster_bits)));
+
+/* Update bitmap with the subclusters that were just written */
+if (has_subclusters(s)) {
+uint64_t written_from = m->cow_start.offset;
+uint64_t written_to = m->cow_end.offset + m->cow_end.nb_bytes;
+uint64_t l2_bitmap = get_l2_bitmap(s, l2_slice, l2_index + i);
+int sc;
+for (sc = 0; sc < s->subclusters_per_cluster; sc++) {
+uint64_t sc_off = i * s->cluster_size + sc * 
s->subcluster_size;
+if (sc_off >= written_from && sc_off < written_to) {
+l2_bitmap |= QCOW_OFLAG_SUB_ALLOC(sc);
+l2_bitmap &= ~QCOW_OFLAG_SUB_ZERO(sc);
+}
+}
+set_l2_bitmap(s, l2_slice, l2_index + i, l2_bitmap);
+}
  }
 
 
-- 
2.20.1




[RFC PATCH v2 14/26] qcow2: Add subcluster support to qcow2_get_cluster_offset()

2019-10-26 Thread Alberto Garcia
The logic of this function remains pretty much the same, except that
it uses count_contiguous_subclusters(), which combines the logic of
count_contiguous_clusters() / count_contiguous_clusters_unallocated()
and checks individual subclusters.

Signed-off-by: Alberto Garcia 
---
 block/qcow2-cluster.c | 111 --
 1 file changed, 52 insertions(+), 59 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 990bc070af..e67559152f 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -372,66 +372,51 @@ fail:
 }
 
 /*
- * Checks how many clusters in a given L2 slice are contiguous in the image
- * file. As soon as one of the flags in the bitmask stop_flags changes compared
- * to the first cluster, the search is stopped and the cluster is not counted
- * as contiguous. (This allows it, for example, to stop at the first compressed
- * cluster which may require a different handling)
+ * Return the number of contiguous subclusters of the exact same type
+ * in a given L2 slice, starting from cluster @l2_index, subcluster
+ * @sc_index. At most @nb_clusters are checked. Allocated clusters are
+ * also required to be contiguous in the image file.
  */
-static int count_contiguous_clusters(BlockDriverState *bs, int nb_clusters,
-int cluster_size, uint64_t *l2_slice, int l2_index, uint64_t 
stop_flags)
+static int count_contiguous_subclusters(BlockDriverState *bs, int nb_clusters,
+unsigned sc_index, uint64_t *l2_slice,
+int l2_index)
 {
 BDRVQcow2State *s = bs->opaque;
-int i;
-QCow2ClusterType first_cluster_type;
-uint64_t mask = stop_flags | L2E_OFFSET_MASK | QCOW_OFLAG_COMPRESSED;
-uint64_t first_entry = get_l2_entry(s, l2_slice, l2_index);
-uint64_t offset = first_entry & mask;
-
-first_cluster_type = qcow2_get_cluster_type(bs, first_entry);
-if (first_cluster_type == QCOW2_CLUSTER_UNALLOCATED) {
-return 0;
+int i, j, count = 0;
+uint64_t l2_entry = get_l2_entry(s, l2_slice, l2_index);
+uint64_t l2_bitmap = get_l2_bitmap(s, l2_slice, l2_index);
+uint64_t expected_offset = l2_entry & L2E_OFFSET_MASK;
+bool check_offset = true;
+QCow2ClusterType type =
+qcow2_get_subcluster_type(bs, l2_entry, l2_bitmap, sc_index);
+
+assert(type != QCOW2_CLUSTER_INVALID); /* The caller should check this */
+
+if (type == QCOW2_CLUSTER_COMPRESSED) {
+return 1; /* Compressed clusters are always counted one by one */
 }
 
-/* must be allocated */
-assert(first_cluster_type == QCOW2_CLUSTER_NORMAL ||
-   first_cluster_type == QCOW2_CLUSTER_ZERO_ALLOC);
-
-for (i = 0; i < nb_clusters; i++) {
-uint64_t l2_entry = get_l2_entry(s, l2_slice, l2_index + i) & mask;
-if (offset + (uint64_t) i * cluster_size != l2_entry) {
-break;
-}
+if (type == QCOW2_CLUSTER_UNALLOCATED || type == QCOW2_CLUSTER_ZERO_PLAIN) 
{
+check_offset = false;
 }
 
-return i;
-}
-
-/*
- * Checks how many consecutive unallocated clusters in a given L2
- * slice have the same cluster type.
- */
-static int count_contiguous_clusters_unallocated(BlockDriverState *bs,
- int nb_clusters,
- uint64_t *l2_slice,
- int l2_index,
- QCow2ClusterType wanted_type)
-{
-BDRVQcow2State *s = bs->opaque;
-int i;
-
-assert(wanted_type == QCOW2_CLUSTER_ZERO_PLAIN ||
-   wanted_type == QCOW2_CLUSTER_UNALLOCATED);
 for (i = 0; i < nb_clusters; i++) {
-uint64_t entry = get_l2_entry(s, l2_slice, l2_index + i);
-QCow2ClusterType type = qcow2_get_cluster_type(bs, entry);
-
-if (type != wanted_type) {
-break;
+l2_entry = get_l2_entry(s, l2_slice, l2_index + i);
+l2_bitmap = get_l2_bitmap(s, l2_slice, l2_index + i);
+if (check_offset && expected_offset != (l2_entry & L2E_OFFSET_MASK)) {
+goto out;
+}
+for (j = (i == 0) ? sc_index : 0; j < s->subclusters_per_cluster; j++) 
{
+if (qcow2_get_subcluster_type(bs, l2_entry, l2_bitmap, j) != type) 
{
+goto out;
+}
+count++;
 }
+expected_offset += s->cluster_size;
 }
 
-return i;
+out:
+return count;
 }
 
 static int coroutine_fn do_perform_cow_read(BlockDriverState *bs,
@@ -514,8 +499,8 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t 
offset,
  unsigned int *bytes, uint64_t *cluster_offset)
 {
 BDRVQcow2State *s = bs->opaque;
-unsigned int l2_index;
-uint64_t l1_index, l2_offset, *l2_slice;
+unsigned int l2_index, sc_index;
+uint64_t l1_index, l2_offset, *l2_slice, l2_bitmap;
 int c;
 

[RFC PATCH v2 19/26] qcow2: Fix offset calculation in handle_dependencies()

2019-10-26 Thread Alberto Garcia
l2meta_cow_start() and l2meta_cow_end() are not necessarily
cluster-aligned if the image has subclusters, so update the
calculation of old_start and old_end to guarantee that no two requests
try to write on the same cluster.

Signed-off-by: Alberto Garcia 
---
 block/qcow2-cluster.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 62f2a9fcc0..fb6cf8df17 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1262,8 +1262,8 @@ static int handle_dependencies(BlockDriverState *bs, 
uint64_t guest_offset,
 
 uint64_t start = guest_offset;
 uint64_t end = start + bytes;
-uint64_t old_start = l2meta_cow_start(old_alloc);
-uint64_t old_end = l2meta_cow_end(old_alloc);
+uint64_t old_start = start_of_cluster(s, l2meta_cow_start(old_alloc));
+uint64_t old_end = ROUND_UP(l2meta_cow_end(old_alloc), 
s->cluster_size);
 
 if (end <= old_start || start >= old_end) {
 /* No intersection */
-- 
2.20.1




[RFC PATCH v2 15/26] qcow2: Add subcluster support to zero_in_l2_slice()

2019-10-26 Thread Alberto Garcia
Setting the QCOW_OFLAG_ZERO bit of the L2 entry is forbidden if an
image has subclusters. Instead, the individual 'all zeroes' bits must
be used.

Signed-off-by: Alberto Garcia 
---
 block/qcow2-cluster.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index e67559152f..3e4ba8d448 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1852,7 +1852,7 @@ static int zero_in_l2_slice(BlockDriverState *bs, 
uint64_t offset,
 assert(nb_clusters <= INT_MAX);
 
 for (i = 0; i < nb_clusters; i++) {
-uint64_t old_offset;
+uint64_t old_offset, l2_entry = 0;
 QCow2ClusterType cluster_type;
 
 old_offset = get_l2_entry(s, l2_slice, l2_index + i);
@@ -1869,12 +1869,18 @@ static int zero_in_l2_slice(BlockDriverState *bs, 
uint64_t offset,
 
 qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_slice);
 if (cluster_type == QCOW2_CLUSTER_COMPRESSED || unmap) {
-set_l2_entry(s, l2_slice, l2_index + i, QCOW_OFLAG_ZERO);
 qcow2_free_any_clusters(bs, old_offset, 1, QCOW2_DISCARD_REQUEST);
 } else {
-uint64_t entry = get_l2_entry(s, l2_slice, l2_index + i);
-set_l2_entry(s, l2_slice, l2_index + i, entry | QCOW_OFLAG_ZERO);
+l2_entry = get_l2_entry(s, l2_slice, l2_index + i);
 }
+
+if (has_subclusters(s)) {
+set_l2_bitmap(s, l2_slice, l2_index + i, 
QCOW_L2_BITMAP_ALL_ZEROES);
+} else {
+l2_entry |= QCOW_OFLAG_ZERO;
+}
+
+set_l2_entry(s, l2_slice, l2_index + i, l2_entry);
 }
 
 qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);
-- 
2.20.1




[RFC PATCH v2 02/26] qcow2: Split cluster_needs_cow() out of count_cow_clusters()

2019-10-26 Thread Alberto Garcia
We are going to need it in other places.

Signed-off-by: Alberto Garcia 
---
 block/qcow2-cluster.c | 34 +++---
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 6c1dcdc781..aa1010a515 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1068,6 +1068,24 @@ static void calculate_l2_meta(BlockDriverState *bs, 
uint64_t host_offset,
 QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight);
 }
 
+/* Returns true if writing to a cluster requires COW */
+static bool cluster_needs_cow(BlockDriverState *bs, uint64_t l2_entry)
+{
+switch (qcow2_get_cluster_type(bs, l2_entry)) {
+case QCOW2_CLUSTER_NORMAL:
+if (l2_entry & QCOW_OFLAG_COPIED) {
+return false;
+}
+case QCOW2_CLUSTER_UNALLOCATED:
+case QCOW2_CLUSTER_COMPRESSED:
+case QCOW2_CLUSTER_ZERO_PLAIN:
+case QCOW2_CLUSTER_ZERO_ALLOC:
+return true;
+default:
+abort();
+}
+}
+
 /*
  * Returns the number of contiguous clusters that can be used for an allocating
  * write, but require COW to be performed (this includes yet unallocated space,
@@ -1080,25 +1098,11 @@ static int count_cow_clusters(BlockDriverState *bs, int 
nb_clusters,
 
 for (i = 0; i < nb_clusters; i++) {
 uint64_t l2_entry = be64_to_cpu(l2_slice[l2_index + i]);
-QCow2ClusterType cluster_type = qcow2_get_cluster_type(bs, l2_entry);
-
-switch(cluster_type) {
-case QCOW2_CLUSTER_NORMAL:
-if (l2_entry & QCOW_OFLAG_COPIED) {
-goto out;
-}
+if (!cluster_needs_cow(bs, l2_entry)) {
 break;
-case QCOW2_CLUSTER_UNALLOCATED:
-case QCOW2_CLUSTER_COMPRESSED:
-case QCOW2_CLUSTER_ZERO_PLAIN:
-case QCOW2_CLUSTER_ZERO_ALLOC:
-break;
-default:
-abort();
 }
 }
 
-out:
 assert(i <= nb_clusters);
 return i;
 }
-- 
2.20.1




[RFC PATCH v2 03/26] qcow2: Process QCOW2_CLUSTER_ZERO_ALLOC clusters in handle_copied()

2019-10-26 Thread Alberto Garcia
When writing to a qcow2 file there are two functions that take a
virtual offset and return a host offset, possibly allocating new
clusters if necessary:

   - handle_copied() looks for normal data clusters that are already
 allocated and have a reference count of 1. In those clusters we
 can simply write the data and there is no need to perform any
 copy-on-write.

   - handle_alloc() looks for clusters that do need copy-on-write,
 either because they haven't been allocated yet, because their
 reference count is != 1 or because they are ZERO_ALLOC clusters.

The ZERO_ALLOC case is a bit special because those are clusters that
are already allocated and they could perfectly be dealt with in
handle_copied() (as long as copy-on-write is performed when required).

In fact, there is extra code specifically for them in handle_alloc()
that tries to reuse the existing allocation if possible and frees them
otherwise.

This patch changes the handling of ZERO_ALLOC clusters so the
semantics of these two functions are now like this:

   - handle_copied() looks for clusters that are already allocated and
 which we can overwrite (NORMAL and ZERO_ALLOC clusters with a
 reference count of 1).

   - handle_alloc() looks for clusters for which we need a new
 allocation (all other cases).

One importante difference after this change is that clusters found in
handle_copied() may now require copy-on-write, but this will be anyway
necessary once we add support for subclusters.

Signed-off-by: Alberto Garcia 
---
 block/qcow2-cluster.c | 177 +++---
 1 file changed, 96 insertions(+), 81 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index aa1010a515..ee6b46f917 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1021,7 +1021,8 @@ void qcow2_alloc_cluster_abort(BlockDriverState *bs, 
QCowL2Meta *m)
 
 /*
  * For a given write request, create a new QCowL2Meta structure and
- * add it to @m.
+ * add it to @m. If the write request does not need copy-on-write or
+ * changes to the L2 metadata then this function does nothing.
  *
  * @host_offset points to the beginning of the first cluster.
  *
@@ -1034,15 +1035,51 @@ void qcow2_alloc_cluster_abort(BlockDriverState *bs, 
QCowL2Meta *m)
  */
 static void calculate_l2_meta(BlockDriverState *bs, uint64_t host_offset,
   uint64_t guest_offset, uint64_t bytes,
-  QCowL2Meta **m, bool keep_old)
+  uint64_t *l2_slice, QCowL2Meta **m, bool 
keep_old)
 {
 BDRVQcow2State *s = bs->opaque;
-unsigned cow_start_from = 0;
+int l2_index = offset_to_l2_slice_index(s, guest_offset);
+uint64_t l2_entry;
+unsigned cow_start_from, cow_end_to;
 unsigned cow_start_to = offset_into_cluster(s, guest_offset);
 unsigned cow_end_from = cow_start_to + bytes;
-unsigned cow_end_to = ROUND_UP(cow_end_from, s->cluster_size);
 unsigned nb_clusters = size_to_clusters(s, cow_end_from);
 QCowL2Meta *old_m = *m;
+QCow2ClusterType type;
+
+/* Return if there's no COW (all clusters are normal and we keep them) */
+if (keep_old) {
+int i;
+for (i = 0; i < nb_clusters; i++) {
+l2_entry = be64_to_cpu(l2_slice[l2_index + i]);
+if (qcow2_get_cluster_type(bs, l2_entry) != QCOW2_CLUSTER_NORMAL) {
+break;
+}
+}
+if (i == nb_clusters) {
+return;
+}
+}
+
+/* Get the L2 entry from the first cluster */
+l2_entry = be64_to_cpu(l2_slice[l2_index]);
+type = qcow2_get_cluster_type(bs, l2_entry);
+
+if (type == QCOW2_CLUSTER_NORMAL && keep_old) {
+cow_start_from = cow_start_to;
+} else {
+cow_start_from = 0;
+}
+
+/* Get the L2 entry from the last cluster */
+l2_entry = be64_to_cpu(l2_slice[l2_index + nb_clusters - 1]);
+type = qcow2_get_cluster_type(bs, l2_entry);
+
+if (type == QCOW2_CLUSTER_NORMAL && keep_old) {
+cow_end_to = cow_end_from;
+} else {
+cow_end_to = ROUND_UP(cow_end_from, s->cluster_size);
+}
 
 *m = g_malloc0(sizeof(**m));
 **m = (QCowL2Meta) {
@@ -1068,18 +1105,18 @@ static void calculate_l2_meta(BlockDriverState *bs, 
uint64_t host_offset,
 QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight);
 }
 
-/* Returns true if writing to a cluster requires COW */
+/* Returns true if the cluster is unallocated or has refcount > 1 */
 static bool cluster_needs_cow(BlockDriverState *bs, uint64_t l2_entry)
 {
 switch (qcow2_get_cluster_type(bs, l2_entry)) {
 case QCOW2_CLUSTER_NORMAL:
+case QCOW2_CLUSTER_ZERO_ALLOC:
 if (l2_entry & QCOW_OFLAG_COPIED) {
 return false;
 }
 case QCOW2_CLUSTER_UNALLOCATED:
 case QCOW2_CLUSTER_COMPRESSED:
 case QCOW2_CLUSTER_ZERO_PLAIN:
-case QCOW2_CLUSTER_ZERO_ALLOC:
 return true;
 default:
  

[RFC PATCH v2 26/26] iotests: Add tests for qcow2 images with extended L2 entries

2019-10-26 Thread Alberto Garcia
Signed-off-by: Alberto Garcia 
---
 tests/qemu-iotests/271 | 235 +
 tests/qemu-iotests/271.out | 183 +
 tests/qemu-iotests/group   |   1 +
 3 files changed, 419 insertions(+)
 create mode 100755 tests/qemu-iotests/271
 create mode 100644 tests/qemu-iotests/271.out

diff --git a/tests/qemu-iotests/271 b/tests/qemu-iotests/271
new file mode 100755
index 00..c49433cdc9
--- /dev/null
+++ b/tests/qemu-iotests/271
@@ -0,0 +1,235 @@
+#!/bin/bash
+#
+# Test qcow2 images with extended L2 entries
+#
+# Copyright (C) 2019 Igalia, S.L.
+# Author: Alberto Garcia 
+#
+# This program 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+# creator
+owner=be...@igalia.com
+
+seq="$(basename $0)"
+echo "QA output created by $seq"
+
+here="$PWD"
+status=1   # failure is the default!
+
+_cleanup()
+{
+   _cleanup_test_img
+rm -f "$TEST_IMG.raw"
+rm -f "$TEST_IMG.backing"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto file nfs
+_supported_os Linux
+
+IMGOPTS="extended_l2=on"
+l2_offset=262144 # 0x4
+
+_verify_img()
+{
+$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG.raw" | grep -v 'Images are 
identical'
+$QEMU_IMG check "$TEST_IMG" | _filter_qemu_img_check | \
+grep -v 'No errors were found on the image'
+}
+
+_read_l2_entry()
+{
+entry_no=$1
+nentries=$2
+offset=$(($l2_offset + $entry_no * 16))
+length=$((nentries * 16))
+$QEMU_IO -f raw -c "read -v $offset $length" "$TEST_IMG" | _filter_qemu_io 
| head -n -2
+}
+
+_test_write()
+{
+cmd="$1"
+l2_entry_idx="$2"
+l2_entry_num="$3"
+raw_cmd=`echo $1 | sed s/-c//` # Raw images don't support -c
+echo "$cmd"
+$QEMU_IO -c "$cmd" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "$raw_cmd" -f raw "$TEST_IMG.raw" | _filter_qemu_io
+_verify_img
+if [ -n "$l2_entry_idx" ]; then
+_read_l2_entry "$l2_entry_idx" "$l2_entry_num"
+fi
+}
+
+_reset_img()
+{
+$QEMU_IMG create -f raw "$TEST_IMG.raw" 1M | _filter_img_create
+if [ "$use_backing_file" = "yes" ]; then
+$QEMU_IMG create -f raw "$TEST_IMG.backing" 1M | _filter_img_create
+$QEMU_IO -c 'write -q -P 0xFF 0 1M' -f raw "$TEST_IMG.backing" | 
_filter_qemu_io
+$QEMU_IO -c 'write -q -P 0xFF 0 1M' -f raw "$TEST_IMG.raw" | 
_filter_qemu_io
+_make_test_img -b "$TEST_IMG.backing" 1M
+else
+_make_test_img 1M
+fi
+}
+
+# Test that writing to an image with subclusters produces the expected
+# results, in images with and without backing files
+for use_backing_file in yes no; do
+echo
+echo "### Standard write tests (backing file: $use_backing_file) ###"
+echo
+_reset_img
+### Write subcluster #0 (beginning of subcluster) ###
+_test_write 'write -q -P 1 0 1k' 0 1
+
+### Write subcluster #1 (middle of subcluster) ###
+_test_write 'write -q -P 2 3k 512' 0 1
+
+### Write subcluster #2 (end of subcluster) ###
+_test_write 'write -q -P 3 5k 1k' 0 1
+
+### Write subcluster #3 (full subcluster) ###
+_test_write 'write -q -P 4 6k 2k' 0 1
+
+### Write subclusters #4-6 (full subclusters) ###
+_test_write 'write -q -P 5 8k 6k' 0 1
+
+### Write subclusters #7-9 (partial subclusters) ###
+_test_write 'write -q -P 6 15k 4k' 0 1
+
+### Write subcluster #16 (partial subcluster) ###
+_test_write 'write -q -P 7 32k 1k' 0 2
+
+### Write subcluster #31-#34 (cluster overlap) ###
+_test_write 'write -q -P 8 63k 4k' 0 2
+
+### Zero subcluster #1 (TODO: use the "all zeros" bit)
+_test_write 'write -q -z 2k 2k' 0 1
+
+### Zero cluster #0
+_test_write 'write -q -z 0 64k' 0 1
+
+### Fill cluster #0 with data
+_test_write 'write -q -P 9 0 64k' 0 1
+
+### Zero and unmap half of cluster #0 (this won't unmap it)
+_test_write 'write -q -z -u 0 32k' 0 1
+
+### Zero and unmap cluster #0
+_test_write 'write -q -z -u 0 64k' 0 1
+
+### Write subcluster #2 (middle of subcluster)
+_test_write 'write -q -P 10 3k 512' 0 1
+
+### Fill cluster #0 with data
+_test_write 'write -q -P 11 0 64k' 0 1
+
+### Discard cluster #0
+_test_write 'discard -q 0 64k' 0 1
+
+### Write compressed data to cluster #0
+_test_write 'write -q -c 

[RFC PATCH v2 24/26] qcow2: Add the 'extended_l2' option and the QCOW2_INCOMPAT_EXTL2 bit

2019-10-26 Thread Alberto Garcia
Now that the implementation of subclusters is complete we can finally
add the necessary options to create and read images with this feature,
which we call "extended L2 entries".

Signed-off-by: Alberto Garcia 
---
 block/qcow2.c|  46 ++
 block/qcow2.h|   8 ++-
 include/block/block_int.h|   1 +
 qapi/block-core.json |   6 ++
 tests/qemu-iotests/031.out   |   8 +--
 tests/qemu-iotests/036.out   |   4 +-
 tests/qemu-iotests/049.out   | 102 +++
 tests/qemu-iotests/060.out   |   1 +
 tests/qemu-iotests/061.out   |  20 +++---
 tests/qemu-iotests/065   |  18 --
 tests/qemu-iotests/082.out   |  48 ---
 tests/qemu-iotests/085.out   |  38 ++--
 tests/qemu-iotests/144.out   |   4 +-
 tests/qemu-iotests/182.out   |   2 +-
 tests/qemu-iotests/185.out   |   8 +--
 tests/qemu-iotests/198.out   |   2 +
 tests/qemu-iotests/206.out   |   4 ++
 tests/qemu-iotests/242.out   |   5 ++
 tests/qemu-iotests/255.out   |   8 +--
 tests/qemu-iotests/common.filter |   1 +
 20 files changed, 224 insertions(+), 110 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 537569ce88..b1fa7ab5da 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1347,6 +1347,12 @@ static int coroutine_fn qcow2_do_open(BlockDriverState 
*bs, QDict *options,
 s->subcluster_size = s->cluster_size / s->subclusters_per_cluster;
 s->subcluster_bits = ctz32(s->subcluster_size);
 
+if (s->subcluster_size < (1 << MIN_CLUSTER_BITS)) {
+error_setg(errp, "Unsupported subcluster size: %d", 
s->subcluster_size);
+ret = -EINVAL;
+goto fail;
+}
+
 /* Check support for various header values */
 if (header.refcount_order > 6) {
 error_setg(errp, "Reference count entry width too large; may not "
@@ -2806,6 +2812,11 @@ int qcow2_update_header(BlockDriverState *bs)
 .bit  = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
 .name = "lazy refcounts",
 },
+{
+.type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
+.bit  = QCOW2_INCOMPAT_EXTL2_BITNR,
+.name = "extended L2 entries",
+},
 };
 
 ret = header_ext_add(buf, QCOW2_EXT_MAGIC_FEATURE_TABLE,
@@ -3271,6 +3282,27 @@ qcow2_co_create(BlockdevCreateOptions *create_options, 
Error **errp)
 goto out;
 }
 
+if (!qcow2_opts->has_extended_l2) {
+qcow2_opts->extended_l2 = false;
+}
+if (qcow2_opts->extended_l2) {
+unsigned min_cluster_size =
+(1 << MIN_CLUSTER_BITS) * QCOW_MAX_SUBCLUSTERS_PER_CLUSTER;
+if (version < 3) {
+error_setg(errp, "Extended L2 entries are only supported with "
+   "compatibility level 1.1 and above (use version=v3 or "
+   "greater)");
+ret = -EINVAL;
+goto out;
+}
+if (cluster_size < min_cluster_size) {
+error_setg(errp, "Extended L2 entries are only supported with "
+   "cluster sizes of at least %u bytes", min_cluster_size);
+ret = -EINVAL;
+goto out;
+}
+}
+
 if (!qcow2_opts->has_preallocation) {
 qcow2_opts->preallocation = PREALLOC_MODE_OFF;
 }
@@ -3392,6 +3424,11 @@ qcow2_co_create(BlockdevCreateOptions *create_options, 
Error **errp)
 cpu_to_be64(QCOW2_AUTOCLEAR_DATA_FILE_RAW);
 }
 
+if (qcow2_opts->extended_l2) {
+header->incompatible_features |=
+cpu_to_be64(QCOW2_INCOMPAT_EXTL2);
+}
+
 ret = blk_pwrite(blk, 0, header, cluster_size, 0);
 g_free(header);
 if (ret < 0) {
@@ -3569,6 +3606,7 @@ static int coroutine_fn qcow2_co_create_opts(const char 
*filename, QemuOpts *opt
 { BLOCK_OPT_BACKING_FMT,"backing-fmt" },
 { BLOCK_OPT_CLUSTER_SIZE,   "cluster-size" },
 { BLOCK_OPT_LAZY_REFCOUNTS, "lazy-refcounts" },
+{ BLOCK_OPT_EXTL2,  "extended-l2" },
 { BLOCK_OPT_REFCOUNT_BITS,  "refcount-bits" },
 { BLOCK_OPT_ENCRYPT,BLOCK_OPT_ENCRYPT_FORMAT },
 { BLOCK_OPT_COMPAT_LEVEL,   "version" },
@@ -4772,6 +4810,8 @@ static ImageInfoSpecific 
*qcow2_get_specific_info(BlockDriverState *bs,
 .corrupt= s->incompatible_features &
   QCOW2_INCOMPAT_CORRUPT,
 .has_corrupt= true,
+.has_extended_l2= true,
+.extended_l2= has_subclusters(s),
 .refcount_bits  = s->refcount_bits,
 .has_bitmaps= !!bitmaps,
 .bitmaps= bitmaps,
@@ -5365,6 +5405,12 @@ static QemuOptsList qcow2_create_opts = {
 .help = "Postpone refcount updates",
 .def_value_str = "off"
 },
+{
+.name = BLOCK_OPT

Re: [RFC PATCH 00/23] Add subcluster allocation to qcow2

2019-10-26 Thread Alberto Garcia
On Wed 23 Oct 2019 12:39:14 PM CEST, Vladimir Sementsov-Ogievskiy wrote:
> Hi!
>
> This is very interesting! Could you please export a branch to look at,
> as patches can't be applied on master now :(

I just sent a new version with some updates and rebased on top of the
current master.

Berto



[PULL 19/25] libqos: pass full QVirtQueue to set_queue_address()

2019-10-26 Thread Michael S. Tsirkin
From: Stefan Hajnoczi 

Instead of just passing the vring page frame number, pass the full
QVirtQueue.  This will allow the VIRTIO 1.0 transport to program the
fine-grained vring address registers in the future.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Sergio Lopez 
Reviewed-by: Thomas Huth 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20191023100425.12168-12-stefa...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 tests/libqos/virtio-mmio.c | 6 --
 tests/libqos/virtio-pci.c  | 6 --
 tests/libqos/virtio.h  | 2 +-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c
index 4db1f1b8bc..e0a2bd7bc6 100644
--- a/tests/libqos/virtio-mmio.c
+++ b/tests/libqos/virtio-mmio.c
@@ -143,9 +143,11 @@ static uint16_t qvirtio_mmio_get_queue_size(QVirtioDevice 
*d)
 return (uint16_t)qtest_readl(dev->qts, dev->addr + 
QVIRTIO_MMIO_QUEUE_NUM_MAX);
 }
 
-static void qvirtio_mmio_set_queue_address(QVirtioDevice *d, uint32_t pfn)
+static void qvirtio_mmio_set_queue_address(QVirtioDevice *d, QVirtQueue *vq)
 {
 QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+uint64_t pfn = vq->desc / dev->page_size;
+
 qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_PFN, pfn);
 }
 
@@ -179,7 +181,7 @@ static QVirtQueue 
*qvirtio_mmio_virtqueue_setup(QVirtioDevice *d,
 
 addr = guest_alloc(alloc, qvring_size(vq->size, dev->page_size));
 qvring_init(dev->qts, alloc, vq, addr);
-qvirtio_mmio_set_queue_address(d, vq->desc / dev->page_size);
+qvirtio_mmio_set_queue_address(d, vq);
 
 return vq;
 }
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 7ecf5d0a52..e4fa318dcc 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -199,9 +199,11 @@ static uint16_t qvirtio_pci_get_queue_size(QVirtioDevice 
*d)
 return qpci_io_readw(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_NUM);
 }
 
-static void qvirtio_pci_set_queue_address(QVirtioDevice *d, uint32_t pfn)
+static void qvirtio_pci_set_queue_address(QVirtioDevice *d, QVirtQueue *vq)
 {
 QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
+uint64_t pfn = vq->desc / VIRTIO_PCI_VRING_ALIGN;
+
 qpci_io_writel(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_PFN, pfn);
 }
 
@@ -239,7 +241,7 @@ static QVirtQueue 
*qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
 addr = guest_alloc(alloc, qvring_size(vqpci->vq.size,
   VIRTIO_PCI_VRING_ALIGN));
 qvring_init(qvpcidev->pdev->bus->qts, alloc, &vqpci->vq, addr);
-qvirtio_pci_set_queue_address(d, vqpci->vq.desc / VIRTIO_PCI_VRING_ALIGN);
+qvirtio_pci_set_queue_address(d, &vqpci->vq);
 
 return &vqpci->vq;
 }
diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index ebbff5193b..529ef7555a 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -81,7 +81,7 @@ struct QVirtioBus {
 uint16_t (*get_queue_size)(QVirtioDevice *d);
 
 /* Set the address of the selected queue */
-void (*set_queue_address)(QVirtioDevice *d, uint32_t pfn);
+void (*set_queue_address)(QVirtioDevice *d, QVirtQueue *vq);
 
 /* Setup the virtqueue specified by index */
 QVirtQueue *(*virtqueue_setup)(QVirtioDevice *d, QGuestAllocator *alloc,
-- 
MST




[PULL 20/25] libqos: add MSI-X callbacks to QVirtioPCIDevice

2019-10-26 Thread Michael S. Tsirkin
From: Stefan Hajnoczi 

The MSI-X vectors are programmed differently in the VIRTIO 1.0 and
Legacy interfaces.  Introduce callbacks so different implementations can
be used depending on the interface version.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Sergio Lopez 
Reviewed-by: Thomas Huth 
Message-Id: <20191023100425.12168-13-stefa...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 tests/libqos/virtio-pci.c | 37 -
 tests/libqos/virtio-pci.h | 12 
 2 files changed, 40 insertions(+), 9 deletions(-)

diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index e4fa318dcc..0725777a8d 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -281,6 +281,31 @@ const QVirtioBus qvirtio_pci = {
 .virtqueue_kick = qvirtio_pci_virtqueue_kick,
 };
 
+static void qvirtio_pci_set_config_vector(QVirtioPCIDevice *d, uint16_t entry)
+{
+uint16_t vector;
+
+qpci_io_writew(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR, entry);
+vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR);
+g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR);
+}
+
+static void qvirtio_pci_set_queue_vector(QVirtioPCIDevice *d, uint16_t vq_idx,
+ uint16_t entry)
+{
+uint16_t vector;
+
+qvirtio_pci_queue_select(&d->vdev, vq_idx);
+qpci_io_writew(d->pdev, d->bar, VIRTIO_MSI_QUEUE_VECTOR, entry);
+vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_QUEUE_VECTOR);
+g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR);
+}
+
+static const QVirtioPCIMSIXOps qvirtio_pci_msix_ops_legacy = {
+.set_config_vector = qvirtio_pci_set_config_vector,
+.set_queue_vector = qvirtio_pci_set_queue_vector,
+};
+
 void qvirtio_pci_device_enable(QVirtioPCIDevice *d)
 {
 qpci_device_enable(d->pdev);
@@ -295,7 +320,6 @@ void qvirtio_pci_device_disable(QVirtioPCIDevice *d)
 void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci,
 QGuestAllocator *alloc, uint16_t entry)
 {
-uint16_t vector;
 uint32_t control;
 uint64_t off;
 
@@ -321,16 +345,12 @@ void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, 
QVirtQueuePCI *vqpci,
off + PCI_MSIX_ENTRY_VECTOR_CTRL,
control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
 
-qvirtio_pci_queue_select(&d->vdev, vqpci->vq.index);
-qpci_io_writew(d->pdev, d->bar, VIRTIO_MSI_QUEUE_VECTOR, entry);
-vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_QUEUE_VECTOR);
-g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR);
+d->msix_ops->set_queue_vector(d, vqpci->vq.index, entry);
 }
 
 void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d,
 QGuestAllocator *alloc, uint16_t entry)
 {
-uint16_t vector;
 uint32_t control;
 uint64_t off;
 
@@ -358,9 +378,7 @@ void 
qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d,
off + PCI_MSIX_ENTRY_VECTOR_CTRL,
control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
 
-qpci_io_writew(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR, entry);
-vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR);
-g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR);
+d->msix_ops->set_config_vector(d, entry);
 }
 
 void qvirtio_pci_destructor(QOSGraphObject *obj)
@@ -383,6 +401,7 @@ static void qvirtio_pci_init_from_pcidev(QVirtioPCIDevice 
*dev, QPCIDevice *pci_
 dev->vdev.device_type = qpci_config_readw(pci_dev, PCI_SUBSYSTEM_ID);
 
 dev->config_msix_entry = -1;
+dev->msix_ops = &qvirtio_pci_msix_ops_legacy;
 
 dev->vdev.bus = &qvirtio_pci;
 dev->vdev.big_endian = qvirtio_pci_is_big_endian(dev);
diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h
index 728b4715f1..4299efc023 100644
--- a/tests/libqos/virtio-pci.h
+++ b/tests/libqos/virtio-pci.h
@@ -14,16 +14,28 @@
 #include "libqos/pci.h"
 #include "libqos/qgraph.h"
 
+typedef struct QVirtioPCIMSIXOps QVirtioPCIMSIXOps;
+
 typedef struct QVirtioPCIDevice {
 QOSGraphObject obj;
 QVirtioDevice vdev;
 QPCIDevice *pdev;
 QPCIBar bar;
+const QVirtioPCIMSIXOps *msix_ops;
 uint16_t config_msix_entry;
 uint64_t config_msix_addr;
 uint32_t config_msix_data;
 } QVirtioPCIDevice;
 
+struct QVirtioPCIMSIXOps {
+/* Set the Configuration Vector for MSI-X */
+void (*set_config_vector)(QVirtioPCIDevice *d, uint16_t entry);
+
+/* Set the Queue Vector for MSI-X */
+void (*set_queue_vector)(QVirtioPCIDevice *d, uint16_t vq_idx,
+ uint16_t entry);
+};
+
 typedef struct QVirtQueuePCI {
 QVirtQueue vq;
 uint16_t msix_entry;
-- 
MST




[PULL 25/25] virtio: drop unused virtio_device_stop_ioeventfd() function

2019-10-26 Thread Michael S. Tsirkin
From: Stefan Hajnoczi 

virtio_device_stop_ioeventfd() has not been used since commit
310837de6c1e0badfd736b1b316b1698c53120a7 ("virtio: introduce
grab/release_ioeventfd to fix vhost") in 2016.

Nowadays ioeventfd is stopped implicitly by the virtio transport when
lifecycle events such as the VM pausing or device unplug occur.

Cc: Paolo Bonzini 
Signed-off-by: Stefan Hajnoczi 
Message-Id: <20191021150343.30742-1-stefa...@redhat.com>
Reviewed-by: Stefano Garzarella 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/virtio.c | 8 
 include/hw/virtio/virtio.h | 1 -
 2 files changed, 9 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 828c27de1f..2e91dec567 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -3665,14 +3665,6 @@ static void 
virtio_device_stop_ioeventfd_impl(VirtIODevice *vdev)
 }
 }
 
-void virtio_device_stop_ioeventfd(VirtIODevice *vdev)
-{
-BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
-VirtioBusState *vbus = VIRTIO_BUS(qbus);
-
-virtio_bus_stop_ioeventfd(vbus);
-}
-
 int virtio_device_grab_ioeventfd(VirtIODevice *vdev)
 {
 BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 40ddeafadb..5560f4a5ea 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -308,7 +308,6 @@ EventNotifier *virtio_queue_get_guest_notifier(VirtQueue 
*vq);
 void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
 bool with_irqfd);
 int virtio_device_start_ioeventfd(VirtIODevice *vdev);
-void virtio_device_stop_ioeventfd(VirtIODevice *vdev);
 int virtio_device_grab_ioeventfd(VirtIODevice *vdev);
 void virtio_device_release_ioeventfd(VirtIODevice *vdev);
 bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev);
-- 
MST




[RFC PATCH v2 08/26] qcow2: Add offset_to_sc_index()

2019-10-26 Thread Alberto Garcia
For a given offset, return the subcluster number within its cluster
(i.e. with 32 subclusters per cluster it returns a number between 0
and 31).

Signed-off-by: Alberto Garcia 
---
 block/qcow2.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/block/qcow2.h b/block/qcow2.h
index 278ca41314..e25758079c 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -559,6 +559,11 @@ static inline int offset_to_l2_slice_index(BDRVQcow2State 
*s, int64_t offset)
 return (offset >> s->cluster_bits) & (s->l2_slice_size - 1);
 }
 
+static inline int offset_to_sc_index(BDRVQcow2State *s, int64_t offset)
+{
+return (offset >> s->subcluster_bits) & (s->subclusters_per_cluster - 1);
+}
+
 static inline int64_t qcow2_vm_state_offset(BDRVQcow2State *s)
 {
 return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
-- 
2.20.1




[RFC PATCH v2 22/26] qcow2: Add subcluster support to handle_alloc_space()

2019-10-26 Thread Alberto Garcia
The bdrv_co_pwrite_zeroes() call here fills complete clusters with
zeroes, but it can happen that some subclusters are not part of the
write request or the copy-on-write. This patch makes sure that only
the affected subclusters are overwritten.

A potential improvement would be to also fill with zeroes the other
subclusters if we can guarantee that we are not overwriting existing
data. However this would waste more disk space, so we should first
evaluate if it's really worth doing.

Signed-off-by: Alberto Garcia 
---
 block/qcow2.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 0261e87709..01322ca449 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2304,6 +2304,9 @@ static int handle_alloc_space(BlockDriverState *bs, 
QCowL2Meta *l2meta)
 
 for (m = l2meta; m != NULL; m = m->next) {
 int ret;
+uint64_t start_offset = m->alloc_offset + m->cow_start.offset;
+uint64_t nb_bytes = m->cow_end.offset + m->cow_end.nb_bytes -
+m->cow_start.offset;
 
 if (!m->cow_start.nb_bytes && !m->cow_end.nb_bytes) {
 continue;
@@ -2318,16 +2321,14 @@ static int handle_alloc_space(BlockDriverState *bs, 
QCowL2Meta *l2meta)
  * efficiently zero out the whole clusters
  */
 
-ret = qcow2_pre_write_overlap_check(bs, 0, m->alloc_offset,
-m->nb_clusters * s->cluster_size,
+ret = qcow2_pre_write_overlap_check(bs, 0, start_offset, nb_bytes,
 true);
 if (ret < 0) {
 return ret;
 }
 
 BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC_SPACE);
-ret = bdrv_co_pwrite_zeroes(s->data_file, m->alloc_offset,
-m->nb_clusters * s->cluster_size,
+ret = bdrv_co_pwrite_zeroes(s->data_file, start_offset, nb_bytes,
 BDRV_REQ_NO_FALLBACK);
 if (ret < 0) {
 if (ret != -ENOTSUP && ret != -EAGAIN) {
-- 
2.20.1




[RFC PATCH v2 06/26] qcow2: Add dummy has_subclusters() function

2019-10-26 Thread Alberto Garcia
This function will be used by the qcow2 code to check if an image has
subclusters or not.

At the moment this simply returns false. Once all patches needed for
subcluster support are ready then QEMU will be able to create and
read images with subclusters and this function will return the actual
value.

Signed-off-by: Alberto Garcia 
---
 block/qcow2.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/block/qcow2.h b/block/qcow2.h
index 940cd4c236..b3826b37c1 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -488,6 +488,12 @@ typedef enum QCow2MetadataOverlap {
 
 #define INV_OFFSET (-1ULL)
 
+static inline bool has_subclusters(BDRVQcow2State *s)
+{
+/* FIXME: Return false until this feature is complete */
+return false;
+}
+
 static inline uint64_t get_l2_entry(BDRVQcow2State *s, uint64_t *l2_slice,
 int idx)
 {
-- 
2.20.1




[RFC PATCH v2 05/26] qcow2: Document the Extended L2 Entries feature

2019-10-26 Thread Alberto Garcia
Subcluster allocation in qcow2 is implemented by extending the
existing L2 table entries and adding additional information to
indicate the allocation status of each subcluster.

This patch documents the changes to the qcow2 format and how they
affect the calculation of the L2 cache size.

Signed-off-by: Alberto Garcia 
---
 docs/interop/qcow2.txt | 68 --
 docs/qcow2-cache.txt   | 19 +++-
 2 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
index af5711e533..d34261f955 100644
--- a/docs/interop/qcow2.txt
+++ b/docs/interop/qcow2.txt
@@ -39,6 +39,9 @@ The first cluster of a qcow2 image contains the file header:
 as the maximum cluster size and won't be able to open 
images
 with larger cluster sizes.
 
+Note: if the image has Extended L2 Entries then 
cluster_bits
+must be at least 14 (i.e. 16384 byte clusters).
+
  24 - 31:   size
 Virtual disk size in bytes.
 
@@ -109,7 +112,12 @@ in the description of a field.
 An External Data File Name header extension may
 be present if this bit is set.
 
-Bits 3-63:  Reserved (set to 0)
+Bit 3:  Extended L2 Entries.  If this bit is set then
+L2 table entries use an extended format that
+allows subcluster-based allocation. See the
+Extended L2 Entries section for more details.
+
+Bits 4-63:  Reserved (set to 0)
 
  80 -  87:  compatible_features
 Bitmask of compatible features. An implementation can
@@ -437,7 +445,7 @@ cannot be relaxed without an incompatible layout change).
 Given an offset into the virtual disk, the offset into the image file can be
 obtained as follows:
 
-l2_entries = (cluster_size / sizeof(uint64_t))
+l2_entries = (cluster_size / sizeof(uint64_t))[*]
 
 l2_index = (offset / cluster_size) % l2_entries
 l1_index = (offset / cluster_size) / l2_entries
@@ -447,6 +455,8 @@ obtained as follows:
 
 return cluster_offset + (offset % cluster_size)
 
+[*] this changes if Extended L2 Entries are enabled, see next section
+
 L1 table entry:
 
 Bit  0 -  8:Reserved (set to 0)
@@ -487,7 +497,8 @@ Standard Cluster Descriptor:
 nor is data read from the backing file if the cluster is
 unallocated.
 
-With version 2, this is always 0.
+With version 2 or with extended L2 entries (see the next
+section), this is always 0.
 
  1 -  8:Reserved (set to 0)
 
@@ -524,6 +535,57 @@ file (except if bit 0 in the Standard Cluster Descriptor 
is set). If there is
 no backing file or the backing file is smaller than the image, they shall read
 zeros for all parts that are not covered by the backing file.
 
+== Extended L2 Entries ==
+
+An image uses Extended L2 Entries if bit 3 is set on the incompatible_features
+field of the header.
+
+In these images standard data clusters are divided into 32 subclusters of the
+same size. They are contiguous and start from the beginning of the cluster.
+Subclusters can be allocated independently and the L2 entry contains 
information
+indicating the status of each one of them. Compressed data clusters don't have
+subclusters so they are treated like in images without this feature.
+
+The size of an extended L2 entry is 128 bits so the number of entries per table
+is calculated using this formula:
+
+l2_entries = (cluster_size / (2 * sizeof(uint64_t)))
+
+The first 64 bits have the same format as the standard L2 table entry described
+in the previous section, with the exception of bit 0 of the standard cluster
+descriptor.
+
+The last 64 bits contain a subcluster allocation bitmap with this format:
+
+Subcluster Allocation Bitmap (for standard clusters):
+
+Bit  0 -  31:   Allocation status (one bit per subcluster)
+
+1: the subcluster is allocated. In this case the
+   host cluster offset field must contain a valid
+   offset.
+0: the subcluster is not allocated. In this case
+   read requests shall go to the backing file or
+   return zeros if there is no backing file data.
+
+Bits are assigned starting from the most significant one.
+(i.e. bit x is used for subcluster 31 - x)
+
+32 -  63Subcluster reads as zeros (one bit per subcluster)
+
+1: the subcluster reads as zeros. In this case the
+   allocation status bit must be unset. The host
+   cluster offset field may or may not be set.
+   

  1   2   >