Re: [PATCH] audio/dsound: fix invalid parameters error

2020-01-30 Thread Gerd Hoffmann
On Mon, Jan 27, 2020 at 02:46:58AM +0100, Zoltán Kővágó wrote:
> On 2020-01-18 07:30, Philippe Mathieu-Daudé wrote:
> > On 1/17/20 7:26 PM, KJ Liew wrote:
> > > QEMU Windows has broken dsound backend since the rewrite of audio API in
> > > version 4.2.0. Both playback and capture buffers failed to lock with
> > > invalid parameters error.
> > 
> > Fixes: 7fa9754ac88 (dsoundaudio: port to the new audio backend api)
> 
> Hmm, I see the old code specified those parameters, but MSDN reads:
> 
> If the application passes NULL for the ppvAudioPtr2 and pdwAudioBytes2
> parameters, the lock extends no further than the end of the buffer and does
> not wrap.
> 
> Looks like this means that if the lock doesn't fit in the buffer it fails
> instead of truncating it.  I'm sure I tested the code under wine, and
> probably in a win8.1 vm too, and it worked there, maybe it's dependent on
> the windows version or sound driver?

Ping.  Any news here?  I'm busy collecting all pending audio fixes for
the next pull request ...

> 
> > 
> > Cc'ing Zoltán who wrote 7fa9754ac88, and Gerd (the maintainer of this
> > file):
> > 
> >    $ ./scripts/get_maintainer.pl -f audio/dsoundaudio.c
> >    Gerd Hoffmann  (maintainer:Audio)
> > 
> > > --- ../orig/qemu-4.2.0/audio/dsoundaudio.c    2019-12-12
> > > 10:20:47.0 -0800
> > > +++ ../qemu-4.2.0/audio/dsoundaudio.c    2020-01-17
> > > 08:05:46.783966900 -0800
> > > @@ -53,6 +53,7 @@
> > >   typedef struct {
> > >   HWVoiceOut hw;
> > >   LPDIRECTSOUNDBUFFER dsound_buffer;
> > > +    void *last_buf;
> > >   dsound *s;
> > >   } DSoundVoiceOut;
> > > @@ -414,10 +415,10 @@
> > >   DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
> > >   LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
> > >   HRESULT hr;
> > > -    DWORD ppos, act_size;
> > > +    DWORD ppos, act_size, last_size;
> > >   size_t req_size;
> > >   int err;
> > > -    void *ret;
> > > +    void *ret, *last_ret;
> > >   hr = IDirectSoundBuffer_GetCurrentPosition(dsb, &ppos, NULL);
> > >   if (FAILED(hr)) {
> > > @@ -426,17 +427,24 @@
> > >   return NULL;
> > >   }
> > > +    if (ppos == hw->pos_emul) {
> > > +    *size = 0;
> > > +    return ds->last_buf;
> > > +    }
> > > +
> > >   req_size = audio_ring_dist(ppos, hw->pos_emul, hw->size_emul);
> > >   req_size = MIN(req_size, hw->size_emul - hw->pos_emul);
> > > -    err = dsound_lock_out(dsb, &hw->info, hw->pos_emul, req_size,
> > > &ret, NULL,
> > > -  &act_size, NULL, false, ds->s);
> > > +    err = dsound_lock_out(dsb, &hw->info, hw->pos_emul, req_size,
> > > &ret, &last_ret,
> > > +  &act_size, &last_size, false, ds->s);
> > >   if (err) {
> > >   dolog("Failed to lock buffer\n");
> > >   *size = 0;
> > >   return NULL;
> > >   }
> > > +    ds->last_buf = g_realloc(ds->last_buf, act_size);
> > > +    memcpy(ds->last_buf, ret, act_size);
> > >   *size = act_size;
> > >   return ret;
> > >   }
> 
> I don't really understand what's happening here, why do you need that memory
> allocation and memcpy?  This function should return a buffer where the
> caller will write data, that *size = 0; when returning ds->last_buf also
> looks incorrect to me (the calling function won't write anything into it).
> 
> I'm attaching a patch with a probably better (and totally untested) way to
> do this (if someone can tell me how to copy-paste a patch into thunderbird
> without it messing up long lines, please tell me).
> 
> 
> > > @@ -445,6 +453,8 @@
> > >   {
> > >   DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
> > >   LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
> > > +    if (len == 0)
> > > +    return 0;
> > >   int err = dsound_unlock_out(dsb, buf, NULL, len, 0);
> > >   if (err) {
> 
> Msdn says "The second pointer is needed even if nothing was written to the
> second pointer." so that NULL doesn't look okay.
> 
> > > @@ -508,10 +518,10 @@
> > >   DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
> > >   LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
> > >   HRESULT hr;
> > > -    DWORD cpos, act_size;
> > > +    DWORD cpos, act_size, last_size;
> > >   size_t req_size;
> > >   int err;
> > > -    void *ret;
> > > +    void *ret, *last_ret;
> > >   hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dscb, &cpos,
> > > NULL);
> > >   if (FAILED(hr)) {
> > > @@ -520,11 +530,16 @@
> > >   return NULL;
> > >   }
> > > +    if (cpos == hw->pos_emul) {
> > > +    *size = 0;
> > > +    return NULL;
> > > +    }
> > > +
> > >   req_size = audio_ring_dist(cpos, hw->pos_emul, hw->size_emul);
> > >   req_size = MIN(req_size, hw->size_emul - hw->pos_emul);
> > > -    err = dsound_lock_in(dscb, &hw->info, hw->pos_emul, req_size,
> > > &ret, NULL,
> > > - &act_size, NULL, false, ds->s);
> > > +    err = dsound_lock_in(dscb, &hw->info, hw->pos_em

Re: Making QEMU easier for management tools and applications

2020-01-30 Thread Paolo Bonzini
On 31/01/20 07:50, Markus Armbruster wrote:
>>> Consider chardev-add.  Example:
>>>
>>> {"execute": "chardev-add",
>>>  "arguments": {"id": "bar",
>>>"backend": {"type": "file",
>>>"data": {"out": "/tmp/bar.log"
>>>
>>> The arguments as dotted keys:
>>>
>>> id=bar,backend.type=file,backend.data.out=/tmp/bar.log
>>>
>>> Observe there's quite some of nesting.  While that's somewhat cumbersome
>>> in JSON, it's a lot worse with dotted keys, because there nesting means
>>> repeated key prefixes.  I could give much worse examples, actually.
>> This is true, but even without the repeated keys (e.g. in a syntax that
>> would use brackets), it would still be unnecessarily verbose and
>> probably hard to remember:
>>
>> id=bar,backend={type=file,data={out=/tmp/bar.log}}
> No argument.  It's unnecessarily verbose in JSON, too.
> 

I think we should be able to switch chardevs to -object/object_add these
days.  Not right now, but it may be possible.  Introducing a warning
when chardev and object ids conflict would be a start.

Paolo




Re: Improving QOM documentation [Was: Re: Making QEMU easier for management tools and applications]

2020-01-30 Thread Paolo Bonzini
On 31/01/20 07:11, Markus Armbruster wrote:
> May I present you Armbru's Comment Trust Levels:
> 
> ACTL2: The comment may be overly terse or incomplete, but the
> probability for it to be outright wrong is low.
> 
> ACTL1: Treat as helpful guidance (with gratitude), but trust only the
> code.
> 
> ACTL0: It is a tale Told by an idiot[**], full of sound and fury,
> Signifying nothing.
> 
> Most comments in decently maintained code are at ACTL1.
> 
> Around the time initial QOM development solidified, object.h's comments
> were ACTL2.  The neglect that is now clearly visible there makes me
> downgrade to ACTL1.
> 
> Paolo will have a more informed and possibly different opinion.

I think around initial development it was ACTL3, now it's around 1.8.

Paolo




Re: [RFC] coreaudio: fix coreaudio_test.diff

2020-01-30 Thread Volker Rümelin
>
> Hi all,
>
> Thanks to the generous help from Mark, I can now report that it is good to 
> hear coreaudio has been restored into a working state with this patch! I 
> tested qemu-system-ppc running MacOS and OSX.
>
> Best,
> Howard

Thank you for testing the two patches. I will wait a few days to see if Zoltán 
wants to write a cleaned up patch. Otherwise I'll try to write a patch that's 
acceptable for submission.

With best regards
Volker



Re: [PATCH v5 5/6] iotests: Skip Python-based tests if QEMU does not support virtio-blk

2020-01-30 Thread Thomas Huth
On 30/01/2020 23.31, Philippe Mathieu-Daudé wrote:
> On 1/21/20 10:52 AM, Thomas Huth wrote:
>> We are going to enable some of the python-based tests in the "auto"
>> group,
>> and these tests require virtio-blk to work properly. Running iotests
>> without virtio-blk likely does not make too much sense anyway, so instead
>> of adding a check for the availability of virtio-blk to each and every
>> test (which does not sound very appealing), let's rather add a check for
>> this a central spot in the "check" script instead (so that it is still
>> possible to run "make check" for qemu-system-tricore for example).
>>
>> Signed-off-by: Thomas Huth 
>> ---
>>   tests/qemu-iotests/check | 12 ++--
>>   1 file changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
>> index 2890785a10..1629b6c914 100755
>> --- a/tests/qemu-iotests/check
>> +++ b/tests/qemu-iotests/check
>> @@ -642,7 +642,15 @@ fi
>>   python_usable=false
>>   if $PYTHON -c 'import sys; sys.exit(0 if sys.version_info >= (3,6)
>> else 1)'
>>   then
>> -    python_usable=true
>> +    # Our python framework also requires virtio-blk
>> +    if "$QEMU_PROG" -M none -device help | grep -q virtio-blk
>> >/dev/null 2>&1
> 
> FYI I proposed a patch adding a binary_get_devices() helper:
> https://lists.gnu.org/archive/html/qemu-devel/2020-01/msg07314.html
> 
> You could use something such
> 
>   @SkipUntil('virtio-blk' in binary_get_devices(qemu_bin))

Unfortunately, that doesn't scale here. You'd have to add this to almost
all python-based iotests, since the virtio-blk dependency is hard-wired
deep in the code there (look at the add_drive function).

 Thomas




Re: [Bug 1860759] Re: [REGRESSION] option `-snapshot` ignored with blockdev

2020-01-30 Thread Ildar
Thank a lot for the detailed answer. Surely it's worth discussing qemu here
leaving libvirt for RH bugzilla.

> But since modern qemu has declared -snapshot to be unsupported with
-blockdev, and modern libvirt has switched to -blockdev, I claim that this
is not a qemu bug, but a libvirt feature request.

I'm convinced this isn't qemu's bug. And everything you wrote is
well-justified. Yet, one question left unanswered:
> Do you mean that snapshot-ing isn't possible totally for blockdev?
> Actually I didn't quite caught the reason why a blockdev supports backing
but not {backing to a file on /tmp then promptly deleted} ? What's the
technical difference?

Thanks!

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1860759

Title:
  [REGRESSION] option `-snapshot` ignored with blockdev

Status in QEMU:
  New

Bug description:
  After upgrade of qemu 3.1.0 → 4.2.0 I found that running with libvirt doesn't 
honor `-snapshot` option anymore. I.e. disk images get modified.
  Using `-hda` option honors `-snapshot`

  So I made a test case without libvirt. Testcase using 4.2.0:

  > qemu -hda tmp-16G.img -cdrom regular-rescue-latest-x86_64.iso -m 2G

  This works fine and tmp-16G.img stays unmodified.

  But:
  > /usr/bin/qemu-system-x86_64 -name guest=test-linux,debug-threads=on -S 
-machine pc-i440fx-3.1,accel=kvm,usb=off,vmport=off,dump-guest-core=off -cpu 
Broadwell-noTSX,vme=on,ss=on,f16c=on,rdrand=on,hypervisor=on,arat=on,tsc-adjust=on,xsaveopt=on,pdpe1gb=on,abm=on
 -m 2048 -overcommit mem-lock=off -smp 3,sockets=3,cores=1,threads=1 -uuid 
d32a9191-f51d-4fae-a419-b73d85b49198 -no-user-config -nodefaults -rtc 
base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet 
-no-shutdown -global PIIX4_PM.disable_s3=1 -global PIIX4_PM.disable_s4=1 -boot 
strict=on -device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x5.0x7 -device 
ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x5 
-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x5.0x1 
-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x5.0x2 
-blockdev 
\{\"driver\":\"file\",\"filename\":\"/tmp/regular-rescue-latest-x86_64.iso\",\"node-name\":\"libvirt-2-storage\",\"auto-read-only\":true,\"discard\":\"unmap\"}
 -blockdev 
\{\"node-name\":\"libvirt-2-format\",\"read-only\":true,\"driver\":\"raw\",\"file\":\"libvirt-2-storage\"}
 -device ide-cd,bus=ide.0,unit=0,drive=libvirt-2-format,id=ide0-0-0,bootindex=1 
-blockdev 
\{\"driver\":\"file\",\"filename\":\"/tmp/tmp-2G.img\",\"node-name\":\"libvirt-1-storage\",\"auto-read-only\":true,\"discard\":\"unmap\"}
 -blockdev 
\{\"node-name\":\"libvirt-1-format\",\"read-only\":false,\"driver\":\"qcow2\",\"file\":\"libvirt-1-storage\",\"backing\":null}
 -device 
virtio-blk-pci,scsi=off,bus=pci.0,addr=0x7,drive=libvirt-1-format,id=virtio-disk0
 -netdev user,id=hostnet0 -device 
e1000,netdev=hostnet0,id=net0,mac=52:54:00:ab:d8:29,bus=pci.0,addr=0x3 -chardev 
pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -device 
qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vram64_size_mb=0,vgamem_mb=16,max_outputs=1,bus=pci.0,addr=0x2
 -device intel-hda,id=sound0,bus=pci.0,addr=0x4 -device 
hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -device 
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 -snapshot -sandbox 
on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny -msg 
timestamp=on

  This modifies tmp-16G.img.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1860759/+subscriptions



Re: [RFC PATCH] hw/arm/virt: Support NMI injection

2020-01-30 Thread Gavin Shan

On 1/29/20 8:04 PM, Marc Zyngier wrote:

On 2020-01-29 02:44, Alexey Kardashevskiy wrote:

On 28/01/2020 17:48, Gavin Shan wrote:

but a NMI is injected
through LAPIC on x86. So I'm not sure what architect (system reset on
ppc or injecting NMI on x86) aarch64 should follow.


I'd say whatever triggers in-kernel debugger or kdump but I am not
familiar with ARM at all :)


All that is completely OS specific, and has no relation to the architecture.
As I mentioned in another part of the thread, the closest thing to this
would be to implement SDEI together with an IMPDEF mechanism to enter it
(or even generate a RAS error).

On the other hand, SDEI is pretty horrible, and means either KVM or QEMU
acting like a firmware for the guest. To say that I'm not keen is a massive
understatement.

     M.


Marc, could you please explain a bit about "IMPDEF mechanism"? I'm not sure if
it means a non-standard SDEI event should be used, corresponding to the HMP/QMP
"nmi" command.

Also, If I'm correct, you agree that a crash dump should be triggered on arm64
guest once HMP/QMP "nmi" command is issued? I also dig into SDEI a bit. It seems
the SDEI support in QEMU isn't upstream yet:


https://patchew.org/QEMU/20191105091056.9541-1-guoh...@huawei.com/

Thanks,
Gavin





Re: [RFC PATCH] hw/arm/virt: Support NMI injection

2020-01-30 Thread Gavin Shan

On 1/30/20 9:58 PM, Marc Zyngier wrote:

On 2020-01-29 21:54, Gavin Shan wrote:

On 1/29/20 6:57 PM, Julien Thierry wrote:

On 1/29/20 3:46 AM, Gavin Shan wrote:

On 1/28/20 7:29 PM, Julien Thierry wrote:


.../...



Julien, thanks for the explanation. The question we're not sure if NMI should
be injected on receiving HMP/QMP "nmi" command. It means it's not clear what
behavior we should have for this command on ARM. However, I have one more
unrelated question: "pseudo" NMI on ARM64 should be PPI? I mean SPI can't
be "pseudo" NMI.



I'm not sure I understand why you say "SPI can't be "pseudo" NMI". Currently both PPI and 
SPI are supported in the "pseudo" NMI scheme. Do you think that should not be the case? If so, can 
you elaborate?

Thanks,



Julien, NMI interrupt is connected to the system by request_nmi() where we have
a check as below. -EINVAL will be returned from request_nmi() on those
interrupts
whose descriptors aren't marked with IRQ_NOAUTOEN. SPI falls into this category.


The IRQ_NOAUTOEN is set on PPIs because you can't enable them all at once,
for obvious reasons.

This doesn't mean you cannot set it on other interrupt classes, including SPIs.
It is actually a fairly common thing to do when you want to decouple requesting
the interrupt from the enabling, if you do not want the interrupt to be able to
fire right away.

     M.


Marc, Ok, thanks for the details, which make things clear.

Thanks,
Gavin




Re: Making QEMU easier for management tools and applications

2020-01-30 Thread Markus Armbruster
Kevin Wolf  writes:

> Am 28.01.2020 um 13:36 hat Markus Armbruster geschrieben:
>> Kevin Wolf  writes:
>> 
>> > Am 27.01.2020 um 21:11 hat John Snow geschrieben:
>> [...]
>> >> (The argument here is: It's a little harder and a little longer to type,
>> >> but the benefits from the schema organization may improve productivity
>> >> of using QEMU directly instead of harming it.)
>> >
>> > I think this is a false dichotomy.
>> >
>> > You can have everything defined by the schema and properly documented
>> > and still have a non-JSON command line. Translating the QAPI schema to
>> > a command line option is a solved problem, this is exactly how
>> > -blockdev works.
>> >
>> > The unsolved part is how to compatibly convert the existing options. If
>> > you're willing to sacrifice compatibility, great. Then we can just
>> > define stuff in the QAPI schema and still keep a command line syntax
>> > that is usable for humans. The code for mapping a QAPI type to the
>> > argument of an option is basically already there.
>> 
>> Correct.
>> 
>> Solving that problem took time, but that's sunk cost now.
>> 
>> > The only question is "is compatibility important"? If the answer is no,
>> > then we'll be there in no time.
>> 
>> I doubt we'll be there in no time, but certainly much sooner than if we
>> have to grapple with compatibility to a byzantine CLI nobody truly
>> understands.
>> 
>> There's one known issue caused by having "a non-JSON command line"
>> (actually: dotted keys as sugar for JSON): pressure to reduce nesting.
>> 
>> Consider chardev-add.  Example:
>> 
>> {"execute": "chardev-add",
>>  "arguments": {"id": "bar",
>>"backend": {"type": "file",
>>"data": {"out": "/tmp/bar.log"
>> 
>> The arguments as dotted keys:
>> 
>> id=bar,backend.type=file,backend.data.out=/tmp/bar.log
>> 
>> Observe there's quite some of nesting.  While that's somewhat cumbersome
>> in JSON, it's a lot worse with dotted keys, because there nesting means
>> repeated key prefixes.  I could give much worse examples, actually.
>
> This is true, but even without the repeated keys (e.g. in a syntax that
> would use brackets), it would still be unnecessarily verbose and
> probably hard to remember:
>
> id=bar,backend={type=file,data={out=/tmp/bar.log}}

No argument.  It's unnecessarily verbose in JSON, too.

>> We'd rather have something like
>> 
>> id=bar,type=file,out=/tmp/bar.log
>> 
>> Back to JSON:
>> 
>> "arguments": {"id": "bar", "type": "file", "out": "/tmp/bar.log"}
>> 
>> QAPI can do this, but it uses feature that predate chardev-add.
>> 
>> We don't want to duplicate the chardev-add schema in modern, flattened
>> form for the CLI.
>> 
>> So the compatibility problem actually shifts to QMP: can we evolve the
>> existing QMP command compatibly at a reasonable cost in design, coding
>> and complexity to support flat arguments?
>
> Well, first of all: Do we need compatibility? If we don't, then we can
> just make the change.

The trouble with flattening this one is QMP, where we promise stability.

> Much of this threads plays with the though that maybe we don't need any
> compatibility and make the radical conclusion that we don't need any
> human-friendly interface at all. Keeping full compatibility is the other
> extreme.
>
> There might be some middle ground where we break compatibility where the
> old way can't easily be maintained with the new infrastructure, but
> don't give up on the idea of being used by humans.

I'm not sure the connection between maintaining compatibility and
supporting human use is as strong as you seem to imply.

As far as I can tell, the "maybe we don't need any compatibility"
discussion is about the CLI.  I'd rephrase it as "maybe we need a
machine-friendly CLI on par with QMP more than we need compatibility to
the current CLI".

"We don't need any human-friendly interface at all" comes in not because
machine-friendly necessarily precludes human-friendly, but only if we're
unwilling (unable?) to do the extra work for it.

Compare the monitor:

* QMP is primarily for machines.  We promise stability: no incompatible
  changes without clear communicaton of intent and a grace period.  We
  provide machine clients tools to deal with the interface evolution,
  e.g. query-qmp-schema.

* HMP is exclusively for humans.  It may change at any time.

For the CLI, we don't have such a separation, and our offerings for
dealing with interface evolution are wholly inadequate.  We *need* to do
better for machines.

Now, the monitor also informs us about the cost of providing a
completely separate interface for humans.

Elsewhere in this thread, we discussed layering (a replacement for) HMP
on top of QMP cleanly, possibly in a separate process, possibly written
in a high-level language like Python.

HMP predates QMP.  We reworked it so the HMP commands are implemented on
top of the QMP commands, or at least on top of common helpers.  But thi

Re: Improving QOM documentation [Was: Re: Making QEMU easier for management tools and applications]

2020-01-30 Thread Markus Armbruster
Kashyap Chamarthy  writes:

> On Wed, Jan 15, 2020 at 03:02:48PM +0100, Markus Armbruster wrote:
>> Daniel P. Berrangé  writes:
>
> [Changed the subject-line to indicate deviation from the original
> topic.]
>
> [...]
>
>> > Libvirt is of course happy to switch to something else instead of
>> > qom-set for these features if QEMU wants to provide a safer
>> > alternative.
>> 
>> Noted.
>> 
>> libvirt's use of qom-set is okay.  What's not okay is the near-complete
>> lack of QOM documentation, its poor QMP interface, in part due to
>> non-integration with QAPI, and last but not least the lack of QOM
>> leadership leaving it adrift.
>
> What can be done to improve QOM documentation (or lack thereof)?

Are you trying to push us from idle grousing to actually improve things?
No fair!

> From a couple of hurried `grep` queries in the QEMU tree, there seems to
> be no explicit qom.rst|txt, or qemu-object-model.txt|rst or some such.
> (I hope I haven't missed any other files.)

As far as I know, all we have is the lovingly[*] written comments in
include/qom/object.h.  Sadly, we've let them rot in places.  In
particular, many newer functions are undocumented.

This is *reference* documentation.  What we lack (sorely!) is an
overview / friendly introduction, and a design document with rationale.
Reconstructing rationale now would involve guesswork.

> Let's dig further.  Ah, I come across this helpful 2016 blog post[1]
> ("An incomplete list of QEMU APIs") by Eduardo from my bookmarks.  Here
> I get some clues:
>
> (a) In the section titled "QOM", Eduardo writes:
>
> "QOM is short for QEMU Object Model and was introduced in 2011.
> It is heavily documented on its header file
> [include/qom/object.h]" 
>
> Opening qom/object.h[2], indeed there is copious amounts of docs,
> expressed as commented-out text.  Two questions:
>
> - How much of this is still accurate?  (Sorry, if that's a loaded
>   question.)

May I present you Armbru's Comment Trust Levels:

ACTL2: The comment may be overly terse or incomplete, but the
probability for it to be outright wrong is low.

ACTL1: Treat as helpful guidance (with gratitude), but trust only the
code.

ACTL0: It is a tale Told by an idiot[**], full of sound and fury,
Signifying nothing.

Most comments in decently maintained code are at ACTL1.

Around the time initial QOM development solidified, object.h's comments
were ACTL2.  The neglect that is now clearly visible there makes me
downgrade to ACTL1.

Paolo will have a more informed and possibly different opinion.

> - If at least 60% is still accurate, is it valuable to extract and
>   publish it as rendered rST, as part of the on-going QEMU Docs
>   improvement?

Beware, personal opinion.

When you put documentation next to the code it documents (which you
absolutely should, because it's your only realistic chance to keep the
two in sync), then extracting API comments is useful, because it
collects them in one place.

It's of next to no use to me when the comments are all in the same place
already, namely the header.

> (b) The other clue is also from the same post, where Eduardo provides
> pointers to past KVM Forum presentations by MarkusA, PaoloB,
> AndreasF on QOM, Qdev et al.
>
> Is it worth slapping all these references (with a clear intro and
> outro) into a qom.rst file in QEMU tree, even if only for
> reference/context?  Or are these references, in-tree docs in
> object.h out-of-date beyond repair?  

Uff.

My qdev talks predate the rebase onto QOM.  They may well confuse /
mislead as much as inform now.

> If it is useful, I'm happy to get the initial doc going, secure in the
> knowledge that more clueful people than me will chip in during the
> review :-)

Ha, nerd sniping!

> [1] https://habkost.net/posts/2016/11/incomplete-list-of-qemu-apis.html
> [2] https://git.qemu.org/?p=qemu.git;a=blob;f=include/qom/object.h
> [3] http://www.linux-kvm.org/images/9/90/Kvmforum14-qom.pdf


[*] Absolutely no irony intended.  Honest, officer!

[**] Don't take it personally, we're all part-time idiots.  Besides,
this is literature.




[PULL 30/34] ppc: spapr: Activate the FWNMI functionality

2020-01-30 Thread David Gibson
From: Aravinda Prasad 

This patch sets the default value of SPAPR_CAP_FWNMI_MCE
to SPAPR_CAP_ON for machine type 5.0.

Signed-off-by: Aravinda Prasad 
Signed-off-by: Ganesh Goudar 
Message-Id: <20200130184423.20519-8-ganes...@linux.ibm.com>
Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 137f5c9a33..c9b2e0a5e0 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4454,7 +4454,7 @@ static void spapr_machine_class_init(ObjectClass *oc, 
void *data)
 smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
 smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
 smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_ON;
-smc->default_caps.caps[SPAPR_CAP_FWNMI_MCE] = SPAPR_CAP_OFF;
+smc->default_caps.caps[SPAPR_CAP_FWNMI_MCE] = SPAPR_CAP_ON;
 spapr_caps_add_properties(smc, &error_abort);
 smc->irq = &spapr_irq_dual;
 smc->dr_phb_enabled = true;
@@ -4527,6 +4527,7 @@ static void spapr_machine_4_2_class_options(MachineClass 
*mc)
 spapr_machine_5_0_class_options(mc);
 compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
 smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
+smc->default_caps.caps[SPAPR_CAP_FWNMI_MCE] = SPAPR_CAP_OFF;
 }
 
 DEFINE_SPAPR_MACHINE(4_2, "4.2", false);
-- 
2.24.1




[PULL 19/34] ppc/pnv: Add models for POWER9 PHB4 PCIe Host bridge

2020-01-30 Thread David Gibson
From: Benjamin Herrenschmidt 

These changes introduces models for the PCIe Host Bridge (PHB4) of the
POWER9 processor. It includes the PowerBus logic interface (PBCQ),
IOMMU support, a single PCIe Gen.4 Root Complex, and support for MSI
and LSI interrupt sources as found on a POWER9 system using the XIVE
interrupt controller.

POWER9 processor comes with 3 PHB4 PEC (PCI Express Controller) and
each PEC can have several PHBs. By default,

  * PEC0 provides 1 PHB  (PHB0)
  * PEC1 provides 2 PHBs (PHB1 and PHB2)
  * PEC2 provides 3 PHBs (PHB3, PHB4 and PHB5)

Each PEC has a set  "global" registers and some "per-stack" (per-PHB)
registers. Those are organized in two XSCOM ranges, the "Nest" range
and the "PCI" range, each range contains both some "PEC" registers and
some "per-stack" registers.

No default device layout is provided and PCI devices can be added on
any of the available PCIe Root Port (pcie.0 .. 2 of a Power9 chip)
with address 0x0 as the firwware (skiboot) only accepts a single
device per root port. To run a simple system with a network and a
storage adapters, use a command line options such as :

  -device e1000e,netdev=net0,mac=C0:FF:EE:00:00:02,bus=pcie.0,addr=0x0
  -netdev 
bridge,id=net0,helper=/usr/libexec/qemu-bridge-helper,br=virbr0,id=hostnet0

  -device megasas,id=scsi0,bus=pcie.1,addr=0x0
  -drive file=$disk,if=none,id=drive-scsi0-0-0-0,format=qcow2,cache=none
  -device 
scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,bootindex=2

If more are needed, include a bridge.

Multi chip is supported, each chip adding its set of PHB4 controllers
and its PCI busses. The model doesn't emulate the EEH error handling.

This model is not ready for hotplug yet.

Signed-off-by: Benjamin Herrenschmidt 
[ clg: - numerous cleanups
   - commit log
   - fix for broken LSI support
   - PHB pic printinfo
   - large QOM rework ]
Signed-off-by: Cédric Le Goater 
Message-Id: <20200127144506.11132-2-...@kaod.org>
[dwg: Use device_class_set_props()]
Signed-off-by: David Gibson 
---
 hw/pci-host/Makefile.objs   |1 +
 hw/pci-host/pnv_phb4.c  | 1438 +++
 hw/pci-host/pnv_phb4_pec.c  |  593 +++
 hw/ppc/Kconfig  |2 +
 hw/ppc/pnv.c|  107 ++
 include/hw/pci-host/pnv_phb4.h  |  230 +
 include/hw/pci-host/pnv_phb4_regs.h |  553 ++
 include/hw/pci/pcie_port.h  |1 +
 include/hw/ppc/pnv.h|7 +
 include/hw/ppc/pnv_xscom.h  |   11 +
 10 files changed, 2943 insertions(+)
 create mode 100644 hw/pci-host/pnv_phb4.c
 create mode 100644 hw/pci-host/pnv_phb4_pec.c
 create mode 100644 include/hw/pci-host/pnv_phb4.h
 create mode 100644 include/hw/pci-host/pnv_phb4_regs.h

diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
index 9c466fab01..8a296e2f93 100644
--- a/hw/pci-host/Makefile.objs
+++ b/hw/pci-host/Makefile.objs
@@ -20,3 +20,4 @@ common-obj-$(CONFIG_PCI_EXPRESS_GENERIC_BRIDGE) += gpex.o
 common-obj-$(CONFIG_PCI_EXPRESS_XILINX) += xilinx-pcie.o
 
 common-obj-$(CONFIG_PCI_EXPRESS_DESIGNWARE) += designware.o
+obj-$(CONFIG_POWERNV) += pnv_phb4.o pnv_phb4_pec.o
diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
new file mode 100644
index 00..61235d13a6
--- /dev/null
+++ b/hw/pci-host/pnv_phb4.c
@@ -0,0 +1,1438 @@
+/*
+ * QEMU PowerPC PowerNV (POWER9) PHB4 model
+ *
+ * Copyright (c) 2018-2020, IBM Corporation.
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/visitor.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "monitor/monitor.h"
+#include "target/ppc/cpu.h"
+#include "hw/pci-host/pnv_phb4_regs.h"
+#include "hw/pci-host/pnv_phb4.h"
+#include "hw/pci/pcie_host.h"
+#include "hw/pci/pcie_port.h"
+#include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_xscom.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+
+#define phb_error(phb, fmt, ...)\
+qemu_log_mask(LOG_GUEST_ERROR, "phb4[%d:%d]: " fmt "\n",\
+  (phb)->chip_id, (phb)->phb_id, ## __VA_ARGS__)
+
+/*
+ * QEMU version of the GETFIELD/SETFIELD macros
+ *
+ * These are common with the PnvXive model.
+ */
+static inline uint64_t GETFIELD(uint64_t mask, uint64_t word)
+{
+return (word & mask) >> ctz64(mask);
+}
+
+static inline uint64_t SETFIELD(uint64_t mask, uint64_t word,
+uint64_t value)
+{
+return (word & ~mask) | ((value << ctz64(mask)) & mask);
+}
+
+static PCIDevice *pnv_phb4_find_cfg_dev(PnvPHB4 *phb)
+{
+PCIHostState *pci = PCI_HOST_BRIDGE(phb);
+uint64_t addr = phb->regs[PHB_CONFIG_ADDRESS >> 3];
+uint8_t bus, devfn;
+
+if (!(addr >> 63)) {
+return NULL;
+}
+bus = (addr >> 52) & 0xff;
+devfn = (addr >> 44) & 0xff;
+
+/* We d

[PULL 32/34] target/ppc: Use probe_access for LMW, STMW

2020-01-30 Thread David Gibson
From: Richard Henderson 

Use a minimum number of mmu lookups for the contiguous bytes
that are accessed.  If the lookup succeeds, we can finish the
operation with host addresses only.

Reported-by: Howard Spoelstra 
Signed-off-by: Richard Henderson 
Message-Id: <20200129235040.24022-3-richard.hender...@linaro.org>
Tested-by: Howard Spoelstra 
Signed-off-by: David Gibson 
---
 target/ppc/mem_helper.c | 45 +
 1 file changed, 32 insertions(+), 13 deletions(-)

diff --git a/target/ppc/mem_helper.c b/target/ppc/mem_helper.c
index 508d472a2f..e7d3a79d96 100644
--- a/target/ppc/mem_helper.c
+++ b/target/ppc/mem_helper.c
@@ -84,26 +84,45 @@ static void *probe_contiguous(CPUPPCState *env, 
target_ulong addr, uint32_t nb,
 
 void helper_lmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
 {
-for (; reg < 32; reg++) {
-if (needs_byteswap(env)) {
-env->gpr[reg] = bswap32(cpu_ldl_data_ra(env, addr, GETPC()));
-} else {
-env->gpr[reg] = cpu_ldl_data_ra(env, addr, GETPC());
+uintptr_t raddr = GETPC();
+int mmu_idx = cpu_mmu_index(env, false);
+void *host = probe_contiguous(env, addr, (32 - reg) * 4,
+  MMU_DATA_LOAD, mmu_idx, raddr);
+
+if (likely(host)) {
+/* Fast path -- the entire operation is in RAM at host.  */
+for (; reg < 32; reg++) {
+env->gpr[reg] = (uint32_t)ldl_be_p(host);
+host += 4;
+}
+} else {
+/* Slow path -- at least some of the operation requires i/o.  */
+for (; reg < 32; reg++) {
+env->gpr[reg] = cpu_ldl_mmuidx_ra(env, addr, mmu_idx, raddr);
+addr = addr_add(env, addr, 4);
 }
-addr = addr_add(env, addr, 4);
 }
 }
 
 void helper_stmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
 {
-for (; reg < 32; reg++) {
-if (needs_byteswap(env)) {
-cpu_stl_data_ra(env, addr, bswap32((uint32_t)env->gpr[reg]),
-   GETPC());
-} else {
-cpu_stl_data_ra(env, addr, (uint32_t)env->gpr[reg], GETPC());
+uintptr_t raddr = GETPC();
+int mmu_idx = cpu_mmu_index(env, false);
+void *host = probe_contiguous(env, addr, (32 - reg) * 4,
+  MMU_DATA_STORE, mmu_idx, raddr);
+
+if (likely(host)) {
+/* Fast path -- the entire operation is in RAM at host.  */
+for (; reg < 32; reg++) {
+stl_be_p(host, env->gpr[reg]);
+host += 4;
+}
+} else {
+/* Slow path -- at least some of the operation requires i/o.  */
+for (; reg < 32; reg++) {
+cpu_stl_mmuidx_ra(env, addr, env->gpr[reg], mmu_idx, raddr);
+addr = addr_add(env, addr, 4);
 }
-addr = addr_add(env, addr, 4);
 }
 }
 
-- 
2.24.1




[PULL 33/34] target/ppc: Remove redundant mask in DCBZ

2020-01-30 Thread David Gibson
From: Richard Henderson 

The value of addr has already been masked, just above.

Signed-off-by: Richard Henderson 
Message-Id: <20200129235040.24022-4-richard.hender...@linaro.org>
Tested-by: Howard Spoelstra 
Signed-off-by: David Gibson 
---
 target/ppc/mem_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/mem_helper.c b/target/ppc/mem_helper.c
index e7d3a79d96..0cb78777e7 100644
--- a/target/ppc/mem_helper.c
+++ b/target/ppc/mem_helper.c
@@ -293,7 +293,7 @@ static void dcbz_common(CPUPPCState *env, target_ulong addr,
 addr &= mask;
 
 /* Check reservation */
-if ((env->reserve_addr & mask) == (addr & mask))  {
+if ((env->reserve_addr & mask) == addr)  {
 env->reserve_addr = (target_ulong)-1ULL;
 }
 
-- 
2.24.1




[PULL 23/34] target/ppc/cpu.h: Put macro parameter in parentheses

2020-01-30 Thread David Gibson
From: BALATON Zoltan 

Fix PPC_INPUT macro to work with more complex expressions by
protecting its argument with parentheses.

Signed-off-by: BALATON Zoltan 
Message-Id: <20200130021619.65fab747...@zero.eik.bme.hu>
Signed-off-by: David Gibson 
---
 target/ppc/cpu.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 96aeea1934..3a1eb76004 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -180,7 +180,7 @@ enum {
 POWERPC_EXCP_TRAP  = 0x40,
 };
 
-#define PPC_INPUT(env) (env->bus_model)
+#define PPC_INPUT(env) ((env)->bus_model)
 
 /*/
 typedef struct opc_handler_t opc_handler_t;
-- 
2.24.1




[PULL 28/34] ppc: spapr: Handle "ibm, nmi-register" and "ibm, nmi-interlock" RTAS calls

2020-01-30 Thread David Gibson
From: Aravinda Prasad 

This patch adds support in QEMU to handle "ibm,nmi-register"
and "ibm,nmi-interlock" RTAS calls.

The machine check notification address is saved when the
OS issues "ibm,nmi-register" RTAS call.

This patch also handles the case when multiple processors
experience machine check at or about the same time by
handling "ibm,nmi-interlock" call. In such cases, as per
PAPR, subsequent processors serialize waiting for the first
processor to issue the "ibm,nmi-interlock" call. The second
processor that also received a machine check error waits
till the first processor is done reading the error log.
The first processor issues "ibm,nmi-interlock" call
when the error log is consumed.

Signed-off-by: Aravinda Prasad 
[Register fwnmi RTAS calls in core_rtas_register_types()
 where other RTAS calls are registered]
Signed-off-by: Ganesh Goudar 
Message-Id: <20200130184423.20519-6-ganes...@linux.ibm.com>
Signed-off-by: David Gibson 
---
 hw/ppc/spapr_caps.c| 10 +++
 hw/ppc/spapr_rtas.c| 59 ++
 include/hw/ppc/spapr.h |  4 ++-
 3 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index 393ee6845e..8b27d3ac09 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -515,6 +515,16 @@ static void cap_fwnmi_mce_apply(SpaprMachineState *spapr, 
uint8_t val,
 if (!val) {
 return; /* Disabled by default */
 }
+
+if (tcg_enabled()) {
+warn_report("Firmware Assisted Non-Maskable Interrupts(FWNMI) not "
+"supported in TCG");
+} else if (kvm_enabled()) {
+if (kvmppc_set_fwnmi() < 0) {
+error_setg(errp, "Firmware Assisted Non-Maskable Interrupts(FWNMI) 
"
+ "not supported by KVM");
+}
+}
 }
 
 SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 89b7eb6c54..35d91260e6 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -399,6 +399,61 @@ static void rtas_get_power_level(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
 rtas_st(rets, 1, 100);
 }
 
+static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
+  SpaprMachineState *spapr,
+  uint32_t token, uint32_t nargs,
+  target_ulong args,
+  uint32_t nret, target_ulong rets)
+{
+hwaddr rtas_addr;
+
+if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI_MCE) == SPAPR_CAP_OFF) {
+rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
+return;
+}
+
+rtas_addr = spapr_get_rtas_addr();
+if (!rtas_addr) {
+rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
+return;
+}
+
+spapr->guest_machine_check_addr = rtas_ld(args, 1);
+rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+}
+
+static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
+   SpaprMachineState *spapr,
+   uint32_t token, uint32_t nargs,
+   target_ulong args,
+   uint32_t nret, target_ulong rets)
+{
+if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI_MCE) == SPAPR_CAP_OFF) {
+rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
+return;
+}
+
+if (spapr->guest_machine_check_addr == -1) {
+/* NMI register not called */
+rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+return;
+}
+
+if (spapr->mc_status != cpu->vcpu_id) {
+/* The vCPU that hit the NMI should invoke "ibm,nmi-interlock" */
+rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+return;
+}
+
+/*
+ * vCPU issuing "ibm,nmi-interlock" is done with NMI handling,
+ * hence unset mc_status.
+ */
+spapr->mc_status = -1;
+qemu_cond_signal(&spapr->mc_delivery_cond);
+rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+}
+
 static struct rtas_call {
 const char *name;
 spapr_rtas_fn fn;
@@ -527,6 +582,10 @@ static void core_rtas_register_types(void)
 rtas_set_power_level);
 spapr_rtas_register(RTAS_GET_POWER_LEVEL, "get-power-level",
 rtas_get_power_level);
+spapr_rtas_register(RTAS_IBM_NMI_REGISTER, "ibm,nmi-register",
+rtas_ibm_nmi_register);
+spapr_rtas_register(RTAS_IBM_NMI_INTERLOCK, "ibm,nmi-interlock",
+rtas_ibm_nmi_interlock);
 }
 
 type_init(core_rtas_register_types)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 652a5514e8..f6f82d88aa 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -656,8 +656,10 @@ target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong 
opcode,
 #define RTAS_IBM_REMOVE_PE_DMA_WINDOW   (RTAS_TOKEN_BASE + 0x28)
 #define RTAS_IBM_RESET_PE_DMA_WINDOW(RTAS_TOKEN_BASE + 0x29)
 #define RTAS_IBM_SUSPEND_ME (RTAS_TOKEN_BASE + 0x2A)
+#define R

[PULL 26/34] target/ppc: Handle NMI guest exit

2020-01-30 Thread David Gibson
From: Aravinda Prasad 

Memory error such as bit flips that cannot be corrected
by hardware are passed on to the kernel for handling.
If the memory address in error belongs to guest then
the guest kernel is responsible for taking suitable action.
Patch [1] enhances KVM to exit guest with exit reason
set to KVM_EXIT_NMI in such cases. This patch handles
KVM_EXIT_NMI exit.

[1] https://www.spinics.net/lists/kvm-ppc/msg12637.html
(e20bbd3d and related commits)

Signed-off-by: Aravinda Prasad 
Signed-off-by: Ganesh Goudar 
Reviewed-by: David Gibson 
Reviewed-by: Greg Kurz 
Message-Id: <20200130184423.20519-4-ganes...@linux.ibm.com>
[dwg: #ifdefs to fix compile for 32-bit target]
Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c  |  8 
 hw/ppc/spapr_events.c   | 37 +
 include/hw/ppc/spapr.h  | 10 ++
 target/ppc/kvm.c| 18 ++
 target/ppc/kvm_ppc.h|  2 ++
 target/ppc/trace-events |  1 +
 6 files changed, 76 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index aa739e943f..06e295cdf1 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1677,6 +1677,12 @@ static void spapr_machine_reset(MachineState *machine)
 first_ppc_cpu->env.gpr[5] = 0;
 
 spapr->cas_reboot = false;
+
+spapr->mc_status = -1;
+spapr->guest_machine_check_addr = -1;
+
+/* Signal all vCPUs waiting on this condition */
+qemu_cond_broadcast(&spapr->mc_delivery_cond);
 }
 
 static void spapr_create_nvram(SpaprMachineState *spapr)
@@ -2971,6 +2977,8 @@ static void spapr_machine_init(MachineState *machine)
 
 kvmppc_spapr_enable_inkernel_multitce();
 }
+
+qemu_cond_init(&spapr->mc_delivery_cond);
 }
 
 static int spapr_kvm_type(MachineState *machine, const char *vm_type)
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index e355e000d0..dfc0de840a 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -40,6 +40,7 @@
 #include "hw/ppc/spapr_drc.h"
 #include "qemu/help_option.h"
 #include "qemu/bcd.h"
+#include "qemu/main-loop.h"
 #include "hw/ppc/spapr_ovec.h"
 #include 
 
@@ -622,6 +623,42 @@ void 
spapr_hotplug_req_remove_by_count_indexed(SpaprDrcType drc_type,
 RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, &drc_id);
 }
 
+void spapr_mce_req_event(PowerPCCPU *cpu)
+{
+SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+CPUState *cs = CPU(cpu);
+
+if (spapr->guest_machine_check_addr == -1) {
+/*
+ * This implies that we have hit a machine check either when the
+ * guest has not registered FWNMI (i.e., "ibm,nmi-register" not
+ * called) or between system reset and "ibm,nmi-register".
+ * Fall back to the old machine check behavior in such cases.
+ */
+cs->exception_index = POWERPC_EXCP_MCHECK;
+ppc_cpu_do_interrupt(cs);
+return;
+}
+
+while (spapr->mc_status != -1) {
+/*
+ * Check whether the same CPU got machine check error
+ * while still handling the mc error (i.e., before
+ * that CPU called "ibm,nmi-interlock")
+ */
+if (spapr->mc_status == cpu->vcpu_id) {
+qemu_system_guest_panicked(NULL);
+return;
+}
+qemu_cond_wait_iothread(&spapr->mc_delivery_cond);
+/* Meanwhile if the system is reset, then just return */
+if (spapr->guest_machine_check_addr == -1) {
+return;
+}
+}
+spapr->mc_status = cpu->vcpu_id;
+}
+
 static void check_exception(PowerPCCPU *cpu, SpaprMachineState *spapr,
 uint32_t token, uint32_t nargs,
 target_ulong args,
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 7bc5fc3a9e..909d3976f9 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -191,6 +191,15 @@ struct SpaprMachineState {
  * occurs during the unplug process. */
 QTAILQ_HEAD(, SpaprDimmState) pending_dimm_unplugs;
 
+/* State related to "ibm,nmi-register" and "ibm,nmi-interlock" calls */
+target_ulong guest_machine_check_addr;
+/*
+ * mc_status is set to -1 if mc is not in progress, else is set to the CPU
+ * handling the mc.
+ */
+int mc_status;
+QemuCond mc_delivery_cond;
+
 /*< public >*/
 char *kvm_type;
 char *host_model;
@@ -804,6 +813,7 @@ void spapr_clear_pending_events(SpaprMachineState *spapr);
 int spapr_max_server_number(SpaprMachineState *spapr);
 void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
   uint64_t pte0, uint64_t pte1);
+void spapr_mce_req_event(PowerPCCPU *cpu);
 
 /* DRC callbacks. */
 void spapr_core_release(DeviceState *dev);
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 4438d0c743..56a6865521 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -1705,6 +1705,13 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run 
*run)
 ret = 0;
 break;
 
+#i

[PULL 20/34] ppc/pnv: Add models for POWER8 PHB3 PCIe Host bridge

2020-01-30 Thread David Gibson
From: Cédric Le Goater 

This is a model of the PCIe Host Bridge (PHB3) found on a POWER8
processor. It includes the PowerBus logic interface (PBCQ), IOMMU
support, a single PCIe Gen.3 Root Complex, and support for MSI and LSI
interrupt sources as found on a POWER8 system using the XICS interrupt
controller.

The POWER8 processor comes in different flavors: Venice, Murano,
Naple, each having a different number of PHBs. To make things simpler,
the models provides 3 PHB3 per chip. Some platforms, like the
Firestone, can also couple PHBs on the first chip to provide more
bandwidth but this is too specific to model in QEMU.

XICS requires some adjustment to support the PHB3 MSI. The changes are
provided here but they could be decoupled in prereq patches.

Signed-off-by: Benjamin Herrenschmidt 
Signed-off-by: Cédric Le Goater 
Message-Id: <20200127144506.11132-3-...@kaod.org>
[dwg: Use device_class_set_props()]
Signed-off-by: David Gibson 
---
 hw/intc/xics.c  |   14 +-
 hw/pci-host/Makefile.objs   |1 +
 hw/pci-host/pnv_phb3.c  | 1195 +++
 hw/pci-host/pnv_phb3_msi.c  |  349 
 hw/pci-host/pnv_phb3_pbcq.c |  357 
 hw/ppc/pnv.c|   69 +-
 include/hw/pci-host/pnv_phb3.h  |  164 
 include/hw/pci-host/pnv_phb3_regs.h |  450 ++
 include/hw/ppc/pnv.h|4 +
 include/hw/ppc/pnv_xscom.h  |9 +
 include/hw/ppc/xics.h   |5 +
 11 files changed, 2614 insertions(+), 3 deletions(-)
 create mode 100644 hw/pci-host/pnv_phb3.c
 create mode 100644 hw/pci-host/pnv_phb3_msi.c
 create mode 100644 hw/pci-host/pnv_phb3_pbcq.c
 create mode 100644 include/hw/pci-host/pnv_phb3.h
 create mode 100644 include/hw/pci-host/pnv_phb3_regs.h

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 785b607528..c5d507e707 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -217,7 +217,7 @@ void icp_eoi(ICPState *icp, uint32_t xirr)
 }
 }
 
-static void icp_irq(ICSState *ics, int server, int nr, uint8_t priority)
+void icp_irq(ICSState *ics, int server, int nr, uint8_t priority)
 {
 ICPState *icp = xics_icp_get(ics->xics, server);
 
@@ -512,8 +512,14 @@ void ics_write_xive(ICSState *ics, int srcno, int server,
 
 static void ics_reject(ICSState *ics, uint32_t nr)
 {
+ICSStateClass *isc = ICS_GET_CLASS(ics);
 ICSIRQState *irq = ics->irqs + nr - ics->offset;
 
+if (isc->reject) {
+isc->reject(ics, nr);
+return;
+}
+
 trace_xics_ics_reject(nr, nr - ics->offset);
 if (irq->flags & XICS_FLAGS_IRQ_MSI) {
 irq->status |= XICS_STATUS_REJECTED;
@@ -524,8 +530,14 @@ static void ics_reject(ICSState *ics, uint32_t nr)
 
 void ics_resend(ICSState *ics)
 {
+ICSStateClass *isc = ICS_GET_CLASS(ics);
 int i;
 
+if (isc->resend) {
+isc->resend(ics);
+return;
+}
+
 for (i = 0; i < ics->nr_irqs; i++) {
 /* FIXME: filter by server#? */
 if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) {
diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
index 8a296e2f93..8c87e8494d 100644
--- a/hw/pci-host/Makefile.objs
+++ b/hw/pci-host/Makefile.objs
@@ -21,3 +21,4 @@ common-obj-$(CONFIG_PCI_EXPRESS_XILINX) += xilinx-pcie.o
 
 common-obj-$(CONFIG_PCI_EXPRESS_DESIGNWARE) += designware.o
 obj-$(CONFIG_POWERNV) += pnv_phb4.o pnv_phb4_pec.o
+obj-$(CONFIG_POWERNV) += pnv_phb3.o pnv_phb3_msi.o pnv_phb3_pbcq.o
diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c
new file mode 100644
index 00..f03399c406
--- /dev/null
+++ b/hw/pci-host/pnv_phb3.c
@@ -0,0 +1,1195 @@
+/*
+ * QEMU PowerPC PowerNV (POWER8) PHB3 model
+ *
+ * Copyright (c) 2014-2020, IBM Corporation.
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/visitor.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "hw/pci-host/pnv_phb3_regs.h"
+#include "hw/pci-host/pnv_phb3.h"
+#include "hw/pci/pcie_host.h"
+#include "hw/pci/pcie_port.h"
+#include "hw/ppc/pnv.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+
+#define phb3_error(phb, fmt, ...)   \
+qemu_log_mask(LOG_GUEST_ERROR, "phb3[%d:%d]: " fmt "\n",\
+  (phb)->chip_id, (phb)->phb_id, ## __VA_ARGS__)
+
+static PCIDevice *pnv_phb3_find_cfg_dev(PnvPHB3 *phb)
+{
+PCIHostState *pci = PCI_HOST_BRIDGE(phb);
+uint64_t addr = phb->regs[PHB_CONFIG_ADDRESS >> 3];
+uint8_t bus, devfn;
+
+if (!(addr >> 63)) {
+return NULL;
+}
+bus = (addr >> 52) & 0xff;
+devfn = (addr >> 44) & 0xff;
+
+return pci_find_device(pci->bus, bus, devfn);
+}
+
+/*
+ * The CONFIG_DATA register expects little endian accesses, but as the
+ * region is big endian, we have to swap the value.
+ */
+static void pnv_phb3_config_write(PnvPHB3 *phb, unsigned off

[PULL 14/34] spapr: Implement get_dt_compatible() callback

2020-01-30 Thread David Gibson
From: Stefan Berger 

For devices that cannot be statically initialized, implement a
get_dt_compatible() callback that allows us to ask the device for
the 'compatible' value.

Signed-off-by: Stefan Berger 
Reviewed-by: Marc-André Lureau 
Reviewed-by: David Gibson 
Message-Id: <20200121152935.649898-3-stef...@linux.ibm.com>
Signed-off-by: David Gibson 
---
 hw/ppc/spapr_vio.c | 11 +--
 include/hw/ppc/spapr_vio.h |  1 +
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index f14944e900..0b085eabe4 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -87,6 +87,7 @@ static int vio_make_devnode(SpaprVioDevice *dev,
 SpaprVioDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
 int vdevice_off, node_off, ret;
 char *dt_name;
+const char *dt_compatible;
 
 vdevice_off = fdt_path_offset(fdt, "/vdevice");
 if (vdevice_off < 0) {
@@ -113,9 +114,15 @@ static int vio_make_devnode(SpaprVioDevice *dev,
 }
 }
 
-if (pc->dt_compatible) {
+if (pc->get_dt_compatible) {
+dt_compatible = pc->get_dt_compatible(dev);
+} else {
+dt_compatible = pc->dt_compatible;
+}
+
+if (dt_compatible) {
 ret = fdt_setprop_string(fdt, node_off, "compatible",
- pc->dt_compatible);
+ dt_compatible);
 if (ret < 0) {
 return ret;
 }
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index ce6d9b0c66..bed7df60e3 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -58,6 +58,7 @@ typedef struct SpaprVioDeviceClass {
 void (*realize)(SpaprVioDevice *dev, Error **errp);
 void (*reset)(SpaprVioDevice *dev);
 int (*devnode)(SpaprVioDevice *dev, void *fdt, int node_off);
+const char *(*get_dt_compatible)(SpaprVioDevice *dev);
 } SpaprVioDeviceClass;
 
 struct SpaprVioDevice {
-- 
2.24.1




[PULL 18/34] docs/specs/tpm: reST-ify TPM documentation

2020-01-30 Thread David Gibson
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Stefan Berger 
Message-Id: <20200121152935.649898-7-stef...@linux.ibm.com>
Signed-off-by: David Gibson 
---
 docs/specs/index.rst |   1 +
 docs/specs/tpm.rst   | 503 +++
 docs/specs/tpm.txt   | 445 --
 3 files changed, 504 insertions(+), 445 deletions(-)
 create mode 100644 docs/specs/tpm.rst
 delete mode 100644 docs/specs/tpm.txt

diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index 984ba44029..de46a8b5e7 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -13,3 +13,4 @@ Contents:
ppc-xive
ppc-spapr-xive
acpi_hw_reduced_hotplug
+   tpm
diff --git a/docs/specs/tpm.rst b/docs/specs/tpm.rst
new file mode 100644
index 00..2bdf637f55
--- /dev/null
+++ b/docs/specs/tpm.rst
@@ -0,0 +1,503 @@
+===
+QEMU TPM Device
+===
+
+Guest-side hardware interface
+=
+
+TIS interface
+-
+
+The QEMU TPM emulation implements a TPM TIS hardware interface
+following the Trusted Computing Group's specification "TCG PC Client
+Specific TPM Interface Specification (TIS)", Specification Version
+1.3, 21 March 2013. (see the `TIS specification`_, or a later version
+of it).
+
+The TIS interface makes a memory mapped IO region in the area
+0xfed4-0xfed44fff available to the guest operating system.
+
+QEMU files related to TPM TIS interface:
+ - ``hw/tpm/tpm_tis.c``
+ - ``hw/tpm/tpm_tis.h``
+
+CRB interface
+-
+
+QEMU also implements a TPM CRB interface following the Trusted
+Computing Group's specification "TCG PC Client Platform TPM Profile
+(PTP) Specification", Family "2.0", Level 00 Revision 01.03 v22, May
+22, 2017. (see the `CRB specification`_, or a later version of it)
+
+The CRB interface makes a memory mapped IO region in the area
+0xfed4-0xfed40fff (1 locality) available to the guest
+operating system.
+
+QEMU files related to TPM CRB interface:
+ - ``hw/tpm/tpm_crb.c``
+
+SPAPR interface
+---
+
+pSeries (ppc64) machines offer a tpm-spapr device model.
+
+QEMU files related to the SPAPR interface:
+ - ``hw/tpm/tpm_spapr.c``
+
+fw_cfg interface
+
+
+The bios/firmware may read the ``"etc/tpm/config"`` fw_cfg entry for
+configuring the guest appropriately.
+
+The entry of 6 bytes has the following content, in little-endian:
+
+.. code-block:: c
+
+#define TPM_VERSION_UNSPEC  0
+#define TPM_VERSION_1_2 1
+#define TPM_VERSION_2_0 2
+
+#define TPM_PPI_VERSION_NONE0
+#define TPM_PPI_VERSION_1_301
+
+struct FwCfgTPMConfig {
+uint32_t tpmppi_address; /* PPI memory location */
+uint8_t tpm_version; /* TPM version */
+uint8_t tpmppi_version;  /* PPI version */
+};
+
+ACPI interface
+==
+
+The TPM device is defined with ACPI ID "PNP0C31". QEMU builds a SSDT
+and passes it into the guest through the fw_cfg device. The device
+description contains the base address of the TIS interface 0xfed4
+and the size of the MMIO area (0x5000). In case a TPM2 is used by
+QEMU, a TPM2 ACPI table is also provided.  The device is described to
+be used in polling mode rather than interrupt mode primarily because
+no unused IRQ could be found.
+
+To support measurement logs to be written by the firmware,
+e.g. SeaBIOS, a TCPA table is implemented. This table provides a 64kb
+buffer where the firmware can write its log into. For TPM 2 only a
+more recent version of the TPM2 table provides support for
+measurements logs and a TCPA table does not need to be created.
+
+The TCPA and TPM2 ACPI tables follow the Trusted Computing Group
+specification "TCG ACPI Specification" Family "1.2" and "2.0", Level
+00 Revision 00.37. (see the `ACPI specification`_, or a later version
+of it)
+
+ACPI PPI Interface
+--
+
+QEMU supports the Physical Presence Interface (PPI) for TPM 1.2 and
+TPM 2. This interface requires ACPI and firmware support. (see the
+`PPI specification`_)
+
+PPI enables a system administrator (root) to request a modification to
+the TPM upon reboot. The PPI specification defines the operation
+requests and the actions the firmware has to take. The system
+administrator passes the operation request number to the firmware
+through an ACPI interface which writes this number to a memory
+location that the firmware knows. Upon reboot, the firmware finds the
+number and sends commands to the TPM. The firmware writes the TPM
+result code and the operation request number to a memory location that
+ACPI can read from and pass the result on to the administrator.
+
+The PPI specification defines a set of mandatory and optional
+operations for the firmware to implement. The ACPI interface also
+allows an administrator to list the supported operations. In QEMU the
+ACPI code is generated by QEMU, yet the firmw

[PULL 31/34] target/ppc: Use probe_access for LSW, STSW

2020-01-30 Thread David Gibson
From: Richard Henderson 

Use a minimum number of mmu lookups for the contiguous bytes
that are accessed.  If the lookup succeeds, we can finish the
operation with host addresses only.

Reported-by: Howard Spoelstra 
Signed-off-by: Richard Henderson 
Message-Id: <20200129235040.24022-2-richard.hender...@linaro.org>
Tested-by: Howard Spoelstra 
Signed-off-by: David Gibson 
---
 target/ppc/mem_helper.c | 148 ++--
 1 file changed, 128 insertions(+), 20 deletions(-)

diff --git a/target/ppc/mem_helper.c b/target/ppc/mem_helper.c
index e8e2a8ac2a..508d472a2f 100644
--- a/target/ppc/mem_helper.c
+++ b/target/ppc/mem_helper.c
@@ -56,6 +56,32 @@ static inline target_ulong addr_add(CPUPPCState *env, 
target_ulong addr,
 }
 }
 
+static void *probe_contiguous(CPUPPCState *env, target_ulong addr, uint32_t nb,
+  MMUAccessType access_type, int mmu_idx,
+  uintptr_t raddr)
+{
+void *host1, *host2;
+uint32_t nb_pg1, nb_pg2;
+
+nb_pg1 = -(addr | TARGET_PAGE_MASK);
+if (likely(nb <= nb_pg1)) {
+/* The entire operation is on a single page.  */
+return probe_access(env, addr, nb, access_type, mmu_idx, raddr);
+}
+
+/* The operation spans two pages.  */
+nb_pg2 = nb - nb_pg1;
+host1 = probe_access(env, addr, nb_pg1, access_type, mmu_idx, raddr);
+addr = addr_add(env, addr, nb_pg1);
+host2 = probe_access(env, addr, nb_pg2, access_type, mmu_idx, raddr);
+
+/* If the two host pages are contiguous, optimize.  */
+if (host2 == host1 + nb_pg1) {
+return host1;
+}
+return NULL;
+}
+
 void helper_lmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
 {
 for (; reg < 32; reg++) {
@@ -84,23 +110,65 @@ void helper_stmw(CPUPPCState *env, target_ulong addr, 
uint32_t reg)
 static void do_lsw(CPUPPCState *env, target_ulong addr, uint32_t nb,
uint32_t reg, uintptr_t raddr)
 {
-int sh;
+int mmu_idx;
+void *host;
+uint32_t val;
 
-for (; nb > 3; nb -= 4) {
-env->gpr[reg] = cpu_ldl_data_ra(env, addr, raddr);
-reg = (reg + 1) % 32;
-addr = addr_add(env, addr, 4);
+if (unlikely(nb == 0)) {
+return;
 }
-if (unlikely(nb > 0)) {
-env->gpr[reg] = 0;
-for (sh = 24; nb > 0; nb--, sh -= 8) {
-env->gpr[reg] |= cpu_ldub_data_ra(env, addr, raddr) << sh;
-addr = addr_add(env, addr, 1);
+
+mmu_idx = cpu_mmu_index(env, false);
+host = probe_contiguous(env, addr, nb, MMU_DATA_LOAD, mmu_idx, raddr);
+
+if (likely(host)) {
+/* Fast path -- the entire operation is in RAM at host.  */
+for (; nb > 3; nb -= 4) {
+env->gpr[reg] = (uint32_t)ldl_be_p(host);
+reg = (reg + 1) % 32;
+host += 4;
+}
+switch (nb) {
+default:
+return;
+case 1:
+val = ldub_p(host) << 24;
+break;
+case 2:
+val = lduw_be_p(host) << 16;
+break;
+case 3:
+val = (lduw_be_p(host) << 16) | (ldub_p(host + 2) << 8);
+break;
+}
+} else {
+/* Slow path -- at least some of the operation requires i/o.  */
+for (; nb > 3; nb -= 4) {
+env->gpr[reg] = cpu_ldl_mmuidx_ra(env, addr, mmu_idx, raddr);
+reg = (reg + 1) % 32;
+addr = addr_add(env, addr, 4);
+}
+switch (nb) {
+default:
+return;
+case 1:
+val = cpu_ldub_mmuidx_ra(env, addr, mmu_idx, raddr) << 24;
+break;
+case 2:
+val = cpu_lduw_mmuidx_ra(env, addr, mmu_idx, raddr) << 16;
+break;
+case 3:
+val = cpu_lduw_mmuidx_ra(env, addr, mmu_idx, raddr) << 16;
+addr = addr_add(env, addr, 2);
+val |= cpu_ldub_mmuidx_ra(env, addr, mmu_idx, raddr) << 8;
+break;
 }
 }
+env->gpr[reg] = val;
 }
 
-void helper_lsw(CPUPPCState *env, target_ulong addr, uint32_t nb, uint32_t reg)
+void helper_lsw(CPUPPCState *env, target_ulong addr,
+uint32_t nb, uint32_t reg)
 {
 do_lsw(env, addr, nb, reg, GETPC());
 }
@@ -130,17 +198,57 @@ void helper_lswx(CPUPPCState *env, target_ulong addr, 
uint32_t reg,
 void helper_stsw(CPUPPCState *env, target_ulong addr, uint32_t nb,
  uint32_t reg)
 {
-int sh;
+uintptr_t raddr = GETPC();
+int mmu_idx;
+void *host;
+uint32_t val;
 
-for (; nb > 3; nb -= 4) {
-cpu_stl_data_ra(env, addr, env->gpr[reg], GETPC());
-reg = (reg + 1) % 32;
-addr = addr_add(env, addr, 4);
+if (unlikely(nb == 0)) {
+return;
 }
-if (unlikely(nb > 0)) {
-for (sh = 24; nb > 0; nb--, sh -= 8) {
-cpu_stb_data_ra(env, addr, (env->gpr[reg] >> sh) & 0xFF, GETPC());
-addr = addr_add(env, addr, 1);
+
+mmu_idx = cpu_mmu_in

[PULL 17/34] hw/ppc/Kconfig: Enable TPM_SPAPR as part of PSERIES config

2020-01-30 Thread David Gibson
From: Stefan Berger 

Signed-off-by: Stefan Berger 
Reviewed-by: Marc-André Lureau 
Reviewed-by: David Gibson 
Message-Id: <20200121152935.649898-6-stef...@linux.ibm.com>
[dwg: Use default in Kconfig rather than select to avoid breaking
 Windows host build]
Signed-off-by: David Gibson 
---
 hw/tpm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/tpm/Kconfig b/hw/tpm/Kconfig
index 4d4ab0855c..9e67d990e8 100644
--- a/hw/tpm/Kconfig
+++ b/hw/tpm/Kconfig
@@ -25,6 +25,6 @@ config TPM_EMULATOR
 
 config TPM_SPAPR
 bool
-default n
+default y
 depends on TPM && PSERIES
 select TPMDEV
-- 
2.24.1




[PULL 24/34] Wrapper function to wait on condition for the main loop mutex

2020-01-30 Thread David Gibson
From: Aravinda Prasad 

Introduce a wrapper function to wait on condition for
the main loop mutex. This function atomically releases
the main loop mutex and causes the calling thread to
block on the condition. This wrapper is required because
qemu_global_mutex is a static variable.

Signed-off-by: Aravinda Prasad 
Signed-off-by: Ganesh Goudar 
Reviewed-by: David Gibson 
Reviewed-by: Greg Kurz 
Message-Id: <20200130184423.20519-2-ganes...@linux.ibm.com>
Signed-off-by: David Gibson 
---
 cpus.c   | 5 +
 include/qemu/main-loop.h | 8 
 2 files changed, 13 insertions(+)

diff --git a/cpus.c b/cpus.c
index b612116f95..b4f8b84b61 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1839,6 +1839,11 @@ void qemu_mutex_unlock_iothread(void)
 qemu_mutex_unlock(&qemu_global_mutex);
 }
 
+void qemu_cond_wait_iothread(QemuCond *cond)
+{
+qemu_cond_wait(cond, &qemu_global_mutex);
+}
+
 static bool all_vcpus_paused(void)
 {
 CPUState *cpu;
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index f6ba78ea73..a6d20b0719 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -295,6 +295,14 @@ void qemu_mutex_lock_iothread_impl(const char *file, int 
line);
  */
 void qemu_mutex_unlock_iothread(void);
 
+/*
+ * qemu_cond_wait_iothread: Wait on condition for the main loop mutex
+ *
+ * This function atomically releases the main loop mutex and causes
+ * the calling thread to block on the condition.
+ */
+void qemu_cond_wait_iothread(QemuCond *cond);
+
 /* internal interfaces */
 
 void qemu_fd_register(int fd);
-- 
2.24.1




[PULL 34/34] target/ppc: Use probe_write for DCBZ

2020-01-30 Thread David Gibson
From: Richard Henderson 

Using probe_write instead of tlb_vaddr_to_host means that we
process watchpoints and notdirty pages more efficiently.

Signed-off-by: Richard Henderson 
Message-Id: <20200129235040.24022-5-richard.hender...@linaro.org>
Tested-by: Howard Spoelstra 
Signed-off-by: David Gibson 
---
 target/ppc/mem_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/mem_helper.c b/target/ppc/mem_helper.c
index 0cb78777e7..98f589552b 100644
--- a/target/ppc/mem_helper.c
+++ b/target/ppc/mem_helper.c
@@ -298,7 +298,7 @@ static void dcbz_common(CPUPPCState *env, target_ulong addr,
 }
 
 /* Try fast path translate */
-haddr = tlb_vaddr_to_host(env, addr, MMU_DATA_STORE, mmu_idx);
+haddr = probe_write(env, addr, dcbz_size, mmu_idx, retaddr);
 if (haddr) {
 memset(haddr, 0, dcbz_size);
 } else {
-- 
2.24.1




[PULL 29/34] migration: Include migration support for machine check handling

2020-01-30 Thread David Gibson
From: Aravinda Prasad 

This patch includes migration support for machine check
handling. Especially this patch blocks VM migration
requests until the machine check error handling is
complete as these errors are specific to the source
hardware and is irrelevant on the target hardware.

Signed-off-by: Aravinda Prasad 
[Do not set FWNMI cap in post_load, now its done in .apply hook]
Signed-off-by: Ganesh Goudar 
Message-Id: <20200130184423.20519-7-ganes...@linux.ibm.com>
Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c | 47 ++
 hw/ppc/spapr_events.c  | 16 +-
 hw/ppc/spapr_rtas.c|  2 ++
 include/hw/ppc/spapr.h |  2 ++
 4 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 06e295cdf1..137f5c9a33 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -46,6 +46,7 @@
 #include "migration/qemu-file-types.h"
 #include "migration/global_state.h"
 #include "migration/register.h"
+#include "migration/blocker.h"
 #include "mmu-hash64.h"
 #include "mmu-book3s-v3.h"
 #include "cpu-models.h"
@@ -1683,6 +1684,8 @@ static void spapr_machine_reset(MachineState *machine)
 
 /* Signal all vCPUs waiting on this condition */
 qemu_cond_broadcast(&spapr->mc_delivery_cond);
+
+migrate_del_blocker(spapr->fwnmi_migration_blocker);
 }
 
 static void spapr_create_nvram(SpaprMachineState *spapr)
@@ -1965,6 +1968,42 @@ static const VMStateDescription vmstate_spapr_dtb = {
 },
 };
 
+static bool spapr_fwnmi_needed(void *opaque)
+{
+SpaprMachineState *spapr = (SpaprMachineState *)opaque;
+
+return spapr->guest_machine_check_addr != -1;
+}
+
+static int spapr_fwnmi_pre_save(void *opaque)
+{
+SpaprMachineState *spapr = (SpaprMachineState *)opaque;
+
+/*
+ * Check if machine check handling is in progress and print a
+ * warning message.
+ */
+if (spapr->mc_status != -1) {
+warn_report("A machine check is being handled during migration. The"
+"handler may run and log hardware error on the destination");
+}
+
+return 0;
+}
+
+static const VMStateDescription vmstate_spapr_machine_check = {
+.name = "spapr_machine_check",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = spapr_fwnmi_needed,
+.pre_save = spapr_fwnmi_pre_save,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(guest_machine_check_addr, SpaprMachineState),
+VMSTATE_INT32(mc_status, SpaprMachineState),
+VMSTATE_END_OF_LIST()
+},
+};
+
 static const VMStateDescription vmstate_spapr = {
 .name = "spapr",
 .version_id = 3,
@@ -1999,6 +2038,7 @@ static const VMStateDescription vmstate_spapr = {
 &vmstate_spapr_cap_large_decr,
 &vmstate_spapr_cap_ccf_assist,
 &vmstate_spapr_cap_fwnmi,
+&vmstate_spapr_machine_check,
 NULL
 }
 };
@@ -2814,6 +2854,13 @@ static void spapr_machine_init(MachineState *machine)
 spapr_create_lmb_dr_connectors(spapr);
 }
 
+if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI_MCE) == SPAPR_CAP_ON) {
+/* Create the error string for live migration blocker */
+error_setg(&spapr->fwnmi_migration_blocker,
+"A machine check is being handled during migration. The handler"
+"may run and log hardware error on the destination");
+}
+
 /* Set up RTAS event infrastructure */
 spapr_events_init(spapr);
 
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index 54eaf28a9e..884e455f02 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -43,6 +43,7 @@
 #include "qemu/main-loop.h"
 #include "hw/ppc/spapr_ovec.h"
 #include 
+#include "migration/blocker.h"
 
 #define RTAS_LOG_VERSION_MASK   0xff00
 #define   RTAS_LOG_VERSION_60x0600
@@ -843,6 +844,8 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
 {
 SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 CPUState *cs = CPU(cpu);
+int ret;
+Error *local_err = NULL;
 
 if (spapr->guest_machine_check_addr == -1) {
 /*
@@ -872,8 +875,19 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
 return;
 }
 }
-spapr->mc_status = cpu->vcpu_id;
 
+ret = migrate_add_blocker(spapr->fwnmi_migration_blocker, &local_err);
+if (ret == -EBUSY) {
+/*
+ * We don't want to abort so we let the migration to continue.
+ * In a rare case, the machine check handler will run on the target.
+ * Though this is not preferable, it is better than aborting
+ * the migration or killing the VM.
+ */
+warn_report("Received a fwnmi while migration was in progress");
+}
+
+spapr->mc_status = cpu->vcpu_id;
 spapr_mce_dispatch_elog(cpu, recovered);
 }
 
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 35d91260e6..883fe28465 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -50,6 +50,7

[PULL 15/34] tpm_spapr: Support TPM for ppc64 using CRQ based interface

2020-01-30 Thread David Gibson
From: Stefan Berger 

Implement support for TPM on ppc64 by implementing the vTPM CRQ interface
as a frontend. It can use the tpm_emulator driver backend with the external
swtpm.

The Linux vTPM driver for ppc64 works with this emulation.

This TPM emulator also handles the TPM 2 case.

Signed-off-by: Stefan Berger 
Reviewed-by: David Gibson 
Message-Id: <20200121152935.649898-4-stef...@linux.ibm.com>
[dwg: Use device_class_set_props(), tweak Kconfig]
Signed-off-by: David Gibson 
---
 docs/specs/tpm.txt   |  20 ++-
 hw/tpm/Kconfig   |   6 +
 hw/tpm/Makefile.objs |   1 +
 hw/tpm/tpm_spapr.c   | 379 +++
 hw/tpm/trace-events  |  12 ++
 include/sysemu/tpm.h |   3 +
 qapi/tpm.json|   6 +-
 7 files changed, 423 insertions(+), 4 deletions(-)
 create mode 100644 hw/tpm/tpm_spapr.c

diff --git a/docs/specs/tpm.txt b/docs/specs/tpm.txt
index 9c8cca042d..9c3e67d8a7 100644
--- a/docs/specs/tpm.txt
+++ b/docs/specs/tpm.txt
@@ -34,6 +34,12 @@ The CRB interface makes a memory mapped IO region in the 
area 0xfed4 -
 QEMU files related to TPM CRB interface:
  - hw/tpm/tpm_crb.c
 
+
+pSeries (ppc64) machines offer a tpm-spapr device model.
+
+QEMU files related to the SPAPR interface:
+ - hw/tpm/tpm_spapr.c
+
 = fw_cfg interface =
 
 The bios/firmware may read the "etc/tpm/config" fw_cfg entry for
@@ -281,7 +287,7 @@ swtpm socket --tpmstate dir=/tmp/mytpm1 \
   --log level=20
 
 Command line to start QEMU with the TPM emulator device communicating with
-the swtpm:
+the swtpm (x86):
 
 qemu-system-x86_64 -display sdl -accel kvm \
   -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
@@ -289,6 +295,18 @@ qemu-system-x86_64 -display sdl -accel kvm \
   -tpmdev emulator,id=tpm0,chardev=chrtpm \
   -device tpm-tis,tpmdev=tpm0 test.img
 
+In case a pSeries machine is emulated, use the following command line:
+
+qemu-system-ppc64 -display sdl -machine pseries,accel=kvm \
+  -m 1024 -bios slof.bin -boot menu=on \
+  -nodefaults -device VGA -device pci-ohci -device usb-kbd \
+  -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
+  -tpmdev emulator,id=tpm0,chardev=chrtpm \
+  -device tpm-spapr,tpmdev=tpm0 \
+  -device spapr-vscsi,id=scsi0,reg=0x2000 \
+  -device 
virtio-blk-pci,scsi=off,bus=pci.0,addr=0x3,drive=drive-virtio-disk0,id=virtio-disk0
 \
+  -drive file=test.img,format=raw,if=none,id=drive-virtio-disk0
+
 
 In case SeaBIOS is used as firmware, it should show the TPM menu item
 after entering the menu with 'ESC'.
diff --git a/hw/tpm/Kconfig b/hw/tpm/Kconfig
index 4c8ee87d67..4d4ab0855c 100644
--- a/hw/tpm/Kconfig
+++ b/hw/tpm/Kconfig
@@ -22,3 +22,9 @@ config TPM_EMULATOR
 bool
 default y
 depends on TPMDEV
+
+config TPM_SPAPR
+bool
+default n
+depends on TPM && PSERIES
+select TPMDEV
diff --git a/hw/tpm/Makefile.objs b/hw/tpm/Makefile.objs
index de0b85d02a..85eb99ae05 100644
--- a/hw/tpm/Makefile.objs
+++ b/hw/tpm/Makefile.objs
@@ -4,3 +4,4 @@ common-obj-$(CONFIG_TPM_TIS) += tpm_tis.o
 common-obj-$(CONFIG_TPM_CRB) += tpm_crb.o
 common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
 common-obj-$(CONFIG_TPM_EMULATOR) += tpm_emulator.o
+obj-$(CONFIG_TPM_SPAPR) += tpm_spapr.o
diff --git a/hw/tpm/tpm_spapr.c b/hw/tpm/tpm_spapr.c
new file mode 100644
index 00..2ac4cb061c
--- /dev/null
+++ b/hw/tpm/tpm_spapr.c
@@ -0,0 +1,379 @@
+/*
+ * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
+ *
+ * PAPR Virtual TPM
+ *
+ * Copyright (c) 2015, 2017, 2019 IBM Corporation.
+ *
+ * Authors:
+ *Stefan Berger 
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+
+#include "sysemu/tpm_backend.h"
+#include "tpm_int.h"
+#include "tpm_util.h"
+
+#include "hw/ppc/spapr.h"
+#include "hw/ppc/spapr_vio.h"
+#include "trace.h"
+
+#define DEBUG_SPAPR 0
+
+#define VIO_SPAPR_VTPM(obj) \
+ OBJECT_CHECK(SpaprTpmState, (obj), TYPE_TPM_SPAPR)
+
+typedef struct TpmCrq {
+uint8_t valid;  /* 0x80: cmd; 0xc0: init crq */
+/* 0x81-0x83: CRQ message response */
+uint8_t msg;/* see below */
+uint16_t len;   /* len of TPM request; len of TPM response */
+uint32_t data;  /* rtce_dma_handle when sending TPM request */
+uint64_t reserved;
+} TpmCrq;
+
+#define SPAPR_VTPM_VALID_INIT_CRQ_COMMAND  0xC0
+#define SPAPR_VTPM_VALID_COMMAND   0x80
+#define SPAPR_VTPM_MSG_RESULT  0x80
+
+/* msg types for valid = SPAPR_VTPM_VALID_INIT_CRQ */
+#define SPAPR_VTPM_INIT_CRQ_RESULT   0x1
+#define SPAPR_VTPM_INIT_CRQ_COMPLETE_RESULT  0x2
+
+/* msg types for valid = SPAPR_VTPM_VALID_CMD */
+#define SPAPR_VTPM_GET_VERSION   0x1
+#define SPAPR_VTPM_TPM_COMMAND   0x2
+#define SPAPR_VTPM_GET_RTCE_BUFFER_SIZE  0x3
+#define SPAPR_VTPM_PRE

[PULL 27/34] target/ppc: Build rtas error log upon an MCE

2020-01-30 Thread David Gibson
From: Aravinda Prasad 

Upon a machine check exception (MCE) in a guest address space,
KVM causes a guest exit to enable QEMU to build and pass the
error to the guest in the PAPR defined rtas error log format.

This patch builds the rtas error log, copies it to the rtas_addr
and then invokes the guest registered machine check handler. The
handler in the guest takes suitable action(s) depending on the type
and criticality of the error. For example, if an error is
unrecoverable memory corruption in an application inside the
guest, then the guest kernel sends a SIGBUS to the application.
For recoverable errors, the guest performs recovery actions and
logs the error.

Signed-off-by: Aravinda Prasad 
[Assume SLOF has allocated enough room for rtas error log]
Signed-off-by: Ganesh Goudar 
Reviewed-by: David Gibson 
Message-Id: <20200130184423.20519-5-ganes...@linux.ibm.com>
Signed-off-by: David Gibson 
---
 hw/ppc/spapr_events.c  | 220 -
 hw/ppc/spapr_rtas.c|  26 +
 include/hw/ppc/spapr.h |   6 +-
 target/ppc/kvm.c   |   4 +-
 4 files changed, 253 insertions(+), 3 deletions(-)

diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index dfc0de840a..54eaf28a9e 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -214,6 +214,104 @@ struct hp_extended_log {
 struct rtas_event_log_v6_hp hp;
 } QEMU_PACKED;
 
+struct rtas_event_log_v6_mc {
+#define RTAS_LOG_V6_SECTION_ID_MC   0x4D43 /* MC */
+struct rtas_event_log_v6_section_header hdr;
+uint32_t fru_id;
+uint32_t proc_id;
+uint8_t error_type;
+#define RTAS_LOG_V6_MC_TYPE_UE   0
+#define RTAS_LOG_V6_MC_TYPE_SLB  1
+#define RTAS_LOG_V6_MC_TYPE_ERAT 2
+#define RTAS_LOG_V6_MC_TYPE_TLB  4
+#define RTAS_LOG_V6_MC_TYPE_D_CACHE  5
+#define RTAS_LOG_V6_MC_TYPE_I_CACHE  7
+uint8_t sub_err_type;
+#define RTAS_LOG_V6_MC_UE_INDETERMINATE  0
+#define RTAS_LOG_V6_MC_UE_IFETCH 1
+#define RTAS_LOG_V6_MC_UE_PAGE_TABLE_WALK_IFETCH 2
+#define RTAS_LOG_V6_MC_UE_LOAD_STORE 3
+#define RTAS_LOG_V6_MC_UE_PAGE_TABLE_WALK_LOAD_STORE 4
+#define RTAS_LOG_V6_MC_SLB_PARITY0
+#define RTAS_LOG_V6_MC_SLB_MULTIHIT  1
+#define RTAS_LOG_V6_MC_SLB_INDETERMINATE 2
+#define RTAS_LOG_V6_MC_ERAT_PARITY   1
+#define RTAS_LOG_V6_MC_ERAT_MULTIHIT 2
+#define RTAS_LOG_V6_MC_ERAT_INDETERMINATE3
+#define RTAS_LOG_V6_MC_TLB_PARITY1
+#define RTAS_LOG_V6_MC_TLB_MULTIHIT  2
+#define RTAS_LOG_V6_MC_TLB_INDETERMINATE 3
+uint8_t reserved_1[6];
+uint64_t effective_address;
+uint64_t logical_address;
+} QEMU_PACKED;
+
+struct mc_extended_log {
+struct rtas_event_log_v6 v6hdr;
+struct rtas_event_log_v6_mc mc;
+} QEMU_PACKED;
+
+struct MC_ierror_table {
+unsigned long srr1_mask;
+unsigned long srr1_value;
+bool nip_valid; /* nip is a valid indicator of faulting address */
+uint8_t error_type;
+uint8_t error_subtype;
+unsigned int initiator;
+unsigned int severity;
+};
+
+static const struct MC_ierror_table mc_ierror_table[] = {
+{ 0x081c, 0x0004, true,
+  RTAS_LOG_V6_MC_TYPE_UE, RTAS_LOG_V6_MC_UE_IFETCH,
+  RTAS_LOG_INITIATOR_CPU, RTAS_LOG_SEVERITY_ERROR_SYNC, },
+{ 0x081c, 0x0008, true,
+  RTAS_LOG_V6_MC_TYPE_SLB, RTAS_LOG_V6_MC_SLB_PARITY,
+  RTAS_LOG_INITIATOR_CPU, RTAS_LOG_SEVERITY_ERROR_SYNC, },
+{ 0x081c, 0x000c, true,
+  RTAS_LOG_V6_MC_TYPE_SLB, RTAS_LOG_V6_MC_SLB_MULTIHIT,
+  RTAS_LOG_INITIATOR_CPU, RTAS_LOG_SEVERITY_ERROR_SYNC, },
+{ 0x081c, 0x0010, true,
+  RTAS_LOG_V6_MC_TYPE_ERAT, RTAS_LOG_V6_MC_ERAT_MULTIHIT,
+  RTAS_LOG_INITIATOR_CPU, RTAS_LOG_SEVERITY_ERROR_SYNC, },
+{ 0x081c, 0x0014, true,
+  RTAS_LOG_V6_MC_TYPE_TLB, RTAS_LOG_V6_MC_TLB_MULTIHIT,
+  RTAS_LOG_INITIATOR_CPU, RTAS_LOG_SEVERITY_ERROR_SYNC, },
+{ 0x081c, 0x0018, true,
+  RTAS_LOG_V6_MC_TYPE_UE, RTAS_LOG_V6_MC_UE_PAGE_TABLE_WALK_IFETCH,
+  RTAS_LOG_INITIATOR_CPU, RTAS_LOG_SEVERITY_ERROR_SYNC, } };
+
+struct MC_derror_table {
+unsigned long dsisr_value;
+bool dar_valid; /* dar is a valid indicator of faulting address */
+uint8_t error_type;
+uint8_t error_subtype;
+unsigned int initiator;
+unsigned int severity;
+};
+
+static const struct MC_derror_table mc_derror_table[] = {
+{ 0x8000, false,
+  RTAS_LOG_V6_MC_TYPE_UE, RTAS_LOG_V6_MC_UE_LOAD_STORE,
+  RTAS_LOG_INITIATOR_CPU, RTAS_LOG_SEVERITY_ERROR_SYNC, },
+{ 0x4000, true,
+  RTAS_LOG_V6_MC_TYPE_UE, RTAS_LOG_V6_MC_UE_PAGE_TABLE_WALK_LOAD_STORE,
+  RTAS_LOG_INITIATOR_CPU, RTAS_LOG_SEVERITY_ERROR

[PULL 12/34] ppc/pnv: Add support for "hostboot" mode

2020-01-30 Thread David Gibson
From: Cédric Le Goater 

When the "hb-mode" option is activated on the powernv machine, the
firmware is mapped at 0x800 and the HRMOR of the HW threads are
set to the same address.

The PNOR mapping on the FW address space of the LPC bus is left enabled
to let the firmware load any other images required to boot the host.

Signed-off-by: Cédric Le Goater 
Message-Id: <20200127144154.10170-4-...@kaod.org>
Signed-off-by: David Gibson 
---
 hw/ppc/pnv.c  | 28 +++-
 hw/ppc/pnv_core.c |  3 +++
 hw/ppc/pnv_lpc.c  |  5 -
 include/hw/ppc/pnv.h  |  2 ++
 include/hw/ppc/pnv_core.h |  1 +
 5 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index e61994cf5a..9442e5eb63 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -716,7 +716,7 @@ static void pnv_init(MachineState *machine)
 exit(1);
 }
 
-fw_size = load_image_targphys(fw_filename, FW_LOAD_ADDR, FW_MAX_SIZE);
+fw_size = load_image_targphys(fw_filename, pnv->fw_load_addr, FW_MAX_SIZE);
 if (fw_size < 0) {
 error_report("Could not load OPAL firmware '%s'", fw_filename);
 exit(1);
@@ -1533,6 +1533,7 @@ static void pnv_chip_core_realize(PnvChip *chip, Error 
**errp)
 PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
 const char *typename = pnv_chip_core_typename(chip);
 int i, core_hwid;
+PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
 
 if (!object_class_by_name(typename)) {
 error_setg(errp, "Unable to find PowerNV CPU Core '%s'", typename);
@@ -1571,6 +1572,8 @@ static void pnv_chip_core_realize(PnvChip *chip, Error 
**errp)
 object_property_set_int(OBJECT(pnv_core),
 pcc->core_pir(chip, core_hwid),
 "pir", &error_fatal);
+object_property_set_int(OBJECT(pnv_core), pnv->fw_load_addr,
+"hrmor", &error_fatal);
 object_property_set_link(OBJECT(pnv_core), OBJECT(chip), "chip",
  &error_abort);
 object_property_set_bool(OBJECT(pnv_core), true, "realized",
@@ -1767,6 +1770,22 @@ static void pnv_machine_power10_class_init(ObjectClass 
*oc, void *data)
 pmc->dt_power_mgt = pnv_dt_power_mgt;
 }
 
+static bool pnv_machine_get_hb(Object *obj, Error **errp)
+{
+PnvMachineState *pnv = PNV_MACHINE(obj);
+
+return !!pnv->fw_load_addr;
+}
+
+static void pnv_machine_set_hb(Object *obj, bool value, Error **errp)
+{
+PnvMachineState *pnv = PNV_MACHINE(obj);
+
+if (value) {
+pnv->fw_load_addr = 0x800;
+}
+}
+
 static void pnv_machine_class_init(ObjectClass *oc, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
@@ -1786,6 +1805,13 @@ static void pnv_machine_class_init(ObjectClass *oc, void 
*data)
  */
 mc->default_ram_size = INITRD_LOAD_ADDR + INITRD_MAX_SIZE;
 ispc->print_info = pnv_pic_print_info;
+
+object_class_property_add_bool(oc, "hb-mode",
+   pnv_machine_get_hb, pnv_machine_set_hb,
+   &error_abort);
+object_class_property_set_description(oc, "hb-mode",
+  "Use a hostboot like boot loader",
+  NULL);
 }
 
 #define DEFINE_PNV8_CHIP_TYPE(type, class_initfn) \
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 5fe3f21e12..f7247222bc 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -56,6 +56,8 @@ static void pnv_core_cpu_reset(PnvCore *pc, PowerPCCPU *cpu)
 env->nip = 0x10;
 env->msr |= MSR_HVB; /* Hypervisor mode */
 
+env->spr[SPR_HRMOR] = pc->hrmor;
+
 pcc->intc_reset(pc->chip, cpu);
 }
 
@@ -289,6 +291,7 @@ static void pnv_core_unrealize(DeviceState *dev, Error 
**errp)
 
 static Property pnv_core_properties[] = {
 DEFINE_PROP_UINT32("pir", PnvCore, pir, 0),
+DEFINE_PROP_UINT64("hrmor", PnvCore, hrmor, 0),
 DEFINE_PROP_LINK("chip", PnvCore, chip, TYPE_PNV_CHIP, PnvChip *),
 DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 22b205532b..d1de98f04c 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -825,6 +825,7 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool 
use_cpld, Error **errp)
 qemu_irq *irqs;
 qemu_irq_handler handler;
 PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
+bool hostboot_mode = !!pnv->fw_load_addr;
 
 /* let isa_bus_new() create its own bridge on SysBus otherwise
  * devices speficied on the command line won't find the bus and
@@ -859,7 +860,9 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool 
use_cpld, Error **errp)
  * Start disabled. The HIOMAP protocol will activate the mapping
  * with HIOMAP_C_CREATE_WRITE_WINDOW
  */
-memory_region_set_enabled(&pnv->pnor->mmio, false);
+if (!hostboot_mode) {
+memory_region_set_enabled(&pnv->pnor->mmio, false);
+}
 
 return isa_bus;
 }
diff -

[PULL 13/34] tpm: Move tpm_tis_show_buffer to tpm_util.c

2020-01-30 Thread David Gibson
From: Stefan Berger 

Signed-off-by: Stefan Berger 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: David Gibson 
Message-Id: <20200121152935.649898-2-stef...@linux.ibm.com>
Signed-off-by: David Gibson 
---
 hw/tpm/tpm_tis.c| 32 
 hw/tpm/tpm_util.c   | 25 +
 hw/tpm/tpm_util.h   |  3 +++
 hw/tpm/trace-events |  2 +-
 4 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 5362df2711..31facb896d 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -107,30 +107,6 @@ static uint8_t tpm_tis_locality_from_addr(hwaddr addr)
 return (uint8_t)((addr >> TPM_TIS_LOCALITY_SHIFT) & 0x7);
 }
 
-static void tpm_tis_show_buffer(const unsigned char *buffer,
-size_t buffer_size, const char *string)
-{
-size_t len, i;
-char *line_buffer, *p;
-
-len = MIN(tpm_cmd_get_size(buffer), buffer_size);
-
-/*
- * allocate enough room for 3 chars per buffer entry plus a
- * newline after every 16 chars and a final null terminator.
- */
-line_buffer = g_malloc(len * 3 + (len / 16) + 1);
-
-for (i = 0, p = line_buffer; i < len; i++) {
-if (i && !(i % 16)) {
-p += sprintf(p, "\n");
-}
-p += sprintf(p, "%.2X ", buffer[i]);
-}
-trace_tpm_tis_show_buffer(string, len, line_buffer);
-
-g_free(line_buffer);
-}
 
 /*
  * Set the given flags in the STS register by clearing the register but
@@ -156,8 +132,8 @@ static void tpm_tis_sts_set(TPMLocality *l, uint32_t flags)
  */
 static void tpm_tis_tpm_send(TPMState *s, uint8_t locty)
 {
-if (trace_event_get_state_backends(TRACE_TPM_TIS_SHOW_BUFFER)) {
-tpm_tis_show_buffer(s->buffer, s->be_buffer_size, "To TPM");
+if (trace_event_get_state_backends(TRACE_TPM_UTIL_SHOW_BUFFER)) {
+tpm_util_show_buffer(s->buffer, s->be_buffer_size, "To TPM");
 }
 
 /*
@@ -325,8 +301,8 @@ static void tpm_tis_request_completed(TPMIf *ti, int ret)
 s->loc[locty].state = TPM_TIS_STATE_COMPLETION;
 s->rw_offset = 0;
 
-if (trace_event_get_state_backends(TRACE_TPM_TIS_SHOW_BUFFER)) {
-tpm_tis_show_buffer(s->buffer, s->be_buffer_size, "From TPM");
+if (trace_event_get_state_backends(TRACE_TPM_UTIL_SHOW_BUFFER)) {
+tpm_util_show_buffer(s->buffer, s->be_buffer_size, "From TPM");
 }
 
 if (TPM_TIS_IS_VALID_LOCTY(s->next_locty)) {
diff --git a/hw/tpm/tpm_util.c b/hw/tpm/tpm_util.c
index 62b091f0c0..c0a0f3d71f 100644
--- a/hw/tpm/tpm_util.c
+++ b/hw/tpm/tpm_util.c
@@ -350,3 +350,28 @@ void tpm_sized_buffer_reset(TPMSizedBuffer *tsb)
 tsb->buffer = NULL;
 tsb->size = 0;
 }
+
+void tpm_util_show_buffer(const unsigned char *buffer,
+  size_t buffer_size, const char *string)
+{
+size_t len, i;
+char *line_buffer, *p;
+
+len = MIN(tpm_cmd_get_size(buffer), buffer_size);
+
+/*
+ * allocate enough room for 3 chars per buffer entry plus a
+ * newline after every 16 chars and a final null terminator.
+ */
+line_buffer = g_malloc(len * 3 + (len / 16) + 1);
+
+for (i = 0, p = line_buffer; i < len; i++) {
+if (i && !(i % 16)) {
+p += sprintf(p, "\n");
+}
+p += sprintf(p, "%.2X ", buffer[i]);
+}
+trace_tpm_util_show_buffer(string, len, line_buffer);
+
+g_free(line_buffer);
+}
diff --git a/hw/tpm/tpm_util.h b/hw/tpm/tpm_util.h
index f397ac21b8..7889081fba 100644
--- a/hw/tpm/tpm_util.h
+++ b/hw/tpm/tpm_util.h
@@ -79,4 +79,7 @@ typedef struct TPMSizedBuffer {
 
 void tpm_sized_buffer_reset(TPMSizedBuffer *tsb);
 
+void tpm_util_show_buffer(const unsigned char *buffer,
+  size_t buffer_size, const char *string);
+
 #endif /* TPM_TPM_UTIL_H */
diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
index 89804bcd64..357c9e9a84 100644
--- a/hw/tpm/trace-events
+++ b/hw/tpm/trace-events
@@ -14,6 +14,7 @@ tpm_util_get_buffer_size_len(uint32_t len, size_t expected) 
"tpm_resp->len = %u,
 tpm_util_get_buffer_size_hdr_len2(uint32_t len, size_t expected) 
"tpm2_resp->hdr.len = %u, expected = %zu"
 tpm_util_get_buffer_size_len2(uint32_t len, size_t expected) "tpm2_resp->len = 
%u, expected = %zu"
 tpm_util_get_buffer_size(size_t len) "buffersize of device: %zu"
+tpm_util_show_buffer(const char *direction, size_t len, const char *buf) 
"direction: %s len: %zu\n%s"
 
 # tpm_emulator.c
 tpm_emulator_set_locality(uint8_t locty) "setting locality to %d"
@@ -36,7 +37,6 @@ tpm_emulator_pre_save(void) ""
 tpm_emulator_inst_init(void) ""
 
 # tpm_tis.c
-tpm_tis_show_buffer(const char *direction, size_t len, const char *buf) 
"direction: %s len: %zu\nbuf: %s"
 tpm_tis_raise_irq(uint32_t irqmask) "Raising IRQ for flag 0x%08x"
 tpm_tis_new_active_locality(uint8_t locty) "Active locality is now %d"
 tpm_tis_abort(uint8_t locty) "New active locality is %d"
-- 
2.24.1




[PULL 04/34] hw/ppc/prep: Remove the deprecated "prep" machine and the OpenHackware BIOS

2020-01-30 Thread David Gibson
From: Thomas Huth 

It's been deprecated since QEMU v3.1. The 40p machine should be
used nowadays instead.

Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: Hervé Poussineau 
Signed-off-by: Thomas Huth 
Message-Id: <20200114114617.28854-1-th...@redhat.com>
Signed-off-by: David Gibson 
---
 .gitmodules   |   3 -
 MAINTAINERS   |   1 -
 Makefile  |   2 +-
 docs/interop/firmware.json|   3 +-
 hw/ppc/ppc.c  |  18 --
 hw/ppc/prep.c | 384 +-
 include/hw/ppc/ppc.h  |   1 -
 pc-bios/README|   3 -
 pc-bios/ppc_rom.bin   | Bin 1048576 -> 0 bytes
 qemu-deprecated.texi  |   6 -
 qemu-doc.texi |  15 +-
 roms/openhackware |   1 -
 tests/qtest/boot-order-test.c |  25 ---
 tests/qtest/cdrom-test.c  |   2 +-
 tests/qtest/endianness-test.c |   2 +-
 15 files changed, 10 insertions(+), 456 deletions(-)
 delete mode 100644 pc-bios/ppc_rom.bin
 delete mode 16 roms/openhackware

diff --git a/.gitmodules b/.gitmodules
index 19792c9a11..9c0501a4d4 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -10,9 +10,6 @@
 [submodule "roms/openbios"]
path = roms/openbios
url = https://git.qemu.org/git/openbios.git
-[submodule "roms/openhackware"]
-   path = roms/openhackware
-   url = https://git.qemu.org/git/openhackware.git
 [submodule "roms/qemu-palcode"]
path = roms/qemu-palcode
url = https://git.qemu.org/git/qemu-palcode.git
diff --git a/MAINTAINERS b/MAINTAINERS
index c45e886d88..8d632ca4d4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1103,7 +1103,6 @@ F: hw/dma/i82374.c
 F: hw/rtc/m48t59-isa.c
 F: include/hw/isa/pc87312.h
 F: include/hw/rtc/m48t59.h
-F: pc-bios/ppc_rom.bin
 F: tests/acceptance/ppc_prep_40p.py
 
 sPAPR
diff --git a/Makefile b/Makefile
index 9a5a1e689c..3b21c0ea48 100644
--- a/Makefile
+++ b/Makefile
@@ -784,7 +784,7 @@ ifdef INSTALL_BLOBS
 BLOBS=bios.bin bios-256k.bin bios-microvm.bin sgabios.bin vgabios.bin 
vgabios-cirrus.bin \
 vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin vgabios-virtio.bin \
 vgabios-ramfb.bin vgabios-bochs-display.bin vgabios-ati.bin \
-ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc QEMU,tcx.bin 
QEMU,cgthree.bin \
+openbios-sparc32 openbios-sparc64 openbios-ppc QEMU,tcx.bin QEMU,cgthree.bin \
 pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \
 pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
 efi-e1000.rom efi-eepro100.rom efi-ne2k_pci.rom \
diff --git a/docs/interop/firmware.json b/docs/interop/firmware.json
index 8ffb7856d2..240f565397 100644
--- a/docs/interop/firmware.json
+++ b/docs/interop/firmware.json
@@ -27,8 +27,7 @@
 #
 # @openfirmware: The interface is defined by the (historical) IEEE
 #1275-1994 standard. Examples for firmware projects that
-#provide this interface are: OpenBIOS, OpenHackWare,
-#SLOF.
+#provide this interface are: OpenBIOS and SLOF.
 #
 # @uboot: Firmware interface defined by the U-Boot project.
 #
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 4c5fa29399..4a11fb1640 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -1490,24 +1490,6 @@ int ppc_dcr_init (CPUPPCState *env, int 
(*read_error)(int dcrn),
 }
 
 /*/
-/* Debug port */
-void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
-{
-addr &= 0xF;
-switch (addr) {
-case 0:
-printf("%c", val);
-break;
-case 1:
-printf("\n");
-fflush(stdout);
-break;
-case 2:
-printf("Set loglevel to %04" PRIx32 "\n", val);
-qemu_set_log(val | 0x100);
-break;
-}
-}
 
 int ppc_cpu_pir(PowerPCCPU *cpu)
 {
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 862345c2ac..111cc80867 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -42,7 +42,7 @@
 #include "hw/loader.h"
 #include "hw/rtc/mc146818rtc.h"
 #include "hw/isa/pc87312.h"
-#include "hw/net/ne2000-isa.h"
+#include "hw/qdev-properties.h"
 #include "sysemu/arch_init.h"
 #include "sysemu/kvm.h"
 #include "sysemu/qtest.h"
@@ -60,178 +60,9 @@
 
 #define CFG_ADDR 0xf510
 
-#define BIOS_SIZE (1 * MiB)
-#define BIOS_FILENAME "ppc_rom.bin"
 #define KERNEL_LOAD_ADDR 0x0100
 #define INITRD_LOAD_ADDR 0x0180
 
-/* Constants for devices init */
-static const int ide_iobase[2] = { 0x1f0, 0x170 };
-static const int ide_iobase2[2] = { 0x3f6, 0x376 };
-static const int ide_irq[2] = { 13, 13 };
-
-#define NE2000_NB_MAX 6
-
-static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 
0x280, 0x380 };
-static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
-
-/* ISA IO ports bridge */
-#define PPC_IO_BASE 0x8000
-
-/* Fake super-io ports for PREP platform (Intel 82378ZB) */
-typedef struct sysctrl_t {
-qemu_irq reset_irq;
-Nvram *nvram;
-uint8_t state;
-uint8_t syscontrol;
-

[PULL 21/34] ppc/pnv: change the PowerNV machine devices to be non user creatable

2020-01-30 Thread David Gibson
From: Cédric Le Goater 

The PowerNV machine emulates an OpenPOWER system and the PowerNV chip
devices are models of the internal logic of the POWER processor. They
can not be instantiated by the user on the QEMU command line.

The PHB3/PHB4 devices could be an exception in the future after some
rework on how the device tree is built. For the moment, exclude them
also.

Signed-off-by: Cédric Le Goater 
Message-Id: <20200129113720.7404-1-...@kaod.org>
Tested-by: Thomas Huth 
Reviewed-by: Greg Kurz 
Signed-off-by: David Gibson 
---
 hw/pci-host/pnv_phb3.c  | 2 ++
 hw/pci-host/pnv_phb3_pbcq.c | 1 +
 hw/pci-host/pnv_phb4.c  | 3 ++-
 hw/pci-host/pnv_phb4_pec.c  | 2 ++
 hw/ppc/pnv_core.c   | 2 ++
 hw/ppc/pnv_homer.c  | 1 +
 hw/ppc/pnv_lpc.c| 1 +
 hw/ppc/pnv_occ.c| 1 +
 8 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c
index f03399c406..74618fadf0 100644
--- a/hw/pci-host/pnv_phb3.c
+++ b/hw/pci-host/pnv_phb3.c
@@ -1115,6 +1115,7 @@ static void pnv_phb3_class_init(ObjectClass *klass, void 
*data)
 dc->realize = pnv_phb3_realize;
 device_class_set_props(dc, pnv_phb3_properties);
 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+dc->user_creatable = false;
 }
 
 static const TypeInfo pnv_phb3_type_info = {
@@ -1168,6 +1169,7 @@ static void pnv_phb3_root_port_class_init(ObjectClass 
*klass, void *data)
 
 device_class_set_parent_realize(dc, pnv_phb3_root_port_realize,
 &rpc->parent_realize);
+dc->user_creatable = false;
 
 k->vendor_id = PCI_VENDOR_ID_IBM;
 k->device_id = 0x03dc;
diff --git a/hw/pci-host/pnv_phb3_pbcq.c b/hw/pci-host/pnv_phb3_pbcq.c
index 6f0c05be68..f232228b0e 100644
--- a/hw/pci-host/pnv_phb3_pbcq.c
+++ b/hw/pci-host/pnv_phb3_pbcq.c
@@ -335,6 +335,7 @@ static void pnv_pbcq_class_init(ObjectClass *klass, void 
*data)
 xdc->dt_xscom = pnv_pbcq_dt_xscom;
 
 dc->realize = pnv_pbcq_realize;
+dc->user_creatable = false;
 }
 
 static const TypeInfo pnv_pbcq_type_info = {
diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index 61235d13a6..23cf093928 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -1290,7 +1290,7 @@ static void pnv_phb4_class_init(ObjectClass *klass, void 
*data)
 dc->realize = pnv_phb4_realize;
 device_class_set_props(dc, pnv_phb4_properties);
 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
-dc->user_creatable  = true;
+dc->user_creatable  = false;
 dc->reset   = pnv_phb4_reset;
 
 xfc->notify = pnv_phb4_xive_notify;
@@ -1368,6 +1368,7 @@ static void pnv_phb4_root_port_class_init(ObjectClass 
*klass, void *data)
 PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass);
 
 dc->desc = "IBM PHB4 PCIE Root Port";
+dc->user_creatable = false;
 
 device_class_set_parent_realize(dc, pnv_phb4_root_port_realize,
 &rpc->parent_realize);
diff --git a/hw/pci-host/pnv_phb4_pec.c b/hw/pci-host/pnv_phb4_pec.c
index fd92041d69..68e1db3eac 100644
--- a/hw/pci-host/pnv_phb4_pec.c
+++ b/hw/pci-host/pnv_phb4_pec.c
@@ -490,6 +490,7 @@ static void pnv_pec_class_init(ObjectClass *klass, void 
*data)
 
 dc->realize = pnv_pec_realize;
 device_class_set_props(dc, pnv_pec_properties);
+dc->user_creatable = false;
 
 pecc->xscom_nest_base = pnv_pec_xscom_nest_base;
 pecc->xscom_pci_base  = pnv_pec_xscom_pci_base;
@@ -568,6 +569,7 @@ static void pnv_pec_stk_class_init(ObjectClass *klass, void 
*data)
 
 device_class_set_props(dc, pnv_pec_stk_properties);
 dc->realize = pnv_pec_stk_realize;
+dc->user_creatable = false;
 
 /* TODO: reset regs ? */
 }
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index f7247222bc..234562040d 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -325,6 +325,7 @@ static void pnv_core_class_init(ObjectClass *oc, void *data)
 dc->realize = pnv_core_realize;
 dc->unrealize = pnv_core_unrealize;
 device_class_set_props(dc, pnv_core_properties);
+dc->user_creatable = false;
 }
 
 #define DEFINE_PNV_CORE_TYPE(family, cpu_model) \
@@ -423,6 +424,7 @@ static void pnv_quad_class_init(ObjectClass *oc, void *data)
 
 dc->realize = pnv_quad_realize;
 device_class_set_props(dc, pnv_quad_properties);
+dc->user_creatable = false;
 }
 
 static const TypeInfo pnv_quad_info = {
diff --git a/hw/ppc/pnv_homer.c b/hw/ppc/pnv_homer.c
index 93ae42f7e4..9a262629b7 100644
--- a/hw/ppc/pnv_homer.c
+++ b/hw/ppc/pnv_homer.c
@@ -360,6 +360,7 @@ static void pnv_homer_class_init(ObjectClass *klass, void 
*data)
 dc->realize = pnv_homer_realize;
 dc->desc = "PowerNV HOMER Memory";
 device_class_set_props(dc, pnv_homer_properties);
+dc->user_creatable = false;
 }
 
 static const TypeInfo pnv_homer_type_info = {
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index d1de98f04c..5989d723c5 100644
--- a/hw/ppc/pnv_

[PULL 07/34] target/ppc: Add privileged message send facilities

2020-01-30 Thread David Gibson
From: Cédric Le Goater 

The Processor Control facility for POWER8 processors and later
provides a mechanism for the hypervisor to send messages to other
threads in the system (msgsnd instruction) and cause hypervisor-level
exceptions. Privileged non-hypervisor programs can also send messages
(msgsndp instruction) but are restricted to the threads of the same
subprocessor and cause privileged-level exceptions.

The Directed Privileged Doorbell Exception State (DPDES) register
reflects the state of pending privileged doorbell exceptions and can
be used to modify that state. The register can be used to read and
modify the state of privileged doorbell exceptions for all threads of
a subprocessor and thus is a shared facility for that subprocessor.
The register can be read/written by the hypervisor and read by the
supervisor if enabled in the HFSCR, otherwise a hypervisor facility
unavailable exception is generated.

The privileged message send and clear instructions (msgsndp & msgclrp)
are used to generate and clear the presence of a directed privileged
doorbell exception, respectively. The msgsndp instruction can be used
to target any thread of the current subprocessor, msgclrp acts on the
thread issuing the instruction. These instructions are privileged, but
will generate a hypervisor facility unavailable exception if not
enabled in the HFSCR and executed in privileged non-hypervisor
state. The HV facility unavailable exception will be addressed in
other patch.

Add and implement this register and instructions by reading or
modifying the pending interrupt state of the cpu.

Note that TCG only supports one thread per core and so we only need to
worry about the cpu making the access.

Signed-off-by: Suraj Jitindar Singh 
Signed-off-by: Cédric Le Goater 
Message-Id: <20200120104935.24449-2-...@kaod.org>
Signed-off-by: David Gibson 
---
 target/ppc/excp_helper.c| 66 +
 target/ppc/helper.h |  4 ++
 target/ppc/misc_helper.c| 36 ++
 target/ppc/translate.c  | 26 +
 target/ppc/translate_init.inc.c | 20 --
 5 files changed, 132 insertions(+), 20 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 5752ed4a4d..1b07c3ed56 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -900,7 +900,11 @@ static void ppc_hw_interrupt(CPUPPCState *env)
 }
 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI);
+if (is_book3s_arch2x(env)) {
+powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_SDOOR);
+} else {
+powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI);
+}
 return;
 }
 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) {
@@ -1221,39 +1225,30 @@ void helper_msgsnd(target_ulong rb)
 }
 
 /* Server Processor Control */
-static int book3s_dbell2irq(target_ulong rb)
-{
-int msg = rb & DBELL_TYPE_MASK;
 
+static bool dbell_type_server(target_ulong rb)
+{
 /*
  * A Directed Hypervisor Doorbell message is sent only if the
  * message type is 5. All other types are reserved and the
  * instruction is a no-op
  */
-return msg == DBELL_TYPE_DBELL_SERVER ? PPC_INTERRUPT_HDOORBELL : -1;
+return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER;
 }
 
 void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb)
 {
-int irq = book3s_dbell2irq(rb);
-
-if (irq < 0) {
+if (!dbell_type_server(rb)) {
 return;
 }
 
-env->pending_interrupts &= ~(1 << irq);
+env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL);
 }
 
-void helper_book3s_msgsnd(target_ulong rb)
+static void book3s_msgsnd_common(int pir, int irq)
 {
-int irq = book3s_dbell2irq(rb);
-int pir = rb & DBELL_PROCIDTAG_MASK;
 CPUState *cs;
 
-if (irq < 0) {
-return;
-}
-
 qemu_mutex_lock_iothread();
 CPU_FOREACH(cs) {
 PowerPCCPU *cpu = POWERPC_CPU(cs);
@@ -1267,6 +1262,45 @@ void helper_book3s_msgsnd(target_ulong rb)
 }
 qemu_mutex_unlock_iothread();
 }
+
+void helper_book3s_msgsnd(target_ulong rb)
+{
+int pir = rb & DBELL_PROCIDTAG_MASK;
+
+if (!dbell_type_server(rb)) {
+return;
+}
+
+book3s_msgsnd_common(pir, PPC_INTERRUPT_HDOORBELL);
+}
+
+#if defined(TARGET_PPC64)
+void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb)
+{
+if (!dbell_type_server(rb)) {
+return;
+}
+
+env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
+}
+
+/*
+ * sends a message to other threads that are on the same
+ * multi-threaded processor
+ */
+void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb)
+{
+int pir = env->spr_cb[SPR_PIR].default_value;
+
+if (!dbell_type_server(rb)) {
+return;
+

[PULL 11/34] ppc/pnv: remove useless "core-pir" property alias.

2020-01-30 Thread David Gibson
From: Cédric Le Goater 

Commit 158e17a65e1a ("ppc/pnv: Link "chip" property to PnvCore::chip
pointer") introduced some cleanups of the PnvCore realize handler.
Let's continue by reworking a bit the interface of the PnvCore
handlers for the CPU threads. These changes make the "core-pir"
property alias unused. Remove it.

Signed-off-by: Cédric Le Goater 
Message-Id: <20200127144154.10170-3-...@kaod.org>
Signed-off-by: David Gibson 
---
 hw/ppc/pnv_core.c | 28 +---
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 8ca5fbd1a9..5fe3f21e12 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -40,11 +40,11 @@ static const char *pnv_core_cpu_typename(PnvCore *pc)
 return cpu_type;
 }
 
-static void pnv_core_cpu_reset(PowerPCCPU *cpu, PnvChip *chip)
+static void pnv_core_cpu_reset(PnvCore *pc, PowerPCCPU *cpu)
 {
 CPUState *cs = CPU(cpu);
 CPUPPCState *env = &cpu->env;
-PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
+PnvChipClass *pcc = PNV_CHIP_GET_CLASS(pc->chip);
 
 cpu_reset(cs);
 
@@ -56,7 +56,7 @@ static void pnv_core_cpu_reset(PowerPCCPU *cpu, PnvChip *chip)
 env->nip = 0x10;
 env->msr |= MSR_HVB; /* Hypervisor mode */
 
-pcc->intc_reset(chip, cpu);
+pcc->intc_reset(pc->chip, cpu);
 }
 
 /*
@@ -162,14 +162,14 @@ static const MemoryRegionOps pnv_core_power9_xscom_ops = {
 .endianness = DEVICE_BIG_ENDIAN,
 };
 
-static void pnv_core_cpu_realize(PowerPCCPU *cpu, PnvChip *chip, Error **errp)
+static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp)
 {
 CPUPPCState *env = &cpu->env;
 int core_pir;
 int thread_index = 0; /* TODO: TCG supports only one thread */
 ppc_spr_t *pir = &env->spr_cb[SPR_PIR];
 Error *local_err = NULL;
-PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
+PnvChipClass *pcc = PNV_CHIP_GET_CLASS(pc->chip);
 
 object_property_set_bool(OBJECT(cpu), true, "realized", &local_err);
 if (local_err) {
@@ -177,13 +177,13 @@ static void pnv_core_cpu_realize(PowerPCCPU *cpu, PnvChip 
*chip, Error **errp)
 return;
 }
 
-pcc->intc_create(chip, cpu, &local_err);
+pcc->intc_create(pc->chip, cpu, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
 }
 
-core_pir = object_property_get_uint(OBJECT(cpu), "core-pir", &error_abort);
+core_pir = object_property_get_uint(OBJECT(pc), "pir", &error_abort);
 
 /*
  * The PIR of a thread is the core PIR + the thread index. We will
@@ -203,7 +203,7 @@ static void pnv_core_reset(void *dev)
 int i;
 
 for (i = 0; i < cc->nr_threads; i++) {
-pnv_core_cpu_reset(pc->threads[i], pc->chip);
+pnv_core_cpu_reset(pc, pc->threads[i]);
 }
 }
 
@@ -231,8 +231,6 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
 
 snprintf(name, sizeof(name), "thread[%d]", i);
 object_property_add_child(OBJECT(pc), name, obj, &error_abort);
-object_property_add_alias(obj, "core-pir", OBJECT(pc),
-  "pir", &error_abort);
 
 cpu->machine_data = g_new0(PnvCPUState, 1);
 
@@ -240,7 +238,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
 }
 
 for (j = 0; j < cc->nr_threads; j++) {
-pnv_core_cpu_realize(pc->threads[j], pc->chip, &local_err);
+pnv_core_cpu_realize(pc, pc->threads[j], &local_err);
 if (local_err) {
 goto err;
 }
@@ -263,12 +261,12 @@ err:
 error_propagate(errp, local_err);
 }
 
-static void pnv_core_cpu_unrealize(PowerPCCPU *cpu, PnvChip *chip)
+static void pnv_core_cpu_unrealize(PnvCore *pc, PowerPCCPU *cpu)
 {
 PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
-PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
+PnvChipClass *pcc = PNV_CHIP_GET_CLASS(pc->chip);
 
-pcc->intc_destroy(chip, cpu);
+pcc->intc_destroy(pc->chip, cpu);
 cpu_remove_sync(CPU(cpu));
 cpu->machine_data = NULL;
 g_free(pnv_cpu);
@@ -284,7 +282,7 @@ static void pnv_core_unrealize(DeviceState *dev, Error 
**errp)
 qemu_unregister_reset(pnv_core_reset, pc);
 
 for (i = 0; i < cc->nr_threads; i++) {
-pnv_core_cpu_unrealize(pc->threads[i], pc->chip);
+pnv_core_cpu_unrealize(pc, pc->threads[i]);
 }
 g_free(pc->threads);
 }
-- 
2.24.1




[PULL 25/34] ppc: spapr: Introduce FWNMI capability

2020-01-30 Thread David Gibson
From: Aravinda Prasad 

Introduce fwnmi an spapr capability and add a helper function
which tries to enable it, which would be used by following patch
of the series. This patch by itself does not change the existing
behavior.

Signed-off-by: Aravinda Prasad 
[eliminate cap_ppc_fwnmi, add fwnmi cap to migration state
 and reprhase the commit message]
Signed-off-by: Ganesh Goudar 
Reviewed-by: David Gibson 
Message-Id: <20200130184423.20519-3-ganes...@linux.ibm.com>
Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c |  2 ++
 hw/ppc/spapr_caps.c| 18 ++
 include/hw/ppc/spapr.h |  5 -
 target/ppc/kvm.c   |  8 
 target/ppc/kvm_ppc.h   |  6 ++
 5 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index fe8266a1d1..aa739e943f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1992,6 +1992,7 @@ static const VMStateDescription vmstate_spapr = {
 &vmstate_spapr_dtb,
 &vmstate_spapr_cap_large_decr,
 &vmstate_spapr_cap_ccf_assist,
+&vmstate_spapr_cap_fwnmi,
 NULL
 }
 };
@@ -4398,6 +4399,7 @@ static void spapr_machine_class_init(ObjectClass *oc, 
void *data)
 smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
 smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
 smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_ON;
+smc->default_caps.caps[SPAPR_CAP_FWNMI_MCE] = SPAPR_CAP_OFF;
 spapr_caps_add_properties(smc, &error_abort);
 smc->irq = &spapr_irq_dual;
 smc->dr_phb_enabled = true;
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index 7f933a98ed..393ee6845e 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -509,6 +509,14 @@ static void cap_ccf_assist_apply(SpaprMachineState *spapr, 
uint8_t val,
 }
 }
 
+static void cap_fwnmi_mce_apply(SpaprMachineState *spapr, uint8_t val,
+Error **errp)
+{
+if (!val) {
+return; /* Disabled by default */
+}
+}
+
 SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
 [SPAPR_CAP_HTM] = {
 .name = "htm",
@@ -608,6 +616,15 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
 .type = "bool",
 .apply = cap_ccf_assist_apply,
 },
+[SPAPR_CAP_FWNMI_MCE] = {
+.name = "fwnmi-mce",
+.description = "Handle fwnmi machine check exceptions",
+.index = SPAPR_CAP_FWNMI_MCE,
+.get = spapr_cap_get_bool,
+.set = spapr_cap_set_bool,
+.type = "bool",
+.apply = cap_fwnmi_mce_apply,
+},
 };
 
 static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr,
@@ -747,6 +764,7 @@ SPAPR_CAP_MIG_STATE(hpt_maxpagesize, 
SPAPR_CAP_HPT_MAXPAGESIZE);
 SPAPR_CAP_MIG_STATE(nested_kvm_hv, SPAPR_CAP_NESTED_KVM_HV);
 SPAPR_CAP_MIG_STATE(large_decr, SPAPR_CAP_LARGE_DECREMENTER);
 SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
+SPAPR_CAP_MIG_STATE(fwnmi, SPAPR_CAP_FWNMI_MCE);
 
 void spapr_caps_init(SpaprMachineState *spapr)
 {
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 61f005c6f6..7bc5fc3a9e 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -79,8 +79,10 @@ typedef enum {
 #define SPAPR_CAP_LARGE_DECREMENTER 0x08
 /* Count Cache Flush Assist HW Instruction */
 #define SPAPR_CAP_CCF_ASSIST0x09
+/* FWNMI machine check handling */
+#define SPAPR_CAP_FWNMI_MCE 0x0A
 /* Num Caps */
-#define SPAPR_CAP_NUM   (SPAPR_CAP_CCF_ASSIST + 1)
+#define SPAPR_CAP_NUM   (SPAPR_CAP_FWNMI_MCE + 1)
 
 /*
  * Capability Values
@@ -869,6 +871,7 @@ extern const VMStateDescription 
vmstate_spapr_cap_hpt_maxpagesize;
 extern const VMStateDescription vmstate_spapr_cap_nested_kvm_hv;
 extern const VMStateDescription vmstate_spapr_cap_large_decr;
 extern const VMStateDescription vmstate_spapr_cap_ccf_assist;
+extern const VMStateDescription vmstate_spapr_cap_fwnmi;
 
 static inline uint8_t spapr_get_cap(SpaprMachineState *spapr, int cap)
 {
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index c05dde5985..4438d0c743 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -2057,6 +2057,14 @@ void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int 
mpic_proxy)
 }
 }
 
+int kvmppc_set_fwnmi(void)
+{
+PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
+CPUState *cs = CPU(cpu);
+
+return kvm_vcpu_enable_cap(cs, KVM_CAP_PPC_FWNMI, 0);
+}
+
 int kvmppc_smt_threads(void)
 {
 return cap_ppc_smt ? cap_ppc_smt : 1;
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index b713097bfb..2c60dedd0d 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -27,6 +27,7 @@ void kvmppc_enable_h_page_init(void);
 void kvmppc_set_papr(PowerPCCPU *cpu);
 int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr);
 void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy);
+int kvmppc_set_fwnmi(void);
 int kvmppc_smt_threads(void);
 void kvmppc_error_append_smt_possible_hint(Er

[PULL 16/34] tpm_spapr: Support suspend and resume

2020-01-30 Thread David Gibson
From: Stefan Berger 

Extend the tpm_spapr frontend with VM suspend and resume support.

Signed-off-by: Stefan Berger 
Message-Id: <20200121152935.649898-5-stef...@linux.ibm.com>
Reviewed-by: Marc-André Lureau 
Signed-off-by: David Gibson 
---
 hw/tpm/tpm_spapr.c  | 52 -
 hw/tpm/trace-events |  2 ++
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/hw/tpm/tpm_spapr.c b/hw/tpm/tpm_spapr.c
index 2ac4cb061c..ce65eb2e45 100644
--- a/hw/tpm/tpm_spapr.c
+++ b/hw/tpm/tpm_spapr.c
@@ -76,6 +76,8 @@ typedef struct {
 
 unsigned char *buffer;
 
+uint32_t numbytes; /* number of bytes to deliver on resume */
+
 TPMBackendCmd cmd;
 
 TPMBackend *be_driver;
@@ -240,6 +242,14 @@ static void tpm_spapr_request_completed(TPMIf *ti, int ret)
 
 /* a max. of be_buffer_size bytes can be transported */
 len = MIN(tpm_cmd_get_size(s->buffer), s->be_buffer_size);
+
+if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
+trace_tpm_spapr_caught_response(len);
+/* defer delivery of response until .post_load */
+s->numbytes = len;
+return;
+}
+
 rc = spapr_vio_dma_write(&s->vdev, be32_to_cpu(crq->data),
  s->buffer, len);
 
@@ -288,6 +298,7 @@ static void tpm_spapr_reset(SpaprVioDevice *dev)
 SpaprTpmState *s = VIO_SPAPR_VTPM(dev);
 
 s->state = SPAPR_VTPM_STATE_NONE;
+s->numbytes = 0;
 
 s->be_tpm_version = tpm_backend_get_tpm_version(s->be_driver);
 
@@ -309,9 +320,48 @@ static enum TPMVersion tpm_spapr_get_version(TPMIf *ti)
 return tpm_backend_get_tpm_version(s->be_driver);
 }
 
+/* persistent state handling */
+
+static int tpm_spapr_pre_save(void *opaque)
+{
+SpaprTpmState *s = opaque;
+
+tpm_backend_finish_sync(s->be_driver);
+/*
+ * we cannot deliver the results to the VM since DMA would touch VM memory
+ */
+
+return 0;
+}
+
+static int tpm_spapr_post_load(void *opaque, int version_id)
+{
+SpaprTpmState *s = opaque;
+
+if (s->numbytes) {
+trace_tpm_spapr_post_load();
+/* deliver the results to the VM via DMA */
+tpm_spapr_request_completed(TPM_IF(s), 0);
+s->numbytes = 0;
+}
+
+return 0;
+}
+
 static const VMStateDescription vmstate_spapr_vtpm = {
 .name = "tpm-spapr",
-.unmigratable = 1,
+.pre_save = tpm_spapr_pre_save,
+.post_load = tpm_spapr_post_load,
+.fields = (VMStateField[]) {
+VMSTATE_SPAPR_VIO(vdev, SpaprTpmState),
+
+VMSTATE_UINT8(state, SpaprTpmState),
+VMSTATE_UINT32(numbytes, SpaprTpmState),
+VMSTATE_VBUFFER_UINT32(buffer, SpaprTpmState, 0, NULL, numbytes),
+/* remember DMA address */
+VMSTATE_UINT32(crq.data, SpaprTpmState),
+VMSTATE_END_OF_LIST(),
+}
 };
 
 static Property tpm_spapr_properties[] = {
diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
index 9143a8eaa3..439e514787 100644
--- a/hw/tpm/trace-events
+++ b/hw/tpm/trace-events
@@ -67,3 +67,5 @@ tpm_spapr_do_crq_get_version(uint32_t version) "response: 
version %u"
 tpm_spapr_do_crq_prepare_to_suspend(void) "response: preparing to suspend"
 tpm_spapr_do_crq_unknown_msg_type(uint8_t type) "Unknown message type 0x%02x"
 tpm_spapr_do_crq_unknown_crq(uint8_t raw1, uint8_t raw2) "unknown CRQ 0x%02x 
0x%02x ..."
+tpm_spapr_post_load(void) "Delivering TPM response after resume"
+tpm_spapr_caught_response(uint32_t v) "Caught response to deliver after 
resume: %u bytes"
-- 
2.24.1




[PULL 06/34] spapr: Fail CAS if option vector table cannot be parsed

2020-01-30 Thread David Gibson
From: Greg Kurz 

Most of the option vector helpers have assertions to check their
arguments aren't null. The guest can provide an arbitrary address
for the CAS structure that would result in such null arguments.
Fail CAS with H_PARAMETER and print a warning instead of aborting
QEMU.

Signed-off-by: Greg Kurz 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <157925255250.397143.10855183619366882459.st...@bahia.lan>
Signed-off-by: David Gibson 
---
 hw/ppc/spapr_hcall.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index f1799b1b70..ffb14641f9 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1703,7 +1703,15 @@ static target_ulong 
h_client_architecture_support(PowerPCCPU *cpu,
 ov_table = addr;
 
 ov1_guest = spapr_ovec_parse_vector(ov_table, 1);
+if (!ov1_guest) {
+warn_report("guest didn't provide option vector 1");
+return H_PARAMETER;
+}
 ov5_guest = spapr_ovec_parse_vector(ov_table, 5);
+if (!ov5_guest) {
+warn_report("guest didn't provide option vector 5");
+return H_PARAMETER;
+}
 if (spapr_ovec_test(ov5_guest, OV5_MMU_BOTH)) {
 error_report("guest requested hash and radix MMU, which is invalid.");
 exit(EXIT_FAILURE);
-- 
2.24.1




[PULL 22/34] spapr: Enable DD2.3 accelerated count cache flush in pseries-5.0 machine

2020-01-30 Thread David Gibson
For POWER9 DD2.2 cpus, the best current Spectre v2 indirect branch
mitigation is "count cache disabled", which is configured with:
-machine cap-ibs=fixed-ccd
However, this option isn't available on DD2.3 CPUs with KVM, because they
don't have the count cache disabled.

For POWER9 DD2.3 cpus, it is "count cache flush with assist", configured
with:
-machine cap-ibs=workaround,cap-ccf-assist=on
However this option isn't available on DD2.2 CPUs with KVM, because they
don't have the special CCF assist instruction this relies on.

On current machine types, we default to "count cache flush w/o assist",
that is:
-machine cap-ibs=workaround,cap-ccf-assist=off
This runs, with mitigation on both DD2.2 and DD2.3 host cpus, but has a
fairly significant performance impact.

It turns out we can do better.  The special instruction that CCF assist
uses to trigger a count cache flush is a no-op on earlier CPUs, rather than
trapping or causing other badness.  It doesn't, of itself, implement the
mitigation, but *if* we have count-cache-disabled, then the count cache
flush is unnecessary, and so using the count cache flush mitigation is
harmless.

Therefore for the new pseries-5.0 machine type, enable cap-ccf-assist by
default.  Along with that, suppress throwing an error if cap-ccf-assist
is selected but KVM doesn't support it, as long as KVM *is* giving us
count-cache-disabled.  To allow TCG to work out of the box, even though it
doesn't implement the ccf flush assist, downgrade the error in that case to
a warning.  This matches several Spectre mitigations where we allow TCG
to operate for debugging, since we don't really make guarantees about TCG
security properties anyway.

While we're there, make the TCG warning for this case match that for other
mitigations.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c  |  5 -
 hw/ppc/spapr_caps.c | 21 +
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a0076e5fbd..fe8266a1d1 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4397,7 +4397,7 @@ static void spapr_machine_class_init(ObjectClass *oc, 
void *data)
 smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 16; /* 64kiB */
 smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
 smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
-smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
+smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_ON;
 spapr_caps_add_properties(smc, &error_abort);
 smc->irq = &spapr_irq_dual;
 smc->dr_phb_enabled = true;
@@ -4465,8 +4465,11 @@ DEFINE_SPAPR_MACHINE(5_0, "5.0", true);
  */
 static void spapr_machine_4_2_class_options(MachineClass *mc)
 {
+SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
 spapr_machine_5_0_class_options(mc);
 compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
+smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
 }
 
 DEFINE_SPAPR_MACHINE(4_2, "4.2", false);
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index 481dfd2a27..7f933a98ed 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -485,11 +485,24 @@ static void cap_ccf_assist_apply(SpaprMachineState 
*spapr, uint8_t val,
 uint8_t kvm_val = kvmppc_get_cap_count_cache_flush_assist();
 
 if (tcg_enabled() && val) {
-/* TODO - for now only allow broken for TCG */
-error_setg(errp,
-"Requested count cache flush assist capability level not supported by tcg,"
-   " try appending -machine cap-ccf-assist=off");
+/* TCG doesn't implement anything here, but allow with a warning */
+warn_report("TCG doesn't support requested feature, 
cap-ccf-assist=on");
 } else if (kvm_enabled() && (val > kvm_val)) {
+uint8_t kvm_ibs = kvmppc_get_cap_safe_indirect_branch();
+
+if (kvm_ibs == SPAPR_CAP_FIXED_CCD) {
+/*
+ * If we don't have CCF assist on the host, the assist
+ * instruction is a harmless no-op.  It won't correctly
+ * implement the cache count flush *but* if we have
+ * count-cache-disabled in the host, that flush is
+ * unnnecessary.  So, specifically allow this case.  This
+ * allows us to have better performance on POWER9 DD2.3,
+ * while still working on POWER9 DD2.2 and POWER8 host
+ * cpus.
+ */
+return;
+}
 error_setg(errp,
 "Requested count cache flush assist capability level not supported by kvm,"
" try appending -machine cap-ccf-assist=off");
-- 
2.24.1




[PULL 08/34] target/ppc: add support for Hypervisor Facility Unavailable Exception

2020-01-30 Thread David Gibson
From: Cédric Le Goater 

The privileged message send and clear instructions (msgsndp & msgclrp)
are privileged, but will generate a hypervisor facility unavailable
exception if not enabled in the HFSCR and executed in privileged
non-hypervisor state.

Add checks when accessing the DPDES register and when using the
msgsndp and msgclrp isntructions.

Signed-off-by: Suraj Jitindar Singh 
Signed-off-by: Cédric Le Goater 
Message-Id: <20200120104935.24449-3-...@kaod.org>
Signed-off-by: David Gibson 
---
 target/ppc/cpu.h |  6 ++
 target/ppc/excp_helper.c | 13 +
 target/ppc/misc_helper.c | 27 +++
 3 files changed, 46 insertions(+)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 8ebeaba649..96aeea1934 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -397,6 +397,10 @@ typedef struct ppc_v3_pate_t {
 #define PSSCR_ESL PPC_BIT(42) /* Enable State Loss */
 #define PSSCR_EC  PPC_BIT(43) /* Exit Criterion */
 
+/* HFSCR bits */
+#define HFSCR_MSGP PPC_BIT(53) /* Privileged Message Send Facilities */
+#define HFSCR_IC_MSGP  0xA
+
 #define msr_sf   ((env->msr >> MSR_SF)   & 1)
 #define msr_isf  ((env->msr >> MSR_ISF)  & 1)
 #define msr_shv  ((env->msr >> MSR_SHV)  & 1)
@@ -1329,6 +1333,8 @@ void cpu_ppc_set_vhyp(PowerPCCPU *cpu, 
PPCVirtualHypervisor *vhyp);
 #endif
 
 void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask);
+void helper_hfscr_facility_check(CPUPPCState *env, uint32_t bit,
+ const char *caller, uint32_t cause);
 
 static inline uint64_t ppc_dump_gpr(CPUPPCState *env, int gprn)
 {
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 1b07c3ed56..027f54c0ed 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -471,6 +471,15 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
 case POWERPC_EXCP_FU: /* Facility unavailable exception  */
 #ifdef TARGET_PPC64
 env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56);
+#endif
+break;
+case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception 
*/
+#ifdef TARGET_PPC64
+env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS);
+srr0 = SPR_HSRR0;
+srr1 = SPR_HSRR1;
+new_msr |= (target_ulong)MSR_HVB;
+new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
 #endif
 break;
 case POWERPC_EXCP_PIT:   /* Programmable interval timer interrupt*/
@@ -1277,6 +1286,8 @@ void helper_book3s_msgsnd(target_ulong rb)
 #if defined(TARGET_PPC64)
 void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb)
 {
+helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP);
+
 if (!dbell_type_server(rb)) {
 return;
 }
@@ -1292,6 +1303,8 @@ void helper_book3s_msgsndp(CPUPPCState *env, target_ulong 
rb)
 {
 int pir = env->spr_cb[SPR_PIR].default_value;
 
+helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP);
+
 if (!dbell_type_server(rb)) {
 return;
 }
diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c
index 0c5919ff08..55b68d1246 100644
--- a/target/ppc/misc_helper.c
+++ b/target/ppc/misc_helper.c
@@ -41,6 +41,18 @@ void helper_store_dump_spr(CPUPPCState *env, uint32_t sprn)
 }
 
 #ifdef TARGET_PPC64
+static void raise_hv_fu_exception(CPUPPCState *env, uint32_t bit,
+  const char *caller, uint32_t cause,
+  uintptr_t raddr)
+{
+qemu_log_mask(CPU_LOG_INT, "HV Facility %d is unavailable (%s)\n",
+  bit, caller);
+
+env->spr[SPR_HFSCR] &= ~((target_ulong)FSCR_IC_MASK << FSCR_IC_POS);
+
+raise_exception_err_ra(env, POWERPC_EXCP_HV_FU, cause, raddr);
+}
+
 static void raise_fu_exception(CPUPPCState *env, uint32_t bit,
uint32_t sprn, uint32_t cause,
uintptr_t raddr)
@@ -55,6 +67,17 @@ static void raise_fu_exception(CPUPPCState *env, uint32_t 
bit,
 }
 #endif
 
+void helper_hfscr_facility_check(CPUPPCState *env, uint32_t bit,
+ const char *caller, uint32_t cause)
+{
+#ifdef TARGET_PPC64
+if ((env->msr_mask & MSR_HVB) && !msr_hv &&
+ !(env->spr[SPR_HFSCR] & (1UL << bit))) {
+raise_hv_fu_exception(env, bit, caller, cause, GETPC());
+}
+#endif
+}
+
 void helper_fscr_facility_check(CPUPPCState *env, uint32_t bit,
 uint32_t sprn, uint32_t cause)
 {
@@ -114,6 +137,8 @@ target_ulong helper_load_dpdes(CPUPPCState *env)
 {
 target_ulong dpdes = 0;
 
+helper_hfscr_facility_check(env, HFSCR_MSGP, "load DPDES", HFSCR_IC_MSGP);
+
 /* TODO: TCG supports only one thread */
 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
 dpdes = 1;
@@ -127,6 +152,8 @@ void helper_store_dpdes(CPUPPCState *env, target_ulong val

[PULL 10/34] ppc/pnv: Add support for HRMOR on Radix host

2020-01-30 Thread David Gibson
From: Cédric Le Goater 

When in HV mode, if EA[0] is 0, the Hypervisor Offset Real Mode
Register controls the access.

Signed-off-by: Cédric Le Goater 
Message-Id: <20200127144154.10170-2-...@kaod.org>
Signed-off-by: David Gibson 
---
 target/ppc/mmu-radix64.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 066e324464..224e646c50 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -235,6 +235,12 @@ int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr 
eaddr, int rwx,
 /* In real mode top 4 effective addr bits (mostly) ignored */
 raddr = eaddr & 0x0FFFULL;
 
+/* In HV mode, add HRMOR if top EA bit is clear */
+if (msr_hv || !env->has_hv_mode) {
+if (!(eaddr >> 63)) {
+raddr |= env->spr[SPR_HRMOR];
+   }
+}
 tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
  PAGE_READ | PAGE_WRITE | PAGE_EXEC, mmu_idx,
  TARGET_PAGE_SIZE);
-- 
2.24.1




[PULL 09/34] spapr: Don't allow multiple active vCPUs at CAS

2020-01-30 Thread David Gibson
From: Greg Kurz 

According to the description of "ibm,client-architecture-support" that
can found in LoPAPR "B.6.2.3 Root Node Methods":

If multiple partition processors or threads are active at the time of
the ibm,client-architecture-support method call, or an error is detected
in the format of the ibm,architecture.vec structure, the err? boolean
shall be TRUE; else FALSE.

We certainly don't want to temper with the platform or with the PCR of
the other vCPUs if they happen to be active. Ensure we have only one
active vCPU and fail CAS otherwise. This is just for conformance and
robustness, it doesn't fix any known bugs.

Signed-off-by: Greg Kurz 
Message-Id: <157969867170.571404.12117797348882189656.st...@bahia.lan>
Signed-off-by: David Gibson 
---
 hw/ppc/spapr_hcall.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index ffb14641f9..b8bb66b5c0 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1676,6 +1676,18 @@ static target_ulong 
h_client_architecture_support(PowerPCCPU *cpu,
 Error *local_err = NULL;
 bool raw_mode_supported = false;
 bool guest_xive;
+CPUState *cs;
+
+/* CAS is supposed to be called early when only the boot vCPU is active. */
+CPU_FOREACH(cs) {
+if (cs == CPU(cpu)) {
+continue;
+}
+if (!cs->halted) {
+warn_report("guest has multiple active vCPUs at CAS, which is not 
allowed");
+return H_MULTI_THREADS_ACTIVE;
+}
+}
 
 cas_pvr = cas_check_pvr(spapr, cpu, &addr, &raw_mode_supported, 
&local_err);
 if (local_err) {
-- 
2.24.1




[PULL 00/34] ppc-for-5.0 queue 20200131

2020-01-30 Thread David Gibson
The following changes since commit 928173659d6e5dc368284f73f90ea1d129e1f57d:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20200130' 
into staging (2020-01-30 16:19:04 +)

are available in the Git repository at:

  git://github.com/dgibson/qemu.git tags/ppc-for-5.0-20200131

for you to fetch changes up to 532fe321cf06d39d864de3642b4e1b18cc83c4de:

  target/ppc: Use probe_write for DCBZ (2020-01-31 14:54:16 +1100)


ppc patch queue 2020-01-31

Here's the next batch of patches for ppc and associated machine types.
Highlights includes:
 * Remove the deprecated "prep" machine type and its OpenHackware
   firmware
 * Add TCG emulation of the msgsndp etc. supervisor privileged
   doorbell instructions
 * Allow "pnv" machine type to run Hostboot style firmwares
 * Add a virtual TPM device for spapr machines
 * Implement devices for POWER8 PHB3 and POWER9 PHB4 host bridges for
   the pnv machine type
 * Use faster Spectre mitigation by default for POWER9 DD2.3 machines
 * Introduce Firmware Assisted NMI dump facility for spapr machines
 * Fix a performance regression with load/store multiple instructions
   in TCG

as well as some other assorted cleanups and fixes.


Aravinda Prasad (7):
  Wrapper function to wait on condition for the main loop mutex
  ppc: spapr: Introduce FWNMI capability
  target/ppc: Handle NMI guest exit
  target/ppc: Build rtas error log upon an MCE
  ppc: spapr: Handle "ibm,nmi-register" and "ibm,nmi-interlock" RTAS calls
  migration: Include migration support for machine check handling
  ppc: spapr: Activate the FWNMI functionality

BALATON Zoltan (1):
  target/ppc/cpu.h: Put macro parameter in parentheses

Benjamin Herrenschmidt (1):
  ppc/pnv: Add models for POWER9 PHB4 PCIe Host bridge

Cédric Le Goater (9):
  ppc/pnv: use QEMU unit definition MiB
  ppc/pnv: improve error logging when a PNOR update fails
  target/ppc: Add privileged message send facilities
  target/ppc: add support for Hypervisor Facility Unavailable Exception
  ppc/pnv: Add support for HRMOR on Radix host
  ppc/pnv: remove useless "core-pir" property alias.
  ppc/pnv: Add support for "hostboot" mode
  ppc/pnv: Add models for POWER8 PHB3 PCIe Host bridge
  ppc/pnv: change the PowerNV machine devices to be non user creatable

David Gibson (1):
  spapr: Enable DD2.3 accelerated count cache flush in pseries-5.0 machine

Fabiano Rosas (1):
  target/ppc: Clarify the meaning of return values in kvm_handle_debug

Greg Kurz (2):
  spapr: Fail CAS if option vector table cannot be parsed
  spapr: Don't allow multiple active vCPUs at CAS

Igor Mammedov (1):
  ppc:virtex_ml507: remove unused arguments

Marc-André Lureau (1):
  docs/specs/tpm: reST-ify TPM documentation

Richard Henderson (4):
  target/ppc: Use probe_access for LSW, STSW
  target/ppc: Use probe_access for LMW, STMW
  target/ppc: Remove redundant mask in DCBZ
  target/ppc: Use probe_write for DCBZ

Stefan Berger (5):
  tpm: Move tpm_tis_show_buffer to tpm_util.c
  spapr: Implement get_dt_compatible() callback
  tpm_spapr: Support TPM for ppc64 using CRQ based interface
  tpm_spapr: Support suspend and resume
  hw/ppc/Kconfig: Enable TPM_SPAPR as part of PSERIES config

Thomas Huth (1):
  hw/ppc/prep: Remove the deprecated "prep" machine and the OpenHackware 
BIOS

 .gitmodules |3 -
 MAINTAINERS |1 -
 Makefile|2 +-
 cpus.c  |5 +
 docs/interop/firmware.json  |3 +-
 docs/specs/index.rst|1 +
 docs/specs/tpm.rst  |  503 
 docs/specs/tpm.txt  |  427 ---
 hw/intc/xics.c  |   14 +-
 hw/pci-host/Makefile.objs   |2 +
 hw/pci-host/pnv_phb3.c  | 1197 +
 hw/pci-host/pnv_phb3_msi.c  |  349 +
 hw/pci-host/pnv_phb3_pbcq.c |  358 +
 hw/pci-host/pnv_phb4.c  | 1439 +++
 hw/pci-host/pnv_phb4_pec.c  |  595 +++
 hw/ppc/Kconfig  |2 +
 hw/ppc/pnv.c|  204 -
 hw/ppc/pnv_core.c   |   33 +-
 hw/ppc/pnv_homer.c  |1 +
 hw/ppc/pnv_lpc.c|6 +-
 hw/ppc/pnv_occ.c|1 +
 hw/ppc/pnv_pnor.c   |6 +-
 hw/ppc/ppc.c|   18 -
 hw/ppc/prep.c   |  384 +-
 hw/ppc/spapr.c  |   63 +-
 hw/ppc/spapr_caps.c |   49 +-
 hw/ppc/spapr_e

[PULL 02/34] ppc/pnv: improve error logging when a PNOR update fails

2020-01-30 Thread David Gibson
From: Cédric Le Goater 

Print out the offset at which the error occured.

Signed-off-by: Cédric Le Goater 
Message-Id: <20200108090348.21224-3-...@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: David Gibson 
---
 hw/ppc/pnv_pnor.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/pnv_pnor.c b/hw/ppc/pnv_pnor.c
index 060c6e6a31..c365ee58b8 100644
--- a/hw/ppc/pnv_pnor.c
+++ b/hw/ppc/pnv_pnor.c
@@ -47,7 +47,8 @@ static void pnv_pnor_update(PnvPnor *s, int offset, int size)
 ret = blk_pwrite(s->blk, offset, s->storage + offset,
  offset_end - offset, 0);
 if (ret < 0) {
-error_report("Could not update PNOR: %s", strerror(-ret));
+error_report("Could not update PNOR offset=0x%" PRIx32" : %s", offset,
+ strerror(-ret));
 }
 }
 
-- 
2.24.1




[PULL 05/34] target/ppc: Clarify the meaning of return values in kvm_handle_debug

2020-01-30 Thread David Gibson
From: Fabiano Rosas 

The kvm_handle_debug function can return 0 to go back into the guest
or return 1 to notify the gdbstub thread and pass control to GDB.

Signed-off-by: Fabiano Rosas 
Message-Id: <20200110151344.278471-2-faro...@linux.ibm.com>
Tested-by: Leonardo Bras 
Signed-off-by: David Gibson 
---
 target/ppc/kvm.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 06fd0cc162..c05dde5985 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -53,6 +53,9 @@
 
 #define PROC_DEVTREE_CPU  "/proc/device-tree/cpus/"
 
+#define DEBUG_RETURN_GUEST 0
+#define DEBUG_RETURN_GDB   1
+
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
 KVM_CAP_LAST_INFO
 };
@@ -1564,7 +1567,7 @@ void kvm_arch_update_guest_debug(CPUState *cs, struct 
kvm_guest_debug *dbg)
 static int kvm_handle_hw_breakpoint(CPUState *cs,
 struct kvm_debug_exit_arch *arch_info)
 {
-int handle = 0;
+int handle = DEBUG_RETURN_GUEST;
 int n;
 int flag = 0;
 
@@ -1572,13 +1575,13 @@ static int kvm_handle_hw_breakpoint(CPUState *cs,
 if (arch_info->status & KVMPPC_DEBUG_BREAKPOINT) {
 n = find_hw_breakpoint(arch_info->address, GDB_BREAKPOINT_HW);
 if (n >= 0) {
-handle = 1;
+handle = DEBUG_RETURN_GDB;
 }
 } else if (arch_info->status & (KVMPPC_DEBUG_WATCH_READ |
 KVMPPC_DEBUG_WATCH_WRITE)) {
 n = find_hw_watchpoint(arch_info->address,  &flag);
 if (n >= 0) {
-handle = 1;
+handle = DEBUG_RETURN_GDB;
 cs->watchpoint_hit = &hw_watchpoint;
 hw_watchpoint.vaddr = hw_debug_points[n].addr;
 hw_watchpoint.flags = flag;
@@ -1590,12 +1593,12 @@ static int kvm_handle_hw_breakpoint(CPUState *cs,
 
 static int kvm_handle_singlestep(void)
 {
-return 1;
+return DEBUG_RETURN_GDB;
 }
 
 static int kvm_handle_sw_breakpoint(void)
 {
-return 1;
+return DEBUG_RETURN_GDB;
 }
 
 static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run)
@@ -1647,7 +1650,7 @@ static int kvm_handle_debug(PowerPCCPU *cpu, struct 
kvm_run *run)
 env->error_code = POWERPC_EXCP_INVAL;
 ppc_cpu_do_interrupt(cs);
 
-return 0;
+return DEBUG_RETURN_GUEST;
 }
 
 int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
-- 
2.24.1




[PULL 03/34] ppc:virtex_ml507: remove unused arguments

2020-01-30 Thread David Gibson
From: Igor Mammedov 

Signed-off-by: Igor Mammedov 
Message-Id: <1579100861-73692-71-git-send-email-imamm...@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: David Gibson 
---
 hw/ppc/virtex_ml507.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 7526947ea7..91dd00ee91 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -89,10 +89,7 @@ static void mmubooke_create_initial_mapping(CPUPPCState *env,
 tlb->PID = 0;
 }
 
-static PowerPCCPU *ppc440_init_xilinx(ram_addr_t *ram_size,
-  int do_init,
-  const char *cpu_type,
-  uint32_t sysclk)
+static PowerPCCPU *ppc440_init_xilinx(const char *cpu_type, uint32_t sysclk)
 {
 PowerPCCPU *cpu;
 CPUPPCState *env;
@@ -213,7 +210,7 @@ static void virtex_init(MachineState *machine)
 int i;
 
 /* init CPUs */
-cpu = ppc440_init_xilinx(&ram_size, 1, machine->cpu_type, 4);
+cpu = ppc440_init_xilinx(machine->cpu_type, 4);
 env = &cpu->env;
 
 if (env->mmu_model != POWERPC_MMU_BOOKE) {
-- 
2.24.1




[PULL 01/34] ppc/pnv: use QEMU unit definition MiB

2020-01-30 Thread David Gibson
From: Cédric Le Goater 

Signed-off-by: Cédric Le Goater 
Message-Id: <20200108090348.21224-2-...@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: David Gibson 
---
 hw/ppc/pnv_pnor.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/pnv_pnor.c b/hw/ppc/pnv_pnor.c
index f761d8dc26..060c6e6a31 100644
--- a/hw/ppc/pnv_pnor.c
+++ b/hw/ppc/pnv_pnor.c
@@ -11,6 +11,7 @@
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "qemu/log.h"
+#include "qemu/units.h"
 #include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/loader.h"
@@ -111,7 +112,7 @@ static void pnv_pnor_realize(DeviceState *dev, Error **errp)
 }
 
 static Property pnv_pnor_properties[] = {
-DEFINE_PROP_INT64("size", PnvPnor, size, 128 << 20),
+DEFINE_PROP_INT64("size", PnvPnor, size, 128 * MiB),
 DEFINE_PROP_DRIVE("drive", PnvPnor, blk),
 DEFINE_PROP_END_OF_LIST(),
 };
-- 
2.24.1




Re: [RFC v3 02/25] hw/iommu: introduce DualStageIOMMUObject

2020-01-30 Thread David Gibson
On Wed, Jan 29, 2020 at 04:16:33AM -0800, Liu, Yi L wrote:
> From: Liu Yi L 
> 
> Currently, many platform vendors provide the capability of dual stage
> DMA address translation in hardware. For example, nested translation
> on Intel VT-d scalable mode, nested stage translation on ARM SMMUv3,
> and etc. In dual stage DMA address translation, there are two stages
> address translation, stage-1 (a.k.a first-level) and stage-2 (a.k.a
> second-level) translation structures. Stage-1 translation results are
> also subjected to stage-2 translation structures. Take vSVA (Virtual
> Shared Virtual Addressing) as an example, guest IOMMU driver owns
> stage-1 translation structures (covers GVA->GPA translation), and host
> IOMMU driver owns stage-2 translation structures (covers GPA->HPA
> translation). VMM is responsible to bind stage-1 translation structures
> to host, thus hardware could achieve GVA->GPA and then GPA->HPA
> translation. For more background on SVA, refer the below links.
>  - https://www.youtube.com/watch?v=Kq_nfGK5MwQ
>  - https://events19.lfasiallc.com/wp-content/uploads/2017/11/\
> Shared-Virtual-Memory-in-KVM_Yi-Liu.pdf
> 
> As above, dual stage DMA translation offers two stage address mappings,
> which could have better DMA address translation support for passthru
> devices. This is also what vIOMMU developers are doing so far. Efforts
> includes vSVA enabling from Yi Liu and SMMUv3 Nested Stage Setup from
> Eric Auger.
> https://www.spinics.net/lists/kvm/msg198556.html
> https://lists.gnu.org/archive/html/qemu-devel/2019-07/msg02842.html
> 
> Both efforts are aiming to expose a vIOMMU with dual stage hardware
> backed. As so, QEMU needs to have an explicit object to stand for
> the dual stage capability from hardware. Such object offers abstract
> for the dual stage DMA translation related operations, like:
> 
>  1) PASID allocation (allow host to intercept in PASID allocation)
>  2) bind stage-1 translation structures to host
>  3) propagate stage-1 cache invalidation to host
>  4) DMA address translation fault (I/O page fault) servicing etc.
> 
> This patch introduces DualStageIOMMUObject to stand for the hardware
> dual stage DMA translation capability. PASID allocation/free are the
> first operation included in it, in future, there will be more operations
> like bind_stage1_pgtbl and invalidate_stage1_cache and etc.
> 
> Cc: Kevin Tian 
> Cc: Jacob Pan 
> Cc: Peter Xu 
> Cc: Eric Auger 
> Cc: Yi Sun 
> Cc: David Gibson 
> Signed-off-by: Liu Yi L 

Several overall queries about this:

1) Since it's explicitly handling PASIDs, this seems a lot more
   specific to SVM than the name suggests.  I'd suggest a rename.

2) Why are you hand rolling structures of pointers, rather than making
   this a QOM class or interface and putting those things into methods?

3) It's not really clear to me if this is for the case where both
   stages of translation are visible to the guest, or only one of
   them.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [RFC v3 03/25] hw/iommu: introduce IOMMUContext

2020-01-30 Thread David Gibson
On Wed, Jan 29, 2020 at 04:16:34AM -0800, Liu, Yi L wrote:
> From: Peter Xu 
> 
> Currently, many platform vendors provide the capability of dual stage
> DMA address translation in hardware. For example, nested translation
> on Intel VT-d scalable mode, nested stage translation on ARM SMMUv3,
> and etc. Also there are efforts to make QEMU vIOMMU be backed by dual
> stage DMA address translation capability provided by hardware to have
> better address translation support for passthru devices.
> 
> As so, making vIOMMU be backed by dual stage translation capability
> requires QEMU vIOMMU to have a way to get aware of such hardware
> capability and also require a way to receive DMA address translation
> faults (e.g. I/O page request) from host as guest owns stage-1 translation
> structures in dual stage DAM address translation.
> 
> This patch adds IOMMUContext as an abstract of vIOMMU related operations.
> Like provide a way for passthru modules (e.g. VFIO) to register
> DualStageIOMMUObject instances. And in future, it is expected to offer
> support for receiving host DMA translation faults happened on stage-1
> translation.
> 
> For more backgrounds, may refer to the discussion below, while there
> is also difference between the current implementation and original
> proposal. This patch introduces the IOMMUContext as an abstract layer
> for passthru module (e.g. VFIO) calls into vIOMMU. The first introduced
> interface is to make QEMU vIOMMU be aware of dual stage translation
> capability.
> 
> https://lists.gnu.org/archive/html/qemu-devel/2019-07/msg05022.html

Again, is there a reason for not making this a QOM class or interface?


I'm not very clear on the relationship betwen an IOMMUContext and a
DualStageIOMMUObject.  Can there be many IOMMUContexts to a
DualStageIOMMUOBject?  The other way around?  Or is it just
zero-or-one DualStageIOMMUObjects to an IOMMUContext?

> Cc: Kevin Tian 
> Cc: Jacob Pan 
> Cc: Peter Xu 
> Cc: Eric Auger 
> Cc: Yi Sun 
> Cc: David Gibson 
> Signed-off-by: Peter Xu 
> Signed-off-by: Liu Yi L 
> ---
>  hw/iommu/Makefile.objs   |  1 +
>  hw/iommu/iommu_context.c | 54 +++
>  include/hw/iommu/iommu_context.h | 61 
> 
>  3 files changed, 116 insertions(+)
>  create mode 100644 hw/iommu/iommu_context.c
>  create mode 100644 include/hw/iommu/iommu_context.h
> 
> diff --git a/hw/iommu/Makefile.objs b/hw/iommu/Makefile.objs
> index d4f3b39..1e45072 100644
> --- a/hw/iommu/Makefile.objs
> +++ b/hw/iommu/Makefile.objs
> @@ -1 +1,2 @@
>  obj-y += dual_stage_iommu.o
> +obj-y += iommu_context.o
> diff --git a/hw/iommu/iommu_context.c b/hw/iommu/iommu_context.c
> new file mode 100644
> index 000..6340ca3
> --- /dev/null
> +++ b/hw/iommu/iommu_context.c
> @@ -0,0 +1,54 @@
> +/*
> + * QEMU abstract of vIOMMU context
> + *
> + * Copyright (C) 2020 Red Hat Inc.
> + *
> + * Authors: Peter Xu ,
> + *  Liu Yi L 
> + *
> + * 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 .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/iommu/iommu_context.h"
> +
> +int iommu_context_register_ds_iommu(IOMMUContext *iommu_ctx,
> +DualStageIOMMUObject *dsi_obj)
> +{
> +if (!iommu_ctx || !dsi_obj) {

Would this ever happen apart from a bug in the caller?  If not it
should be an assert().

> +return -ENOENT;
> +}
> +
> +if (iommu_ctx->ops && iommu_ctx->ops->register_ds_iommu) {
> +return iommu_ctx->ops->register_ds_iommu(iommu_ctx, dsi_obj);
> +}
> +return -ENOENT;
> +}
> +
> +void iommu_context_unregister_ds_iommu(IOMMUContext *iommu_ctx,
> +  DualStageIOMMUObject *dsi_obj)
> +{
> +if (!iommu_ctx || !dsi_obj) {
> +return;
> +}
> +
> +if (iommu_ctx->ops && iommu_ctx->ops->unregister_ds_iommu) {
> +iommu_ctx->ops->unregister_ds_iommu(iommu_ctx, dsi_obj);
> +}
> +}
> +
> +void iommu_context_init(IOMMUContext *iommu_ctx, IOMMUContextOps *ops)
> +{
> +iommu_ctx->ops = ops;
> +}
> diff --git a/include/hw/iommu/iommu_context.h 
> b/include/hw/iommu/iommu_context.h
> new file mode 100644
> index 000..6f2ccb5
> --- /dev/null
> +++ b/include/hw/iommu/iommu_context.h
> @@ -0,0 +1,61 @@
> +/*
> + * QEMU abstraction of IOMMU Context
> + *
> + * Copyright (C) 2020 Red H

Re: [PATCH rc4 24/29] hw/avr: Add some ATmega microcontrollers

2020-01-30 Thread Aleksandar Markovic
On Fri, Jan 31, 2020 at 4:45 AM Aleksandar Markovic
 wrote:
>
> On Fri, Jan 31, 2020 at 4:09 AM Philippe Mathieu-Daudé  
> wrote:
> >
> > Hi Aleksandar,
> >
> > Cc'ing Thomas & Daniel who are not lawyers but tried to explain me few
> > times how licensing works.
> >
> > On Fri, Jan 31, 2020 at 2:56 AM Aleksandar Markovic
> >  wrote:
> > > On Fri, Jan 31, 2020 at 1:03 AM Aleksandar Markovic
> > >  wrote:
> > > >
> > > > From: Philippe Mathieu-Daudé 
> > > >
> > > > Add some AVR microcontrollers from the ATmega family:
> > > >
> > > >   - middle range: ATmega168 and ATmega328
> > > >   - high range: ATmega1280 and ATmega2560
> > > >
> > > > For product comparison:
> > > >   
> > > > https://www.microchip.com/wwwproducts/ProductCompare/ATmega168P/ATmega328P
> > > >   
> > > > https://www.microchip.com/wwwproducts/ProductCompare/ATmega1280/ATmega2560
> > > >
> > > > Datasheets:
> > > >   
> > > > http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
> > > >   
> > > > http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf
> > > >
> > > > [AM: Remove word 'Atmel' from filenames and all elements of code]
> > > > Suggested-by: Aleksandar Markovic 
> > > >
> > > > Signed-off-by: Philippe Mathieu-Daudé 
> > > > Signed-off-by: Richard Henderson 
> > > > Signed-off-by: Aleksandar Markovic 
> > > > ---
> > > >  hw/avr/Kconfig   |   5 +
> > > >  hw/avr/Makefile.objs |   1 +
> > > >  hw/avr/atmega.c  | 470 
> > > > +++
> > > >  hw/avr/atmega.h  |  48 ++
> > > >  4 files changed, 524 insertions(+)
> > > >  create mode 100644 hw/avr/Kconfig
> > > >  create mode 100644 hw/avr/atmega.c
> > > >  create mode 100644 hw/avr/atmega.h
> > > >
> > > > diff --git a/hw/avr/Kconfig b/hw/avr/Kconfig
> > > > new file mode 100644
> > > > index 000..9e6527e
> > > > --- /dev/null
> > > > +++ b/hw/avr/Kconfig
> > > > @@ -0,0 +1,5 @@
> > > > +config AVR_ATMEGA_MCU
> > > > +bool
> > > > +select AVR_TIMER16
> > > > +select AVR_USART
> > > > +select AVR_POWER
> > > > diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
> > > > index 123f174..af0fdde 100644
> > > > --- a/hw/avr/Makefile.objs
> > > > +++ b/hw/avr/Makefile.objs
> > > > @@ -1 +1,2 @@
> > > >  obj-y += boot.o
> > > > +obj-$(CONFIG_AVR_ATMEGA_MCU) += atmega.o
> > > > diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
> > > > new file mode 100644
> > > > index 000..8cdf28b
> > > > --- /dev/null
> > > > +++ b/hw/avr/atmega.c
> > > > @@ -0,0 +1,470 @@
> > > > +/*
> > > > + * QEMU ATmega MCU
> > > > + *
> > > > + * Copyright (c) 2019 Philippe Mathieu-Daudé
> > > > + *
> > > > + * This work is licensed under the terms of the GNU GPLv2 or later.
> > > > + * See the COPYING file in the top-level directory.
> > > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > > + */
> > >
> > > Philippe,
> > >
> > > Michael and I already agreed at some moment that the whole target AVR
> > > should have harmonized licenses, and Sarrah agreed to change her
> > > license to achieve this. Do you agree to harmonize your licenses with
> > > the rest of the project? (This would mean changing the preable, but of
> > > course you remain copyright carrier as is now.)
> >
> > What license do you want to use? I always use "GPLv2 or later" with
> > QEMU, mostly following what the others do.
> >
> > Per https://wiki.qemu.org/License:
> >
> >   Source files with no licensing information are released under the
> > GNU General Public License, version 2 or (at your option) any later
> > version.
> >
> > Reading about licensing is not fun :(
> >
>
> Philippe, here is the deal: All new files for AVR platform has the
> following preamble, that Michael chose from the outset:
>
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library 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
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see
> + * 
>
> Now, it is preferable that licenses are harmonized within a module,
> and I ask you to change the preamble to be the same as the rest of the
> module, that is all. This practically means LGPL2.1+later instead
> LGPL2.0+later. I think it is reasonable that we want to simplify out
> license stuff, not complicate it with different licenses within a
> module. There are examples of complications in cases of different
> license within the

Re: [PATCH rc4 24/29] hw/avr: Add some ATmega microcontrollers

2020-01-30 Thread Aleksandar Markovic
On Fri, Jan 31, 2020 at 4:09 AM Philippe Mathieu-Daudé  wrote:
>
> Hi Aleksandar,
>
> Cc'ing Thomas & Daniel who are not lawyers but tried to explain me few
> times how licensing works.
>
> On Fri, Jan 31, 2020 at 2:56 AM Aleksandar Markovic
>  wrote:
> > On Fri, Jan 31, 2020 at 1:03 AM Aleksandar Markovic
> >  wrote:
> > >
> > > From: Philippe Mathieu-Daudé 
> > >
> > > Add some AVR microcontrollers from the ATmega family:
> > >
> > >   - middle range: ATmega168 and ATmega328
> > >   - high range: ATmega1280 and ATmega2560
> > >
> > > For product comparison:
> > >   
> > > https://www.microchip.com/wwwproducts/ProductCompare/ATmega168P/ATmega328P
> > >   
> > > https://www.microchip.com/wwwproducts/ProductCompare/ATmega1280/ATmega2560
> > >
> > > Datasheets:
> > >   
> > > http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
> > >   
> > > http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf
> > >
> > > [AM: Remove word 'Atmel' from filenames and all elements of code]
> > > Suggested-by: Aleksandar Markovic 
> > >
> > > Signed-off-by: Philippe Mathieu-Daudé 
> > > Signed-off-by: Richard Henderson 
> > > Signed-off-by: Aleksandar Markovic 
> > > ---
> > >  hw/avr/Kconfig   |   5 +
> > >  hw/avr/Makefile.objs |   1 +
> > >  hw/avr/atmega.c  | 470 
> > > +++
> > >  hw/avr/atmega.h  |  48 ++
> > >  4 files changed, 524 insertions(+)
> > >  create mode 100644 hw/avr/Kconfig
> > >  create mode 100644 hw/avr/atmega.c
> > >  create mode 100644 hw/avr/atmega.h
> > >
> > > diff --git a/hw/avr/Kconfig b/hw/avr/Kconfig
> > > new file mode 100644
> > > index 000..9e6527e
> > > --- /dev/null
> > > +++ b/hw/avr/Kconfig
> > > @@ -0,0 +1,5 @@
> > > +config AVR_ATMEGA_MCU
> > > +bool
> > > +select AVR_TIMER16
> > > +select AVR_USART
> > > +select AVR_POWER
> > > diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
> > > index 123f174..af0fdde 100644
> > > --- a/hw/avr/Makefile.objs
> > > +++ b/hw/avr/Makefile.objs
> > > @@ -1 +1,2 @@
> > >  obj-y += boot.o
> > > +obj-$(CONFIG_AVR_ATMEGA_MCU) += atmega.o
> > > diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
> > > new file mode 100644
> > > index 000..8cdf28b
> > > --- /dev/null
> > > +++ b/hw/avr/atmega.c
> > > @@ -0,0 +1,470 @@
> > > +/*
> > > + * QEMU ATmega MCU
> > > + *
> > > + * Copyright (c) 2019 Philippe Mathieu-Daudé
> > > + *
> > > + * This work is licensed under the terms of the GNU GPLv2 or later.
> > > + * See the COPYING file in the top-level directory.
> > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > + */
> >
> > Philippe,
> >
> > Michael and I already agreed at some moment that the whole target AVR
> > should have harmonized licenses, and Sarrah agreed to change her
> > license to achieve this. Do you agree to harmonize your licenses with
> > the rest of the project? (This would mean changing the preable, but of
> > course you remain copyright carrier as is now.)
>
> What license do you want to use? I always use "GPLv2 or later" with
> QEMU, mostly following what the others do.
>
> Per https://wiki.qemu.org/License:
>
>   Source files with no licensing information are released under the
> GNU General Public License, version 2 or (at your option) any later
> version.
>
> Reading about licensing is not fun :(
>

Philippe, here is the deal: All new files for AVR platform has the
following preamble, that Michael chose from the outset:

+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 

Now, it is preferable that licenses are harmonized within a module,
and I ask you to change the preamble to be the same as the rest of the
module, that is all. This practically means LGPL2.1+later instead
LGPL2.0+later. I think it is reasonable that we want to simplify out
license stuff, not complicate it with different licenses within a
module. There are examples of complications in cases of different
license within the same module, so it would be ideal if we avoid such
situations.

Aleksandar

> >
> > Thanks,
> > Aleksandar



Re: [PATCH rc4 24/29] hw/avr: Add some ATmega microcontrollers

2020-01-30 Thread Philippe Mathieu-Daudé
Hi Aleksandar,

Cc'ing Thomas & Daniel who are not lawyers but tried to explain me few
times how licensing works.

On Fri, Jan 31, 2020 at 2:56 AM Aleksandar Markovic
 wrote:
> On Fri, Jan 31, 2020 at 1:03 AM Aleksandar Markovic
>  wrote:
> >
> > From: Philippe Mathieu-Daudé 
> >
> > Add some AVR microcontrollers from the ATmega family:
> >
> >   - middle range: ATmega168 and ATmega328
> >   - high range: ATmega1280 and ATmega2560
> >
> > For product comparison:
> >   https://www.microchip.com/wwwproducts/ProductCompare/ATmega168P/ATmega328P
> >   https://www.microchip.com/wwwproducts/ProductCompare/ATmega1280/ATmega2560
> >
> > Datasheets:
> >   
> > http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
> >   
> > http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf
> >
> > [AM: Remove word 'Atmel' from filenames and all elements of code]
> > Suggested-by: Aleksandar Markovic 
> >
> > Signed-off-by: Philippe Mathieu-Daudé 
> > Signed-off-by: Richard Henderson 
> > Signed-off-by: Aleksandar Markovic 
> > ---
> >  hw/avr/Kconfig   |   5 +
> >  hw/avr/Makefile.objs |   1 +
> >  hw/avr/atmega.c  | 470 
> > +++
> >  hw/avr/atmega.h  |  48 ++
> >  4 files changed, 524 insertions(+)
> >  create mode 100644 hw/avr/Kconfig
> >  create mode 100644 hw/avr/atmega.c
> >  create mode 100644 hw/avr/atmega.h
> >
> > diff --git a/hw/avr/Kconfig b/hw/avr/Kconfig
> > new file mode 100644
> > index 000..9e6527e
> > --- /dev/null
> > +++ b/hw/avr/Kconfig
> > @@ -0,0 +1,5 @@
> > +config AVR_ATMEGA_MCU
> > +bool
> > +select AVR_TIMER16
> > +select AVR_USART
> > +select AVR_POWER
> > diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
> > index 123f174..af0fdde 100644
> > --- a/hw/avr/Makefile.objs
> > +++ b/hw/avr/Makefile.objs
> > @@ -1 +1,2 @@
> >  obj-y += boot.o
> > +obj-$(CONFIG_AVR_ATMEGA_MCU) += atmega.o
> > diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
> > new file mode 100644
> > index 000..8cdf28b
> > --- /dev/null
> > +++ b/hw/avr/atmega.c
> > @@ -0,0 +1,470 @@
> > +/*
> > + * QEMU ATmega MCU
> > + *
> > + * Copyright (c) 2019 Philippe Mathieu-Daudé
> > + *
> > + * This work is licensed under the terms of the GNU GPLv2 or later.
> > + * See the COPYING file in the top-level directory.
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + */
>
> Philippe,
>
> Michael and I already agreed at some moment that the whole target AVR
> should have harmonized licenses, and Sarrah agreed to change her
> license to achieve this. Do you agree to harmonize your licenses with
> the rest of the project? (This would mean changing the preable, but of
> course you remain copyright carrier as is now.)

What license do you want to use? I always use "GPLv2 or later" with
QEMU, mostly following what the others do.

Per https://wiki.qemu.org/License:

  Source files with no licensing information are released under the
GNU General Public License, version 2 or (at your option) any later
version.

Reading about licensing is not fun :(

>
> Thanks,
> Aleksandar



Re: [PATCH v4 7/7] tests/boot_linux_console: Tag Emcraft Smartfusion2 as running 'u-boot'

2020-01-30 Thread Philippe Mathieu-Daudé

On 1/21/20 12:51 AM, Philippe Mathieu-Daudé wrote:

Avocado tags are handy to automatically select tests matching
the tags. Since this test also runs U-Boot, tag it.

We can run all the tests using U-Boot as once with:

   $ avocado --show=app run -t u-boot tests/acceptance/
   JOB LOG: avocado/job-results/job-2020-01-21T00.16-ee9344e/job.log
(1/3) 
tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_emcraft_sf2: 
PASS (16.59 s)
(2/3) 
tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_uboot: 
PASS (0.47 s)
(3/3) 
tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_aarch64_raspi3_uboot:
 PASS (2.43 s)
   RESULTS: PASS 3 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | 
CANCEL 0
   JOB TIME   : 19.78 s

Signed-off-by: Philippe Mathieu-Daudé 
---
  tests/acceptance/boot_linux_console.py | 1 +
  1 file changed, 1 insertion(+)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 22b360118d..4a4cf9d0ea 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -305,6 +305,7 @@ class BootLinuxConsole(Test):
  :avocado: tags=arch:arm
  :avocado: tags=machine:emcraft-sf2
  :avocado: tags=endian:little
+:avocado: tags=u-boot
  """
  uboot_url = ('https://raw.githubusercontent.com/'
   'Subbaraya-Sundeep/qemu-test-binaries/'



Thanks, applied to my python-next tree:
https://gitlab.com/philmd/qemu/commits/python-next




[Bug 1861468] [NEW] always fail to build qemu statically

2020-01-30 Thread zwq
Public bug reported:

I want to build qemu statically so as to use qemu on Android platform(Though 
Limbo emulator is available on github,it's even slower than qemu in UserLAnd(an 
Android APP that provides proot container for Linux dists)).
When I finished building qemu normally on my phone(Ubuntu devel in proot 
environment),I started to build qemu statically.I removed the old source code 
dir and unpack the qemu source code. I had built many libraries like libSDL2 
and libiSCSI for qemu,and of course these libraries were able to be detected by 
qemu configure program.But when I ran the command:

 ❯ ./configure --static --prefix=/home/admin/qemu/build 
--target-list=aarch64-softmmu,x86_64-softmmu,i386-softmmu,mips64-softmmu,ppc64-softmmu
 --enable-sdl   
  ERROR: User requested feature sdl 
  
configure was not able to find it.  
Install SDL2 devel

I had to give up the SDL feature.
I disabled the SDL feature and ran configure again.The configure didn't report 
error,but besides SDL ,many other libraries like libUSB,libpng were missing.I 
ran 'make -j8 &&make install'.All seemed perfect.But when it comes to the final 
process--linking executables,the ld program went wrong.It said it could not 
find the libraries like -lgtk3 -ldrm -lsystemd,etc.
I was confused.I had already had a test building which successfully finished.
Could you give me a possible way to solve the problem?

Platform information:
Ubuntu devel 20.04 ARM64 with GCC 9.2.1
QEMU version:I have tested almost all versions from 2.11 to 4.2.0.

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1861468

Title:
  always fail to build qemu statically

Status in QEMU:
  New

Bug description:
  I want to build qemu statically so as to use qemu on Android platform(Though 
Limbo emulator is available on github,it's even slower than qemu in UserLAnd(an 
Android APP that provides proot container for Linux dists)).
  When I finished building qemu normally on my phone(Ubuntu devel in proot 
environment),I started to build qemu statically.I removed the old source code 
dir and unpack the qemu source code. I had built many libraries like libSDL2 
and libiSCSI for qemu,and of course these libraries were able to be detected by 
qemu configure program.But when I ran the command:

   ❯ ./configure --static --prefix=/home/admin/qemu/build 
--target-list=aarch64-softmmu,x86_64-softmmu,i386-softmmu,mips64-softmmu,ppc64-softmmu
 --enable-sdl   
  ERROR: User requested feature sdl 
  
  configure was not able to find it.
  
  Install SDL2 devel

  I had to give up the SDL feature.
  I disabled the SDL feature and ran configure again.The configure didn't 
report error,but besides SDL ,many other libraries like libUSB,libpng were 
missing.I ran 'make -j8 &&make install'.All seemed perfect.But when it comes to 
the final process--linking executables,the ld program went wrong.It said it 
could not find the libraries like -lgtk3 -ldrm -lsystemd,etc.
  I was confused.I had already had a test building which successfully finished.
  Could you give me a possible way to solve the problem?

  Platform information:
  Ubuntu devel 20.04 ARM64 with GCC 9.2.1
  QEMU version:I have tested almost all versions from 2.11 to 4.2.0.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1861468/+subscriptions



Re: [PATCH rc4 24/29] hw/avr: Add some ATmega microcontrollers

2020-01-30 Thread Aleksandar Markovic
On Fri, Jan 31, 2020 at 1:03 AM Aleksandar Markovic
 wrote:
>
> From: Philippe Mathieu-Daudé 
>
> Add some AVR microcontrollers from the ATmega family:
>
>   - middle range: ATmega168 and ATmega328
>   - high range: ATmega1280 and ATmega2560
>
> For product comparison:
>   https://www.microchip.com/wwwproducts/ProductCompare/ATmega168P/ATmega328P
>   https://www.microchip.com/wwwproducts/ProductCompare/ATmega1280/ATmega2560
>
> Datasheets:
>   
> http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
>   
> http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf
>
> [AM: Remove word 'Atmel' from filenames and all elements of code]
> Suggested-by: Aleksandar Markovic 
>
> Signed-off-by: Philippe Mathieu-Daudé 
> Signed-off-by: Richard Henderson 
> Signed-off-by: Aleksandar Markovic 
> ---
>  hw/avr/Kconfig   |   5 +
>  hw/avr/Makefile.objs |   1 +
>  hw/avr/atmega.c  | 470 
> +++
>  hw/avr/atmega.h  |  48 ++
>  4 files changed, 524 insertions(+)
>  create mode 100644 hw/avr/Kconfig
>  create mode 100644 hw/avr/atmega.c
>  create mode 100644 hw/avr/atmega.h
>
> diff --git a/hw/avr/Kconfig b/hw/avr/Kconfig
> new file mode 100644
> index 000..9e6527e
> --- /dev/null
> +++ b/hw/avr/Kconfig
> @@ -0,0 +1,5 @@
> +config AVR_ATMEGA_MCU
> +bool
> +select AVR_TIMER16
> +select AVR_USART
> +select AVR_POWER
> diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
> index 123f174..af0fdde 100644
> --- a/hw/avr/Makefile.objs
> +++ b/hw/avr/Makefile.objs
> @@ -1 +1,2 @@
>  obj-y += boot.o
> +obj-$(CONFIG_AVR_ATMEGA_MCU) += atmega.o
> diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
> new file mode 100644
> index 000..8cdf28b
> --- /dev/null
> +++ b/hw/avr/atmega.c
> @@ -0,0 +1,470 @@
> +/*
> + * QEMU ATmega MCU
> + *
> + * Copyright (c) 2019 Philippe Mathieu-Daudé
> + *
> + * This work is licensed under the terms of the GNU GPLv2 or later.
> + * See the COPYING file in the top-level directory.
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */

Philippe,

Michael and I already agreed at some moment that the whole target AVR
should have harmonized licenses, and Sarrah agreed to change her
license to achieve this. Do you agree to harmonize your licenses with
the rest of the project? (This would mean changing the preable, but of
course you remain copyright carrier as is now.)

Thanks,
Aleksandar

> +
> +#include "qemu/osdep.h"
> +#include "qemu/module.h"
> +#include "qemu/units.h"
> +#include "qapi/error.h"
> +#include "exec/memory.h"
> +#include "exec/address-spaces.h"
> +#include "sysemu/sysemu.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/sysbus.h"
> +#include "hw/boards.h" /* FIXME memory_region_allocate_system_memory for 
> sram */
> +#include "hw/misc/unimp.h"
> +#include "atmega.h"
> +
> +enum AtmegaPeripheral {
> +POWER0, POWER1,
> +GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF,
> +GPIOG, GPIOH, GPIOI, GPIOJ, GPIOK, GPIOL,
> +USART0, USART1, USART2, USART3,
> +TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5,
> +PERIFMAX
> +};
> +
> +#define GPIO(n) (n + GPIOA)
> +#define USART(n)(n + USART0)
> +#define TIMER(n)(n + TIMER0)
> +#define POWER(n)(n + POWER0)
> +
> +typedef struct {
> +uint16_t addr;
> +enum AtmegaPeripheral power_index;
> +uint8_t power_bit;
> +/* timer specific */
> +uint16_t intmask_addr;
> +uint16_t intflag_addr;
> +bool is_timer16;
> +} peripheral_cfg;
> +
> +typedef struct AtmegaMcuClass {
> +/*< private >*/
> +SysBusDeviceClass parent_class;
> +/*< public >*/
> +const char *uc_name;
> +const char *cpu_type;
> +size_t flash_size;
> +size_t eeprom_size;
> +size_t sram_size;
> +size_t io_size;
> +size_t gpio_count;
> +size_t adc_count;
> +const uint8_t *irq;
> +const peripheral_cfg *dev;
> +} AtmegaMcuClass;
> +
> +#define ATMEGA_MCU_CLASS(klass) \
> +OBJECT_CLASS_CHECK(AtmegaMcuClass, (klass), TYPE_ATMEGA_MCU)
> +#define ATMEGA_MCU_GET_CLASS(obj) \
> +OBJECT_GET_CLASS(AtmegaMcuClass, (obj), TYPE_ATMEGA_MCU)
> +
> +static const peripheral_cfg dev168_328[PERIFMAX] = {
> +[USART0]= {  0xc0, POWER0, 1 },
> +[TIMER2]= {  0xb0, POWER0, 6, 0x70, 0x37, false },
> +[TIMER1]= {  0x80, POWER0, 3, 0x6f, 0x36, true },
> +[POWER0]= {  0x64 },
> +[TIMER0]= {  0x44, POWER0, 5, 0x6e, 0x35, false },
> +[GPIOD] = {  0x29 },
> +[GPIOC] = {  0x26 },
> +[GPIOB] = {  0x23 },
> +}, dev1280_2560[PERIFMAX] = {
> +[USART3]= { 0x130, POWER1, 2 },
> +[TIMER5]= { 0x120, POWER1, 5, 0x73, 0x3a, true },
> +[GPIOL] = { 0x109 },
> +[GPIOK] = { 0x106 },
> +[GPIOJ] = { 0x103 },
> +[GPIOH] = { 0x100 },
> +[USART2]= {  0xd0, P

Re: [PATCH 0/4] target/ppc: Use probe_access

2020-01-30 Thread David Gibson
On Wed, Jan 29, 2020 at 03:50:36PM -0800, Richard Henderson wrote:
> The first two address the performance regression noticed
> by Howard Spoelstra.  The last two are just something I
> noticed at the same time.

Applied to ppc-for-5.0, thanks.

> 
> 
> r~
> 
> 
> Richard Henderson (4):
>   target/ppc: Use probe_access for LSW, STSW
>   target/ppc: Use probe_access for LMW, STMW
>   target/ppc: Remove redundant mask in DCBZ
>   target/ppc: Use probe_write for DCBZ
> 
>  target/ppc/mem_helper.c | 197 +---
>  1 file changed, 162 insertions(+), 35 deletions(-)
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH rc2 01/25] target/avr: Add outward facing interfaces and core CPU logic

2020-01-30 Thread Philippe Mathieu-Daudé

Hi Richard,

On 1/27/20 2:38 PM, Michael Rolnik wrote:

Hi Joaquin.

I looks like that the CPU families are not well defined. There are some 
small variations within the families themselves i.e. some MCUs do not 
support all the features of their families.
To get the features I looked at this file in gcc 
https://github.com/gcc-mirror/gcc/blob/master/gcc/config/avr/avr-devices.c
Have a look here 
https://github.com/gcc-mirror/gcc/blob/master/gcc/config/avr/avr-mcus.def. 
you can see that not all xmega support RMW instructions. so whenever 
QEMU has atxmega128d4 implemented, atxmega128d4 modelit will have to 
remove RMW feature.


What source should we trust here? The various datasheets or GCC?
GCC is eventually tested more thoroughly...


Regards,
Michael Rolnik

On Mon, Jan 27, 2020 at 3:27 PM Joaquin de Andres 
mailto:m...@xcancerberox.com.ar>> wrote:


On 1/24/20 1:51 AM, Philippe Mathieu-Daudé wrote:
 > From: Michael Rolnik mailto:mrol...@gmail.com>>
 >
 > This includes:
 > - CPU data structures
 > - object model classes and functions
 > - migration functions
 > - GDB hooks
 >
 > Co-developed-by: Michael Rolnik mailto:mrol...@gmail.com>>
 > Co-developed-by: Sarah Harris mailto:s.e.har...@kent.ac.uk>>
 > Signed-off-by: Michael Rolnik mailto:mrol...@gmail.com>>
 > Signed-off-by: Sarah Harris mailto:s.e.har...@kent.ac.uk>>
 > Signed-off-by: Michael Rolnik mailto:mrol...@gmail.com>>
 > Acked-by: Igor Mammedov mailto:imamm...@redhat.com>>
 > Tested-by: Philippe Mathieu-Daudé mailto:phi...@redhat.com>>
 > Message-Id: <20200118191416.19934-2-mrol...@gmail.com
>
 > Signed-off-by: Richard Henderson mailto:richard.hender...@linaro.org>>
 > ---
 > ...
 > diff --git a/target/avr/cpu.c b/target/avr/cpu.c
 > new file mode 100644
 > index 00..c74c5106fe
 > --- /dev/null
 > +++ b/target/avr/cpu.c
 > @@ -0,0 +1,826 @@
 > ...
 > +/*
 > + * Setting features of AVR core type avr1
 > + * --
 > + *
 > + * This type of AVR core is present in the following AVR MCUs:
 > + *
 > + * at90s1200, attiny11, attiny12, attiny15, attiny28
 > + */
 > +static void avr_avr1_initfn(Object *obj)
 > +{
 > +    AVRCPU *cpu = AVR_CPU(obj);
 > +    CPUAVRState *env = &cpu->env;
 > +> +    avr_set_feature(env, AVR_FEATURE_LPM);

Hi! According to the datasheets the at90s1200 is an special case and the
LPM instruction is not present.

 > +    avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
 > +    avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);

Ok. Checked with at90s1200 datasheet.

 > +}
 > +
 > +/*
 > + * Setting features of AVR core type avr2
 > + * --
 > + *
 > + * This type of AVR core is present in the following AVR MCUs:
 > + *
 > + * at90s2313, at90s2323, at90s2333, at90s2343, attiny22,
attiny26, at90s4414,
 > + * at90s4433, at90s4434, at90s8515, at90c8534, at90s8535
 > + */
 > +static void avr_avr2_initfn(Object *obj)
 > +{
 > +    AVRCPU *cpu = AVR_CPU(obj);
 > +    CPUAVRState *env = &cpu->env;
 > +
 > +    avr_set_feature(env, AVR_FEATURE_LPM);

Ok. Checked with at90s2313 datasheet.

 > +    avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);

Ok. Checked with at90s2313 datasheet.

 > +    avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);

Ok. Checked with at90s2313 datasheet.

 > +    avr_set_feature(env, AVR_FEATURE_SRAM);

Ok. Checked with at90s2313 datasheet.

 > +    avr_set_feature(env, AVR_FEATURE_BREAK);
 > +
 > +    avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);

Ok. Checked with at90s2313 datasheet.

 > +    avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
 > +}
 > +
 > +/*
 > + * Setting features of AVR core type avr25
 > + * --
 > + *
 > + * This type of AVR core is present in the following AVR MCUs:
 > + *
 > + * ata5272, ata6616c, attiny13, attiny13a, attiny2313,
attiny2313a, attiny24,
 > + * attiny24a, attiny4313, attiny44, attiny44a, attiny441,
attiny84, attiny84a,
 > + * attiny25, attiny45, attiny85, attiny261, attiny261a,
attiny461, attiny461a,
 > + * attiny861, attiny861a, attiny43u, attiny87, attiny48,
attiny88, attiny828,
 > + * attiny841, at86rf401
 > + */
 > +static void avr_avr25_initfn(Object *obj)
 > +{
 > +    AVRCPU *cpu = AVR_CPU(obj);
 > +    CPUAVRState *env = &cpu->env;
 > +
 > +    avr_set_feature(env, AVR_FEATURE_LPM);

Ok. Checked with attiny13 datasheet.

 > +    avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);

Ok. Checked with attiny13 datasheet.

 > +    avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);

Ok. Checked with attiny13 datasheet.

 > +  

Re: [PATCH rc4 00/29] target/avr merger

2020-01-30 Thread Philippe Mathieu-Daudé

On 1/31/20 1:12 AM, Aleksandar Markovic wrote:

Michael, Philippe,

Can you guys do a quick checkup of this rc4? rc4, rc3,and rc2 should
be functionally 100% equivalent.


Tested OK.

git-backport-diff with rc2:

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/31:[down] 'target/avr: Add basic parameters for new AVR platform'
002/31:[down] 'target/avr: Introduce AVR CPU class object'
003/31:[down] 'target/avr: Add migration support'
004/31:[down] 'target/avr: Add GDB support'
005/31:[down] 'target/avr: Introduce enumeration AVRFeature'
006/31:[down] 'target/avr: Add defintions of AVR core types'
007/31:[0148] [FC] 'target/avr: Add instruction helpers'
008/31:[down] 'target/avr: Add instruction translation - Register 
definitions'
009/31:[] [--] 'target/avr: Add instruction translation - Arithmetic 
and Logic Instructions'
010/31:[] [--] 'target/avr: Add instruction translation - Branch 
Instructions'
011/31:[] [--] 'target/avr: Add instruction translation - Data 
Transfer Instructions'
012/31:[] [--] 'target/avr: Add instruction translation - Bit and 
Bit-test Instructions'
013/31:[] [--] 'target/avr: Add instruction translation - MCU 
Control Instructions'
014/31:[] [--] 'target/avr: Add instruction translation - CPU main 
translation function'

015/31:[] [--] 'target/avr: Add instruction disassembly function'
016/31:[down] 'hw/char: Add limited support for AVR USART peripheral'
017/31:[down] 'hw/timer: Add limited support for AVR 16-bit timer 
peripheral'

018/31:[down] 'hw/misc: Add limited support for AVR power device'
019/31:[0012] [FC] 'target/avr: Add section about AVR into QEMU 
documentation'

020/31:[0002] [FC] 'target/avr: Register AVR support with the rest of QEMU'
021/31:[] [--] 'target/avr: Add machine none test'
022/31:[0014] [FC] 'target/avr: Update MAINTAINERS file'
023/31:[0002] [FC] 'hw/avr: Add helper to load raw/ELF firmware binaries'
024/31:[0026] [FC] 'hw/avr: Add some ATmega microcontrollers'
025/31:[0009] [FC] 'hw/avr: Add some Arduino boards'
026/31:[] [--] 'target/avr: Update build system'
027/31:[] [--] 'tests/boot-serial-test: Test some Arduino boards 
(AVR based)'

028/31:[] [--] 'tests/acceptance: Test the Arduino MEGA2560 board'
029/31:[] [--] '.travis.yml: Run the AVR acceptance tests'
030/31:[down] '!fixup "hw/misc: Add limited support for AVR power device"'
031/31:[down] '!fixup "hw/timer: Add limited support for AVR 16-bit 
timer peripheral"'


One thing that annoys me is we ignored the review comments from Joaquin, 
but I think it might now be easier to address them as new patches, once 
this series is merged.


I made 2 comments (definitions in incorrect patch, and definition 
misplaced in elf.h), and sent 2 patches converting the PRINTF() to 
trace-events. Thanks for preparing the rc4, hopefully we are done!




Thank you,
Aleksandar

On Fri, Jan 31, 2020 at 1:06 AM Aleksandar Markovic
 wrote:


From: Aleksandar Markovic 

This is the AVR port from Michael, release (merge) candidate 4.

The series can be found also in this repository:

https://github.com/AMarkovic/qemu-avr-merger-rc4

History:

Since v3:

- Removed a patch on load_elf() modification, since it has been merged
- Removed references to CONFIG_USER_ONLY and provided a guard against
   building lunux user mode for AVR
- Removed all references to 'Atmel' (including file renames)
- Rebased the code (there was common interface change regarding 'props')
- Various corrections of commit messages
- A bit field for AVRFeatures is nor 64 bit long
- Other minor fixes

Since v2:

- First patch is split into six smaller logical units (net result
   remains the same)
- Patch "hw/core/loader: Let load_elf populate the processor-specific
   flags" was redone to reflect the original intent that was lost in
   transalation between multiple autors
- Patch "hw/avr: Add helper to load raw/ELF firmware binaries" was
   corrected only in one line to rectify type of "e_flags"
- Patch "target/avr: Add section about AVR into QEMU documentation"
- Spurious  elements were removed
- The series was rebased to the latest code

Since v1:

- Addressed Thomas comments
- Fixed a non-critical bug in ATmega (incorrect SRAM base address)
- Added ELF parsing requested by Aleksandar
- Dropped default machine (as with the ARM port)

Michael Rolnik (25):
   target/avr: Add basic parameters for new AVR platform
   target/avr: Introduce AVR CPU class object
   target/avr: Add migration support
   target/avr: Add GDB support
   target/avr: Introduce enumeration AVRFeature
   target/avr: Add defintions of AVR core types
   target/avr: Add instruction helpers
   target/avr: Add instruction translation - Register definitions
   target/avr: Add instruction translation - Arithmetic and Logic
 Instructions
   target/avr: Ad

Re: [PATCH 0/2] !fixup target/avr merger-rc4

2020-01-30 Thread Aleksandar Markovic
On Fri, Jan 31, 2020 at 2:09 AM Philippe Mathieu-Daudé 
wrote:
>
> Aleksandar, I addressed Alex Bennée comment as fixup, so you
> can squash directly. See:
> https://www.mail-archive.com/qemu-devel@nongnu.org/msg673846.html
>
> - convert DB_PRINT() to trace-events
> - fix style/indentation
>
> Based-on: <1580428993-4767-1-git-send-email-aleksandar.marko...@rt-rk.com>
>

That is great!

I am going to squash it into corresponding patches, and mention that in
commit messages.
Then I guess some r-b (by Alex) can be added.

Cool!

> Philippe Mathieu-Daudé (2):
>   !fixup "hw/misc: Add limited support for AVR power device"
>   !fixup "hw/timer: Add limited support for AVR 16-bit timer peripheral"
>
>  hw/misc/avr_power.c| 17 +
>  hw/timer/avr_timer16.c | 25 +++--
>  hw/misc/trace-events   |  4 
>  hw/timer/trace-events  | 12 
>  4 files changed, 40 insertions(+), 18 deletions(-)
>
> --
> 2.21.1
>


[PATCH 1/2] !fixup "hw/misc: Add limited support for AVR power device"

2020-01-30 Thread Philippe Mathieu-Daudé
- convert DB_PRINT() to trace-events
- fix style/indentation

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/misc/avr_power.c  | 17 +
 hw/misc/trace-events |  4 
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/hw/misc/avr_power.c b/hw/misc/avr_power.c
index 598bc7279c..65ff7c4405 100644
--- a/hw/misc/avr_power.c
+++ b/hw/misc/avr_power.c
@@ -27,9 +27,7 @@
 #include "qemu/log.h"
 #include "hw/qdev-properties.h"
 #include "hw/irq.h"
-
-#define DB_PRINT(fmt, args...) /* Nothing */
-/*#define DB_PRINT(fmt, args...) printf("%s: " fmt "\n", __func__, ## args)*/
+#include "trace.h"
 
 static void avr_mask_reset(DeviceState *dev)
 {
@@ -48,19 +46,20 @@ static uint64_t avr_mask_read(void *opaque, hwaddr offset, 
unsigned size)
 assert(offset == 0);
 AVRMaskState *s = opaque;
 
+trace_avr_power_read(s->val);
+
 return (uint64_t)s->val;
 }
 
 static void avr_mask_write(void *opaque, hwaddr offset,
-  uint64_t val64, unsigned size)
+   uint64_t val64, unsigned size)
 {
 assert(size == 1);
 assert(offset == 0);
 AVRMaskState *s = opaque;
 uint8_t val8 = val64;
 
-DB_PRINT("write %d to offset %d", val8, (uint8_t)offset);
-
+trace_avr_power_write(val8);
 s->val = val8;
 for (int i = 0; i < 8; i++) {
 qemu_set_irq(s->irq[i], (val8 & (1 << i)) != 0);
@@ -71,7 +70,9 @@ static const MemoryRegionOps avr_mask_ops = {
 .read = avr_mask_read,
 .write = avr_mask_write,
 .endianness = DEVICE_NATIVE_ENDIAN,
-.impl = {.max_access_size = 1}
+.impl = {
+.max_access_size = 1,
+},
 };
 
 static void avr_mask_init(Object *dev)
@@ -80,7 +81,7 @@ static void avr_mask_init(Object *dev)
 SysBusDevice *busdev = SYS_BUS_DEVICE(dev);
 
 memory_region_init_io(&s->iomem, dev, &avr_mask_ops, s, TYPE_AVR_MASK,
-0x01);
+  0x01);
 sysbus_init_mmio(busdev, &s->iomem);
 
 for (int i = 0; i < 8; i++) {
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 7f0f5dff3a..f716881bb1 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -179,3 +179,7 @@ via1_rtc_cmd_pram_read(int addr, int value) "addr=%u 
value=0x%02x"
 via1_rtc_cmd_pram_write(int addr, int value) "addr=%u value=0x%02x"
 via1_rtc_cmd_pram_sect_read(int sector, int offset, int addr, int value) 
"sector=%u offset=%u addr=%d value=0x%02x"
 via1_rtc_cmd_pram_sect_write(int sector, int offset, int addr, int value) 
"sector=%u offset=%u addr=%d value=0x%02x"
+
+# avr_power.c
+avr_power_read(uint8_t value) "power_reduc read value:%u"
+avr_power_write(uint8_t value) "power_reduc write value:%u"
-- 
2.21.1




[PATCH 0/2] !fixup target/avr merger-rc4

2020-01-30 Thread Philippe Mathieu-Daudé
Aleksandar, I addressed Alex Bennée comment as fixup, so you
can squash directly. See:
https://www.mail-archive.com/qemu-devel@nongnu.org/msg673846.html

- convert DB_PRINT() to trace-events
- fix style/indentation

Based-on: <1580428993-4767-1-git-send-email-aleksandar.marko...@rt-rk.com>

Philippe Mathieu-Daudé (2):
  !fixup "hw/misc: Add limited support for AVR power device"
  !fixup "hw/timer: Add limited support for AVR 16-bit timer peripheral"

 hw/misc/avr_power.c| 17 +
 hw/timer/avr_timer16.c | 25 +++--
 hw/misc/trace-events   |  4 
 hw/timer/trace-events  | 12 
 4 files changed, 40 insertions(+), 18 deletions(-)

-- 
2.21.1




[PATCH 2/2] !fixup "hw/timer: Add limited support for AVR 16-bit timer peripheral"

2020-01-30 Thread Philippe Mathieu-Daudé
Convert DB_PRINT() to trace events.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/timer/avr_timer16.c | 25 +++--
 hw/timer/trace-events  | 12 
 2 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/hw/timer/avr_timer16.c b/hw/timer/avr_timer16.c
index 4e16afc61c..073f36aa76 100644
--- a/hw/timer/avr_timer16.c
+++ b/hw/timer/avr_timer16.c
@@ -36,6 +36,7 @@
 #include "qemu/log.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "trace.h"
 
 /* Register offsets */
 #define T16_CRA 0x0
@@ -104,7 +105,6 @@
 /* Helper macros */
 #define VAL16(l, h) ((h << 8) | l)
 #define DB_PRINT(fmt, args...) /* Nothing */
-/*#define DB_PRINT(fmt, args...) printf("%s: " fmt "\n", __func__, ## args)*/
 
 static inline int64_t avr_timer16_ns_to_ticks(AVRTimer16State *t16, int64_t t)
 {
@@ -168,8 +168,8 @@ static void avr_timer16_clksrc_update(AVRTimer16State *t16)
 if (divider) {
 t16->freq_hz = t16->cpu_freq_hz / divider;
 t16->period_ns = NANOSECONDS_PER_SECOND / t16->freq_hz;
-DB_PRINT("Timer frequency %" PRIu64 " hz, period %" PRIu64 " ns (%f 
s)",
- t16->freq_hz, t16->period_ns, 1 / (double)t16->freq_hz);
+trace_avr_timer16_clksrc_update(t16->freq_hz, t16->period_ns,
+(uint64_t)(1e6 / t16->freq_hz));
 }
 }
 
@@ -235,8 +235,7 @@ static void avr_timer16_set_alarm(AVRTimer16State *t16)
 t16->reset_time_ns + ((CNT(t16) + alarm_offset) * t16->period_ns);
 timer_mod(t16->timer, alarm_ns);
 
-DB_PRINT("next alarm %" PRIu64 " ns from now",
-alarm_offset * t16->period_ns);
+trace_avr_timer16_next_alarm(alarm_offset * t16->period_ns);
 }
 
 static void avr_timer16_interrupt(void *opaque)
@@ -253,11 +252,11 @@ static void avr_timer16_interrupt(void *opaque)
 return;
 }
 
-DB_PRINT("interrupt, cnt = %d", CNT(t16));
+trace_avr_timer16_interrupt_count(CNT(t16));
 
 /* Counter overflow */
 if (t16->next_interrupt == OVERFLOW) {
-DB_PRINT("0x overflow");
+trace_avr_timer16_interrupt_overflow("counter 0x");
 avr_timer16_clock_reset(t16);
 if (t16->imsk & T16_INT_TOV) {
 t16->ifr |= T16_INT_TOV;
@@ -266,12 +265,12 @@ static void avr_timer16_interrupt(void *opaque)
 }
 /* Check for ocra overflow in CTC mode */
 if (mode == T16_MODE_CTC_OCRA && t16->next_interrupt == COMPA) {
-DB_PRINT("CTC OCRA overflow");
+trace_avr_timer16_interrupt_overflow("CTC OCRA");
 avr_timer16_clock_reset(t16);
 }
 /* Check for icr overflow in CTC mode */
 if (mode == T16_MODE_CTC_ICR && t16->next_interrupt == CAPT) {
-DB_PRINT("CTC ICR overflow");
+trace_avr_timer16_interrupt_overflow("CTC ICR");
 avr_timer16_clock_reset(t16);
 if (t16->imsk & T16_INT_IC) {
 t16->ifr |= T16_INT_IC;
@@ -367,6 +366,8 @@ static uint64_t avr_timer16_read(void *opaque, hwaddr 
offset, unsigned size)
 default:
 break;
 }
+trace_avr_timer16_read(offset, retval);
+
 return (uint64_t)retval;
 }
 
@@ -378,7 +379,7 @@ static void avr_timer16_write(void *opaque, hwaddr offset,
 uint8_t val8 = (uint8_t)val64;
 uint8_t prev_clk_src = CLKSRC(t16);
 
-DB_PRINT("write %d to offset %d", val8, (uint8_t)offset);
+trace_avr_timer16_write(offset, val8);
 
 switch (offset) {
 case T16_CRA:
@@ -475,6 +476,7 @@ static uint64_t avr_timer16_imsk_read(void *opaque,
 {
 assert(size == 1);
 AVRTimer16State *t16 = opaque;
+trace_avr_timer16_read_imsk(offset ? 0 : t16->imsk);
 if (offset != 0) {
 return 0;
 }
@@ -486,6 +488,7 @@ static void avr_timer16_imsk_write(void *opaque, hwaddr 
offset,
 {
 assert(size == 1);
 AVRTimer16State *t16 = opaque;
+trace_avr_timer16_write_imsk(val64);
 if (offset != 0) {
 return;
 }
@@ -498,6 +501,7 @@ static uint64_t avr_timer16_ifr_read(void *opaque,
 {
 assert(size == 1);
 AVRTimer16State *t16 = opaque;
+trace_avr_timer16_read_ifr(offset ? 0 : t16->ifr);
 if (offset != 0) {
 return 0;
 }
@@ -509,6 +513,7 @@ static void avr_timer16_ifr_write(void *opaque, hwaddr 
offset,
 {
 assert(size == 1);
 AVRTimer16State *t16 = opaque;
+trace_avr_timer16_write_imsk(val64);
 if (offset != 0) {
 return;
 }
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
index 29fda7870e..5d9f4c93fb 100644
--- a/hw/timer/trace-events
+++ b/hw/timer/trace-events
@@ -74,3 +74,15 @@ nrf51_timer_write(uint64_t addr, uint32_t value, unsigned 
size) "write addr 0x%"
 bcm2835_systmr_irq(bool enable) "timer irq state %u"
 bcm2835_systmr_read(uint64_t offset, uint64_t data) "timer read: offset 0x%" 
PRIx64 " data 0x%" PRIx64
 bcm2835_systmr_write(uint64_t offset, uint64_t data) "timer write: offset 0x%" 
PRIx64 " data 0x%" PRIx64
+
+# avr_timer16.c
+avr_timer16_read(uint8_t addr, uint8_t value) "ti

Re: [PATCH rc4 23/29] hw/avr: Add helper to load raw/ELF firmware binaries

2020-01-30 Thread Aleksandar Markovic
On Fri, Jan 31, 2020 at 1:28 AM Philippe Mathieu-Daudé
 wrote:
>
> On 1/31/20 1:26 AM, Aleksandar Markovic wrote:
> > On Fri, Jan 31, 2020 at 1:20 AM Philippe Mathieu-Daudé
> >  wrote:
> >>
> >> On 1/31/20 1:03 AM, Aleksandar Markovic wrote:
> >>> From: Philippe Mathieu-Daudé 
> >>>
> >>> Add avr_load_firmware() function to load firmware in ELF or
> >>> raw binary format.
> >>>
> >>> [AM: Corrected the type of the variable containing e_flags]
> >>>
> >>> Suggested-by: Aleksandar Markovic 
> >>> Signed-off-by: Philippe Mathieu-Daudé 
> >>> Signed-off-by: Aleksandar Markovic 
> >>> ---
> >>>hw/avr/Makefile.objs |  1 +
> >>>hw/avr/boot.c| 74 
> >>> 
> >>>hw/avr/boot.h| 33 +++
> >>>include/elf.h|  2 ++
> >>>4 files changed, 110 insertions(+)
> >>>create mode 100644 hw/avr/Makefile.objs
> >>>create mode 100644 hw/avr/boot.c
> >>>create mode 100644 hw/avr/boot.h
> >>>
> >>> diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
> >>> new file mode 100644
> >>> index 000..123f174
> >>> --- /dev/null
> >>> +++ b/hw/avr/Makefile.objs
> >>> @@ -0,0 +1 @@
> >>> +obj-y += boot.o
> >>> diff --git a/hw/avr/boot.c b/hw/avr/boot.c
> >>> new file mode 100644
> >>> index 000..9ac2c88
> >>> --- /dev/null
> >>> +++ b/hw/avr/boot.c
> >>> @@ -0,0 +1,74 @@
> >>> +/*
> >>> + * AVR loader helpers
> >>> + *
> >>> + * Copyright (c) 2019 Philippe Mathieu-Daudé
> >>> + *
> >>> + * This work is licensed under the terms of the GNU GPLv2 or later.
> >>> + * See the COPYING file in the top-level directory.
> >>> + * SPDX-License-Identifier: GPL-2.0-or-later
> >>> + */
> >>> +
> >>> +#include "qemu/osdep.h"
> >>> +#include "qemu-common.h"
> >>> +#include "hw/loader.h"
> >>> +#include "elf.h"
> >>> +#include "boot.h"
> >>> +#include "qemu/error-report.h"
> >>> +
> >>> +bool avr_load_firmware(AVRCPU *cpu, MachineState *ms,
> >>> +   MemoryRegion *mr, const char *firmware)
> >>> +{
> >>> +const char *filename;
> >>> +int bytes_loaded;
> >>> +uint64_t entry;
> >>> +uint32_t e_flags;
> >>> +
> >>> +filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware);
> >>> +if (filename == NULL) {
> >>> +error_report("Unable to find %s", firmware);
> >>> +return false;
> >>> +}
> >>> +
> >>> +bytes_loaded = load_elf_ram_sym(filename,
> >>> +NULL, NULL, NULL,
> >>> +&entry, NULL, NULL,
> >>> +&e_flags, 0, EM_AVR, 0, 0,
> >>> +NULL, true, NULL);
> >>> +if (bytes_loaded >= 0) {
> >>> +/* If ELF file is provided, determine CPU type reading ELF 
> >>> e_flags. */
> >>> +const char *elf_cpu = avr_flags_to_cpu_type(e_flags, NULL);
> >>> +const char *mcu_cpu_type = object_get_typename(OBJECT(cpu));
> >>> +int cpu_len = strlen(mcu_cpu_type) - strlen(AVR_CPU_TYPE_SUFFIX);
> >>> +
> >>> +if (entry) {
> >>> +error_report("BIOS entry_point must be 0x "
> >>> + "(ELF image '%s' has entry_point 0x%04" PRIx64 
> >>> ")",
> >>> + firmware, entry);
> >>> +return false;
> >>> +}
> >>> +if (!elf_cpu) {
> >>> +warn_report("Could not determine CPU type for ELF image 
> >>> '%s', "
> >>> +"assuming '%.*s' CPU",
> >>> + firmware, cpu_len, mcu_cpu_type);
> >>> +return true;
> >>> +}
> >>> +if (strcmp(elf_cpu, mcu_cpu_type)) {
> >>> +error_report("Current machine: %s with '%.*s' CPU",
> >>> + MACHINE_GET_CLASS(ms)->desc, cpu_len, 
> >>> mcu_cpu_type);
> >>> +error_report("ELF image '%s' is for '%.*s' CPU",
> >>> + firmware,
> >>> + (int)(strlen(elf_cpu) - 
> >>> strlen(AVR_CPU_TYPE_SUFFIX)),
> >>> + elf_cpu);
> >>> +return false;
> >>> +}
> >>> +} else {
> >>> +bytes_loaded = load_image_targphys(filename, OFFSET_CODE,
> >>> +   memory_region_size(mr));
> >>> +}
> >>> +if (bytes_loaded < 0) {
> >>> +error_report("Unable to load firmware image %s as ELF or raw 
> >>> binary",
> >>> + firmware);
> >>> +return false;
> >>> +}
> >>> +return true;
> >>> +}
> >>> diff --git a/hw/avr/boot.h b/hw/avr/boot.h
> >>> new file mode 100644
> >>> index 000..62bc10c
> >>> --- /dev/null
> >>> +++ b/hw/avr/boot.h
> >>> @@ -0,0 +1,33 @@
> >>> +/*
> >>> + * AVR loader helpers
> >>> + *
> >>> + * Copyright (c) 2019 Philippe Mathieu-Daudé
> >>> + *
> >>> + * This work is licensed under the terms of the GNU GPLv2 or later.
> >>> + * See the COPYING file in the top-level directory.
> >>> + * SPDX-Lic

Re: [PATCH rc4 23/29] hw/avr: Add helper to load raw/ELF firmware binaries

2020-01-30 Thread Philippe Mathieu-Daudé

On 1/31/20 1:26 AM, Aleksandar Markovic wrote:

On Fri, Jan 31, 2020 at 1:20 AM Philippe Mathieu-Daudé
 wrote:


On 1/31/20 1:03 AM, Aleksandar Markovic wrote:

From: Philippe Mathieu-Daudé 

Add avr_load_firmware() function to load firmware in ELF or
raw binary format.

[AM: Corrected the type of the variable containing e_flags]

Suggested-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Aleksandar Markovic 
---
   hw/avr/Makefile.objs |  1 +
   hw/avr/boot.c| 74 

   hw/avr/boot.h| 33 +++
   include/elf.h|  2 ++
   4 files changed, 110 insertions(+)
   create mode 100644 hw/avr/Makefile.objs
   create mode 100644 hw/avr/boot.c
   create mode 100644 hw/avr/boot.h

diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
new file mode 100644
index 000..123f174
--- /dev/null
+++ b/hw/avr/Makefile.objs
@@ -0,0 +1 @@
+obj-y += boot.o
diff --git a/hw/avr/boot.c b/hw/avr/boot.c
new file mode 100644
index 000..9ac2c88
--- /dev/null
+++ b/hw/avr/boot.c
@@ -0,0 +1,74 @@
+/*
+ * AVR loader helpers
+ *
+ * Copyright (c) 2019 Philippe Mathieu-Daudé
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/loader.h"
+#include "elf.h"
+#include "boot.h"
+#include "qemu/error-report.h"
+
+bool avr_load_firmware(AVRCPU *cpu, MachineState *ms,
+   MemoryRegion *mr, const char *firmware)
+{
+const char *filename;
+int bytes_loaded;
+uint64_t entry;
+uint32_t e_flags;
+
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware);
+if (filename == NULL) {
+error_report("Unable to find %s", firmware);
+return false;
+}
+
+bytes_loaded = load_elf_ram_sym(filename,
+NULL, NULL, NULL,
+&entry, NULL, NULL,
+&e_flags, 0, EM_AVR, 0, 0,
+NULL, true, NULL);
+if (bytes_loaded >= 0) {
+/* If ELF file is provided, determine CPU type reading ELF e_flags. */
+const char *elf_cpu = avr_flags_to_cpu_type(e_flags, NULL);
+const char *mcu_cpu_type = object_get_typename(OBJECT(cpu));
+int cpu_len = strlen(mcu_cpu_type) - strlen(AVR_CPU_TYPE_SUFFIX);
+
+if (entry) {
+error_report("BIOS entry_point must be 0x "
+ "(ELF image '%s' has entry_point 0x%04" PRIx64 ")",
+ firmware, entry);
+return false;
+}
+if (!elf_cpu) {
+warn_report("Could not determine CPU type for ELF image '%s', "
+"assuming '%.*s' CPU",
+ firmware, cpu_len, mcu_cpu_type);
+return true;
+}
+if (strcmp(elf_cpu, mcu_cpu_type)) {
+error_report("Current machine: %s with '%.*s' CPU",
+ MACHINE_GET_CLASS(ms)->desc, cpu_len, mcu_cpu_type);
+error_report("ELF image '%s' is for '%.*s' CPU",
+ firmware,
+ (int)(strlen(elf_cpu) - strlen(AVR_CPU_TYPE_SUFFIX)),
+ elf_cpu);
+return false;
+}
+} else {
+bytes_loaded = load_image_targphys(filename, OFFSET_CODE,
+   memory_region_size(mr));
+}
+if (bytes_loaded < 0) {
+error_report("Unable to load firmware image %s as ELF or raw binary",
+ firmware);
+return false;
+}
+return true;
+}
diff --git a/hw/avr/boot.h b/hw/avr/boot.h
new file mode 100644
index 000..62bc10c
--- /dev/null
+++ b/hw/avr/boot.h
@@ -0,0 +1,33 @@
+/*
+ * AVR loader helpers
+ *
+ * Copyright (c) 2019 Philippe Mathieu-Daudé
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_AVR_BOOT_H
+#define HW_AVR_BOOT_H
+
+#include "hw/boards.h"
+#include "cpu.h"
+
+/**
+ * avr_load_firmware:   load an image into a memory region
+ *
+ * @cpu:Handle a AVR CPU object
+ * @ms: A MachineState
+ * @mr: Memory Region to load into
+ * @firmware:   Path to the firmware file (raw binary or ELF format)
+ *
+ * Load a firmware supplied by the machine or by the user  with the
+ * '-bios' command line option, and put it in target memory.
+ *
+ * Returns: true on success, false on error.
+ */
+bool avr_load_firmware(AVRCPU *cpu, MachineState *ms,
+   MemoryRegion *mr, const char *firmware);
+
+#endif
diff --git a/include/elf.h b/include/elf.h
index 8fbfe60..3f08f68 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -202,6 +202,8 @@ typedef 

Re: [PATCH rc4 20/29] target/avr: Register AVR support with the rest of QEMU

2020-01-30 Thread Aleksandar Markovic
On Fri, Jan 31, 2020 at 1:23 AM Philippe Mathieu-Daudé
 wrote:
>
> On 1/31/20 1:03 AM, Aleksandar Markovic wrote:
> > From: Michael Rolnik 
> >
> > Add AVR related definitions into QEMU.
> >
> > [AM: Remove word 'Atmel' from filenames and all elements of code]
> > Suggested-by: Aleksandar Markovic 
> >
> > Signed-off-by: Michael Rolnik 
> > Tested-by: Philippe Mathieu-Daudé 
> > Reviewed-by: Aleksandar Markovic 
> > Signed-off-by: Richard Henderson 
> > Signed-off-by: Aleksandar Markovic 
> > ---
> >   arch_init.c|  2 ++
> >   include/disas/dis-asm.h| 19 +++
> >   include/sysemu/arch_init.h |  1 +
> >   qapi/machine.json  |  3 ++-
> >   4 files changed, 24 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch_init.c b/arch_init.c
> > index 705d0b9..6a74116 100644
> > --- a/arch_init.c
> > +++ b/arch_init.c
> > @@ -89,6 +89,8 @@ int graphic_depth = 32;
> >   #define QEMU_ARCH QEMU_ARCH_UNICORE32
> >   #elif defined(TARGET_XTENSA)
> >   #define QEMU_ARCH QEMU_ARCH_XTENSA
> > +#elif defined(TARGET_AVR)
> > +#define QEMU_ARCH QEMU_ARCH_AVR
> >   #endif
> >
> >   const uint32_t arch_type = QEMU_ARCH;
> > diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
> > index f87f468..a36e658 100644
> > --- a/include/disas/dis-asm.h
> > +++ b/include/disas/dis-asm.h
> > @@ -211,6 +211,25 @@ enum bfd_architecture
> >   #define bfd_mach_m32r  0  /* backwards compatibility */
> > bfd_arch_mn10200,/* Matsushita MN10200 */
> > bfd_arch_mn10300,/* Matsushita MN10300 */
> > +  bfd_arch_avr,/* AVR microcontrollers */
> > +#define bfd_mach_avr1   1
> > +#define bfd_mach_avr2   2
> > +#define bfd_mach_avr25  25
> > +#define bfd_mach_avr3   3
> > +#define bfd_mach_avr31  31
> > +#define bfd_mach_avr35  35
> > +#define bfd_mach_avr4   4
> > +#define bfd_mach_avr5   5
> > +#define bfd_mach_avr51  51
> > +#define bfd_mach_avr6   6
> > +#define bfd_mach_avrtiny100
> > +#define bfd_mach_avrxmega1  101
> > +#define bfd_mach_avrxmega2  102
> > +#define bfd_mach_avrxmega3  103
> > +#define bfd_mach_avrxmega4  104
> > +#define bfd_mach_avrxmega5  105
> > +#define bfd_mach_avrxmega6  106
> > +#define bfd_mach_avrxmega7  107
>
> I think the changes in include/disas/dis-asm.h should go in patch #6
> "target/avr: Add defintions of AVR core types" where the definitions are
> used:
>
>const char *avr_flags_to_cpu_type(uint32_t flags, const char
> *def_cpu_type)
>{
>switch (flags & EF_AVR_MACH) {
>case bfd_mach_avr1:
>return AVR_CPU_TYPE_NAME("avr1");
>

I agree.

> > bfd_arch_cris,   /* Axis CRIS */
> >   #define bfd_mach_cris_v0_v10   255
> >   #define bfd_mach_cris_v32  32
> > diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
> > index 62c6fe4..893df26 100644
> > --- a/include/sysemu/arch_init.h
> > +++ b/include/sysemu/arch_init.h
> > @@ -24,6 +24,7 @@ enum {
> >   QEMU_ARCH_NIOS2 = (1 << 17),
> >   QEMU_ARCH_HPPA = (1 << 18),
> >   QEMU_ARCH_RISCV = (1 << 19),
> > +QEMU_ARCH_AVR = (1 << 20),
> >   };
> >
> >   extern const uint32_t arch_type;
> > diff --git a/qapi/machine.json b/qapi/machine.json
> > index b3d30bc..f2dc385 100644
> > --- a/qapi/machine.json
> > +++ b/qapi/machine.json
> > @@ -21,11 +21,12 @@
> >   #is true even for "qemu-system-x86_64".
> >   #
> >   # ppcemb: dropped in 3.1
> > +# avr: since 5.0
> >   #
> >   # Since: 3.0
> >   ##
> >   { 'enum' : 'SysEmuTarget',
> > -  'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32',
> > +  'data' : [ 'aarch64', 'alpha', 'arm', 'avr', 'cris', 'hppa', 'i386', 
> > 'lm32',
> >'m68k', 'microblaze', 'microblazeel', 'mips', 'mips64',
> >'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc',
> >'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4',
> >
>



Re: [PATCH rc4 23/29] hw/avr: Add helper to load raw/ELF firmware binaries

2020-01-30 Thread Aleksandar Markovic
On Fri, Jan 31, 2020 at 1:20 AM Philippe Mathieu-Daudé
 wrote:
>
> On 1/31/20 1:03 AM, Aleksandar Markovic wrote:
> > From: Philippe Mathieu-Daudé 
> >
> > Add avr_load_firmware() function to load firmware in ELF or
> > raw binary format.
> >
> > [AM: Corrected the type of the variable containing e_flags]
> >
> > Suggested-by: Aleksandar Markovic 
> > Signed-off-by: Philippe Mathieu-Daudé 
> > Signed-off-by: Aleksandar Markovic 
> > ---
> >   hw/avr/Makefile.objs |  1 +
> >   hw/avr/boot.c| 74 
> > 
> >   hw/avr/boot.h| 33 +++
> >   include/elf.h|  2 ++
> >   4 files changed, 110 insertions(+)
> >   create mode 100644 hw/avr/Makefile.objs
> >   create mode 100644 hw/avr/boot.c
> >   create mode 100644 hw/avr/boot.h
> >
> > diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
> > new file mode 100644
> > index 000..123f174
> > --- /dev/null
> > +++ b/hw/avr/Makefile.objs
> > @@ -0,0 +1 @@
> > +obj-y += boot.o
> > diff --git a/hw/avr/boot.c b/hw/avr/boot.c
> > new file mode 100644
> > index 000..9ac2c88
> > --- /dev/null
> > +++ b/hw/avr/boot.c
> > @@ -0,0 +1,74 @@
> > +/*
> > + * AVR loader helpers
> > + *
> > + * Copyright (c) 2019 Philippe Mathieu-Daudé
> > + *
> > + * This work is licensed under the terms of the GNU GPLv2 or later.
> > + * See the COPYING file in the top-level directory.
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu-common.h"
> > +#include "hw/loader.h"
> > +#include "elf.h"
> > +#include "boot.h"
> > +#include "qemu/error-report.h"
> > +
> > +bool avr_load_firmware(AVRCPU *cpu, MachineState *ms,
> > +   MemoryRegion *mr, const char *firmware)
> > +{
> > +const char *filename;
> > +int bytes_loaded;
> > +uint64_t entry;
> > +uint32_t e_flags;
> > +
> > +filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware);
> > +if (filename == NULL) {
> > +error_report("Unable to find %s", firmware);
> > +return false;
> > +}
> > +
> > +bytes_loaded = load_elf_ram_sym(filename,
> > +NULL, NULL, NULL,
> > +&entry, NULL, NULL,
> > +&e_flags, 0, EM_AVR, 0, 0,
> > +NULL, true, NULL);
> > +if (bytes_loaded >= 0) {
> > +/* If ELF file is provided, determine CPU type reading ELF 
> > e_flags. */
> > +const char *elf_cpu = avr_flags_to_cpu_type(e_flags, NULL);
> > +const char *mcu_cpu_type = object_get_typename(OBJECT(cpu));
> > +int cpu_len = strlen(mcu_cpu_type) - strlen(AVR_CPU_TYPE_SUFFIX);
> > +
> > +if (entry) {
> > +error_report("BIOS entry_point must be 0x "
> > + "(ELF image '%s' has entry_point 0x%04" PRIx64 
> > ")",
> > + firmware, entry);
> > +return false;
> > +}
> > +if (!elf_cpu) {
> > +warn_report("Could not determine CPU type for ELF image '%s', "
> > +"assuming '%.*s' CPU",
> > + firmware, cpu_len, mcu_cpu_type);
> > +return true;
> > +}
> > +if (strcmp(elf_cpu, mcu_cpu_type)) {
> > +error_report("Current machine: %s with '%.*s' CPU",
> > + MACHINE_GET_CLASS(ms)->desc, cpu_len, 
> > mcu_cpu_type);
> > +error_report("ELF image '%s' is for '%.*s' CPU",
> > + firmware,
> > + (int)(strlen(elf_cpu) - 
> > strlen(AVR_CPU_TYPE_SUFFIX)),
> > + elf_cpu);
> > +return false;
> > +}
> > +} else {
> > +bytes_loaded = load_image_targphys(filename, OFFSET_CODE,
> > +   memory_region_size(mr));
> > +}
> > +if (bytes_loaded < 0) {
> > +error_report("Unable to load firmware image %s as ELF or raw 
> > binary",
> > + firmware);
> > +return false;
> > +}
> > +return true;
> > +}
> > diff --git a/hw/avr/boot.h b/hw/avr/boot.h
> > new file mode 100644
> > index 000..62bc10c
> > --- /dev/null
> > +++ b/hw/avr/boot.h
> > @@ -0,0 +1,33 @@
> > +/*
> > + * AVR loader helpers
> > + *
> > + * Copyright (c) 2019 Philippe Mathieu-Daudé
> > + *
> > + * This work is licensed under the terms of the GNU GPLv2 or later.
> > + * See the COPYING file in the top-level directory.
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + */
> > +
> > +#ifndef HW_AVR_BOOT_H
> > +#define HW_AVR_BOOT_H
> > +
> > +#include "hw/boards.h"
> > +#include "cpu.h"
> > +
> > +/**
> > + * avr_load_firmware:   load an image into a memory region
> > + *
> > + * @cpu:Handle a AVR CPU object
> > + * @ms: A MachineState
> > + * @mr: Memory Region to load into
> > + * @firmware:   P

Re: [PATCH rc4 20/29] target/avr: Register AVR support with the rest of QEMU

2020-01-30 Thread Philippe Mathieu-Daudé

On 1/31/20 1:03 AM, Aleksandar Markovic wrote:

From: Michael Rolnik 

Add AVR related definitions into QEMU.

[AM: Remove word 'Atmel' from filenames and all elements of code]
Suggested-by: Aleksandar Markovic 

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
  arch_init.c|  2 ++
  include/disas/dis-asm.h| 19 +++
  include/sysemu/arch_init.h |  1 +
  qapi/machine.json  |  3 ++-
  4 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/arch_init.c b/arch_init.c
index 705d0b9..6a74116 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -89,6 +89,8 @@ int graphic_depth = 32;
  #define QEMU_ARCH QEMU_ARCH_UNICORE32
  #elif defined(TARGET_XTENSA)
  #define QEMU_ARCH QEMU_ARCH_XTENSA
+#elif defined(TARGET_AVR)
+#define QEMU_ARCH QEMU_ARCH_AVR
  #endif
  
  const uint32_t arch_type = QEMU_ARCH;

diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index f87f468..a36e658 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -211,6 +211,25 @@ enum bfd_architecture
  #define bfd_mach_m32r  0  /* backwards compatibility */
bfd_arch_mn10200,/* Matsushita MN10200 */
bfd_arch_mn10300,/* Matsushita MN10300 */
+  bfd_arch_avr,/* AVR microcontrollers */
+#define bfd_mach_avr1   1
+#define bfd_mach_avr2   2
+#define bfd_mach_avr25  25
+#define bfd_mach_avr3   3
+#define bfd_mach_avr31  31
+#define bfd_mach_avr35  35
+#define bfd_mach_avr4   4
+#define bfd_mach_avr5   5
+#define bfd_mach_avr51  51
+#define bfd_mach_avr6   6
+#define bfd_mach_avrtiny100
+#define bfd_mach_avrxmega1  101
+#define bfd_mach_avrxmega2  102
+#define bfd_mach_avrxmega3  103
+#define bfd_mach_avrxmega4  104
+#define bfd_mach_avrxmega5  105
+#define bfd_mach_avrxmega6  106
+#define bfd_mach_avrxmega7  107


I think the changes in include/disas/dis-asm.h should go in patch #6 
"target/avr: Add defintions of AVR core types" where the definitions are 
used:


  const char *avr_flags_to_cpu_type(uint32_t flags, const char 
*def_cpu_type)

  {
  switch (flags & EF_AVR_MACH) {
  case bfd_mach_avr1:
  return AVR_CPU_TYPE_NAME("avr1");


bfd_arch_cris,   /* Axis CRIS */
  #define bfd_mach_cris_v0_v10   255
  #define bfd_mach_cris_v32  32
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 62c6fe4..893df26 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -24,6 +24,7 @@ enum {
  QEMU_ARCH_NIOS2 = (1 << 17),
  QEMU_ARCH_HPPA = (1 << 18),
  QEMU_ARCH_RISCV = (1 << 19),
+QEMU_ARCH_AVR = (1 << 20),
  };
  
  extern const uint32_t arch_type;

diff --git a/qapi/machine.json b/qapi/machine.json
index b3d30bc..f2dc385 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -21,11 +21,12 @@
  #is true even for "qemu-system-x86_64".
  #
  # ppcemb: dropped in 3.1
+# avr: since 5.0
  #
  # Since: 3.0
  ##
  { 'enum' : 'SysEmuTarget',
-  'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32',
+  'data' : [ 'aarch64', 'alpha', 'arm', 'avr', 'cris', 'hppa', 'i386', 'lm32',
   'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64',
   'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc',
   'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4',






Re: [PATCH v2 15/29] tests: rename virtio_seg_max_adjust to virtio_check_params

2020-01-30 Thread Philippe Mathieu-Daudé

On 1/29/20 10:23 PM, Philippe Mathieu-Daudé wrote:

From: Denis Plotnikov 

Since, virtio_seg_max_adjust checks not only seg_max, but also
virtqueue_size parameter, let's make the test more general and
add new parameters to be checked there in the future.

Signed-off-by: Denis Plotnikov 
Message-Id: <20200129140702.5411-5-dplotni...@virtuozzo.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
  .../{virtio_seg_max_adjust.py => virtio_check_params.py}  | 0
  1 file changed, 0 insertions(+), 0 deletions(-)
  rename tests/acceptance/{virtio_seg_max_adjust.py => virtio_check_params.py} 
(100%)

diff --git a/tests/acceptance/virtio_seg_max_adjust.py 
b/tests/acceptance/virtio_check_params.py
similarity index 100%
rename from tests/acceptance/virtio_seg_max_adjust.py
rename to tests/acceptance/virtio_check_params.py



Thanks, applied to my python-next tree:
https://gitlab.com/philmd/qemu/commits/python-next




[PATCH rc4 17/29] hw/timer: Add limited support for AVR 16-bit timer peripheral

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

These were designed to facilitate testing but should provide enough
function to be useful in other contexts.  Only a subset of the functions
of each peripheral is implemented, mainly due to the lack of a standard
way to handle electrical connections (like GPIO pins).

[AM: Remove word 'Atmel' from filenames and all elements of code]
Suggested-by: Aleksandar Markovic 

Signed-off-by: Sarah Harris 
Signed-off-by: Ed Robbins 
Signed-off-by: Philippe Mathieu-Daudé 
[rth: Squash info mtree fixes and a file rename from f4bug]
Signed-off-by: Richard Henderson 
[PMD: Use qemu_log_mask(LOG_UNIMP), replace goto by return]
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Alex Bennée 
Signed-off-by: Aleksandar Markovic 
---
 hw/timer/Kconfig   |   3 +
 hw/timer/Makefile.objs |   2 +
 hw/timer/avr_timer16.c | 604 +
 include/hw/timer/avr_timer16.h |  94 +++
 4 files changed, 703 insertions(+)
 create mode 100644 hw/timer/avr_timer16.c
 create mode 100644 include/hw/timer/avr_timer16.h

diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig
index 59b3f44..2521056 100644
--- a/hw/timer/Kconfig
+++ b/hw/timer/Kconfig
@@ -35,3 +35,6 @@ config CMSDK_APB_TIMER
 config CMSDK_APB_DUALTIMER
 bool
 select PTIMER
+
+config AVR_TIMER16
+bool
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index dece235..af0913c 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -35,3 +35,5 @@ common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
 common-obj-$(CONFIG_CMSDK_APB_DUALTIMER) += cmsdk-apb-dualtimer.o
 common-obj-$(CONFIG_MSF2) += mss-timer.o
 common-obj-$(CONFIG_RASPI) += bcm2835_systmr.o
+
+obj-$(CONFIG_AVR_TIMER16) += avr_timer16.o
diff --git a/hw/timer/avr_timer16.c b/hw/timer/avr_timer16.c
new file mode 100644
index 000..4e16afc
--- /dev/null
+++ b/hw/timer/avr_timer16.c
@@ -0,0 +1,604 @@
+/*
+ * AVR 16-bit timer
+ *
+ * Copyright (c) 2018 University of Kent
+ * Author: Ed Robbins
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+/*
+ * Driver for 16 bit timers on 8 bit AVR devices.
+ * Note:
+ * ATmega640/V-1280/V-1281/V-2560/V-2561/V timers 1, 3, 4 and 5 are 16 bit
+ */
+
+/*
+ * XXX TODO: Power Reduction Register support
+ *   prescaler pause support
+ *   PWM modes, GPIO, output capture pins, input compare pin
+ */
+
+#include "qemu/osdep.h"
+#include "hw/timer/avr_timer16.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+
+/* Register offsets */
+#define T16_CRA 0x0
+#define T16_CRB 0x1
+#define T16_CRC 0x2
+#define T16_CNTL0x4
+#define T16_CNTH0x5
+#define T16_ICRL0x6
+#define T16_ICRH0x7
+#define T16_OCRAL   0x8
+#define T16_OCRAH   0x9
+#define T16_OCRBL   0xa
+#define T16_OCRBH   0xb
+#define T16_OCRCL   0xc
+#define T16_OCRCH   0xd
+
+/* Field masks */
+#define T16_CRA_WGM01   0x3
+#define T16_CRA_COMC0xc
+#define T16_CRA_COMB0x30
+#define T16_CRA_COMA0xc0
+#define T16_CRA_OC_CONF \
+(T16_CRA_COMA | T16_CRA_COMB | T16_CRA_COMC)
+
+#define T16_CRB_CS  0x7
+#define T16_CRB_WGM23   0x18
+#define T16_CRB_ICES0x40
+#define T16_CRB_ICNC0x80
+
+#define T16_CRC_FOCC0x20
+#define T16_CRC_FOCB0x40
+#define T16_CRC_FOCA0x80
+
+/* Fields masks both TIMSK and TIFR (interrupt mask/flag registers) */
+#define T16_INT_TOV0x1 /* Timer overflow */
+#define T16_INT_OCA0x2 /* Output compare A */
+#define T16_INT_OCB0x4 /* Output compare B */
+#define T16_INT_OCC0x8 /* Output compare C */
+#define T16_INT_IC 0x20 /* Input capture */
+
+/* Clock source values */
+#define T16_CLKSRC_STOPPED 0
+#define T16_CLKSRC_DIV11
+#define T16_CLKSRC_DIV82
+#define T16_CLKSRC_DIV64   3
+#define T16_CLKSRC_DIV256  4
+#define T16_CLKSRC_DIV1024 5
+#define T16_CLKSRC_EXT_FALLING 6
+#define T16_CLKSRC_EXT_RISING  7
+
+/* Timer mode values (not including PWM modes) */
+#define T16_MODE_NORMAL 0
+#define T16_MODE_CTC_OCRA   4
+#define T16_MODE_CTC_ICR12
+
+/* Accessors */
+#define CLKSRC(t16) (t16->crb & T16_CRB_CS)
+#define MODE(t16)   (((t16->crb & T16_CRB_WGM23) >> 1) | \
+ (t16->cra & T16_CRA_WGM01))
+#define CNT(t16)VAL16(t16->cntl, t16->cnth)
+#define OCRA(t16)   VAL16(t16->ocral

Re: [PATCH rc4 23/29] hw/avr: Add helper to load raw/ELF firmware binaries

2020-01-30 Thread Philippe Mathieu-Daudé

On 1/31/20 1:03 AM, Aleksandar Markovic wrote:

From: Philippe Mathieu-Daudé 

Add avr_load_firmware() function to load firmware in ELF or
raw binary format.

[AM: Corrected the type of the variable containing e_flags]

Suggested-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Aleksandar Markovic 
---
  hw/avr/Makefile.objs |  1 +
  hw/avr/boot.c| 74 
  hw/avr/boot.h| 33 +++
  include/elf.h|  2 ++
  4 files changed, 110 insertions(+)
  create mode 100644 hw/avr/Makefile.objs
  create mode 100644 hw/avr/boot.c
  create mode 100644 hw/avr/boot.h

diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
new file mode 100644
index 000..123f174
--- /dev/null
+++ b/hw/avr/Makefile.objs
@@ -0,0 +1 @@
+obj-y += boot.o
diff --git a/hw/avr/boot.c b/hw/avr/boot.c
new file mode 100644
index 000..9ac2c88
--- /dev/null
+++ b/hw/avr/boot.c
@@ -0,0 +1,74 @@
+/*
+ * AVR loader helpers
+ *
+ * Copyright (c) 2019 Philippe Mathieu-Daudé
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/loader.h"
+#include "elf.h"
+#include "boot.h"
+#include "qemu/error-report.h"
+
+bool avr_load_firmware(AVRCPU *cpu, MachineState *ms,
+   MemoryRegion *mr, const char *firmware)
+{
+const char *filename;
+int bytes_loaded;
+uint64_t entry;
+uint32_t e_flags;
+
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware);
+if (filename == NULL) {
+error_report("Unable to find %s", firmware);
+return false;
+}
+
+bytes_loaded = load_elf_ram_sym(filename,
+NULL, NULL, NULL,
+&entry, NULL, NULL,
+&e_flags, 0, EM_AVR, 0, 0,
+NULL, true, NULL);
+if (bytes_loaded >= 0) {
+/* If ELF file is provided, determine CPU type reading ELF e_flags. */
+const char *elf_cpu = avr_flags_to_cpu_type(e_flags, NULL);
+const char *mcu_cpu_type = object_get_typename(OBJECT(cpu));
+int cpu_len = strlen(mcu_cpu_type) - strlen(AVR_CPU_TYPE_SUFFIX);
+
+if (entry) {
+error_report("BIOS entry_point must be 0x "
+ "(ELF image '%s' has entry_point 0x%04" PRIx64 ")",
+ firmware, entry);
+return false;
+}
+if (!elf_cpu) {
+warn_report("Could not determine CPU type for ELF image '%s', "
+"assuming '%.*s' CPU",
+ firmware, cpu_len, mcu_cpu_type);
+return true;
+}
+if (strcmp(elf_cpu, mcu_cpu_type)) {
+error_report("Current machine: %s with '%.*s' CPU",
+ MACHINE_GET_CLASS(ms)->desc, cpu_len, mcu_cpu_type);
+error_report("ELF image '%s' is for '%.*s' CPU",
+ firmware,
+ (int)(strlen(elf_cpu) - strlen(AVR_CPU_TYPE_SUFFIX)),
+ elf_cpu);
+return false;
+}
+} else {
+bytes_loaded = load_image_targphys(filename, OFFSET_CODE,
+   memory_region_size(mr));
+}
+if (bytes_loaded < 0) {
+error_report("Unable to load firmware image %s as ELF or raw binary",
+ firmware);
+return false;
+}
+return true;
+}
diff --git a/hw/avr/boot.h b/hw/avr/boot.h
new file mode 100644
index 000..62bc10c
--- /dev/null
+++ b/hw/avr/boot.h
@@ -0,0 +1,33 @@
+/*
+ * AVR loader helpers
+ *
+ * Copyright (c) 2019 Philippe Mathieu-Daudé
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_AVR_BOOT_H
+#define HW_AVR_BOOT_H
+
+#include "hw/boards.h"
+#include "cpu.h"
+
+/**
+ * avr_load_firmware:   load an image into a memory region
+ *
+ * @cpu:Handle a AVR CPU object
+ * @ms: A MachineState
+ * @mr: Memory Region to load into
+ * @firmware:   Path to the firmware file (raw binary or ELF format)
+ *
+ * Load a firmware supplied by the machine or by the user  with the
+ * '-bios' command line option, and put it in target memory.
+ *
+ * Returns: true on success, false on error.
+ */
+bool avr_load_firmware(AVRCPU *cpu, MachineState *ms,
+   MemoryRegion *mr, const char *firmware);
+
+#endif
diff --git a/include/elf.h b/include/elf.h
index 8fbfe60..3f08f68 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -202,6 +202,8 @@ typedef struct mips_elf_abiflags_v0 {
  #define EM_MOXIE   223 /* Moxie processor family */
  #define EM_MOXIE_OLD

[PATCH rc4 24/29] hw/avr: Add some ATmega microcontrollers

2020-01-30 Thread Aleksandar Markovic
From: Philippe Mathieu-Daudé 

Add some AVR microcontrollers from the ATmega family:

  - middle range: ATmega168 and ATmega328
  - high range: ATmega1280 and ATmega2560

For product comparison:
  https://www.microchip.com/wwwproducts/ProductCompare/ATmega168P/ATmega328P
  https://www.microchip.com/wwwproducts/ProductCompare/ATmega1280/ATmega2560

Datasheets:
  
http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
  
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf

[AM: Remove word 'Atmel' from filenames and all elements of code]
Suggested-by: Aleksandar Markovic 

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 hw/avr/Kconfig   |   5 +
 hw/avr/Makefile.objs |   1 +
 hw/avr/atmega.c  | 470 +++
 hw/avr/atmega.h  |  48 ++
 4 files changed, 524 insertions(+)
 create mode 100644 hw/avr/Kconfig
 create mode 100644 hw/avr/atmega.c
 create mode 100644 hw/avr/atmega.h

diff --git a/hw/avr/Kconfig b/hw/avr/Kconfig
new file mode 100644
index 000..9e6527e
--- /dev/null
+++ b/hw/avr/Kconfig
@@ -0,0 +1,5 @@
+config AVR_ATMEGA_MCU
+bool
+select AVR_TIMER16
+select AVR_USART
+select AVR_POWER
diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
index 123f174..af0fdde 100644
--- a/hw/avr/Makefile.objs
+++ b/hw/avr/Makefile.objs
@@ -1 +1,2 @@
 obj-y += boot.o
+obj-$(CONFIG_AVR_ATMEGA_MCU) += atmega.o
diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
new file mode 100644
index 000..8cdf28b
--- /dev/null
+++ b/hw/avr/atmega.c
@@ -0,0 +1,470 @@
+/*
+ * QEMU ATmega MCU
+ *
+ * Copyright (c) 2019 Philippe Mathieu-Daudé
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "hw/boards.h" /* FIXME memory_region_allocate_system_memory for sram 
*/
+#include "hw/misc/unimp.h"
+#include "atmega.h"
+
+enum AtmegaPeripheral {
+POWER0, POWER1,
+GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF,
+GPIOG, GPIOH, GPIOI, GPIOJ, GPIOK, GPIOL,
+USART0, USART1, USART2, USART3,
+TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5,
+PERIFMAX
+};
+
+#define GPIO(n) (n + GPIOA)
+#define USART(n)(n + USART0)
+#define TIMER(n)(n + TIMER0)
+#define POWER(n)(n + POWER0)
+
+typedef struct {
+uint16_t addr;
+enum AtmegaPeripheral power_index;
+uint8_t power_bit;
+/* timer specific */
+uint16_t intmask_addr;
+uint16_t intflag_addr;
+bool is_timer16;
+} peripheral_cfg;
+
+typedef struct AtmegaMcuClass {
+/*< private >*/
+SysBusDeviceClass parent_class;
+/*< public >*/
+const char *uc_name;
+const char *cpu_type;
+size_t flash_size;
+size_t eeprom_size;
+size_t sram_size;
+size_t io_size;
+size_t gpio_count;
+size_t adc_count;
+const uint8_t *irq;
+const peripheral_cfg *dev;
+} AtmegaMcuClass;
+
+#define ATMEGA_MCU_CLASS(klass) \
+OBJECT_CLASS_CHECK(AtmegaMcuClass, (klass), TYPE_ATMEGA_MCU)
+#define ATMEGA_MCU_GET_CLASS(obj) \
+OBJECT_GET_CLASS(AtmegaMcuClass, (obj), TYPE_ATMEGA_MCU)
+
+static const peripheral_cfg dev168_328[PERIFMAX] = {
+[USART0]= {  0xc0, POWER0, 1 },
+[TIMER2]= {  0xb0, POWER0, 6, 0x70, 0x37, false },
+[TIMER1]= {  0x80, POWER0, 3, 0x6f, 0x36, true },
+[POWER0]= {  0x64 },
+[TIMER0]= {  0x44, POWER0, 5, 0x6e, 0x35, false },
+[GPIOD] = {  0x29 },
+[GPIOC] = {  0x26 },
+[GPIOB] = {  0x23 },
+}, dev1280_2560[PERIFMAX] = {
+[USART3]= { 0x130, POWER1, 2 },
+[TIMER5]= { 0x120, POWER1, 5, 0x73, 0x3a, true },
+[GPIOL] = { 0x109 },
+[GPIOK] = { 0x106 },
+[GPIOJ] = { 0x103 },
+[GPIOH] = { 0x100 },
+[USART2]= {  0xd0, POWER1, 1 },
+[USART1]= {  0xc8, POWER1, 0 },
+[USART0]= {  0xc0, POWER0, 1 },
+[TIMER2]= {  0xb0, POWER0, 6, 0x70, 0x37, false }, /* TODO async */
+[TIMER4]= {  0xa0, POWER1, 4, 0x72, 0x39, true },
+[TIMER3]= {  0x90, POWER1, 3, 0x71, 0x38, true },
+[TIMER1]= {  0x80, POWER0, 3, 0x6f, 0x36, true },
+[POWER1]= {  0x65 },
+[POWER0]= {  0x64 },
+[TIMER0]= {  0x44, POWER0, 5, 0x6e, 0x35, false },
+[GPIOG] = {  0x32 },
+[GPIOF] = {  0x2f },
+[GPIOE] = {  0x2c },
+[GPIOD] = {  0x29 },
+[GPIOC] = {  0x26 },
+[GPIOB] = {  0

Re: [PATCH v2 18/29] tests/acceptance/virtio_check_params: List machine being tested

2020-01-30 Thread Philippe Mathieu-Daudé

On 1/29/20 10:23 PM, Philippe Mathieu-Daudé wrote:

Add logging for easier debugging of failures:

   $ avocado --show=machine run tests/acceptance/virtio_check_params.py
(1/1) 
tests/acceptance/virtio_check_params.py:VirtioMaxSegSettingsCheck.test_machine_types:
   machine: {'name': 'pc-i440fx-2.12', 'seg_max_adjust': 'false', 'device': 
'virtio-scsi-pci'}
   machine: {'name': 'pc-i440fx-2.0', 'seg_max_adjust': 'false', 'device': 
'virtio-scsi-pci'}
   machine: {'name': 'pc-q35-4.2', 'seg_max_adjust': 'false', 'device': 
'virtio-scsi-pci'}
   machine: {'name': 'pc-i440fx-2.5', 'seg_max_adjust': 'false', 'device': 
'virtio-scsi-pci'}
   machine: {'name': 'pc-i440fx-4.2', 'seg_max_adjust': 'false', 'device': 
'virtio-scsi-pci'}
   ...

Signed-off-by: Philippe Mathieu-Daudé 
---
  tests/acceptance/virtio_check_params.py | 4 
  1 file changed, 4 insertions(+)

diff --git a/tests/acceptance/virtio_check_params.py 
b/tests/acceptance/virtio_check_params.py
index 51a2dd76e8..f679b0eec7 100755
--- a/tests/acceptance/virtio_check_params.py
+++ b/tests/acceptance/virtio_check_params.py
@@ -21,6 +21,7 @@
  import sys
  import os
  import re
+import logging
  
  sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))

  from qemu.machine import QEMUMachine
@@ -73,6 +74,9 @@ class VirtioMaxSegSettingsCheck(Test):
  return query_ok, props, error
  
  def check_mt(self, mt, dev_type_name):

+mt['device'] = dev_type_name # Only for the debug() call.
+logger = logging.getLogger('machine')
+logger.debug(mt)
  with QEMUMachine(self.qemu_bin) as vm:
  vm.set_machine(mt["name"])
  for s in VM_DEV_PARAMS[dev_type_name]:



Thanks, applied to my python-next tree:
https://gitlab.com/philmd/qemu/commits/python-next




[PATCH rc4 28/29] tests/acceptance: Test the Arduino MEGA2560 board

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

The test is based on
https://github.com/seharris/qemu-avr-tests/tree/master/free-rtos/Demo
demo which. If working correctly, prints 'ABCDEFGHIJKLMNOPQRSTUVWX' out.
it also demostrates that timer and IRQ are working

As the path name demonstrates, the FreeRTOS tests target a
board based on a ATMega2560 MCU. We have one, the Arduino
MEGA2560.

Complementary documentation:

https://feilipu.me/2012/01/15/ethermega-arduino-mega-2560-and-freertos/
https://feilipu.me/2015/11/24/arduino_freertos/ (see 'Compatibility')

Signed-off-by: Michael Rolnik 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Acked-by: Thomas Huth 
Signed-off-by: Philippe Mathieu-Daudé 
[rth: Squash multiple avocado fixups from f4bug]
Tested-by: Richard Henderson 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 tests/acceptance/machine_avr6.py | 50 
 1 file changed, 50 insertions(+)
 create mode 100644 tests/acceptance/machine_avr6.py

diff --git a/tests/acceptance/machine_avr6.py b/tests/acceptance/machine_avr6.py
new file mode 100644
index 000..b644d2a
--- /dev/null
+++ b/tests/acceptance/machine_avr6.py
@@ -0,0 +1,50 @@
+#
+# QEMU AVR
+#
+# Copyright (c) 2019 Michael Rolnik 
+#
+# 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 .
+#
+
+import time
+
+from avocado_qemu import Test
+
+class AVR6Machine(Test):
+timeout = 5
+
+def test_freertos(self):
+"""
+:avocado: tags=arch:avr
+:avocado: tags=machine:arduino-mega-2560-v3
+"""
+"""
+
https://github.com/seharris/qemu-avr-tests/raw/master/free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf
+constantly prints out 
'ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX'
+"""
+rom_url = ('https://github.com/seharris/qemu-avr-tests'
+   '/raw/36c3e67b8755dcf/free-rtos/Demo'
+   '/AVR_ATMega2560_GCC/demo.elf')
+rom_hash = '7eb521f511ca8f2622e0a3c5e8dd686efbb911d4'
+rom_path = self.fetch_asset(rom_url, asset_hash=rom_hash)
+
+self.vm.add_args('-bios', rom_path)
+self.vm.add_args('-nographic')
+self.vm.launch()
+
+time.sleep(2)
+self.vm.shutdown()
+
+self.assertIn('ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX',
+self.vm.get_log())
-- 
2.7.4




[PATCH rc4 25/29] hw/avr: Add some Arduino boards

2020-01-30 Thread Aleksandar Markovic
From: Philippe Mathieu-Daudé 

Arduino boards are build with AVR chipsets.
Add some of the popular boards:

- Arduino Duemilanove
- Arduino Uno
- Arduino Mega

For more information:
  https://www.arduino.cc/en/Main/Products
  https://store.arduino.cc/arduino-genuino/most-popular

[AM: Remove word 'Atmel' from filenames and all elements of code]
Suggested-by: Aleksandar Markovic 

Reviewed-by: Igor Mammedov 
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Reviewed-by: Joaquin de Andres 
Signed-off-by: Aleksandar Markovic 
---
 MAINTAINERS  |   7 +++
 hw/avr/Kconfig   |   4 ++
 hw/avr/Makefile.objs |   1 +
 hw/avr/arduino.c | 151 +++
 4 files changed, 163 insertions(+)
 create mode 100644 hw/avr/arduino.c

diff --git a/MAINTAINERS b/MAINTAINERS
index d0a114b..97c8ef7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -905,6 +905,13 @@ F: include/hw/timer/avr_timer16.h
 F: hw/misc/avr_power.c
 F: include/hw/misc/avr_power.h
 F: tests/acceptance/machine_avr6.py
+F: hw/avr/atmega.*
+
+Arduino
+M: Philippe Mathieu-Daudé 
+R: Sarah Harris 
+S: Maintained
+F: hw/avr/arduino.c
 
 CRIS Machines
 -
diff --git a/hw/avr/Kconfig b/hw/avr/Kconfig
index 9e6527e..d31298c 100644
--- a/hw/avr/Kconfig
+++ b/hw/avr/Kconfig
@@ -3,3 +3,7 @@ config AVR_ATMEGA_MCU
 select AVR_TIMER16
 select AVR_USART
 select AVR_POWER
+
+config ARDUINO
+select AVR_ATMEGA_MCU
+select UNIMP
diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
index af0fdde..4dca064 100644
--- a/hw/avr/Makefile.objs
+++ b/hw/avr/Makefile.objs
@@ -1,2 +1,3 @@
 obj-y += boot.o
 obj-$(CONFIG_AVR_ATMEGA_MCU) += atmega.o
+obj-$(CONFIG_ARDUINO) += arduino.o
diff --git a/hw/avr/arduino.c b/hw/avr/arduino.c
new file mode 100644
index 000..00d67c9
--- /dev/null
+++ b/hw/avr/arduino.c
@@ -0,0 +1,151 @@
+/*
+ * QEMU Arduino boards
+ *
+ * Copyright (c) 2019 Philippe Mathieu-Daudé
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/* TODO: Implement the use of EXTRAM */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "atmega.h"
+#include "boot.h"
+
+typedef struct ArduinoMachineState {
+/*< private >*/
+MachineState parent_obj;
+/*< public >*/
+AtmegaMcuState mcu;
+} ArduinoMachineState;
+
+typedef struct ArduinoMachineClass {
+/*< private >*/
+MachineClass parent_class;
+/*< public >*/
+const char *mcu_type;
+uint64_t xtal_hz;
+} ArduinoMachineClass;
+
+#define TYPE_ARDUINO_MACHINE \
+MACHINE_TYPE_NAME("arduino")
+#define ARDUINO_MACHINE(obj) \
+OBJECT_CHECK(ArduinoMachineState, (obj), TYPE_ARDUINO_MACHINE)
+#define ARDUINO_MACHINE_CLASS(klass) \
+OBJECT_CLASS_CHECK(ArduinoMachineClass, (klass), TYPE_ARDUINO_MACHINE)
+#define ARDUINO_MACHINE_GET_CLASS(obj) \
+OBJECT_GET_CLASS(ArduinoMachineClass, (obj), TYPE_ARDUINO_MACHINE)
+
+static void arduino_machine_init(MachineState *machine)
+{
+ArduinoMachineClass *amc = ARDUINO_MACHINE_GET_CLASS(machine);
+ArduinoMachineState *ams = ARDUINO_MACHINE(machine);
+
+sysbus_init_child_obj(OBJECT(machine), "mcu", &ams->mcu, sizeof(ams->mcu),
+  amc->mcu_type);
+object_property_set_uint(OBJECT(&ams->mcu), amc->xtal_hz,
+ "xtal-frequency-hz", &error_abort);
+object_property_set_bool(OBJECT(&ams->mcu), true, "realized",
+ &error_abort);
+
+if (machine->firmware) {
+if (!avr_load_firmware(&ams->mcu.cpu, machine,
+   &ams->mcu.flash, machine->firmware)) {
+exit(1);
+}
+}
+}
+
+static void arduino_machine_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+
+mc->init = arduino_machine_init;
+mc->default_cpus = 1;
+mc->min_cpus = mc->default_cpus;
+mc->max_cpus = mc->default_cpus;
+mc->no_floppy = 1;
+mc->no_cdrom = 1;
+mc->no_parallel = 1;
+}
+
+static void arduino_duemilanove_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
+
+/* https://www.arduino.cc/en/Main/ArduinoBoardDuemilanove */
+mc->desc= "Arduino Duemilanove (ATmega168)",
+mc->alias   = "2009";
+amc->mcu_type   = TYPE_ATMEGA168_MCU;
+amc->xtal_hz= 16 * 1000 * 1000;
+};
+
+static void arduino_uno_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
+
+/* https://store.arduino.cc/arduino-uno-rev3 */
+mc->desc= "Arduino UNO (ATmega328P)";
+mc->alias   = "uno";
+amc->mcu_type   = TYPE_ATMEGA328_MCU;
+amc->xtal_hz= 16 * 1000 * 1000;
+};
+
+static void arduino_m

[PATCH rc4 16/29] hw/char: Add limited support for AVR USART peripheral

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

These were designed to facilitate testing but should provide enough
function to be useful in other contexts.  Only a subset of the functions
of each peripheral is implemented, mainly due to the lack of a standard
way to handle electrical connections (like GPIO pins).

[AM: Remove word 'Atmel' from filenames and all elements of code]
Suggested-by: Aleksandar Markovic 

Signed-off-by: Sarah Harris 
Signed-off-by: Philippe Mathieu-Daudé 
[rth: Squash I/O size fix and file rename from f4bug]
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 hw/char/Kconfig |   3 +
 hw/char/Makefile.objs   |   1 +
 hw/char/avr_usart.c | 320 
 include/hw/char/avr_usart.h |  93 +
 4 files changed, 417 insertions(+)
 create mode 100644 hw/char/avr_usart.c
 create mode 100644 include/hw/char/avr_usart.h

diff --git a/hw/char/Kconfig b/hw/char/Kconfig
index 40e7a8b..331b209 100644
--- a/hw/char/Kconfig
+++ b/hw/char/Kconfig
@@ -46,3 +46,6 @@ config SCLPCONSOLE
 
 config TERMINAL3270
 bool
+
+config AVR_USART
+bool
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
index 02d8a66..f05c1f5 100644
--- a/hw/char/Makefile.objs
+++ b/hw/char/Makefile.objs
@@ -21,6 +21,7 @@ obj-$(CONFIG_PSERIES) += spapr_vty.o
 obj-$(CONFIG_DIGIC) += digic-uart.o
 obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
 obj-$(CONFIG_RASPI) += bcm2835_aux.o
+common-obj-$(CONFIG_AVR_USART) += avr_usart.o
 
 common-obj-$(CONFIG_CMSDK_APB_UART) += cmsdk-apb-uart.o
 common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
diff --git a/hw/char/avr_usart.c b/hw/char/avr_usart.c
new file mode 100644
index 000..fbe2a11
--- /dev/null
+++ b/hw/char/avr_usart.c
@@ -0,0 +1,320 @@
+/*
+ * AVR USART
+ *
+ * Copyright (c) 2018 University of Kent
+ * Author: Sarah Harris
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "hw/char/avr_usart.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+
+static int avr_usart_can_receive(void *opaque)
+{
+AVRUsartState *usart = opaque;
+
+if (usart->data_valid || !(usart->csrb & USART_CSRB_RXEN)) {
+return 0;
+}
+return 1;
+}
+
+static void avr_usart_receive(void *opaque, const uint8_t *buffer, int size)
+{
+AVRUsartState *usart = opaque;
+assert(size == 1);
+assert(!usart->data_valid);
+usart->data = buffer[0];
+usart->data_valid = true;
+usart->csra |= USART_CSRA_RXC;
+if (usart->csrb & USART_CSRB_RXCIE) {
+qemu_set_irq(usart->rxc_irq, 1);
+}
+}
+
+static void update_char_mask(AVRUsartState *usart)
+{
+uint8_t mode = ((usart->csrc & USART_CSRC_CSZ0) ? 1 : 0) |
+((usart->csrc & USART_CSRC_CSZ1) ? 2 : 0) |
+((usart->csrb & USART_CSRB_CSZ2) ? 4 : 0);
+switch (mode) {
+case 0:
+usart->char_mask = 0b1;
+break;
+case 1:
+usart->char_mask = 0b11;
+break;
+case 2:
+usart->char_mask = 0b111;
+break;
+case 3:
+usart->char_mask = 0b;
+break;
+case 4:
+/* Fallthrough. */
+case 5:
+/* Fallthrough. */
+case 6:
+qemu_log_mask(
+LOG_GUEST_ERROR,
+"%s: Reserved character size 0x%x\n",
+__func__,
+mode);
+break;
+case 7:
+qemu_log_mask(
+LOG_GUEST_ERROR,
+"%s: Nine bit character size not supported (forcing eight)\n",
+__func__);
+usart->char_mask = 0b;
+break;
+default:
+assert(0);
+}
+}
+
+static void avr_usart_reset(DeviceState *dev)
+{
+AVRUsartState *usart = AVR_USART(dev);
+usart->data_valid = false;
+usart->csra = 0b0010;
+usart->csrb = 0b;
+usart->csrc = 0b0110;
+usart->brrl = 0;
+usart->brrh = 0;
+update_char_mask(usart);
+qemu_set_irq(usart->rxc_irq, 0);
+qemu_set_irq(usart->txc_irq, 0);
+qemu_set_irq(usart->dre_irq, 0);
+}
+
+static uint64_t avr_usart_read(void *opaque, hwaddr addr, unsigned int size)
+{
+AVRUsartState *usart = opaque;
+uint8_t data;
+assert(size == 1);
+
+if (!usart->enabled) {
+return 0;
+}
+
+switch (addr) {
+case USART_DR:
+   

Re: [PATCH] migration/postcopy: not necessary to discard all RAM at the beginning

2020-01-30 Thread Wei Yang
Hi, David and Juan

Does it look good to you?

On Mon, Oct 07, 2019 at 05:10:08PM +0800, Wei Yang wrote:
>ram_discard_range() unmap page for specific range. To be specific, this
>clears related page table entries so that userfault would be triggered.
>But this step is not necessary at the very beginning.
>
>ram_postcopy_incoming_init() is called when destination gets ADVISE
>command. ADVISE command is sent when migration thread just starts, which
>implies destination is not running yet. This means no page fault
>happened and memory region's page tables entries are empty.
>
>This patch removes the discard at the beginning.
>
>Signed-off-by: Wei Yang 
>---
> migration/postcopy-ram.c | 46 
> migration/postcopy-ram.h |  7 --
> migration/ram.c  | 16 --
> migration/ram.h  |  1 -
> migration/savevm.c   |  4 
> 5 files changed, 74 deletions(-)
>
>diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
>index 5da6de8c8b..459be8e780 100644
>--- a/migration/postcopy-ram.c
>+++ b/migration/postcopy-ram.c
>@@ -443,32 +443,6 @@ out:
> return ret;
> }
> 
>-/*
>- * Setup an area of RAM so that it *can* be used for postcopy later; this
>- * must be done right at the start prior to pre-copy.
>- * opaque should be the MIS.
>- */
>-static int init_range(RAMBlock *rb, void *opaque)
>-{
>-const char *block_name = qemu_ram_get_idstr(rb);
>-void *host_addr = qemu_ram_get_host_addr(rb);
>-ram_addr_t offset = qemu_ram_get_offset(rb);
>-ram_addr_t length = qemu_ram_get_used_length(rb);
>-trace_postcopy_init_range(block_name, host_addr, offset, length);
>-
>-/*
>- * We need the whole of RAM to be truly empty for postcopy, so things
>- * like ROMs and any data tables built during init must be zero'd
>- * - we're going to get the copy from the source anyway.
>- * (Precopy will just overwrite this data, so doesn't need the discard)
>- */
>-if (ram_discard_range(block_name, 0, length)) {
>-return -1;
>-}
>-
>-return 0;
>-}
>-
> /*
>  * At the end of migration, undo the effects of init_range
>  * opaque should be the MIS.
>@@ -506,20 +480,6 @@ static int cleanup_range(RAMBlock *rb, void *opaque)
> return 0;
> }
> 
>-/*
>- * Initialise postcopy-ram, setting the RAM to a state where we can go into
>- * postcopy later; must be called prior to any precopy.
>- * called from arch_init's similarly named ram_postcopy_incoming_init
>- */
>-int postcopy_ram_incoming_init(MigrationIncomingState *mis)
>-{
>-if (foreach_not_ignored_block(init_range, NULL)) {
>-return -1;
>-}
>-
>-return 0;
>-}
>-
> /*
>  * Manage a single vote to the QEMU balloon inhibitor for all postcopy usage,
>  * last caller wins.
>@@ -1282,12 +1242,6 @@ bool 
>postcopy_ram_supported_by_host(MigrationIncomingState *mis)
> return false;
> }
> 
>-int postcopy_ram_incoming_init(MigrationIncomingState *mis)
>-{
>-error_report("postcopy_ram_incoming_init: No OS support");
>-return -1;
>-}
>-
> int postcopy_ram_incoming_cleanup(MigrationIncomingState *mis)
> {
> assert(0);
>diff --git a/migration/postcopy-ram.h b/migration/postcopy-ram.h
>index c0ccf64a96..1c79c6e51f 100644
>--- a/migration/postcopy-ram.h
>+++ b/migration/postcopy-ram.h
>@@ -22,13 +22,6 @@ bool postcopy_ram_supported_by_host(MigrationIncomingState 
>*mis);
>  */
> int postcopy_ram_incoming_setup(MigrationIncomingState *mis);
> 
>-/*
>- * Initialise postcopy-ram, setting the RAM to a state where we can go into
>- * postcopy later; must be called prior to any precopy.
>- * called from ram.c's similarly named ram_postcopy_incoming_init
>- */
>-int postcopy_ram_incoming_init(MigrationIncomingState *mis);
>-
> /*
>  * At the end of a migration where postcopy_ram_incoming_init was called.
>  */
>diff --git a/migration/ram.c b/migration/ram.c
>index dfc50d57d5..9a853703d8 100644
>--- a/migration/ram.c
>+++ b/migration/ram.c
>@@ -4015,22 +4015,6 @@ static int ram_load_cleanup(void *opaque)
> return 0;
> }
> 
>-/**
>- * ram_postcopy_incoming_init: allocate postcopy data structures
>- *
>- * Returns 0 for success and negative if there was one error
>- *
>- * @mis: current migration incoming state
>- *
>- * Allocate data structures etc needed by incoming migration with
>- * postcopy-ram. postcopy-ram's similarly names
>- * postcopy_ram_incoming_init does the work.
>- */
>-int ram_postcopy_incoming_init(MigrationIncomingState *mis)
>-{
>-return postcopy_ram_incoming_init(mis);
>-}
>-
> /**
>  * ram_load_postcopy: load a page in postcopy case
>  *
>diff --git a/migration/ram.h b/migration/ram.h
>index 44fe4753ad..66cbff1d52 100644
>--- a/migration/ram.h
>+++ b/migration/ram.h
>@@ -58,7 +58,6 @@ void ram_postcopy_migrated_memory_release(MigrationState 
>*ms);
> int ram_postcopy_send_discard_bitmap(MigrationState *ms);
> /* For incoming postcopy discard */
> int ram_discard_range(const char *block_name, uint64_t start, size_t length

[PATCH rc4 19/29] target/avr: Add section about AVR into QEMU documentation

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

Explains basic ways of using AVR target in QEMU.

Signed-off-by: Michael Rolnik 
Message-Id: <20200118191416.19934-16-mrol...@gmail.com>
Signed-off-by: Richard Henderson 
[PMD: Fixed typos]
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Aleksandar Markovic 
---
 qemu-doc.texi | 51 +++
 1 file changed, 51 insertions(+)

diff --git a/qemu-doc.texi b/qemu-doc.texi
index 2328e7e..aaf4e54 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -1723,6 +1723,7 @@ differences are mentioned in the following sections.
 * Microblaze System emulator::
 * SH4 System emulator::
 * Xtensa System emulator::
+* AVR System emulator::
 @end menu
 
 @node PowerPC System emulator
@@ -2496,6 +2497,56 @@ so should only be used with trusted guest OS.
 
 @c man end
 
+@node AVR System emulator
+@section AVR System emulator
+@cindex system emulation (AVR)
+
+Use the executable @file{qemu-system-avr} to emulates a AVR 8 bit based machine
+having one for the following cores: avr1, avr2, avr25, avr3, avr31, avr35, 
avr4,
+avr5, avr51, avr6, avrtiny, xmega2, xmega3, xmega4, xmega5, xmega6 and xmega7.
+
+As for now it supports few Arduino boards for educational and testing purposes.
+These boards use a ATmega controller, which model is limited to USART & 16 bit
+timer devices, enought to run FreeRTOS based applications (like this 
@url{https://github.com/seharris/qemu-avr-tests/blob/master/free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf,,demo})
+
+Following are examples of possible usages, assuming demo.elf is compiled for
+AVR cpu
+@itemize
+
+@item Continuous non interrupted execution
+@example
+qemu-system-avr -machine mega2560 -bios demo.elf
+@end example
+
+@item Continuous non interrupted execution with serial output into telnet 
window
+@example
+qemu-system-avr -machine mega2560 -bios demo.elf -serial 
tcp::5678,server,nowait -nographic
+@end example
+and then in another shell
+@example
+telnet localhost 5678
+@end example
+
+@item Debugging wit GDB debugger
+@example
+qemu-system-avr -machine mega2560 -bios demo.elf -s -S
+@end example
+and then in another shell
+@example
+avr-gdb demo.elf
+@end example
+and then within GDB shell
+@example
+target remote :1234
+@end example
+
+@item Print out executed instructions
+@example
+qemu-system-avr -machine mega2560 -bios demo.elf -d in_asm
+@end example
+
+@end itemize
+
 @node QEMU User space emulator
 @chapter QEMU User space emulator
 
-- 
2.7.4




[PATCH rc4 29/29] .travis.yml: Run the AVR acceptance tests

2020-01-30 Thread Aleksandar Markovic
From: Philippe Mathieu-Daudé 

We have one test so far, and it is very fast:

  $ avocado --show=app run -t arch:avr tests/acceptance/
  (1/1) tests/acceptance/machine_avr6.py:AVR6Machine.test_freertos: PASS (2.13 
s)
  RESULTS: PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | 
CANCEL 0
  JOB TIME   : 2.30 s

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 .travis.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index 1ae645e..71390e2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -268,7 +268,7 @@ matrix:
 
 # Acceptance (Functional) tests
 - env:
-- CONFIG="--python=/usr/bin/python3 
--target-list=x86_64-softmmu,mips-softmmu,mips64el-softmmu,aarch64-softmmu,arm-softmmu,s390x-softmmu,alpha-softmmu,ppc-softmmu,ppc64-softmmu,m68k-softmmu,sparc-softmmu"
+- CONFIG="--python=/usr/bin/python3 
--target-list=x86_64-softmmu,mips-softmmu,mips64el-softmmu,aarch64-softmmu,arm-softmmu,s390x-softmmu,alpha-softmmu,ppc-softmmu,ppc64-softmmu,m68k-softmmu,sparc-softmmu,avr-softmmu"
 - TEST_CMD="make check-acceptance"
   after_script:
 - python3 -c 'import json; r = 
json.load(open("tests/results/latest/results.json")); [print(t["logfile"]) for 
t in r["tests"] if t["status"] not in ("PASS", "SKIP")]' | xargs cat
-- 
2.7.4




[PATCH rc4 27/29] tests/boot-serial-test: Test some Arduino boards (AVR based)

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

Print out 'T' through serial port

The Arduino Duemilanove is based on a AVR5 CPU, while the
Arduino MEGA2560 on a AVR6 CPU.

Signed-off-by: Michael Rolnik 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Acked-by: Thomas Huth 
Signed-off-by: Philippe Mathieu-Daudé 
[rth: Squash Arduino adjustments from f4bug]
Tested-by: Richard Henderson 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 tests/qtest/Makefile.include   |  2 ++
 tests/qtest/boot-serial-test.c | 11 +++
 2 files changed, 13 insertions(+)

diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include
index e6bb4ab..4817b63 100644
--- a/tests/qtest/Makefile.include
+++ b/tests/qtest/Makefile.include
@@ -65,6 +65,8 @@ check-qtest-i386-y += numa-test
 
 check-qtest-x86_64-y += $(check-qtest-i386-y)
 
+check-qtest-avr-y += boot-serial-test
+
 check-qtest-alpha-y += boot-serial-test
 check-qtest-alpha-$(CONFIG_VGA) += display-vga-test
 
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
index 8e8c5b0..55a37a4 100644
--- a/tests/qtest/boot-serial-test.c
+++ b/tests/qtest/boot-serial-test.c
@@ -16,6 +16,15 @@
 #include "qemu/osdep.h"
 #include "libqtest.h"
 
+static const uint8_t bios_avr[] = {
+0x88, 0xe0, /* ldi r24, 0x08   */
+0x80, 0x93, 0xc1, 0x00, /* sts 0x00C1, r24 ; Enable tx */
+0x86, 0xe0, /* ldi r24, 0x06   */
+0x80, 0x93, 0xc2, 0x00, /* sts 0x00C2, r24 ; Set the data bits to 8 */
+0x84, 0xe5, /* ldi r24, 0x54   */
+0x80, 0x93, 0xc6, 0x00, /* sts 0x00C6, r24 ; Output 'T' */
+};
+
 static const uint8_t kernel_mcf5208[] = {
 0x41, 0xf9, 0xfc, 0x06, 0x00, 0x00, /* lea 0xfc06,%a0 */
 0x10, 0x3c, 0x00, 0x54, /* move.b #'T',%d0 */
@@ -103,6 +112,8 @@ typedef struct testdef {
 
 static testdef_t tests[] = {
 { "alpha", "clipper", "", "PCI:" },
+{ "avr", "arduino-duemilanove", "", "T", sizeof(bios_avr), NULL, bios_avr 
},
+{ "avr", "arduino-mega-2560-v3", "", "T", sizeof(bios_avr), NULL, 
bios_avr},
 { "ppc", "ppce500", "", "U-Boot" },
 { "ppc", "40p", "-vga none -boot d", "Trying cd:," },
 { "ppc", "g3beige", "", "PowerPC,750" },
-- 
2.7.4




[PATCH rc4 20/29] target/avr: Register AVR support with the rest of QEMU

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

Add AVR related definitions into QEMU.

[AM: Remove word 'Atmel' from filenames and all elements of code]
Suggested-by: Aleksandar Markovic 

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 arch_init.c|  2 ++
 include/disas/dis-asm.h| 19 +++
 include/sysemu/arch_init.h |  1 +
 qapi/machine.json  |  3 ++-
 4 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/arch_init.c b/arch_init.c
index 705d0b9..6a74116 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -89,6 +89,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_UNICORE32
 #elif defined(TARGET_XTENSA)
 #define QEMU_ARCH QEMU_ARCH_XTENSA
+#elif defined(TARGET_AVR)
+#define QEMU_ARCH QEMU_ARCH_AVR
 #endif
 
 const uint32_t arch_type = QEMU_ARCH;
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index f87f468..a36e658 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -211,6 +211,25 @@ enum bfd_architecture
 #define bfd_mach_m32r  0  /* backwards compatibility */
   bfd_arch_mn10200,/* Matsushita MN10200 */
   bfd_arch_mn10300,/* Matsushita MN10300 */
+  bfd_arch_avr,/* AVR microcontrollers */
+#define bfd_mach_avr1   1
+#define bfd_mach_avr2   2
+#define bfd_mach_avr25  25
+#define bfd_mach_avr3   3
+#define bfd_mach_avr31  31
+#define bfd_mach_avr35  35
+#define bfd_mach_avr4   4
+#define bfd_mach_avr5   5
+#define bfd_mach_avr51  51
+#define bfd_mach_avr6   6
+#define bfd_mach_avrtiny100
+#define bfd_mach_avrxmega1  101
+#define bfd_mach_avrxmega2  102
+#define bfd_mach_avrxmega3  103
+#define bfd_mach_avrxmega4  104
+#define bfd_mach_avrxmega5  105
+#define bfd_mach_avrxmega6  106
+#define bfd_mach_avrxmega7  107
   bfd_arch_cris,   /* Axis CRIS */
 #define bfd_mach_cris_v0_v10   255
 #define bfd_mach_cris_v32  32
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 62c6fe4..893df26 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -24,6 +24,7 @@ enum {
 QEMU_ARCH_NIOS2 = (1 << 17),
 QEMU_ARCH_HPPA = (1 << 18),
 QEMU_ARCH_RISCV = (1 << 19),
+QEMU_ARCH_AVR = (1 << 20),
 };
 
 extern const uint32_t arch_type;
diff --git a/qapi/machine.json b/qapi/machine.json
index b3d30bc..f2dc385 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -21,11 +21,12 @@
 #is true even for "qemu-system-x86_64".
 #
 # ppcemb: dropped in 3.1
+# avr: since 5.0
 #
 # Since: 3.0
 ##
 { 'enum' : 'SysEmuTarget',
-  'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32',
+  'data' : [ 'aarch64', 'alpha', 'arm', 'avr', 'cris', 'hppa', 'i386', 'lm32',
  'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64',
  'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc',
  'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4',
-- 
2.7.4




[PATCH rc4 22/29] target/avr: Update MAINTAINERS file

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

Include AVR maintaners in MAINTAINERS file

Signed-off-by: Michael Rolnik 
Signed-off-by: Philippe Mathieu-Daudé 
[rth: Squash ordering fixes from f4bug]
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 MAINTAINERS | 24 
 1 file changed, 24 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index c45e886..d0a114b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -163,6 +163,14 @@ S: Maintained
 F: hw/arm/smmu*
 F: include/hw/arm/smmu*
 
+AVR TCG CPUs
+M: Michael Rolnik 
+R: Sarah Harris 
+S: Maintained
+F: target/avr/
+F: default-configs/avr-softmmu.mak
+F: gdb-xml/avr-cpu.xml
+
 CRIS TCG CPUs
 M: Edgar E. Iglesias 
 S: Maintained
@@ -882,6 +890,22 @@ F: include/hw/*/nrf51*.h
 F: include/hw/*/microbit*.h
 F: tests/qtest/microbit-test.c
 
+AVR Machines
+-
+
+AVR MCUs
+M: Michael Rolnik 
+R: Sarah Harris 
+S: Maintained
+F: hw/avr/
+F: hw/char/avr_usart.c
+F: include/hw/char/avr_usart.h
+F: hw/timer/avr_timer16.c
+F: include/hw/timer/avr_timer16.h
+F: hw/misc/avr_power.c
+F: include/hw/misc/avr_power.h
+F: tests/acceptance/machine_avr6.py
+
 CRIS Machines
 -
 Axis Dev88
-- 
2.7.4




Re: [PATCH rc4 00/29] target/avr merger

2020-01-30 Thread Aleksandar Markovic
Michael, Philippe,

Can you guys do a quick checkup of this rc4? rc4, rc3,and rc2 should
be functionally 100% equivalent.

Thank you,
Aleksandar

On Fri, Jan 31, 2020 at 1:06 AM Aleksandar Markovic
 wrote:
>
> From: Aleksandar Markovic 
>
> This is the AVR port from Michael, release (merge) candidate 4.
>
> The series can be found also in this repository:
>
> https://github.com/AMarkovic/qemu-avr-merger-rc4
>
> History:
>
> Since v3:
>
> - Removed a patch on load_elf() modification, since it has been merged
> - Removed references to CONFIG_USER_ONLY and provided a guard against
>   building lunux user mode for AVR
> - Removed all references to 'Atmel' (including file renames)
> - Rebased the code (there was common interface change regarding 'props')
> - Various corrections of commit messages
> - A bit field for AVRFeatures is nor 64 bit long
> - Other minor fixes
>
> Since v2:
>
> - First patch is split into six smaller logical units (net result
>   remains the same)
> - Patch "hw/core/loader: Let load_elf populate the processor-specific
>   flags" was redone to reflect the original intent that was lost in
>   transalation between multiple autors
> - Patch "hw/avr: Add helper to load raw/ELF firmware binaries" was
>   corrected only in one line to rectify type of "e_flags"
> - Patch "target/avr: Add section about AVR into QEMU documentation"
> - Spurious  elements were removed
> - The series was rebased to the latest code
>
> Since v1:
>
> - Addressed Thomas comments
> - Fixed a non-critical bug in ATmega (incorrect SRAM base address)
> - Added ELF parsing requested by Aleksandar
> - Dropped default machine (as with the ARM port)
>
> Michael Rolnik (25):
>   target/avr: Add basic parameters for new AVR platform
>   target/avr: Introduce AVR CPU class object
>   target/avr: Add migration support
>   target/avr: Add GDB support
>   target/avr: Introduce enumeration AVRFeature
>   target/avr: Add defintions of AVR core types
>   target/avr: Add instruction helpers
>   target/avr: Add instruction translation - Register definitions
>   target/avr: Add instruction translation - Arithmetic and Logic
> Instructions
>   target/avr: Add instruction translation - Branch Instructions
>   target/avr: Add instruction translation - Data Transfer Instructions
>   target/avr: Add instruction translation - Bit and Bit-test
> Instructions
>   target/avr: Add instruction translation - MCU Control Instructions
>   target/avr: Add instruction translation - CPU main translation
> function
>   target/avr: Add instruction disassembly function
>   hw/char: Add limited support for AVR USART peripheral
>   hw/timer: Add limited support for AVR 16-bit timer peripheral
>   hw/misc: Add limited support for AVR power device
>   target/avr: Add section about AVR into QEMU documentation
>   target/avr: Register AVR support with the rest of QEMU
>   target/avr: Add machine none test
>   target/avr: Update MAINTAINERS file
>   target/avr: Update build system
>   tests/boot-serial-test: Test some Arduino boards (AVR based)
>   tests/acceptance: Test the Arduino MEGA2560 board
>
> Philippe Mathieu-Daudé (4):
>   hw/avr: Add helper to load raw/ELF firmware binaries
>   hw/avr: Add some ATmega microcontrollers
>   hw/avr: Add some Arduino boards
>   .travis.yml: Run the AVR acceptance tests
>
>  .travis.yml  |2 +-
>  MAINTAINERS  |   31 +
>  arch_init.c  |2 +
>  configure|7 +
>  default-configs/avr-softmmu.mak  |5 +
>  gdb-xml/avr-cpu.xml  |   49 +
>  hw/avr/Kconfig   |9 +
>  hw/avr/Makefile.objs |3 +
>  hw/avr/arduino.c |  151 ++
>  hw/avr/atmega.c  |  470 ++
>  hw/avr/atmega.h  |   48 +
>  hw/avr/boot.c|   74 +
>  hw/avr/boot.h|   33 +
>  hw/char/Kconfig  |3 +
>  hw/char/Makefile.objs|1 +
>  hw/char/avr_usart.c  |  320 
>  hw/misc/Kconfig  |3 +
>  hw/misc/Makefile.objs|2 +
>  hw/misc/avr_power.c  |  112 ++
>  hw/timer/Kconfig |3 +
>  hw/timer/Makefile.objs   |2 +
>  hw/timer/avr_timer16.c   |  604 
>  include/disas/dis-asm.h  |   19 +
>  include/elf.h|2 +
>  include/hw/char/avr_usart.h  |   93 ++
>  include/hw/misc/avr_power.h  |   46 +
>  include/hw/timer/avr_timer16.h   |   94 ++
>  include/sysemu/arch_init.h   |1 +
>  qapi/machine.json|3 +-
>  qemu-doc.texi|   51 +
>  target/avr/Makefile.objs |   34 +
>  target/avr/cpu-param.h   |   37 +
>  target/avr/cpu-qom.h |   54 +
>  target/avr/cpu.c |  818 +++
>  target/avr/cpu.h |  259 
>  target/avr/disas.c   |  246 
>  target/avr/gd

[PATCH rc4 23/29] hw/avr: Add helper to load raw/ELF firmware binaries

2020-01-30 Thread Aleksandar Markovic
From: Philippe Mathieu-Daudé 

Add avr_load_firmware() function to load firmware in ELF or
raw binary format.

[AM: Corrected the type of the variable containing e_flags]

Suggested-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Aleksandar Markovic 
---
 hw/avr/Makefile.objs |  1 +
 hw/avr/boot.c| 74 
 hw/avr/boot.h| 33 +++
 include/elf.h|  2 ++
 4 files changed, 110 insertions(+)
 create mode 100644 hw/avr/Makefile.objs
 create mode 100644 hw/avr/boot.c
 create mode 100644 hw/avr/boot.h

diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
new file mode 100644
index 000..123f174
--- /dev/null
+++ b/hw/avr/Makefile.objs
@@ -0,0 +1 @@
+obj-y += boot.o
diff --git a/hw/avr/boot.c b/hw/avr/boot.c
new file mode 100644
index 000..9ac2c88
--- /dev/null
+++ b/hw/avr/boot.c
@@ -0,0 +1,74 @@
+/*
+ * AVR loader helpers
+ *
+ * Copyright (c) 2019 Philippe Mathieu-Daudé
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/loader.h"
+#include "elf.h"
+#include "boot.h"
+#include "qemu/error-report.h"
+
+bool avr_load_firmware(AVRCPU *cpu, MachineState *ms,
+   MemoryRegion *mr, const char *firmware)
+{
+const char *filename;
+int bytes_loaded;
+uint64_t entry;
+uint32_t e_flags;
+
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware);
+if (filename == NULL) {
+error_report("Unable to find %s", firmware);
+return false;
+}
+
+bytes_loaded = load_elf_ram_sym(filename,
+NULL, NULL, NULL,
+&entry, NULL, NULL,
+&e_flags, 0, EM_AVR, 0, 0,
+NULL, true, NULL);
+if (bytes_loaded >= 0) {
+/* If ELF file is provided, determine CPU type reading ELF e_flags. */
+const char *elf_cpu = avr_flags_to_cpu_type(e_flags, NULL);
+const char *mcu_cpu_type = object_get_typename(OBJECT(cpu));
+int cpu_len = strlen(mcu_cpu_type) - strlen(AVR_CPU_TYPE_SUFFIX);
+
+if (entry) {
+error_report("BIOS entry_point must be 0x "
+ "(ELF image '%s' has entry_point 0x%04" PRIx64 ")",
+ firmware, entry);
+return false;
+}
+if (!elf_cpu) {
+warn_report("Could not determine CPU type for ELF image '%s', "
+"assuming '%.*s' CPU",
+ firmware, cpu_len, mcu_cpu_type);
+return true;
+}
+if (strcmp(elf_cpu, mcu_cpu_type)) {
+error_report("Current machine: %s with '%.*s' CPU",
+ MACHINE_GET_CLASS(ms)->desc, cpu_len, mcu_cpu_type);
+error_report("ELF image '%s' is for '%.*s' CPU",
+ firmware,
+ (int)(strlen(elf_cpu) - strlen(AVR_CPU_TYPE_SUFFIX)),
+ elf_cpu);
+return false;
+}
+} else {
+bytes_loaded = load_image_targphys(filename, OFFSET_CODE,
+   memory_region_size(mr));
+}
+if (bytes_loaded < 0) {
+error_report("Unable to load firmware image %s as ELF or raw binary",
+ firmware);
+return false;
+}
+return true;
+}
diff --git a/hw/avr/boot.h b/hw/avr/boot.h
new file mode 100644
index 000..62bc10c
--- /dev/null
+++ b/hw/avr/boot.h
@@ -0,0 +1,33 @@
+/*
+ * AVR loader helpers
+ *
+ * Copyright (c) 2019 Philippe Mathieu-Daudé
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_AVR_BOOT_H
+#define HW_AVR_BOOT_H
+
+#include "hw/boards.h"
+#include "cpu.h"
+
+/**
+ * avr_load_firmware:   load an image into a memory region
+ *
+ * @cpu:Handle a AVR CPU object
+ * @ms: A MachineState
+ * @mr: Memory Region to load into
+ * @firmware:   Path to the firmware file (raw binary or ELF format)
+ *
+ * Load a firmware supplied by the machine or by the user  with the
+ * '-bios' command line option, and put it in target memory.
+ *
+ * Returns: true on success, false on error.
+ */
+bool avr_load_firmware(AVRCPU *cpu, MachineState *ms,
+   MemoryRegion *mr, const char *firmware);
+
+#endif
diff --git a/include/elf.h b/include/elf.h
index 8fbfe60..3f08f68 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -202,6 +202,8 @@ typedef struct mips_elf_abiflags_v0 {
 #define EM_MOXIE   223 /* Moxie processor family */
 #define EM_MOXIE_OLD   0xFEED
 
+#define EM_AVR 83 /* AVR 8-bit microcontroller

[PATCH rc4 15/29] target/avr: Add instruction disassembly function

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

Provide function disassembles executed instruction when `-d in_asm` is
provided

Example:
`./avr-softmmu/qemu-system-avr -bios free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf 
-d in_asm` will produce something like the following

```
...
IN:
0x014a:  CALL  0x3808

IN: main
0x3808:  CALL  0x4b4

IN: vParTestInitialise
0x04b4:  LDI   r24, 255
0x04b6:  STS   r24, 0
0x04b8:  MULS  r16, r20
0x04ba:  OUT   $1, r24
0x04bc:  LDS   r24, 0
0x04be:  MULS  r16, r20
0x04c0:  OUT   $2, r24
0x04c2:  RET
...
```

Signed-off-by: Michael Rolnik 
Suggested-by: Richard Henderson 
Suggested-by: Philippe Mathieu-Daudé 
Suggested-by: Aleksandar Markovic 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
[rth: Fix spacing and const mnemonic arrays]
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 target/avr/cpu.c   |   2 +-
 target/avr/cpu.h   |   1 +
 target/avr/disas.c | 246 +
 target/avr/translate.c |  12 +++
 4 files changed, 260 insertions(+), 1 deletion(-)
 create mode 100644 target/avr/disas.c

diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index e0ae055..930dd10 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -84,7 +84,7 @@ static void avr_cpu_reset(CPUState *cs)
 static void avr_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
 {
 info->mach = bfd_arch_avr;
-info->print_insn = NULL;
+info->print_insn = avr_print_insn;
 }
 
 static void avr_cpu_realizefn(DeviceState *dev, Error **errp)
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index e94dab3..4169add 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -162,6 +162,7 @@ bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int avr_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+int avr_print_insn(bfd_vma addr, disassemble_info *info);
 
 static inline int avr_feature(CPUAVRState *env, AVRFeature feature)
 {
diff --git a/target/avr/disas.c b/target/avr/disas.c
new file mode 100644
index 000..23bd991
--- /dev/null
+++ b/target/avr/disas.c
@@ -0,0 +1,246 @@
+/*
+ * AVR disassembler
+ *
+ * Copyright (c) 2019 Richard Henderson 
+ * Copyright (c) 2019 Michael Rolnik 
+ *
+ * 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 .
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+
+typedef struct {
+disassemble_info *info;
+uint16_t next_word;
+bool next_word_used;
+} DisasContext;
+
+static int to_regs_16_31_by_one(DisasContext *ctx, int indx)
+{
+return 16 + (indx % 16);
+}
+
+static int to_regs_16_23_by_one(DisasContext *ctx, int indx)
+{
+return 16 + (indx % 8);
+}
+
+static int to_regs_24_30_by_two(DisasContext *ctx, int indx)
+{
+return 24 + (indx % 4) * 2;
+}
+
+static int to_regs_00_30_by_two(DisasContext *ctx, int indx)
+{
+return (indx % 16) * 2;
+}
+
+static uint16_t next_word(DisasContext *ctx)
+{
+ctx->next_word_used = true;
+return ctx->next_word;
+}
+
+static int append_16(DisasContext *ctx, int x)
+{
+return x << 16 | next_word(ctx);
+}
+
+
+/* Include the auto-generated decoder.  */
+static bool decode_insn(DisasContext *ctx, uint16_t insn);
+#include "decode_insn.inc.c"
+
+#define output(mnemonic, format, ...) \
+(pctx->info->fprintf_func(pctx->info->stream, "%-9s " format, \
+mnemonic, ##__VA_ARGS__))
+
+int avr_print_insn(bfd_vma addr, disassemble_info *info)
+{
+DisasContext ctx;
+DisasContext *pctx = &ctx;
+bfd_byte buffer[4];
+uint16_t insn;
+int status;
+
+ctx.info = info;
+
+status = info->read_memory_func(addr, buffer, 4, info);
+if (status != 0) {
+info->memory_error_func(status, addr, info);
+return -1;
+}
+insn = bfd_getl16(buffer);
+ctx.next_word = bfd_getl16(buffer + 2);
+ctx.next_word_used = false;
+
+if (!decode_insn(&ctx, insn)) {
+output(".db", "0x%02x, 0x%02x", buffer[0], buffer[1]);
+}
+
+return ctx.next_word_used ? 4 : 2;
+}
+
+
+#define INSN(opcode, format, ...)   \
+static bool trans_##opcode(DisasContext *pctx, arg_##opc

[PATCH rc4 21/29] target/avr: Add machine none test

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

Add a single code line that will automatically provide 'machine none'
test.

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Reviewed-by: Thomas Huth 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 tests/qtest/machine-none-test.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/qtest/machine-none-test.c b/tests/qtest/machine-none-test.c
index 5953d31..3e5c74e 100644
--- a/tests/qtest/machine-none-test.c
+++ b/tests/qtest/machine-none-test.c
@@ -27,6 +27,7 @@ static struct arch2cpu cpus_map[] = {
 /* tested targets list */
 { "arm", "cortex-a15" },
 { "aarch64", "cortex-a57" },
+{ "avr", "avr6-avr-cpu" },
 { "x86_64", "qemu64,apic-id=0" },
 { "i386", "qemu32,apic-id=0" },
 { "alpha", "ev67" },
-- 
2.7.4




[PATCH rc4 26/29] target/avr: Update build system

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

Make AVR support buildable.

[AM: Remove word 'Atmel' from filenames and all elements of code]
Suggested-by: Aleksandar Markovic 

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 configure   |  7 +++
 default-configs/avr-softmmu.mak |  5 +
 target/avr/Makefile.objs| 34 ++
 3 files changed, 46 insertions(+)
 create mode 100644 default-configs/avr-softmmu.mak
 create mode 100644 target/avr/Makefile.objs

diff --git a/configure b/configure
index a72a5de..51f0b9e 100755
--- a/configure
+++ b/configure
@@ -7640,6 +7640,10 @@ case "$target_name" in
 mttcg="yes"
 gdb_xml_files="aarch64-core.xml aarch64-fpu.xml arm-core.xml arm-vfp.xml 
arm-vfp3.xml arm-neon.xml"
   ;;
+  avr)
+gdb_xml_files="avr-cpu.xml"
+target_compiler=$cross_cc_avr
+  ;;
   cris)
   ;;
   hppa)
@@ -7859,6 +7863,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   disas_config "ARM_A64"
 fi
   ;;
+  avr)
+disas_config "AVR"
+  ;;
   cris)
 disas_config "CRIS"
   ;;
diff --git a/default-configs/avr-softmmu.mak b/default-configs/avr-softmmu.mak
new file mode 100644
index 000..80218ad
--- /dev/null
+++ b/default-configs/avr-softmmu.mak
@@ -0,0 +1,5 @@
+# Default configuration for avr-softmmu
+
+# Boards:
+#
+CONFIG_ARDUINO=y
diff --git a/target/avr/Makefile.objs b/target/avr/Makefile.objs
new file mode 100644
index 000..7523e0c
--- /dev/null
+++ b/target/avr/Makefile.objs
@@ -0,0 +1,34 @@
+#
+#  QEMU AVR CPU
+#
+#  Copyright (c) 2019 Michael Rolnik
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License, or (at your option) any later version.
+#
+#  This library 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
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, see
+#  
+#
+
+DECODETREE = $(SRC_PATH)/scripts/decodetree.py
+decode-y = $(SRC_PATH)/target/avr/insn.decode
+
+target/avr/decode_insn.inc.c: $(decode-y) $(DECODETREE)
+   $(call quiet-command, \
+ $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn --insnwidth 16 $<, 
\
+ "GEN", $(TARGET_DIR)$@)
+
+target/avr/translate.o: target/avr/decode_insn.inc.c
+
+obj-y += translate.o cpu.o helper.o
+obj-y += gdbstub.o
+obj-y += disas.o
+obj-$(CONFIG_SOFTMMU) += machine.o
-- 
2.7.4




[PATCH rc4 13/29] target/avr: Add instruction translation - MCU Control Instructions

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

This includes:
- BREAK
- NOP
- SLEEP
- WDR

Signed-off-by: Michael Rolnik 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 target/avr/insn.decode |  8 ++
 target/avr/translate.c | 68 ++
 2 files changed, 76 insertions(+)

diff --git a/target/avr/insn.decode b/target/avr/insn.decode
index 4ee5586..f8d32f2 100644
--- a/target/avr/insn.decode
+++ b/target/avr/insn.decode
@@ -172,3 +172,11 @@ BST  101 rd:5 0 bit:3
 BLD  100 rd:5 0 bit:3
 BSET1001 0100 0 bit:3 1000
 BCLR1001 0100 1 bit:3 1000
+
+#
+# MCU Control Instructions
+#
+BREAK   1001 0101 1001 1000
+NOP    
+SLEEP   1001 0101 1000 1000
+WDR 1001 0101 1010 1000
diff --git a/target/avr/translate.c b/target/avr/translate.c
index 58775af..4c68007 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -2681,3 +2681,71 @@ static bool trans_BCLR(DisasContext *ctx, arg_BCLR *a)
 
 return true;
 }
+
+/*
+ * MCU Control Instructions
+ */
+
+/*
+ *  The BREAK instruction is used by the On-chip Debug system, and is
+ *  normally not used in the application software. When the BREAK instruction 
is
+ *  executed, the AVR CPU is set in the Stopped Mode. This gives the On-chip
+ *  Debugger access to internal resources.  If any Lock bits are set, or either
+ *  the JTAGEN or OCDEN Fuses are unprogrammed, the CPU will treat the BREAK
+ *  instruction as a NOP and will not enter the Stopped mode.  This instruction
+ *  is not available in all devices. Refer to the device specific instruction
+ *  set summary.
+ */
+static bool trans_BREAK(DisasContext *ctx, arg_BREAK *a)
+{
+if (!avr_have_feature(ctx, AVR_FEATURE_BREAK)) {
+return true;
+}
+
+#ifdef BREAKPOINT_ON_BREAK
+tcg_gen_movi_tl(cpu_pc, ctx->npc - 1);
+gen_helper_debug(cpu_env);
+ctx->bstate = DISAS_EXIT;
+#else
+/* NOP */
+#endif
+
+return true;
+}
+
+
+/*
+ *  This instruction performs a single cycle No Operation.
+ */
+static bool trans_NOP(DisasContext *ctx, arg_NOP *a)
+{
+
+/* NOP */
+
+return true;
+}
+
+
+/*
+ *  This instruction sets the circuit in sleep mode defined by the MCU
+ *  Control Register.
+ */
+static bool trans_SLEEP(DisasContext *ctx, arg_SLEEP *a)
+{
+gen_helper_sleep(cpu_env);
+ctx->bstate = DISAS_NORETURN;
+return true;
+}
+
+
+/*
+ *  This instruction resets the Watchdog Timer. This instruction must be
+ *  executed within a limited time given by the WD prescaler. See the Watchdog
+ *  Timer hardware specification.
+ */
+static bool trans_WDR(DisasContext *ctx, arg_WDR *a)
+{
+gen_helper_wdr(cpu_env);
+
+return true;
+}
-- 
2.7.4




[PATCH rc4 18/29] hw/misc: Add limited support for AVR power device

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

This is a simple device of just one register, and whenever this
register is written to it calls qemu_set_irq function for each
of 8 bits/IRQs. It is used to implement AVR Power Reduction.

[AM: Remove word 'Atmel' from filenames and all elements of code]
Suggested-by: Aleksandar Markovic 

Signed-off-by: Michael Rolnik 
Signed-off-by: Philippe Mathieu-Daudé 
[rth: Squash include fix and file rename from f4bug]
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 hw/misc/Kconfig |   3 ++
 hw/misc/Makefile.objs   |   2 +
 hw/misc/avr_power.c | 112 
 include/hw/misc/avr_power.h |  46 ++
 4 files changed, 163 insertions(+)
 create mode 100644 hw/misc/avr_power.c
 create mode 100644 include/hw/misc/avr_power.h

diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index bdd77d8..92c397c 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -131,4 +131,7 @@ config MAC_VIA
 select MOS6522
 select ADB
 
+config AVR_POWER
+bool
+
 source macio/Kconfig
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index da993f4..df8e457 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -85,3 +85,5 @@ common-obj-$(CONFIG_NRF51_SOC) += nrf51_rng.o
 obj-$(CONFIG_MAC_VIA) += mac_via.o
 
 common-obj-$(CONFIG_GRLIB) += grlib_ahb_apb_pnp.o
+
+obj-$(CONFIG_AVR_POWER) += avr_power.o
diff --git a/hw/misc/avr_power.c b/hw/misc/avr_power.c
new file mode 100644
index 000..598bc72
--- /dev/null
+++ b/hw/misc/avr_power.c
@@ -0,0 +1,112 @@
+/*
+ * AVR Power Reduction Management
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * 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 "hw/misc/avr_power.h"
+#include "qemu/log.h"
+#include "hw/qdev-properties.h"
+#include "hw/irq.h"
+
+#define DB_PRINT(fmt, args...) /* Nothing */
+/*#define DB_PRINT(fmt, args...) printf("%s: " fmt "\n", __func__, ## args)*/
+
+static void avr_mask_reset(DeviceState *dev)
+{
+AVRMaskState *s = AVR_MASK(dev);
+
+s->val = 0x00;
+
+for (int i = 0; i < 8; i++) {
+qemu_set_irq(s->irq[i], 0);
+}
+}
+
+static uint64_t avr_mask_read(void *opaque, hwaddr offset, unsigned size)
+{
+assert(size == 1);
+assert(offset == 0);
+AVRMaskState *s = opaque;
+
+return (uint64_t)s->val;
+}
+
+static void avr_mask_write(void *opaque, hwaddr offset,
+  uint64_t val64, unsigned size)
+{
+assert(size == 1);
+assert(offset == 0);
+AVRMaskState *s = opaque;
+uint8_t val8 = val64;
+
+DB_PRINT("write %d to offset %d", val8, (uint8_t)offset);
+
+s->val = val8;
+for (int i = 0; i < 8; i++) {
+qemu_set_irq(s->irq[i], (val8 & (1 << i)) != 0);
+}
+}
+
+static const MemoryRegionOps avr_mask_ops = {
+.read = avr_mask_read,
+.write = avr_mask_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {.max_access_size = 1}
+};
+
+static void avr_mask_init(Object *dev)
+{
+AVRMaskState *s = AVR_MASK(dev);
+SysBusDevice *busdev = SYS_BUS_DEVICE(dev);
+
+memory_region_init_io(&s->iomem, dev, &avr_mask_ops, s, TYPE_AVR_MASK,
+0x01);
+sysbus_init_mmio(busdev, &s->iomem);
+
+for (int i = 0; i < 8; i++) {
+sysbus_init_irq(busdev, &s->irq[i]);
+}
+s->val = 0x00;
+}
+
+static void avr_mask_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->reset = avr_mask_reset;
+}
+
+static const TypeInfo avr_mask_info = {
+.name  = TYPE_AVR_MASK,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(AVRMaskState),
+.class_init= avr_mask_class_init,
+.instance_init = avr_mask_init,
+};
+
+static void avr_mask_register_types(void)
+{
+type_register_static(&avr_mask_info);
+}
+
+type_init(avr_mask_register_types)
diff --git a/include/hw/misc/avr_power.h b/inc

[PATCH rc4 03/29] target/avr: Add migration support

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

Add migration functions for AVR cores.

[AM: Split a larger AVR introduction patch into logical units]
Suggested-by: Aleksandar Markovic 

Co-developed-by: Michael Rolnik 
Co-developed-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Signed-off-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Acked-by: Igor Mammedov 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 target/avr/cpu.c |   1 +
 target/avr/cpu.h |   2 +
 target/avr/machine.c | 121 +++
 3 files changed, 124 insertions(+)
 create mode 100644 target/avr/machine.c

diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index beda91e..49e32af 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -205,6 +205,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
 cc->set_pc = avr_cpu_set_pc;
 cc->memory_rw_debug = avr_cpu_memory_rw_debug;
 cc->get_phys_page_debug = avr_cpu_get_phys_page_debug;
+cc->vmsd = &vms_avr_cpu;
 cc->disas_set_info = avr_cpu_disas_set_info;
 cc->tlb_fill = avr_cpu_tlb_fill;
 cc->tcg_initialize = avr_cpu_tcg_init;
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index 08f4415..2907a37 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -119,6 +119,8 @@ typedef struct AVRCPU {
 CPUAVRState env;
 } AVRCPU;
 
+extern const struct VMStateDescription vms_avr_cpu;
+
 void avr_cpu_do_interrupt(CPUState *cpu);
 bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/avr/machine.c b/target/avr/machine.c
new file mode 100644
index 000..ba44bd0
--- /dev/null
+++ b/target/avr/machine.c
@@ -0,0 +1,121 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "migration/cpu.h"
+
+static int get_sreg(QEMUFile *f, void *opaque, size_t size,
+const VMStateField *field)
+{
+CPUAVRState *env = opaque;
+uint8_t sreg;
+
+sreg = qemu_get_byte(f);
+cpu_set_sreg(env, sreg);
+return 0;
+}
+
+static int put_sreg(
+QEMUFile *f, void *opaque, size_t size,
+const VMStateField *field, QJSON *vmdesc)
+{
+CPUAVRState *env = opaque;
+uint8_t sreg = cpu_get_sreg(env);
+
+qemu_put_byte(f, sreg);
+return 0;
+}
+
+static const VMStateInfo vms_sreg = {
+.name = "sreg",
+.get = get_sreg,
+.put = put_sreg,
+};
+
+static int get_segment(
+QEMUFile *f, void *opaque, size_t size, const VMStateField *field)
+{
+uint32_t *ramp = opaque;
+uint8_t temp;
+
+temp = qemu_get_byte(f);
+*ramp = ((uint32_t)temp) << 16;
+return 0;
+}
+
+static int put_segment(
+QEMUFile *f, void *opaque, size_t size,
+const VMStateField *field, QJSON *vmdesc)
+{
+uint32_t *ramp = opaque;
+uint8_t temp = *ramp >> 16;
+
+qemu_put_byte(f, temp);
+return 0;
+}
+
+static const VMStateInfo vms_rampD = {
+.name = "rampD",
+.get = get_segment,
+.put = put_segment,
+};
+static const VMStateInfo vms_rampX = {
+.name = "rampX",
+.get = get_segment,
+.put = put_segment,
+};
+static const VMStateInfo vms_rampY = {
+.name = "rampY",
+.get = get_segment,
+.put = put_segment,
+};
+static const VMStateInfo vms_rampZ = {
+.name = "rampZ",
+.get = get_segment,
+.put = put_segment,
+};
+static const VMStateInfo vms_eind = {
+.name = "eind",
+.get = get_segment,
+.put = put_segment,
+};
+
+const VMStateDescription vms_avr_cpu = {
+.name = "cpu",
+.version_id = 0,
+.minimum_version_id = 0,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(env.pc_w, AVRCPU),
+VMSTATE_UINT32(env.sp, AVRCPU),
+VMSTATE_UINT32(env.skip, AVRCPU),
+
+VMSTATE_UINT32_ARRAY(env.r, AVRCPU, NUMBER_OF_CPU_REGISTERS),
+
+VMSTATE_SINGLE(env, AVRCPU, 0, vms_sreg, CPUAVRState),
+VMSTATE_SINGLE(env.rampD, AVRCPU, 0, vms_rampD, uint32_t),
+VMSTATE_SINGLE(env.rampX, AVRCPU, 0, vms_rampX, uint32_t),
+VMSTATE_SINGLE(env.rampY, AVRCPU, 0, vms_rampY, uint32_t),
+VMSTATE_SINGLE(env.rampZ, AVRCPU, 0, vms_rampZ, uint32_t),
+VMSTATE_SINGLE(env.eind, AVRCPU, 0, vms_eind, uint32_t),
+
+ 

[PATCH rc4 09/29] target/avr: Add instruction translation - Arithmetic and Logic Instructions

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

This includes:
- ADD, ADC, ADIW
- SBIW, SUB, SUBI, SBC, SBCI
- AND, ANDI
- OR, ORI, EOR
- COM, NEG
- INC, DEC
- MUL, MULS, MULSU
- FMUL, FMULS, FMULSU
- DES

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 target/avr/insn.decode |  93 ++
 target/avr/translate.c | 752 +
 2 files changed, 845 insertions(+)
 create mode 100644 target/avr/insn.decode

diff --git a/target/avr/insn.decode b/target/avr/insn.decode
new file mode 100644
index 000..9c71ed6
--- /dev/null
+++ b/target/avr/insn.decode
@@ -0,0 +1,93 @@
+#
+# AVR instruction decode definitions.
+#
+# Copyright (c) 2019 Michael Rolnik 
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, see .
+#
+
+#
+#   regs_16_31_by_one = [16 .. 31]
+#   regs_16_23_by_one = [16 .. 23]
+#   regs_24_30_by_two = [24, 26, 28, 30]
+#   regs_00_30_by_two = [0, 2, 4, 6, 8, .. 30]
+
+%rd 4:5
+%rr 9:1 0:4
+
+%rd_a   4:4 !function=to_regs_16_31_by_one
+%rd_b   4:3 !function=to_regs_16_23_by_one
+%rd_c   4:2 !function=to_regs_24_30_by_two
+%rd_d   4:4 !function=to_regs_00_30_by_two
+%rr_a   0:4 !function=to_regs_16_31_by_one
+%rr_b   0:3 !function=to_regs_16_23_by_one
+%rr_d   0:4 !function=to_regs_00_30_by_two
+
+%imm6   6:2 0:4
+%imm8   8:4 0:4
+
+%io_imm 9:2 0:4
+%ldst_d_imm 13:1 10:2 0:3
+
+# The 22-bit immediate is partially in the opcode word,
+# and partially in the next.  Use append_16 to build the
+# complete 22-bit value.
+%imm_call   4:5 0:1 !function=append_16
+
+
+&rd_rr  rd rr
+&rd_imm rd imm
+
+@op_rd_rr    .. . . &rd_rr  rd=%rd rr=%rr
+@op_rd_imm6   .. .. &rd_imm rd=%rd_c imm=%imm6
+@op_rd_imm8     &rd_imm rd=%rd_a imm=%imm8
+@op_bit   . bit:3 
+@op_bit_imm  .. imm:s7 bit:3
+@fmul     . ... . ...   &rd_rr  rd=%rd_b rr=%rr_b
+@io_rd_imm   . .. . &rd_imm rd=%rd imm=%io_imm
+@ldst_d .. . . .. . rd:5  . ... &rd_imm imm=%ldst_d_imm
+
+# The 16-bit immediate is completely in the next word.
+# Fields cannot be defined with no bits, so we cannot play
+# the same trick and append to a zero-bit value.
+# Defer reading the immediate until trans_{LDS,STS}.
+@ldst_s  ... rd:5   imm=0
+
+#
+# Arithmetic Instructions
+#
+ADD  11 . . @op_rd_rr
+ADC 0001 11 . . @op_rd_rr
+ADIW1001 0110 .. .. @op_rd_imm6
+SUB 0001 10 . . @op_rd_rr
+SUBI0101    @op_rd_imm8
+SBC  10 . . @op_rd_rr
+SBCI0100    @op_rd_imm8
+SBIW1001 0111 .. .. @op_rd_imm6
+AND 0010 00 . . @op_rd_rr
+ANDI0111    @op_rd_imm8
+OR  0010 10 . . @op_rd_rr
+ORI 0110    @op_rd_imm8
+EOR 0010 01 . . @op_rd_rr
+COM 1001 010 rd:5 
+NEG 1001 010 rd:5 0001
+INC 1001 010 rd:5 0011
+DEC 1001 010 rd:5 1010
+MUL 1001 11 . . @op_rd_rr
+MULS 0010   &rd_rr  rd=%rd_a rr=%rr_a
+MULSU    0011 0 ... 0 ...   @fmul
+FMUL 0011 0 ... 1 ...   @fmul
+FMULS    0011 1 ... 0 ...   @fmul
+FMULSU   0011 1 ... 1 ...   @fmul
+DES 1001 0100 imm:4 1011
diff --git a/target/avr/translate.c b/target/avr/translate.c
index 535f666..00fb3f5 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -169,3 +169,755 @@ static bool avr_have_feature(DisasContext *ctx, int 
feature)
 
 static bool decode_insn(DisasContext *ctx, uint16_t insn);
 #include "decode_insn.inc.c"
+
+/*
+ * Arithmetic Instructions
+ */

[PATCH rc4 02/29] target/avr: Introduce AVR CPU class object

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

This patch introduces AVR CPU class object and its basic elements
and functions.

[AM: Split a larger AVR introduction patch into logical units]
Suggested-by: Aleksandar Markovic 

Co-developed-by: Michael Rolnik 
Co-developed-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Signed-off-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Acked-by: Igor Mammedov 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 target/avr/cpu-qom.h |  54 +
 target/avr/cpu.c | 212 +++
 target/avr/cpu.h | 136 +
 target/avr/helper.c  | 139 +
 4 files changed, 541 insertions(+)
 create mode 100644 target/avr/cpu-qom.h
 create mode 100644 target/avr/cpu.c
 create mode 100644 target/avr/helper.c

diff --git a/target/avr/cpu-qom.h b/target/avr/cpu-qom.h
new file mode 100644
index 000..e28b58c
--- /dev/null
+++ b/target/avr/cpu-qom.h
@@ -0,0 +1,54 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#ifndef QEMU_AVR_QOM_H
+#define QEMU_AVR_QOM_H
+
+#include "hw/core/cpu.h"
+
+#define TYPE_AVR_CPU "avr-cpu"
+
+#define AVR_CPU_CLASS(klass) \
+OBJECT_CLASS_CHECK(AVRCPUClass, (klass), TYPE_AVR_CPU)
+#define AVR_CPU(obj) \
+OBJECT_CHECK(AVRCPU, (obj), TYPE_AVR_CPU)
+#define AVR_CPU_GET_CLASS(obj) \
+OBJECT_GET_CLASS(AVRCPUClass, (obj), TYPE_AVR_CPU)
+
+/**
+ *  AVRCPUClass:
+ *  @parent_realize: The parent class' realize handler.
+ *  @parent_reset: The parent class' reset handler.
+ *  @vr: Version Register value.
+ *
+ *  A AVR CPU model.
+ */
+typedef struct AVRCPUClass {
+/*< private >*/
+CPUClass parent_class;
+/*< public >*/
+DeviceRealize parent_realize;
+void (*parent_reset)(CPUState *cpu);
+} AVRCPUClass;
+
+typedef struct AVRCPU AVRCPU;
+
+
+#endif /* !defined (QEMU_AVR_CPU_QOM_H) */
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
new file mode 100644
index 000..beda91e
--- /dev/null
+++ b/target/avr/cpu.c
@@ -0,0 +1,212 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/qemu-print.h"
+#include "exec/exec-all.h"
+#include "cpu.h"
+#include "disas/dis-asm.h"
+
+static void avr_cpu_set_pc(CPUState *cs, vaddr value)
+{
+AVRCPU *cpu = AVR_CPU(cs);
+
+cpu->env.pc_w = value / 2; /* internally PC points to words */
+}
+
+static bool avr_cpu_has_work(CPUState *cs)
+{
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = &cpu->env;
+
+return (cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_RESET))
+&& cpu_interrupts_enabled(env);
+}
+
+static void avr_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
+{
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = &cpu->env;
+
+env->pc_w = tb->pc / 2; /* internally PC points to words */
+}
+
+static void avr_cpu_reset(CPUState *cs)
+{
+AVRCPU *cpu = AVR_CPU(cs);
+AVRCPUClass *mcc = AVR_CPU_GET_CLASS(cpu);
+CPUAVRState *env = &cpu->env;
+
+mcc->parent_reset(cs);
+
+env->pc_w = 0;
+env->sregI = 1;
+env->sregC = 0;
+env->sregZ = 0;
+env->sregN = 0;
+env->sregV = 0;
+env->sregS = 0;
+env->sregH = 0;
+env->sregT = 0;
+
+env->rampD = 0;
+env->rampX = 0;
+env->rampY = 0;
+env->rampZ = 0;
+env->eind = 0;
+env->sp = 0;
+
+env->skip = 0;
+
+memset(env->r, 0, sizeof(env->r));
+
+tlb_flush(cs);
+}
+
+static void avr_cpu_disas_set_info(CPU

[PATCH rc4 14/29] target/avr: Add instruction translation - CPU main translation function

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

Co-developed-by: Richard Henderson 
Co-developed-by: Michael Rolnik 

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 target/avr/translate.c | 234 +
 1 file changed, 234 insertions(+)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index 4c68007..af88bb2 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -2749,3 +2749,237 @@ static bool trans_WDR(DisasContext *ctx, arg_WDR *a)
 
 return true;
 }
+
+
+void avr_cpu_tcg_init(void)
+{
+int i;
+
+#define AVR_REG_OFFS(x) offsetof(CPUAVRState, x)
+cpu_pc = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(pc_w), "pc");
+cpu_Cf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregC), "Cf");
+cpu_Zf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregZ), "Zf");
+cpu_Nf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregN), "Nf");
+cpu_Vf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregV), "Vf");
+cpu_Sf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregS), "Sf");
+cpu_Hf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregH), "Hf");
+cpu_Tf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregT), "Tf");
+cpu_If = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregI), "If");
+cpu_rampD = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampD), "rampD");
+cpu_rampX = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampX), "rampX");
+cpu_rampY = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampY), "rampY");
+cpu_rampZ = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampZ), "rampZ");
+cpu_eind = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(eind), "eind");
+cpu_sp = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sp), "sp");
+cpu_skip = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(skip), "skip");
+
+for (i = 0; i < NUMBER_OF_CPU_REGISTERS; i++) {
+cpu_r[i] = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(r[i]),
+  reg_names[i]);
+}
+#undef AVR_REG_OFFS
+}
+
+static void translate(DisasContext *ctx)
+{
+uint32_t opcode = next_word(ctx);
+
+if (!decode_insn(ctx, opcode)) {
+gen_helper_unsupported(cpu_env);
+ctx->bstate = DISAS_NORETURN;
+}
+}
+
+/* Standardize the cpu_skip condition to NE.  */
+static bool canonicalize_skip(DisasContext *ctx)
+{
+switch (ctx->skip_cond) {
+case TCG_COND_NEVER:
+/* Normal case: cpu_skip is known to be false.  */
+return false;
+
+case TCG_COND_ALWAYS:
+/*
+ * Breakpoint case: cpu_skip is known to be true, via TB_FLAGS_SKIP.
+ * The breakpoint is on the instruction being skipped, at the start
+ * of the TranslationBlock.  No need to update.
+ */
+return false;
+
+case TCG_COND_NE:
+if (ctx->skip_var1 == NULL) {
+tcg_gen_mov_tl(cpu_skip, ctx->skip_var0);
+} else {
+tcg_gen_xor_tl(cpu_skip, ctx->skip_var0, ctx->skip_var1);
+ctx->skip_var1 = NULL;
+}
+break;
+
+default:
+/* Convert to a NE condition vs 0. */
+if (ctx->skip_var1 == NULL) {
+tcg_gen_setcondi_tl(ctx->skip_cond, cpu_skip, ctx->skip_var0, 0);
+} else {
+tcg_gen_setcond_tl(ctx->skip_cond, cpu_skip,
+   ctx->skip_var0, ctx->skip_var1);
+ctx->skip_var1 = NULL;
+}
+ctx->skip_cond = TCG_COND_NE;
+break;
+}
+if (ctx->free_skip_var0) {
+tcg_temp_free(ctx->skip_var0);
+ctx->free_skip_var0 = false;
+}
+ctx->skip_var0 = cpu_skip;
+return true;
+}
+
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
+{
+CPUAVRState *env = cs->env_ptr;
+DisasContext ctx = {
+.tb = tb,
+.cs = cs,
+.env = env,
+.memidx = 0,
+.bstate = DISAS_NEXT,
+.skip_cond = TCG_COND_NEVER,
+.singlestep = cs->singlestep_enabled,
+};
+target_ulong pc_start = tb->pc / 2;
+int num_insns = 0;
+
+if (tb->flags & TB_FLAGS_FULL_ACCESS) {
+/*
+ * This flag is set by ST/LD instruction we will regenerate it ONLY
+ * with mem/cpu memory access instead of mem access
+ */
+max_insns = 1;
+}
+if (ctx.singlestep) {
+max_insns = 1;
+}
+
+gen_tb_start(tb);
+
+ctx.npc = pc_start;
+if (tb->flags & TB_FLAGS_SKIP) {
+ctx.skip_cond = TCG_COND_ALWAYS;
+ctx.skip_var0 = cpu_skip;
+}
+
+do {
+TCGLabel *skip_label = NULL;
+
+/* translate current instruction */
+tcg_gen_insn_start(ctx.npc);
+num_insns++;
+
+/*
+ * this is due to some strange GDB behavior
+ * let's assume main has address 0x100
+ * b main   - sets breakpoint at address 0x0100 (code)
+ * b *0x100 -

[PATCH rc4 10/29] target/avr: Add instruction translation - Branch Instructions

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

This includes:
- RJMP, IJMP, EIJMP, JMP
- RCALL, ICALL, EICALL, CALL
- RET, RETI
- CPSE, CP, CPC, CPI
- SBRC, SBRS, SBIC, SBIS
- BRBC, BRBS

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 target/avr/insn.decode |  24 +++
 target/avr/translate.c | 532 +
 2 files changed, 556 insertions(+)

diff --git a/target/avr/insn.decode b/target/avr/insn.decode
index 9c71ed6..32034c1 100644
--- a/target/avr/insn.decode
+++ b/target/avr/insn.decode
@@ -91,3 +91,27 @@ FMUL 0011 0 ... 1 ...   @fmul
 FMULS    0011 1 ... 0 ...   @fmul
 FMULSU   0011 1 ... 1 ...   @fmul
 DES 1001 0100 imm:4 1011
+
+#
+# Branch Instructions
+#
+RJMP1100 imm:s12
+IJMP1001 0100  1001
+EIJMP   1001 0100 0001 1001
+JMP 1001 010 . 110 .imm=%imm_call
+RCALL   1101 imm:s12
+ICALL   1001 0101  1001
+EICALL  1001 0101 0001 1001
+CALL1001 010 . 111 .imm=%imm_call
+RET 1001 0101  1000
+RETI1001 0101 0001 1000
+CPSE0001 00 . . @op_rd_rr
+CP  0001 01 . . @op_rd_rr
+CPC  01 . . @op_rd_rr
+CPI 0011    @op_rd_imm8
+SBRC 110 rr:5 0 bit:3
+SBRS 111 rr:5 0 bit:3
+SBIC1001 1001 reg:5 bit:3
+SBIS1001 1011 reg:5 bit:3
+BRBS 00 ... ... @op_bit_imm
+BRBC 01 ... ... @op_bit_imm
diff --git a/target/avr/translate.c b/target/avr/translate.c
index 00fb3f5..3d40057 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -921,3 +921,535 @@ static bool trans_DES(DisasContext *ctx, arg_DES *a)
 
 return true;
 }
+
+/*
+ * Branch Instructions
+ */
+static void gen_jmp_ez(DisasContext *ctx)
+{
+tcg_gen_deposit_tl(cpu_pc, cpu_r[30], cpu_r[31], 8, 8);
+tcg_gen_or_tl(cpu_pc, cpu_pc, cpu_eind);
+ctx->bstate = DISAS_LOOKUP;
+}
+
+static void gen_jmp_z(DisasContext *ctx)
+{
+tcg_gen_deposit_tl(cpu_pc, cpu_r[30], cpu_r[31], 8, 8);
+ctx->bstate = DISAS_LOOKUP;
+}
+
+static void gen_push_ret(DisasContext *ctx, int ret)
+{
+if (avr_feature(ctx->env, AVR_FEATURE_1_BYTE_PC)) {
+
+TCGv t0 = tcg_const_i32((ret & 0xff));
+
+tcg_gen_qemu_st_tl(t0, cpu_sp, MMU_DATA_IDX, MO_UB);
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+
+tcg_temp_free_i32(t0);
+} else if (avr_feature(ctx->env, AVR_FEATURE_2_BYTE_PC)) {
+
+TCGv t0 = tcg_const_i32((ret & 0x00));
+
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+tcg_gen_qemu_st_tl(t0, cpu_sp, MMU_DATA_IDX, MO_BEUW);
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+
+tcg_temp_free_i32(t0);
+
+} else if (avr_feature(ctx->env, AVR_FEATURE_3_BYTE_PC)) {
+
+TCGv lo = tcg_const_i32((ret & 0xff));
+TCGv hi = tcg_const_i32((ret & 0x00) >> 8);
+
+tcg_gen_qemu_st_tl(lo, cpu_sp, MMU_DATA_IDX, MO_UB);
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 2);
+tcg_gen_qemu_st_tl(hi, cpu_sp, MMU_DATA_IDX, MO_BEUW);
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+
+tcg_temp_free_i32(lo);
+tcg_temp_free_i32(hi);
+}
+}
+
+static void gen_pop_ret(DisasContext *ctx, TCGv ret)
+{
+if (avr_feature(ctx->env, AVR_FEATURE_1_BYTE_PC)) {
+tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
+tcg_gen_qemu_ld_tl(ret, cpu_sp, MMU_DATA_IDX, MO_UB);
+} else if (avr_feature(ctx->env, AVR_FEATURE_2_BYTE_PC)) {
+tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
+tcg_gen_qemu_ld_tl(ret, cpu_sp, MMU_DATA_IDX, MO_BEUW);
+tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
+} else if (avr_feature(ctx->env, AVR_FEATURE_3_BYTE_PC)) {
+TCGv lo = tcg_temp_new_i32();
+TCGv hi = tcg_temp_new_i32();
+
+tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
+tcg_gen_qemu_ld_tl(hi, cpu_sp, MMU_DATA_IDX, MO_BEUW);
+
+tcg_gen_addi_tl(cpu_sp, cpu_sp, 2);
+tcg_gen_qemu_ld_tl(lo, cpu_sp, MMU_DATA_IDX, MO_UB);
+
+tcg_gen_deposit_tl(ret, lo, hi, 8, 16);
+
+tcg_temp_free_i32(lo);
+tcg_temp_free_i32(hi);
+}
+}
+
+static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
+{
+TranslationBlock *tb = ctx->tb;
+
+if (ctx->singlestep == 0) {
+tcg_gen_goto_tb(n);
+tcg_gen_movi_i32(cpu_pc, dest);
+tcg_gen_exit_tb(tb, n);
+} else {
+tcg_gen_movi_i32(cpu_pc, dest);
+gen_helper_debug(cpu_env);
+tcg_gen_exit_tb(NULL, 0);
+}
+ctx->bstate = DISAS_NORETURN;
+}
+
+/*
+ *  Relative jump to an address within PC - 2K +1 and PC + 2K (words). For
+ *  AVR microcontrollers with Program memory not exceeding 4K words (8KB) this
+ *  instruction 

[PATCH rc4 08/29] target/avr: Add instruction translation - Register definitions

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

Start implementation of instructions by adding register definitions.

Signed-off-by: Michael Rolnik 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 target/avr/translate.c | 171 +
 1 file changed, 171 insertions(+)
 create mode 100644 target/avr/translate.c

diff --git a/target/avr/translate.c b/target/avr/translate.c
new file mode 100644
index 000..535f666
--- /dev/null
+++ b/target/avr/translate.c
@@ -0,0 +1,171 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/qemu-print.h"
+#include "tcg/tcg.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "tcg/tcg-op.h"
+#include "exec/cpu_ldst.h"
+#include "exec/helper-proto.h"
+#include "exec/helper-gen.h"
+#include "exec/log.h"
+#include "exec/translator.h"
+#include "exec/gen-icount.h"
+
+/*
+ *  Define if you want a BREAK instruction translated to a breakpoint
+ *  Active debugging connection is assumed
+ *  This is for
+ *  https://github.com/seharris/qemu-avr-tests/tree/master/instruction-tests
+ *  tests
+ */
+#undef BREAKPOINT_ON_BREAK
+
+static TCGv cpu_pc;
+
+static TCGv cpu_Cf;
+static TCGv cpu_Zf;
+static TCGv cpu_Nf;
+static TCGv cpu_Vf;
+static TCGv cpu_Sf;
+static TCGv cpu_Hf;
+static TCGv cpu_Tf;
+static TCGv cpu_If;
+
+static TCGv cpu_rampD;
+static TCGv cpu_rampX;
+static TCGv cpu_rampY;
+static TCGv cpu_rampZ;
+
+static TCGv cpu_r[NUMBER_OF_CPU_REGISTERS];
+static TCGv cpu_eind;
+static TCGv cpu_sp;
+
+static TCGv cpu_skip;
+
+static const char reg_names[NUMBER_OF_CPU_REGISTERS][8] = {
+"r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
+"r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
+"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+};
+#define REG(x) (cpu_r[x])
+
+enum {
+DISAS_EXIT   = DISAS_TARGET_0,  /* We want return to the cpu main loop.  */
+DISAS_LOOKUP = DISAS_TARGET_1,  /* We have a variable condition exit.  */
+DISAS_CHAIN  = DISAS_TARGET_2,  /* We have a single condition exit.  */
+};
+
+typedef struct DisasContext DisasContext;
+
+/* This is the state at translation time. */
+struct DisasContext {
+TranslationBlock *tb;
+
+CPUAVRState *env;
+CPUState *cs;
+
+target_long npc;
+uint32_t opcode;
+
+/* Routine used to access memory */
+int memidx;
+int bstate;
+int singlestep;
+
+/*
+ * some AVR instructions can make the following instruction to be skipped
+ * Let's name those instructions
+ * A   - instruction that can skip the next one
+ * B   - instruction that can be skipped. this depends on execution of 
A
+ * there are two scenarios
+ * 1. A and B belong to the same translation block
+ * 2. A is the last instruction in the translation block and B is the last
+ *
+ * following variables are used to simplify the skipping logic, they are
+ * used in the following manner (sketch)
+ *
+ * TCGLabel *skip_label = NULL;
+ * if (ctx.skip_cond != TCG_COND_NEVER) {
+ * skip_label = gen_new_label();
+ * tcg_gen_brcond_tl(skip_cond, skip_var0, skip_var1, skip_label);
+ * }
+ *
+ * if (free_skip_var0) {
+ * tcg_temp_free(skip_var0);
+ * free_skip_var0 = false;
+ * }
+ *
+ * translate(&ctx);
+ *
+ * if (skip_label) {
+ * gen_set_label(skip_label);
+ * }
+ */
+TCGv skip_var0;
+TCGv skip_var1;
+TCGCond skip_cond;
+bool free_skip_var0;
+};
+
+static int to_regs_16_31_by_one(DisasContext *ctx, int indx)
+{
+return 16 + (indx % 16);
+}
+
+static int to_regs_16_23_by_one(DisasContext *ctx, int indx)
+{
+return 16 + (indx % 8);
+}
+static int to_regs_24_30_by_two(DisasContext *ctx, int indx)
+{
+return 24 + (indx % 4) * 2;
+}
+static int to_regs_00_30_by_two(DisasContext *ctx, int indx)
+{
+return (indx % 16) * 2;
+}
+
+static uint16_t next_word(DisasContext *ctx)
+{
+return cpu_lduw_code(ctx->env, ctx->npc++ * 2);
+}
+
+static int append_16(DisasContext *ctx, int x)
+{
+return x << 16 | next_word(ctx);
+}

[PATCH rc4 04/29] target/avr: Add GDB support

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

This includes GDB hooks for reading from wnd wrtiting to AVR
registers, and xml register definition file as well.

[AM: Split a larger AVR introduction patch into logical units]
Suggested-by: Aleksandar Markovic 

Co-developed-by: Michael Rolnik 
Co-developed-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Signed-off-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Acked-by: Igor Mammedov 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 gdb-xml/avr-cpu.xml  | 49 ++
 target/avr/cpu.c |  4 +++
 target/avr/cpu.h |  2 ++
 target/avr/gdbstub.c | 84 
 4 files changed, 139 insertions(+)
 create mode 100644 gdb-xml/avr-cpu.xml
 create mode 100644 target/avr/gdbstub.c

diff --git a/gdb-xml/avr-cpu.xml b/gdb-xml/avr-cpu.xml
new file mode 100644
index 000..c4747f5
--- /dev/null
+++ b/gdb-xml/avr-cpu.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 49e32af..f41a887 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -210,4 +210,8 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
 cc->tlb_fill = avr_cpu_tlb_fill;
 cc->tcg_initialize = avr_cpu_tcg_init;
 cc->synchronize_from_tb = avr_cpu_synchronize_from_tb;
+cc->gdb_read_register = avr_cpu_gdb_read_register;
+cc->gdb_write_register = avr_cpu_gdb_write_register;
+cc->gdb_num_core_regs = 35;
+cc->gdb_core_xml_file = "avr-cpu.xml";
 }
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index 2907a37..91dfa0f 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -124,6 +124,8 @@ extern const struct VMStateDescription vms_avr_cpu;
 void avr_cpu_do_interrupt(CPUState *cpu);
 bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int avr_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #define cpu_list avr_cpu_list
 #define cpu_signal_handler cpu_avr_signal_handler
diff --git a/target/avr/gdbstub.c b/target/avr/gdbstub.c
new file mode 100644
index 000..733184c
--- /dev/null
+++ b/target/avr/gdbstub.c
@@ -0,0 +1,84 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "exec/gdbstub.h"
+
+int avr_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = &cpu->env;
+
+/*  R */
+if (n < 32) {
+return gdb_get_reg8(mem_buf, env->r[n]);
+}
+
+/*  SREG */
+if (n == 32) {
+uint8_t sreg = cpu_get_sreg(env);
+
+return gdb_get_reg8(mem_buf, sreg);
+}
+
+/*  SP */
+if (n == 33) {
+return gdb_get_reg16(mem_buf, env->sp & 0x);
+}
+
+/*  PC */
+if (n == 34) {
+return gdb_get_reg32(mem_buf, env->pc_w * 2);
+}
+
+return 0;
+}
+
+int avr_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = &cpu->env;
+
+/*  R */
+if (n < 32) {
+env->r[n] = *mem_buf;
+return 1;
+}
+
+/*  SREG */
+if (n == 32) {
+cpu_set_sreg(env, *mem_buf);
+return 1;
+}
+
+/*  SP */
+if (n == 33) {
+env->sp = lduw_p(mem_buf);
+return 2;
+}
+
+/*  PC */
+if (n == 34) {
+env->pc_w = ldl_p(mem_buf) / 2;
+return 4;
+}
+
+return 0;
+}
-- 
2.7.4




[PATCH rc4 00/29] target/avr merger

2020-01-30 Thread Aleksandar Markovic
From: Aleksandar Markovic 

This is the AVR port from Michael, release (merge) candidate 4.

The series can be found also in this repository:

https://github.com/AMarkovic/qemu-avr-merger-rc4

History:

Since v3:

- Removed a patch on load_elf() modification, since it has been merged
- Removed references to CONFIG_USER_ONLY and provided a guard against
  building lunux user mode for AVR
- Removed all references to 'Atmel' (including file renames)
- Rebased the code (there was common interface change regarding 'props')
- Various corrections of commit messages
- A bit field for AVRFeatures is nor 64 bit long
- Other minor fixes

Since v2:

- First patch is split into six smaller logical units (net result
  remains the same)
- Patch "hw/core/loader: Let load_elf populate the processor-specific
  flags" was redone to reflect the original intent that was lost in
  transalation between multiple autors
- Patch "hw/avr: Add helper to load raw/ELF firmware binaries" was
  corrected only in one line to rectify type of "e_flags"
- Patch "target/avr: Add section about AVR into QEMU documentation"
- Spurious  elements were removed
- The series was rebased to the latest code

Since v1:

- Addressed Thomas comments
- Fixed a non-critical bug in ATmega (incorrect SRAM base address)
- Added ELF parsing requested by Aleksandar
- Dropped default machine (as with the ARM port)

Michael Rolnik (25):
  target/avr: Add basic parameters for new AVR platform
  target/avr: Introduce AVR CPU class object
  target/avr: Add migration support
  target/avr: Add GDB support
  target/avr: Introduce enumeration AVRFeature
  target/avr: Add defintions of AVR core types
  target/avr: Add instruction helpers
  target/avr: Add instruction translation - Register definitions
  target/avr: Add instruction translation - Arithmetic and Logic
Instructions
  target/avr: Add instruction translation - Branch Instructions
  target/avr: Add instruction translation - Data Transfer Instructions
  target/avr: Add instruction translation - Bit and Bit-test
Instructions
  target/avr: Add instruction translation - MCU Control Instructions
  target/avr: Add instruction translation - CPU main translation
function
  target/avr: Add instruction disassembly function
  hw/char: Add limited support for AVR USART peripheral
  hw/timer: Add limited support for AVR 16-bit timer peripheral
  hw/misc: Add limited support for AVR power device
  target/avr: Add section about AVR into QEMU documentation
  target/avr: Register AVR support with the rest of QEMU
  target/avr: Add machine none test
  target/avr: Update MAINTAINERS file
  target/avr: Update build system
  tests/boot-serial-test: Test some Arduino boards (AVR based)
  tests/acceptance: Test the Arduino MEGA2560 board

Philippe Mathieu-Daudé (4):
  hw/avr: Add helper to load raw/ELF firmware binaries
  hw/avr: Add some ATmega microcontrollers
  hw/avr: Add some Arduino boards
  .travis.yml: Run the AVR acceptance tests

 .travis.yml  |2 +-
 MAINTAINERS  |   31 +
 arch_init.c  |2 +
 configure|7 +
 default-configs/avr-softmmu.mak  |5 +
 gdb-xml/avr-cpu.xml  |   49 +
 hw/avr/Kconfig   |9 +
 hw/avr/Makefile.objs |3 +
 hw/avr/arduino.c |  151 ++
 hw/avr/atmega.c  |  470 ++
 hw/avr/atmega.h  |   48 +
 hw/avr/boot.c|   74 +
 hw/avr/boot.h|   33 +
 hw/char/Kconfig  |3 +
 hw/char/Makefile.objs|1 +
 hw/char/avr_usart.c  |  320 
 hw/misc/Kconfig  |3 +
 hw/misc/Makefile.objs|2 +
 hw/misc/avr_power.c  |  112 ++
 hw/timer/Kconfig |3 +
 hw/timer/Makefile.objs   |2 +
 hw/timer/avr_timer16.c   |  604 
 include/disas/dis-asm.h  |   19 +
 include/elf.h|2 +
 include/hw/char/avr_usart.h  |   93 ++
 include/hw/misc/avr_power.h  |   46 +
 include/hw/timer/avr_timer16.h   |   94 ++
 include/sysemu/arch_init.h   |1 +
 qapi/machine.json|3 +-
 qemu-doc.texi|   51 +
 target/avr/Makefile.objs |   34 +
 target/avr/cpu-param.h   |   37 +
 target/avr/cpu-qom.h |   54 +
 target/avr/cpu.c |  818 +++
 target/avr/cpu.h |  259 
 target/avr/disas.c   |  246 
 target/avr/gdbstub.c |   84 ++
 target/avr/helper.c  |  342 +
 target/avr/helper.h  |   29 +
 target/avr/insn.decode   |  182 +++
 target/avr/machine.c |  121 ++
 target/avr/translate.c   | 2997 ++
 tests/acceptance/machine_avr6.py |   50 +
 tests/qtest/Makefile.include |2 +
 tests/qtest/boot-serial-test.c   |   11 +
 test

[PATCH rc4 11/29] target/avr: Add instruction translation - Data Transfer Instructions

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

This includes:
- MOV, MOVW
- LDI, LDS LDX LDY LDZ
- LDDY, LDDZ
- STS, STX STY STZ
- STDY, STDZ
- LPM, LPMX
- ELPM, ELPMX
- SPM, SPMX
- IN, OUT
- PUSH, POP
- XCH
- LAS, LAC LAT

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 target/avr/insn.decode |  43 +++
 target/avr/translate.c | 987 +
 2 files changed, 1030 insertions(+)

diff --git a/target/avr/insn.decode b/target/avr/insn.decode
index 32034c1..3f9304f 100644
--- a/target/avr/insn.decode
+++ b/target/avr/insn.decode
@@ -115,3 +115,46 @@ SBIC1001 1001 reg:5 bit:3
 SBIS1001 1011 reg:5 bit:3
 BRBS 00 ... ... @op_bit_imm
 BRBC 01 ... ... @op_bit_imm
+
+#
+# Data Transfer Instructions
+#
+MOV 0010 11 . . @op_rd_rr
+MOVW 0001   &rd_rr  rd=%rd_d rr=%rr_d
+LDI 1110    @op_rd_imm8
+LDS 1001 000 .  @ldst_s
+LDX11001 000 rd:5 1100
+LDX21001 000 rd:5 1101
+LDX31001 000 rd:5 1110
+LDY21001 000 rd:5 1001
+LDY31001 000 rd:5 1010
+LDZ21001 000 rd:5 0001
+LDZ31001 000 rd:5 0010
+LDDY10 . 0 .. 0 . 1 ... @ldst_d
+LDDZ10 . 0 .. 0 . 0 ... @ldst_d
+STS 1001 001 .  @ldst_s
+STX11001 001 rr:5 1100
+STX21001 001 rr:5 1101
+STX31001 001 rr:5 1110
+STY21001 001 rd:5 1001
+STY31001 001 rd:5 1010
+STZ21001 001 rd:5 0001
+STZ31001 001 rd:5 0010
+STDY10 . 0 .. 1 . 1 ... @ldst_d
+STDZ10 . 0 .. 1 . 0 ... @ldst_d
+LPM11001 0101 1100 1000
+LPM21001 000 rd:5 0100
+LPMX1001 000 rd:5 0101
+ELPM1   1001 0101 1101 1000
+ELPM2   1001 000 rd:5 0110
+ELPMX   1001 000 rd:5 0111
+SPM 1001 0101 1110 1000
+SPMX1001 0101  1000
+IN  1011 0 .. . @io_rd_imm
+OUT 1011 1 .. . @io_rd_imm
+PUSH1001 001 rd:5 
+POP 1001 000 rd:5 
+XCH 1001 001 rd:5 0100
+LAC 1001 001 rd:5 0110
+LAS 1001 001 rd:5 0101
+LAT 1001 001 rd:5 0111
diff --git a/target/avr/translate.c b/target/avr/translate.c
index 3d40057..4a62d93 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -1453,3 +1453,990 @@ static bool trans_BRBS(DisasContext *ctx, arg_BRBS *a)
 ctx->bstate = DISAS_CHAIN;
 return true;
 }
+
+/*
+ * Data Transfer Instructions
+ */
+
+/*
+ *  in the gen_set_addr & gen_get_addr functions
+ *  H assumed to be in 0x00ff format
+ *  M assumed to be in 0x00ff format
+ *  L assumed to be in 0x00ff format
+ */
+static void gen_set_addr(TCGv addr, TCGv H, TCGv M, TCGv L)
+{
+
+tcg_gen_andi_tl(L, addr, 0x00ff);
+
+tcg_gen_andi_tl(M, addr, 0xff00);
+tcg_gen_shri_tl(M, M, 8);
+
+tcg_gen_andi_tl(H, addr, 0x00ff);
+}
+
+static void gen_set_xaddr(TCGv addr)
+{
+gen_set_addr(addr, cpu_rampX, cpu_r[27], cpu_r[26]);
+}
+
+static void gen_set_yaddr(TCGv addr)
+{
+gen_set_addr(addr, cpu_rampY, cpu_r[29], cpu_r[28]);
+}
+
+static void gen_set_zaddr(TCGv addr)
+{
+gen_set_addr(addr, cpu_rampZ, cpu_r[31], cpu_r[30]);
+}
+
+static TCGv gen_get_addr(TCGv H, TCGv M, TCGv L)
+{
+TCGv addr = tcg_temp_new_i32();
+
+tcg_gen_deposit_tl(addr, M, H, 8, 8);
+tcg_gen_deposit_tl(addr, L, addr, 8, 16);
+
+return addr;
+}
+
+static TCGv gen_get_xaddr(void)
+{
+return gen_get_addr(cpu_rampX, cpu_r[27], cpu_r[26]);
+}
+
+static TCGv gen_get_yaddr(void)
+{
+return gen_get_addr(cpu_rampY, cpu_r[29], cpu_r[28]);
+}
+
+static TCGv gen_get_zaddr(void)
+{
+return gen_get_addr(cpu_rampZ, cpu_r[31], cpu_r[30]);
+}
+
+/*
+ *  Load one byte indirect from data space to register and stores an clear
+ *  the bits in data space specified by the register. The instruction can only
+ *  be used towards internal SRAM.  The data location is pointed to by the Z 
(16
+ *  bits) Pointer Register in the Register File. Memory access is limited to 
the
+ *  current data segment of 64KB. To access another data segment in devices 
with
+ *  more than 64KB data space, the RAMPZ in register in the I/O area has to be
+ *  changed.  The Z-pointer Register is left unchanged by the operation. This
+ *  instruction is especially suited for clearing status bits stored in SRAM.
+ */
+static void gen_data_store(DisasContext *ctx, TCGv data, TCGv addr)
+{
+if (ctx->tb->flags & TB_FLAGS_FULL_ACCESS) {
+gen_helper_fullwr(cpu_env, data, addr);
+} else {
+tcg_gen_qemu_st8(data

[PATCH rc4 06/29] target/avr: Add defintions of AVR core types

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

AVR core types are:

  - avr1
  - avr2
  - avr25
  - avr3
  - avr31
  - avr35
  - avr4
  - avr5
  - avr51
  - avr6
  - avrtiny
  - xmega2
  - xmega3
  - xmega4
  - xmega5
  - xmega6
  - xmega7

Each core type covers multiple AVR MCUs, mentioned in the comments
before definition of particular AVR core type (part of this patch).

AVR core type defines shared features that are valid for all AVR
MCUs belonging in that type.

[AM: Split a larger AVR introduction patch into logical units]
Suggested-by: Aleksandar Markovic 

Co-developed-by: Michael Rolnik 
Co-developed-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Signed-off-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Acked-by: Igor Mammedov 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 target/avr/cpu.c | 601 +++
 1 file changed, 601 insertions(+)

diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index f41a887..e0ae055 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -215,3 +215,604 @@ static void avr_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->gdb_num_core_regs = 35;
 cc->gdb_core_xml_file = "avr-cpu.xml";
 }
+
+/*
+ * Setting features of AVR core type avr1
+ * --
+ *
+ * This type of AVR core is present in the following AVR MCUs:
+ *
+ * at90s1200, attiny11, attiny12, attiny15, attiny28
+ */
+static void avr_avr1_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = &cpu->env;
+
+set_avr_feature(env, AVR_FEATURE_LPM);
+set_avr_feature(env, AVR_FEATURE_2_BYTE_SP);
+set_avr_feature(env, AVR_FEATURE_2_BYTE_PC);
+}
+
+/*
+ * Setting features of AVR core type avr2
+ * --
+ *
+ * This type of AVR core is present in the following AVR MCUs:
+ *
+ * at90s2313, at90s2323, at90s2333, at90s2343, attiny22, attiny26, at90s4414,
+ * at90s4433, at90s4434, at90s8515, at90c8534, at90s8535
+ */
+static void avr_avr2_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = &cpu->env;
+
+set_avr_feature(env, AVR_FEATURE_LPM);
+set_avr_feature(env, AVR_FEATURE_IJMP_ICALL);
+set_avr_feature(env, AVR_FEATURE_ADIW_SBIW);
+set_avr_feature(env, AVR_FEATURE_SRAM);
+set_avr_feature(env, AVR_FEATURE_BREAK);
+
+set_avr_feature(env, AVR_FEATURE_2_BYTE_PC);
+set_avr_feature(env, AVR_FEATURE_2_BYTE_SP);
+}
+
+/*
+ * Setting features of AVR core type avr25
+ * --
+ *
+ * This type of AVR core is present in the following AVR MCUs:
+ *
+ * ata5272, ata6616c, attiny13, attiny13a, attiny2313, attiny2313a, attiny24,
+ * attiny24a, attiny4313, attiny44, attiny44a, attiny441, attiny84, attiny84a,
+ * attiny25, attiny45, attiny85, attiny261, attiny261a, attiny461, attiny461a,
+ * attiny861, attiny861a, attiny43u, attiny87, attiny48, attiny88, attiny828,
+ * attiny841, at86rf401
+ */
+static void avr_avr25_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = &cpu->env;
+
+set_avr_feature(env, AVR_FEATURE_LPM);
+set_avr_feature(env, AVR_FEATURE_IJMP_ICALL);
+set_avr_feature(env, AVR_FEATURE_ADIW_SBIW);
+set_avr_feature(env, AVR_FEATURE_SRAM);
+set_avr_feature(env, AVR_FEATURE_BREAK);
+
+set_avr_feature(env, AVR_FEATURE_2_BYTE_PC);
+set_avr_feature(env, AVR_FEATURE_2_BYTE_SP);
+set_avr_feature(env, AVR_FEATURE_LPMX);
+set_avr_feature(env, AVR_FEATURE_MOVW);
+}
+
+/*
+ * Setting features of AVR core type avr3
+ * --
+ *
+ * This type of AVR core is present in the following AVR MCUs:
+ *
+ * at43usb355, at76c711
+ */
+static void avr_avr3_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = &cpu->env;
+
+set_avr_feature(env, AVR_FEATURE_LPM);
+set_avr_feature(env, AVR_FEATURE_IJMP_ICALL);
+set_avr_feature(env, AVR_FEATURE_ADIW_SBIW);
+set_avr_feature(env, AVR_FEATURE_SRAM);
+set_avr_feature(env, AVR_FEATURE_BREAK);
+
+set_avr_feature(env, AVR_FEATURE_2_BYTE_PC);
+set_avr_feature(env, AVR_FEATURE_2_BYTE_SP);
+set_avr_feature(env, AVR_FEATURE_JMP_CALL);
+}
+
+/*
+ * Setting features of AVR core type avr31
+ * --
+ *
+ * This type of AVR core is present in the following AVR MCUs:
+ *
+ * atmega103, at43usb320
+ */
+static void avr_avr31_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = &cpu->env;
+
+set_avr_feature(env, AVR_FEATURE_LPM);
+set_avr_feature(env, AVR_FEATURE_IJMP_ICALL);
+set_avr_feature(env, AVR_FEATURE_ADIW_SBIW);
+set_avr_feature(env, AVR_FEATURE_SRAM);
+set_avr_feature(env, AVR_FEATURE_BREAK);
+
+set_avr_feature(env, AVR_FEATURE_2_BYTE_PC);
+set_avr_feature(env, AVR_FEATURE_2_BYTE_SP);
+set_avr_feature(env, AVR_FEATURE_RAMPZ);
+set_avr_feature(env, AVR_FEATURE_ELPM);
+set_avr

[PATCH rc4 12/29] target/avr: Add instruction translation - Bit and Bit-test Instructions

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

This includes:
- LSR, ROR
- ASR
- SWAP
- SBI, CBI
- BST, BLD
- BSET, BCLR

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 target/avr/insn.decode |  14 +++
 target/avr/translate.c | 241 +
 2 files changed, 255 insertions(+)

diff --git a/target/avr/insn.decode b/target/avr/insn.decode
index 3f9304f..4ee5586 100644
--- a/target/avr/insn.decode
+++ b/target/avr/insn.decode
@@ -158,3 +158,17 @@ XCH 1001 001 rd:5 0100
 LAC 1001 001 rd:5 0110
 LAS 1001 001 rd:5 0101
 LAT 1001 001 rd:5 0111
+
+#
+# Bit and Bit-test Instructions
+#
+LSR 1001 010 rd:5 0110
+ROR 1001 010 rd:5 0111
+ASR 1001 010 rd:5 0101
+SWAP1001 010 rd:5 0010
+SBI 1001 1010 reg:5 bit:3
+CBI 1001 1000 reg:5 bit:3
+BST  101 rd:5 0 bit:3
+BLD  100 rd:5 0 bit:3
+BSET1001 0100 0 bit:3 1000
+BCLR1001 0100 1 bit:3 1000
diff --git a/target/avr/translate.c b/target/avr/translate.c
index 4a62d93..58775af 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -2440,3 +2440,244 @@ static bool trans_LAT(DisasContext *ctx, arg_LAT *a)
 
 return true;
 }
+
+/*
+ * Bit and Bit-test Instructions
+ */
+static void gen_rshift_ZNVSf(TCGv R)
+{
+tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
+tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf = R(7) */
+tcg_gen_xor_tl(cpu_Vf, cpu_Nf, cpu_Cf);
+tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */
+}
+
+/*
+ *  Shifts all bits in Rd one place to the right. Bit 7 is cleared. Bit 0 is
+ *  loaded into the C Flag of the SREG. This operation effectively divides an
+ *  unsigned value by two. The C Flag can be used to round the result.
+ */
+static bool trans_LSR(DisasContext *ctx, arg_LSR *a)
+{
+TCGv Rd = cpu_r[a->rd];
+
+tcg_gen_andi_tl(cpu_Cf, Rd, 1);
+tcg_gen_shri_tl(Rd, Rd, 1);
+/* update status register */
+tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, Rd, 0); /* Zf = Rd == 0 */
+tcg_gen_movi_tl(cpu_Nf, 0);
+tcg_gen_mov_tl(cpu_Vf, cpu_Cf);
+tcg_gen_mov_tl(cpu_Sf, cpu_Vf);
+
+return true;
+}
+
+/*
+ *  Shifts all bits in Rd one place to the right. The C Flag is shifted into
+ *  bit 7 of Rd. Bit 0 is shifted into the C Flag.  This operation, combined
+ *  with ASR, effectively divides multi-byte signed values by two. Combined 
with
+ *  LSR it effectively divides multi-byte unsigned values by two. The Carry 
Flag
+ *  can be used to round the result.
+ */
+static bool trans_ROR(DisasContext *ctx, arg_ROR *a)
+{
+TCGv Rd = cpu_r[a->rd];
+TCGv t0 = tcg_temp_new_i32();
+
+tcg_gen_shli_tl(t0, cpu_Cf, 7);
+/* update status register */
+tcg_gen_andi_tl(cpu_Cf, Rd, 1);
+/* update output register */
+tcg_gen_shri_tl(Rd, Rd, 1);
+tcg_gen_or_tl(Rd, Rd, t0);
+/* update status register */
+gen_rshift_ZNVSf(Rd);
+
+tcg_temp_free_i32(t0);
+
+return true;
+}
+
+/*
+ *  Shifts all bits in Rd one place to the right. Bit 7 is held constant. Bit 0
+ *  is loaded into the C Flag of the SREG. This operation effectively divides a
+ *  signed value by two without changing its sign. The Carry Flag can be used 
to
+ *  round the result.
+ */
+static bool trans_ASR(DisasContext *ctx, arg_ASR *a)
+{
+TCGv Rd = cpu_r[a->rd];
+TCGv t0 = tcg_temp_new_i32();
+
+/* update status register */
+tcg_gen_andi_tl(cpu_Cf, Rd, 1); /* Cf = Rd(0) */
+/* update output register */
+tcg_gen_andi_tl(t0, Rd, 0x80); /* Rd = (Rd & 0x80) | (Rd >> 1) */
+tcg_gen_shri_tl(Rd, Rd, 1);
+tcg_gen_or_tl(Rd, Rd, t0);
+/* update status register */
+gen_rshift_ZNVSf(Rd);
+
+tcg_temp_free_i32(t0);
+
+return true;
+}
+
+/*
+ *  Swaps high and low nibbles in a register.
+ */
+static bool trans_SWAP(DisasContext *ctx, arg_SWAP *a)
+{
+TCGv Rd = cpu_r[a->rd];
+TCGv t0 = tcg_temp_new_i32();
+TCGv t1 = tcg_temp_new_i32();
+
+tcg_gen_andi_tl(t0, Rd, 0x0f);
+tcg_gen_shli_tl(t0, t0, 4);
+tcg_gen_andi_tl(t1, Rd, 0xf0);
+tcg_gen_shri_tl(t1, t1, 4);
+tcg_gen_or_tl(Rd, t0, t1);
+
+tcg_temp_free_i32(t1);
+tcg_temp_free_i32(t0);
+
+return true;
+}
+
+/*
+ *  Sets a specified bit in an I/O Register. This instruction operates on
+ *  the lower 32 I/O Registers -- addresses 0-31.
+ */
+static bool trans_SBI(DisasContext *ctx, arg_SBI *a)
+{
+TCGv data = tcg_temp_new_i32();
+TCGv port = tcg_const_i32(a->reg);
+
+gen_helper_inb(data, cpu_env, port);
+tcg_gen_ori_tl(data, data, 1 << a->bit);
+gen_helper_outb(cpu_env, port, data);
+
+tcg_temp_free_i32(port);
+tcg_temp_free_i32(data);
+
+return true;
+}
+
+/*
+ *  Clears a specified bit in an I/O Register. This instruction operates on
+ *  the lower 32

[PATCH rc4 05/29] target/avr: Introduce enumeration AVRFeature

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

This patch introduces enumeration "AVRFeature" that will be
used for defining various AVR core types.

[AM: Split a larger AVR introduction patch into logical units]
Suggested-by: Aleksandar Markovic 

Co-developed-by: Michael Rolnik 
Co-developed-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Signed-off-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Acked-by: Igor Mammedov 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 target/avr/cpu.h | 46 ++
 1 file changed, 46 insertions(+)

diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index 91dfa0f..e94dab3 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -73,6 +73,42 @@
 
 #define EF_AVR_MACH 0x7F
 
+typedef enum AVRFeature {
+AVR_FEATURE_SRAM,
+
+AVR_FEATURE_1_BYTE_PC,
+AVR_FEATURE_2_BYTE_PC,
+AVR_FEATURE_3_BYTE_PC,
+
+AVR_FEATURE_1_BYTE_SP,
+AVR_FEATURE_2_BYTE_SP,
+
+AVR_FEATURE_BREAK,
+AVR_FEATURE_DES,
+AVR_FEATURE_RMW, /* Read Modify Write - XCH LAC LAS LAT */
+
+AVR_FEATURE_EIJMP_EICALL,
+AVR_FEATURE_IJMP_ICALL,
+AVR_FEATURE_JMP_CALL,
+
+AVR_FEATURE_ADIW_SBIW,
+
+AVR_FEATURE_SPM,
+AVR_FEATURE_SPMX,
+
+AVR_FEATURE_ELPMX,
+AVR_FEATURE_ELPM,
+AVR_FEATURE_LPMX,
+AVR_FEATURE_LPM,
+
+AVR_FEATURE_MOVW,
+AVR_FEATURE_MUL,
+AVR_FEATURE_RAMPD,
+AVR_FEATURE_RAMPX,
+AVR_FEATURE_RAMPY,
+AVR_FEATURE_RAMPZ,
+} AVRFeature;
+
 typedef struct CPUAVRState CPUAVRState;
 
 struct CPUAVRState {
@@ -127,6 +163,16 @@ hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr 
addr);
 int avr_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
+static inline int avr_feature(CPUAVRState *env, AVRFeature feature)
+{
+return (env->features & (1U << feature)) != 0;
+}
+
+static inline void set_avr_feature(CPUAVRState *env, int feature)
+{
+env->features |= (1U << feature);
+}
+
 #define cpu_list avr_cpu_list
 #define cpu_signal_handler cpu_avr_signal_handler
 #define cpu_mmu_index avr_cpu_mmu_index
-- 
2.7.4




[PATCH rc4 07/29] target/avr: Add instruction helpers

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

Add helpers for instructions that need to interact with QEMU. Also,
add stubs for unimplemented instructions. Instructions SPM and WDR
are left unimplemented because they require emulation of complex
peripherals. The implementation of instruction SLEEP is very limited
due to the lack of peripherals to generate wake interrupts. Memory
access instructions are implemented here because some address ranges
actually refer to CPU registers.

Signed-off-by: Michael Rolnik 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 target/avr/helper.c | 203 
 target/avr/helper.h |  29 
 2 files changed, 232 insertions(+)
 create mode 100644 target/avr/helper.h

diff --git a/target/avr/helper.c b/target/avr/helper.c
index 354def2..c582312 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -137,3 +137,206 @@ bool avr_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 
 return true;
 }
+
+/*
+ *  helpers
+ */
+
+void helper_sleep(CPUAVRState *env)
+{
+CPUState *cs = env_cpu(env);
+
+cs->exception_index = EXCP_HLT;
+cpu_loop_exit(cs);
+}
+
+void helper_unsupported(CPUAVRState *env)
+{
+CPUState *cs = env_cpu(env);
+
+/*
+ *  I count not find what happens on the real platform, so
+ *  it's EXCP_DEBUG for meanwhile
+ */
+cs->exception_index = EXCP_DEBUG;
+if (qemu_loglevel_mask(LOG_UNIMP)) {
+qemu_log("UNSUPPORTED\n");
+cpu_dump_state(cs, stderr, 0);
+}
+cpu_loop_exit(cs);
+}
+
+void helper_debug(CPUAVRState *env)
+{
+CPUState *cs = env_cpu(env);
+
+cs->exception_index = EXCP_DEBUG;
+cpu_loop_exit(cs);
+}
+
+void helper_break(CPUAVRState *env)
+{
+CPUState *cs = env_cpu(env);
+
+cs->exception_index = EXCP_DEBUG;
+cpu_loop_exit(cs);
+}
+
+void helper_wdr(CPUAVRState *env)
+{
+CPUState *cs = env_cpu(env);
+
+/* WD is not implemented yet, placeholder */
+cs->exception_index = EXCP_DEBUG;
+cpu_loop_exit(cs);
+}
+
+/*
+ * This function implements IN instruction
+ *
+ * It does the following
+ * a.  if an IO register belongs to CPU, its value is read and returned
+ * b.  otherwise io address is translated to mem address and physical memory
+ * is read.
+ * c.  it caches the value for sake of SBI, SBIC, SBIS & CBI implementation
+ *
+ */
+target_ulong helper_inb(CPUAVRState *env, uint32_t port)
+{
+target_ulong data = 0;
+
+switch (port) {
+case 0x38: /* RAMPD */
+data = 0xff & (env->rampD >> 16);
+break;
+case 0x39: /* RAMPX */
+data = 0xff & (env->rampX >> 16);
+break;
+case 0x3a: /* RAMPY */
+data = 0xff & (env->rampY >> 16);
+break;
+case 0x3b: /* RAMPZ */
+data = 0xff & (env->rampZ >> 16);
+break;
+case 0x3c: /* EIND */
+data = 0xff & (env->eind >> 16);
+break;
+case 0x3d: /* SPL */
+data = env->sp & 0x00ff;
+break;
+case 0x3e: /* SPH */
+data = env->sp >> 8;
+break;
+case 0x3f: /* SREG */
+data = cpu_get_sreg(env);
+break;
+default:
+/* not a special register, pass to normal memory access */
+cpu_physical_memory_read(OFFSET_IO_REGISTERS + port, &data, 1);
+}
+
+return data;
+}
+
+/*
+ *  This function implements OUT instruction
+ *
+ *  It does the following
+ *  a.  if an IO register belongs to CPU, its value is written into the 
register
+ *  b.  otherwise io address is translated to mem address and physical memory
+ *  is written.
+ *  c.  it caches the value for sake of SBI, SBIC, SBIS & CBI implementation
+ *
+ */
+void helper_outb(CPUAVRState *env, uint32_t port, uint32_t data)
+{
+data &= 0x00ff;
+
+switch (port) {
+case 0x38: /* RAMPD */
+if (avr_feature(env, AVR_FEATURE_RAMPD)) {
+env->rampD = (data & 0xff) << 16;
+}
+break;
+case 0x39: /* RAMPX */
+if (avr_feature(env, AVR_FEATURE_RAMPX)) {
+env->rampX = (data & 0xff) << 16;
+}
+break;
+case 0x3a: /* RAMPY */
+if (avr_feature(env, AVR_FEATURE_RAMPY)) {
+env->rampY = (data & 0xff) << 16;
+}
+break;
+case 0x3b: /* RAMPZ */
+if (avr_feature(env, AVR_FEATURE_RAMPZ)) {
+env->rampZ = (data & 0xff) << 16;
+}
+break;
+case 0x3c: /* EIDN */
+env->eind = (data & 0xff) << 16;
+break;
+case 0x3d: /* SPL */
+env->sp = (env->sp & 0xff00) | (data);
+break;
+case 0x3e: /* SPH */
+if (avr_feature(env, AVR_FEATURE_2_BYTE_SP)) {
+env->sp = (env->sp & 0x00ff) | (data << 8);
+}
+break;
+case 0x3f: /* SREG */
+cpu_set_sreg(env, data);
+break;
+default:
+/* not a special register, pass to normal memory access */
+cpu_physical_memory_write(OFFSET_I

[PATCH rc4 01/29] target/avr: Add basic parameters for new AVR platform

2020-01-30 Thread Aleksandar Markovic
From: Michael Rolnik 

This includes definitions of various basic parameters needed
for integration of a new platform into QEMU.

[AM: Split a larger AVR introduction patch into logical units]
Suggested-by: Aleksandar Markovic 

Co-developed-by: Michael Rolnik 
Co-developed-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Signed-off-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Acked-by: Igor Mammedov 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
---
 target/avr/cpu-param.h | 37 ++
 target/avr/cpu.h   | 72 ++
 2 files changed, 109 insertions(+)
 create mode 100644 target/avr/cpu-param.h
 create mode 100644 target/avr/cpu.h

diff --git a/target/avr/cpu-param.h b/target/avr/cpu-param.h
new file mode 100644
index 000..0c29ce4
--- /dev/null
+++ b/target/avr/cpu-param.h
@@ -0,0 +1,37 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#ifndef AVR_CPU_PARAM_H
+#define AVR_CPU_PARAM_H
+
+#define TARGET_LONG_BITS 32
+/*
+ * TARGET_PAGE_BITS cannot be more than 8 bits because
+ * 1.  all IO registers occupy [0x .. 0x00ff] address range, and they
+ * should be implemented as a device and not memory
+ * 2.  SRAM starts at the address 0x0100
+ */
+#define TARGET_PAGE_BITS 8
+#define TARGET_PHYS_ADDR_SPACE_BITS 24
+#define TARGET_VIRT_ADDR_SPACE_BITS 24
+#define NB_MMU_MODES 2
+
+
+#endif
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
new file mode 100644
index 000..d122611
--- /dev/null
+++ b/target/avr/cpu.h
@@ -0,0 +1,72 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#ifndef QEMU_AVR_CPU_H
+#define QEMU_AVR_CPU_H
+
+#include "cpu-qom.h"
+#include "exec/cpu-defs.h"
+
+#define TCG_GUEST_DEFAULT_MO 0
+#define AVR_CPU_TYPE_SUFFIX "-" TYPE_AVR_CPU
+#define AVR_CPU_TYPE_NAME(name) (name AVR_CPU_TYPE_SUFFIX)
+#define CPU_RESOLVING_TYPE TYPE_AVR_CPU
+
+/*
+ * AVR has two memory spaces, data & code.
+ * e.g. both have 0 address
+ * ST/LD instructions access data space
+ * LPM/SPM and instruction fetching access code memory space
+ */
+#define MMU_CODE_IDX 0
+#define MMU_DATA_IDX 1
+
+#define EXCP_RESET 1
+#define EXCP_INT(n) (EXCP_RESET + (n) + 1)
+
+/* Number of CPU registers */
+#define NUMBER_OF_CPU_REGISTERS 32
+/* Number of IO registers accessible by ld/st/in/out */
+#define NUMBER_OF_IO_REGISTERS 64
+
+/*
+ * Offsets of AVR memory regions in host memory space.
+ *
+ * This is needed because the AVR has separate code and data address
+ * spaces that both have start from zero but have to go somewhere in
+ * host memory.
+ *
+ * It's also useful to know where some things are, like the IO registers.
+ */
+/* Flash program memory */
+#define OFFSET_CODE 0x
+/* CPU registers, IO registers, and SRAM */
+#define OFFSET_DATA 0x0080
+/* CPU registers specifically, these are mapped at the start of data */
+#define OFFSET_CPU_REGISTERS OFFSET_DATA
+/*
+ * IO registers, including status register, stack pointer, and memory
+ * mapped peripherals, mapped just after CPU registers
+ */
+#define OFFSET_IO_REGISTERS (OFFSET_DATA + NUMBER_OF_CPU_REGISTERS)
+
+#define EF_AVR_MACH 0x7F
+
+#endif /* !defined (QEMU_AVR_CPU_H) */
-- 
2.7.4




  1   2   3   4   5   >