Re: [Qemu-devel] [PATCH 2/2] char: i.MX: Add support for "TX complete" interrupt

2018-03-15 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Andrey Smirnov had to 
walk into mine at 12:11 on Thursday 15 March 2018 and say:

> Add support for "TX complete"/TXDC interrupt generate by real HW since
> it is needed to support guests other than Linux.
> 
> Based on the patch by Bill Paul as found here:
> https://bugs.launchpad.net/qemu/+bug/1753314
> 
> Cc: qemu-devel@nongnu.org
> Cc: qemu-...@nongnu.org
> Cc: Bill Paul <wp...@windriver.com>
> Cc: Peter Maydell <peter.mayd...@linaro.org>
> Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
> ---
> 
> Bill:
> 
> I only tested this with i.MX7/Linux guest combo and am hoping you can
> take this and previous patch and give it a try on your VxWorks setup.

I tried it and it seems to work as well as my original patch did. There is one 
thing I noticed, which is that when printing a lot of output to the console, 
sometimes the output will stall until you press a key to generate an input 
interrupt, and then it resumes. This happens with my original patch too. My 
suspicion is that this has to do with the lack of emulation of the FIFO 
feature of the i.MX6 UART, but I'm not certain. (It's still much better than 
not having it work at all, so I didn't really mind this. :) ) All I know for 
sure is that the stalls don't happen on real hardware.

FYI, I uploaded a sample VxWorks image that you can use for testing. You can 
find it here:

http://people.freebsd.org/~wpaul/qemu/sabrelite

The file vxWorks is the kernel, which is really all you need. This is an SMP 
image so you need to run QEMU with the -smp 4 option. The uVxWorks image and 
.dtb file are used on a real board with U-Boot and the bootm command. The 
qemu_imx.sh script contains the options I use for testing. I usually do:

% qemu_imx.sh vxWorks

You can download all the files at once by grabbing:

http://people.freebsd.org/~wpaul/qemu/sabrelite/vxworks_test.zip

At the -> prompt, you can type the following things (among others):

-> i -- show running task info
-> vxbIoctlShow -- show VxBus device tree
-> vxbDevShow -- show VxBus device tree in a different format
-> vxbDrvShow -- show VxBus drivers
-> vxbIntShow -- show information about interrupt bindings
-> vmContextShow -- show MMU mappings
-> memShow -- show heap usage
-> ifconfig -- show network interfaces
-> routec "show" -- show network routing table
-> netstat "-a" -- show network socket info

The image also includes network support. You can use ifconfig to set the enet0 
interface's addresss like this:

-> ifconfig "enet0 10.0.2.15 netmask 255.255.255.0 up"

You should then be able to telnet to the VxWorks image from the host machine 
by doing:

% telnet localhost 10023

To exit the telnet session, type logout:

-> logout

NOTE: this only works if you've patched the imx_fec module to fix the 
interrupt vector bug that I also reported.

If you run vxbIoctlShow, which generates a lot of output, you should be able 
to see the stall condition I'm talking about. If you don't, then maybe it has 
something to do with me running QEMU on FreeBSD.
 
> Peter:
> 
> Bill is the author of original code, so I am not sure how to handle
> Signed-off-by from him. I'd like to add it to this patch, but since
> his original submission to launchpad didn't have one it is currently
> omitted.

My original goal was to report the bug and provide as much info as I could on 
how to maybe fix it, and let somebody else make a proper fix/patch.

-Bill
 
>  include/hw/char/imx_serial.h |  3 +++
>  hw/char/imx_serial.c | 20 +---
>  2 files changed, 20 insertions(+), 3 deletions(-)
> 
> diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
> index baeec3183f..5b99cee7cf 100644
> --- a/include/hw/char/imx_serial.h
> +++ b/include/hw/char/imx_serial.h
> @@ -67,6 +67,8 @@
>  #define UCR2_RXEN   (1<<1)/* Receiver enable */
>  #define UCR2_SRST   (1<<0)/* Reset complete */
> 
> +#define UCR4_TCEN   BIT(3)/* TX complete interrupt enable */
> +
>  #define UTS1_TXEMPTY(1<<6)
>  #define UTS1_RXEMPTY(1<<5)
>  #define UTS1_TXFULL (1<<4)
> @@ -95,6 +97,7 @@ typedef struct IMXSerialState {
>  uint32_t ubmr;
>  uint32_t ubrc;
>  uint32_t ucr3;
> +uint32_t ucr4;
> 
>  qemu_irq irq;
>  CharBackend chr;
> diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
> index d1e8586280..1e5540472b 100644
> --- a/hw/char/imx_serial.c
> +++ b/hw/char/imx_serial.c
> @@ -37,8 +37,8 @@
> 
>  static const VMStateDescription vmstate_imx_serial = {
>  .name = TYPE_IMX_SERIAL,
> -.version_id = 1,
> -.minimum_version_id = 1,
> +.version_id = 2,
> +.minimum_version_id = 2,

Re: [Qemu-devel] [PATCH 2/2] char: i.MX: Add support for "TX complete" interrupt

2018-03-15 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Bill Paul had to walk 
into mine at 13:45 on Thursday 15 March 2018 and say:

> Of all the gin joints in all the towns in all the world, Andrey Smirnov had
> to
> 
> walk into mine at 12:11 on Thursday 15 March 2018 and say:
> > Add support for "TX complete"/TXDC interrupt generate by real HW since
> > it is needed to support guests other than Linux.
> > 
> > Based on the patch by Bill Paul as found here:
> > https://bugs.launchpad.net/qemu/+bug/1753314
> > 
> > Cc: qemu-devel@nongnu.org
> > Cc: qemu-...@nongnu.org
> > Cc: Bill Paul <wp...@windriver.com>
> > Cc: Peter Maydell <peter.mayd...@linaro.org>
> > Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
> > ---
> > 
> > Bill:
> > 
> > I only tested this with i.MX7/Linux guest combo and am hoping you can
> > take this and previous patch and give it a try on your VxWorks setup.
> 
> I tried it and it seems to work as well as my original patch did. There is
> one thing I noticed, which is that when printing a lot of output to the
> console, sometimes the output will stall until you press a key to generate
> an input interrupt, and then it resumes. This happens with my original
> patch too. My suspicion is that this has to do with the lack of emulation
> of the FIFO feature of the i.MX6 UART, but I'm not certain. (It's still
> much better than not having it work at all, so I didn't really mind this.
> :) ) All I know for sure is that the stalls don't happen on real hardware.

In retrospect, I think the problem may not be with the UART emulation. I went 
back and created a uniprocessor VxWorks image instead of an SMP image, and it 
doesn't seem to have the same stall behavior.

I added a vxWorks_up image to the URL below so that you can try that too. It 
may well be that having more than a 1 byte FIFO would fix the problem with the 
SMP image too, but I don't want to force you to implement that. If you want to 
try to fix the issue, great, otherwise I am happy with the patch as it is, so 
I will provide this:

Signed-off-by: Bill Paul <wp...@windriver.com>

-Bill

> 
> FYI, I uploaded a sample VxWorks image that you can use for testing. You
> can find it here:
> 
> http://people.freebsd.org/~wpaul/qemu/sabrelite
> 
> The file vxWorks is the kernel, which is really all you need. This is an
> SMP image so you need to run QEMU with the -smp 4 option. The uVxWorks
> image and .dtb file are used on a real board with U-Boot and the bootm
> command. The qemu_imx.sh script contains the options I use for testing. I
> usually do:
> 
> % qemu_imx.sh vxWorks
> 
> You can download all the files at once by grabbing:
> 
> http://people.freebsd.org/~wpaul/qemu/sabrelite/vxworks_test.zip
> 
> At the -> prompt, you can type the following things (among others):
> 
> -> i -- show running task info
> -> vxbIoctlShow -- show VxBus device tree
> -> vxbDevShow -- show VxBus device tree in a different format
> -> vxbDrvShow -- show VxBus drivers
> -> vxbIntShow -- show information about interrupt bindings
> -> vmContextShow -- show MMU mappings
> -> memShow -- show heap usage
> -> ifconfig -- show network interfaces
> -> routec "show" -- show network routing table
> -> netstat "-a" -- show network socket info
> 
> The image also includes network support. You can use ifconfig to set the
> enet0 interface's addresss like this:
> 
> -> ifconfig "enet0 10.0.2.15 netmask 255.255.255.0 up"
> 
> You should then be able to telnet to the VxWorks image from the host
> machine by doing:
> 
> % telnet localhost 10023
> 
> To exit the telnet session, type logout:
> 
> -> logout
> 
> NOTE: this only works if you've patched the imx_fec module to fix the
> interrupt vector bug that I also reported.
> 
> If you run vxbIoctlShow, which generates a lot of output, you should be
> able to see the stall condition I'm talking about. If you don't, then
> maybe it has something to do with me running QEMU on FreeBSD.
> 
> > Peter:
> > 
> > Bill is the author of original code, so I am not sure how to handle
> > Signed-off-by from him. I'd like to add it to this patch, but since
> > his original submission to launchpad didn't have one it is currently
> > omitted.
> 
> My original goal was to report the bug and provide as much info as I could
> on how to maybe fix it, and let somebody else make a proper fix/patch.
> 
> -Bill
> 
> >  include/hw/char/imx_serial.h |  3 +++
> >  hw/char/imx_serial.c | 20 +---
> >  2 files changed, 20 insertions(+), 3 deletions(-)

[Qemu-devel] [Bug 1753314] Re: UART in sabrelite machine simulation doesn't work with VxWorks 7

2018-03-15 Thread Bill Paul
As I said before:

"I'm not submitting this as a patch to the development list as I'm not
fully certain it complies with the hardware spec and doesn't break any
other functionality."

What I'm trying to say here is that while I may have been able to cobble
together a hack to make the UART nominally compatible with VxWorks, I do
not understand the hardware or QEMU well enough to really fix this the
right way. Even with my hack, every once in a while when printing lots
of data on the console, the output from the UART will stall unless I
press a key on the serial port, and I don't know why it does that. I did
try to investigate it a little but wasn't able to make much progress.
(My suspicion is that it has something to do with the fact that the
imx_serial module doesn't implement FIFO support, but even if that's
true I don't know how to fix it.)

Even so, I figured it was still worth it to attach my changes to the bug
report so that somebody who is better at this than me could use it as a
starting point, and so that anybody else who might want to experiment
with VxWorks using the QEMU sabrelite machine model wouldn't be totally
stuck like I was.

In short, the changes I made are good enough for my own needs (the
output stalls don't happen often enough to really bother me), but
they're not a fully debugged fix. That's why I filed a bug report
instead of just submitting a patch in the first place: I wanted somebody
sexier than me to create a fully debugged fix.

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

Title:
  UART in sabrelite machine simulation doesn't work with VxWorks 7

Status in QEMU:
  New

Bug description:
  The imx_serial.c driver currently implements only partial support for
  the i.MX6 UART hardware. (I understand it's a work in progress and
  that's fine.) dIn particular, it does not implement support for the
  Transmit Complete Interrupt Enable bit in the UCR4 register. The
  VxWorks 7 i.MX6 serial driver depends on the behavior of this bit in
  actual hardware in order to send characters through the UART
  correctly. The result is that with the current machine model, VxWorks
  will boot and run in QEMU but it's unable to print any characters to
  the console serial port.

  I have produced a small patch for the imx_serial.c module to make it
  nominally functional with VxWorks 7. It works well enough to allow the
  boot banner to appear and for the user to interact with the target
  shell.

  I'm not submitting this as a patch to the development list as I'm not
  fully certain it complies with the hardware spec and doesn't break any
  other functionality. I would prefer if the maintainer (or someone)
  reviewed it for any issues/refinements first.

  I'm attaching the patch to this bug report. A copy can also be
  obtained from:

  http://people.freebsd.org/~wpaul/qemu/imx_serial.zip

  This patch was generated against QEMU 2.11.0 but also works with QEMU
  2.11.1.

  My host environment is FreeBSD/amd64 11.1-RELEASE with QEMU
  2.11.0/2.11.11 built from source.

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



Re: [Qemu-devel] [PATCH] fsl-imx6: Swap Ethernet interrupt defines

2018-03-09 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Guenter Roeck had to 
walk into mine at 13:38 on Friday 09 March 2018 and say:

[...]
> > > > Do I have that right?
> > > 
> > > Pretty much.
> > 
> > There may be a 4th option.
> > 
> > Since older kernels work because they were looking at vector 151, you
> > could patch the imx_fec.c module so that when it signals an event for
> > vector 150, it also signals vector 151 too. This would keep newer
> > versions of QEMU "bug- compatible" with older versions while also fixing
> > support for newer Linux kernels and other guests (e.g. VxWorks) that
> > follow the hardware spec correctly.
> > 
> > I think this would require only a small modification to this function:
> > 
> > static void imx_eth_update(IMXFECState *s)
> > {
> > 
> > if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_TS_TIMER) {
> > 
> > qemu_set_irq(s->irq[1], 1);
> > 
> > } else {
> > 
> > qemu_set_irq(s->irq[1], 0);
> > 
> > }
> > 
> > if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_MAC) {
> > 
> > qemu_set_irq(s->irq[0], 1);
> > 
> > } else {
> > 
> > qemu_set_irq(s->irq[0], 0);
> > 
> > }
> > 
> > }
> > 
> > (For ENET_INT_MAC events, just signal both s->irq[0] and s->irq[1]).
> 
> Now this is an excellent idea.
> 
> > This of course means signaling spurious events on vector 151, but you're
> > doing that now anyway. :)
> 
> Actually, it doesn't. It looks like the first interrupt is handled,
> resetting the interrupt status, and the second interrupt is never even
> executed. I tested this with all kernel releases back to v3.16.

I just did a quick test with your patch and I can confirm that VxWorks 7 also 
works correctly.

-Bill

> I'll send out patch v2 with this change and let Peter decide which version
> to apply.
> 
> Thanks,
> Guenter
-- 
=
-Bill Paul(510) 749-2329 | Senior Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   "I put a dollar in a change machine. Nothing changed." - George Carlin
=



Re: [Qemu-devel] [PATCH] fsl-imx6: Swap Ethernet interrupt defines

2018-03-09 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Bill Paul had to walk 
into mine at 10:53 on Friday 09 March 2018 and say:

> Of all the gin joints in all the towns in all the world, Guenter Roeck had
> to
> 
> walk into mine at 10:20 on Friday 09 March 2018 and say:
> > On Fri, Mar 09, 2018 at 05:47:16PM +, Peter Maydell wrote:
> > > On 8 March 2018 at 18:28, Bill Paul <wp...@windriver.com> wrote:
> > > > Anyway, this means that the only reason older Linux kernels worked in
> > > > QEMU with the broken interrupt configuration is that they also
> > > > registered a handler on vector 151 (119). Even though QEMU could not
> > > > send events via GPIO6, it was mistakenly sending them via vector 151,
> > > > so it looked like things worked. On real hardware, the older kernels
> > > > would have gotten their interrupts via GPIO6 and also worked. The
> > > > older kernels would _not_ work if you fix QEMU because now they would
> > > > never get interrupts on either vector, unless you fudge things so
> > > > that the ENET module triggers both vector 150 and the vector for
> > > > GPIO6 in the GIC or patch them to back out the erratum 6678
> > > > workaround as later kernels do.
> > > 
> > > Thanks for that really useful writeup. So if I understand correctly
> > > 
> > > we have several choices here:
> > >  (1) we could implement a model of the IOMUX block that is at least
> > >  sufficient to support guests that configure it to route the ENET
> > >  interrupt line to a GPIO pin. Then we could apply this patch that
> > >  fixes the ENET line definitions. Old kernels would continue to work
> > >  (for the same reason they worked on hardware), and new ones would
> > >  work now too. This is in some ways the preferred option, but it's
> > >  possibly a lot of code and we're nearly in freeze for 2.12.
> > >  
> > >  (2) we could leave everything as it is for 2.12. This would mean that
> > >  at least we don't regress setups that used to work on older QEMU
> > >  versions. Downside is that we wouldn't be able to run Linux v4.15+, or
> > >  other guest OSes that don't have the bug that older Linux kernels do.
> > >  (Presumably we'd only do this on the understanding that we were going
> > >  to go down route (1) for 2.13.)
> > >  
> > >  (3) we could apply this patch for 2.12. Linux v4.15+ now works, as
> > >  do other guest OSes that use the ENET interrupt. v4.1 and older Linux
> > >  guests that used to boot in QEMU stop doing so, and 4.2-4.9 boot but
> > >  lose the ethernet device support. Perhaps for 2.13 we might
> > >  take route (1) to make those older guests start working again.
> > > 
> > > Do I have that right?
> > 
> > Pretty much.
> 
> There may be a 4th option.
> 
> Since older kernels work because they were looking at vector 151, you could
> patch the imx_fec.c module so that when it signals an event for vector 150,
> it also signals vector 151 too. This would keep newer versions of QEMU
> "bug- compatible" with older versions while also fixing support for newer
> Linux kernels and other guests (e.g. VxWorks) that follow the hardware
> spec correctly.

Oops, just to be clear: I mean that the vector definitions should be fixed and 
this backward-compatibility change should be applied at the same time.

-Bill
 
> I think this would require only a small modification to this function:
> 
> static void imx_eth_update(IMXFECState *s)
> {
> if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_TS_TIMER) {
> qemu_set_irq(s->irq[1], 1);
> } else {
> qemu_set_irq(s->irq[1], 0);
> }
> 
> if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_MAC) {
> qemu_set_irq(s->irq[0], 1);
> } else {
> qemu_set_irq(s->irq[0], 0);
> }
> }
> 
> (For ENET_INT_MAC events, just signal both s->irq[0] and s->irq[1]).
> 
> This of course means signaling spurious events on vector 151, but you're
> doing that now anyway. :)
> 
> This is much less work than implementing an IOMUX module. Creating an IOMUX
> module for QEMU just for this one fixup would probably be the most elegant
> solution, but adding IOMUX support to QEMU also doesn't make much sense
> since QEMU has no actual pins.
> 
> -Bill
> 
> > > None of these options seems especially palatable to me, so we're
> > > choosing the lesser evil, I think... (unless somebody wants to say
> > > that option (1) would be 2

Re: [Qemu-devel] [PATCH] fsl-imx6: Swap Ethernet interrupt defines

2018-03-09 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Guenter Roeck had to 
walk into mine at 10:20 on Friday 09 March 2018 and say:

> On Fri, Mar 09, 2018 at 05:47:16PM +, Peter Maydell wrote:
> > On 8 March 2018 at 18:28, Bill Paul <wp...@windriver.com> wrote:
> > > Anyway, this means that the only reason older Linux kernels worked in
> > > QEMU with the broken interrupt configuration is that they also
> > > registered a handler on vector 151 (119). Even though QEMU could not
> > > send events via GPIO6, it was mistakenly sending them via vector 151,
> > > so it looked like things worked. On real hardware, the older kernels
> > > would have gotten their interrupts via GPIO6 and also worked. The
> > > older kernels would _not_ work if you fix QEMU because now they would
> > > never get interrupts on either vector, unless you fudge things so that
> > > the ENET module triggers both vector 150 and the vector for GPIO6 in
> > > the GIC or patch them to back out the erratum 6678 workaround as later
> > > kernels do.
> > 
> > Thanks for that really useful writeup. So if I understand correctly
> > 
> > we have several choices here:
> >  (1) we could implement a model of the IOMUX block that is at least
> >  sufficient to support guests that configure it to route the ENET
> >  interrupt line to a GPIO pin. Then we could apply this patch that fixes
> >  the ENET line definitions. Old kernels would continue to work (for the
> >  same reason they worked on hardware), and new ones would work now too.
> >  This is in some ways the preferred option, but it's possibly a lot of
> >  code and we're nearly in freeze for 2.12.
> >  
> >  (2) we could leave everything as it is for 2.12. This would mean that
> >  at least we don't regress setups that used to work on older QEMU
> >  versions. Downside is that we wouldn't be able to run Linux v4.15+, or
> >  other guest OSes that don't have the bug that older Linux kernels do.
> >  (Presumably we'd only do this on the understanding that we were going
> >  to go down route (1) for 2.13.)
> >  
> >  (3) we could apply this patch for 2.12. Linux v4.15+ now works, as
> >  do other guest OSes that use the ENET interrupt. v4.1 and older Linux
> >  guests that used to boot in QEMU stop doing so, and 4.2-4.9 boot but
> >  lose the ethernet device support. Perhaps for 2.13 we might
> >  take route (1) to make those older guests start working again.
> > 
> > Do I have that right?
> 
> Pretty much.

There may be a 4th option.

Since older kernels work because they were looking at vector 151, you could 
patch the imx_fec.c module so that when it signals an event for vector 150, it 
also signals vector 151 too. This would keep newer versions of QEMU "bug-
compatible" with older versions while also fixing support for newer Linux 
kernels and other guests (e.g. VxWorks) that follow the hardware spec 
correctly.

I think this would require only a small modification to this function:

static void imx_eth_update(IMXFECState *s)
{
if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_TS_TIMER) {
qemu_set_irq(s->irq[1], 1);
} else {
qemu_set_irq(s->irq[1], 0);
}

if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_MAC) {
qemu_set_irq(s->irq[0], 1);
} else {
qemu_set_irq(s->irq[0], 0);
}
}

(For ENET_INT_MAC events, just signal both s->irq[0] and s->irq[1]).

This of course means signaling spurious events on vector 151, but you're doing 
that now anyway. :)

This is much less work than implementing an IOMUX module. Creating an IOMUX 
module for QEMU just for this one fixup would probably be the most elegant 
solution, but adding IOMUX support to QEMU also doesn't make much sense since 
QEMU has no actual pins.

-Bill

> > None of these options seems especially palatable to me, so we're
> > choosing the lesser evil, I think... (unless somebody wants to say
> > that option (1) would be 20 lines of code and here's the patch :-))
> > I guess in the absence of (1) that (3) is better than (2) ?
> 
> I would prefer (2). This is what I decided to use in my "local"
> version of qemu. Older versions of Linux can be fixed by applying one
> (4.2..4.9) or two (4.1 and older) upstream patches; anyone interested
> running those kernels in qemu with Ethernet working should apply those
> patches (or, alternatively, provide a patch adding IOMUX support to
> qemu).
> 
> Thanks,
> Guenter
-- 
=
-Bill Paul(510) 749-2329 | Senior Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   "I put a dollar in a change machine. Nothing changed." - George Carlin
=



Re: [Qemu-devel] [PATCH] fsl-imx6: Swap Ethernet interrupt defines

2018-03-08 Thread Bill Paul
h the broken interrupt configuration is that they also registered a handler 
on vector 151 (119). Even though QEMU could not send events via GPIO6, it was 
mistakenly sending them via vector 151, so it looked like things worked. On 
real hardware, the older kernels would have gotten their interrupts via GPIO6 
and also worked. The older kernels would _not_ work if you fix QEMU because 
now they would never get interrupts on either vector, unless you fudge things 
so that the ENET module triggers both vector 150 and the vector for GPIO6 in 
the GIC or patch them to back out the erratum 6678 workaround as later kernels 
do.

Later kernels that register vectors 150 and 151 would work with both broken 
and fixed QEMU and real hardware.

But you should fix the incorrect interrupt configuration regardless. :)
 
-Bill

> Any idea how to fix this ?
> 
> Guenter
-- 
=
-Bill Paul(510) 749-2329 | Senior Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   "I put a dollar in a change machine. Nothing changed." - George Carlin
=



[Qemu-devel] [Bug 1753309] Re: Ethernet interrupt vectors for sabrelite machine are defined backwards

2018-03-06 Thread Bill Paul
"4.14+: Both versions of qemu (as-is and interrupts reverted) work fine"

Hm. I really wonder how it can be possible that Linux works with the
interrupt vectors reversed, though to be fair I have not looked at the
Linux i.MX6 ENET driver code. I suppose it's possible that the driver is
binding the same interrupt service routine to both interrupt vectors. If
so, then it works by accident. :)

I think U-Boot uses polling so it wouldn't care if the interrupt vectors
are wrong.

We have several SabreLite boards in house. We also have NXP Sabre SD
reference boards which use the same i.MX6Q SoC and the exact same
ethernet driver with the same interrupt configuration. I have always
used VxWorks with them rather than Linux, and I can say for a fact that
the VxWorks ENET driver only binds an ISR to vector 150 (118) (VxWorks
doesn't currently support the IEEE 1588 feature with this interface so
it never uses vector 151) and it works as expected -- network interrupt
events are indeed received via vector 150.

The same VxWorks image that works with real hardware does not work with
QEMU unless I fix the vectors in fsl-imx6.h.

In short, both the hardware and the manual seem to agree. QEMU is doing
it wrong. :)

Also, the errata sheet for the i.MX6 is here:

https://www.nxp.com/docs/en/errata/IMX6DQCE.pdf

Apparently erratum 6687 is related to power management and wakeup
events. I'm not sure how that factors in to how Linux behaves.

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

Title:
  Ethernet interrupt vectors for sabrelite machine are defined backwards

Status in QEMU:
  New

Bug description:
  The sabrelite machine model used by qemu-system-arm is based on the
  Freescale/NXP i.MX6Q processor. This SoC has an on-board ethernet
  controller which is supported in QEMU using the imx_fec.c module
  (actually called imx.enet for this model.)

  The include/hw/arm/fsm-imx6.h file defines the interrupt vectors for
  the imx.enet device like this:

  #define FSL_IMX6_ENET_MAC_1588_IRQ 118
  #define FSL_IMX6_ENET_MAC_IRQ 119

  However, this is backwards. The reference manual for the i.MX6D/Q
  devices can be found here:

  https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf

  On page 225, in Table 3-1. ARM Cortex A9 domain interrupt summary, it
  shows the following:

  150 ENET
  MAC 0 IRQ, Logical OR of:
  MAC 0 Periodic Timer Overflow
  MAC 0 Time Stamp Available
  MAC 0 Time Stamp Available
  MAC 0 Time Stamp Available
  MAC 0 Payload Receive Error
  MAC 0 Transmit FIFO Underrun
  MAC 0 Collision Retry Limit
  MAC 0 Late Collision
  MAC 0 Ethernet Bus Error
  MAC 0 MII Data Transfer Done
  MAC 0 Receive Buffer Done
  MAC 0 Receive Frame Done
  MAC 0 Transmit Buffer Done
  MAC 0 Transmit Frame Done
  MAC 0 Graceful Stop
  MAC 0 Babbling Transmit Error
  MAC 0 Babbling Receive Error
  MAC 0 Wakeup Request [synchronous]

  151 ENET
  MAC 0 1588 Timer interrupt [synchronous] request

  Note:
  150 - 32 == 118
  151 - 32 == 119

  In other words, the vector definitions in the fsl-imx6.h file are
  reversed. The correct definition is:

  #define FSL_IMX6_ENET_MAC_IRQ 118
  #define FSL_IMX6_ENET_MAC_1588_IRQ 119

  I tested the sabrelite simulation using VxWorks 7 (which supports the
  SabreLite board) and found that while I was able to send and receive
  packet data via the simulated ethernet interface, the VxWorks i.MX6
  ethernet driver failed to receive any interrupts. When I corrected the
  interrupt vector definitions as shown above and recompiled QEMU,
  everything worked as expected. I was able to exchange ICMP packets
  with the simulated target and telnet to/from the VxWorks instance
  running in the virtual machine. I used the tap interface for this.

  As a workaround I was also able to make the ethernet work by modifying
  the VxWorks imx6q-sabrelite.dts file to change the ethernet interrupt
  property from 150 to 151.

  This problem was observed with the following environment:

  Host: FreeBSD/amd64 11.1-RELEASE
  QEMU version: 2.11.0 and 2.11.1 built from source code

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



[Qemu-devel] [Bug 1753314] [NEW] UART in sabrelite machine simulation doesn't work with VxWorks 7

2018-03-04 Thread Bill Paul
Public bug reported:

The imx_serial.c driver currently implements only partial support for
the i.MX6 UART hardware. (I understand it's a work in progress and
that's fine.) dIn particular, it does not implement support for the
Transmit Complete Interrupt Enable bit in the UCR4 register. The VxWorks
7 i.MX6 serial driver depends on the behavior of this bit in actual
hardware in order to send characters through the UART correctly. The
result is that with the current machine model, VxWorks will boot and run
in QEMU but it's unable to print any characters to the console serial
port.

I have produced a small patch for the imx_serial.c module to make it
nominally functional with VxWorks 7. It works well enough to allow the
boot banner to appear and for the user to interact with the target
shell.

I'm not submitting this as a patch to the development list as I'm not
fully certain it complies with the hardware spec and doesn't break any
other functionality. I would prefer if the maintainer (or someone)
reviewed it for any issues/refinements first.

I'm attaching the patch to this bug report. A copy can also be obtained
from:

http://people.freebsd.org/~wpaul/qemu/imx_serial.zip

This patch was generated against QEMU 2.11.0 but also works with QEMU
2.11.1.

My host environment is FreeBSD/amd64 11.1-RELEASE with QEMU
2.11.0/2.11.11 built from source.

** Affects: qemu
 Importance: Undecided
 Status: New


** Tags: arm sabrelite uart

** Patch added: "Patch for imx_serial.c/h to make it work with VxWorks"
   
https://bugs.launchpad.net/bugs/1753314/+attachment/5069246/+files/imx_serial.zip

** Summary changed:

- UART in sabrelite machine simulation doesn't work wth VxWorks
+ UART in sabrelite machine simulation doesn't work with VxWorks 7

** Description changed:

  The imx_serial.c driver currently implements only partial support for
- the i.MX6 UART hardware. In particular, it does not implement support
- for the Transmit Complete Interrupt Enable bit in the UCR4 register. The
- VxWorks 7 i.MX6 serial driver depends on the behavior of this bit in
- actual hardware in order to send characters through the UART correctly.
- The result is that with the current machine model, VxWorks will boot and
- run in QEMU but it's unable to print any characters to the console
- serial port.
+ the i.MX6 UART hardware. (I understand it's a work in progress and
+ that's fine.) In particular, it does not implement support for the
+ Transmit Complete Interrupt Enable bit in the UCR4 register. The VxWorks
+ 7 i.MX6 serial driver depends on the behavior of this bit in actual
+ hardware in order to send characters through the UART correctly. The
+ result is that with the current machine model, VxWorks will boot and run
+ in QEMU but it's unable to print any characters to the console serial
+ port.
  
  I have produced a small patch for the imx_serial.c module to make it
  nominally functional with VxWorks 7. It works well enough to allow the
  boot banner to appear and for the user to interact with the target
  shell.
  
  I'm not submitting this as a patch to the development list as I'm not
  fully certain it complies with the hardware spec and doesn't break any
  other functionality. I would prefer if the maintainer (or someone)
  reviewed it for any issues/refinements first.
  
  I'm attaching the patch to this bug report. A copy can also be obtained
  from:
  
  http://people.freebsd.org/~wpaul/qemu/imx_serial.zip
  
  This patch was generated against QEMU 2.11.0 but also works with QEMU
  2.11.1.

** Description changed:

  The imx_serial.c driver currently implements only partial support for
  the i.MX6 UART hardware. (I understand it's a work in progress and
- that's fine.) In particular, it does not implement support for the
+ that's fine.) dIn particular, it does not implement support for the
  Transmit Complete Interrupt Enable bit in the UCR4 register. The VxWorks
  7 i.MX6 serial driver depends on the behavior of this bit in actual
  hardware in order to send characters through the UART correctly. The
  result is that with the current machine model, VxWorks will boot and run
  in QEMU but it's unable to print any characters to the console serial
  port.
  
  I have produced a small patch for the imx_serial.c module to make it
  nominally functional with VxWorks 7. It works well enough to allow the
  boot banner to appear and for the user to interact with the target
  shell.
  
  I'm not submitting this as a patch to the development list as I'm not
  fully certain it complies with the hardware spec and doesn't break any
  other functionality. I would prefer if the maintainer (or someone)
  reviewed it for any issues/refinements first.
  
  I'm attaching the patch to this bug report. A copy can also be obtained
  from:
  
  http://people.freebsd.org/~wpaul/qemu/imx_serial.zip
  
  This patch was generated against QEMU 2.11.0 but also works with QEMU
  2.11.1.
+ 
+ My host environment is FreeBSD/amd64 11.1-RELEASE 

[Qemu-devel] [Bug 1753309] [NEW] Ethernet interrupt vectors for sabrelite machine are defined backwards

2018-03-04 Thread Bill Paul
Public bug reported:

The sabrelite machine model used by qemu-system-arm is based on the
Freescale/NXP i.MX6Q processor. This SoC has an on-board ethernet
controller which is supported in QEMU using the imx_fec.c module
(actually called imx.enet for this model.)

The include/hw/arm/fsm-imx6.h file defines the interrupt vectors for the
imx.enet device like this:

#define FSL_IMX6_ENET_MAC_1588_IRQ 118
#define FSL_IMX6_ENET_MAC_IRQ 119

However, this is backwards. The reference manual for the i.MX6D/Q
devices can be found here:

https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf

On page 225, in Table 3-1. ARM Cortex A9 domain interrupt summary, it
shows the following:

150 ENET
MAC 0 IRQ, Logical OR of:
MAC 0 Periodic Timer Overflow
MAC 0 Time Stamp Available
MAC 0 Time Stamp Available
MAC 0 Time Stamp Available
MAC 0 Payload Receive Error
MAC 0 Transmit FIFO Underrun
MAC 0 Collision Retry Limit
MAC 0 Late Collision
MAC 0 Ethernet Bus Error
MAC 0 MII Data Transfer Done
MAC 0 Receive Buffer Done
MAC 0 Receive Frame Done
MAC 0 Transmit Buffer Done
MAC 0 Transmit Frame Done
MAC 0 Graceful Stop
MAC 0 Babbling Transmit Error
MAC 0 Babbling Receive Error
MAC 0 Wakeup Request [synchronous]

151 ENET
MAC 0 1588 Timer interrupt [synchronous] request

Note:
150 - 32 == 118
151 - 32 == 119

In other words, the vector definitions in the fsl-imx6.h file are
reversed. The correct definition is:

#define FSL_IMX6_ENET_MAC_IRQ 118
#define FSL_IMX6_ENET_MAC_1588_IRQ 119

I tested the sabrelite simulation using VxWorks 7 (which supports the
SabreLite board) and found that while I was able to send and receive
packet data via the simulated ethernet interface, the VxWorks i.MX6
ethernet driver failed to receive any interrupts. When I corrected the
interrupt vector definitions as shown above and recompiled QEMU,
everything worked as expected. I was able to exchange ICMP packets with
the simulated target and telnet to/from the VxWorks instance running in
the virtual machine. I used the tap interface for this.

As a workaround I was also able to make the ethernet work by modifying
the VxWorks imx6q-sabrelite.dts file to change the ethernet interrupt
property from 150 to 151.

This problem was observed with the following environment:

Host: FreeBSD/amd64 11.1-RELEASE
QEMU version: 2.11.0 and 2.11.1 built from source code

** Affects: qemu
 Importance: Undecided
 Status: New


** Tags: arm imx.enet sabrelite

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

Title:
  Ethernet interrupt vectors for sabrelite machine are defined backwards

Status in QEMU:
  New

Bug description:
  The sabrelite machine model used by qemu-system-arm is based on the
  Freescale/NXP i.MX6Q processor. This SoC has an on-board ethernet
  controller which is supported in QEMU using the imx_fec.c module
  (actually called imx.enet for this model.)

  The include/hw/arm/fsm-imx6.h file defines the interrupt vectors for
  the imx.enet device like this:

  #define FSL_IMX6_ENET_MAC_1588_IRQ 118
  #define FSL_IMX6_ENET_MAC_IRQ 119

  However, this is backwards. The reference manual for the i.MX6D/Q
  devices can be found here:

  https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf

  On page 225, in Table 3-1. ARM Cortex A9 domain interrupt summary, it
  shows the following:

  150 ENET
  MAC 0 IRQ, Logical OR of:
  MAC 0 Periodic Timer Overflow
  MAC 0 Time Stamp Available
  MAC 0 Time Stamp Available
  MAC 0 Time Stamp Available
  MAC 0 Payload Receive Error
  MAC 0 Transmit FIFO Underrun
  MAC 0 Collision Retry Limit
  MAC 0 Late Collision
  MAC 0 Ethernet Bus Error
  MAC 0 MII Data Transfer Done
  MAC 0 Receive Buffer Done
  MAC 0 Receive Frame Done
  MAC 0 Transmit Buffer Done
  MAC 0 Transmit Frame Done
  MAC 0 Graceful Stop
  MAC 0 Babbling Transmit Error
  MAC 0 Babbling Receive Error
  MAC 0 Wakeup Request [synchronous]

  151 ENET
  MAC 0 1588 Timer interrupt [synchronous] request

  Note:
  150 - 32 == 118
  151 - 32 == 119

  In other words, the vector definitions in the fsl-imx6.h file are
  reversed. The correct definition is:

  #define FSL_IMX6_ENET_MAC_IRQ 118
  #define FSL_IMX6_ENET_MAC_1588_IRQ 119

  I tested the sabrelite simulation using VxWorks 7 (which supports the
  SabreLite board) and found that while I was able to send and receive
  packet data via the simulated ethernet interface, the VxWorks i.MX6
  ethernet driver failed to receive any interrupts. When I corrected the
  interrupt vector definitions as shown above and recompiled QEMU,
  everything worked as expected. I was able to exchange ICMP packets
  with the simulated target and telnet to/from the VxWorks instance
  running in the virtual machine. I used the tap interface for this.

  As a workaround I was also able to make the ethernet work by modifying
  the VxWorks imx6q-sabrelite.dts file to change the ethernet interrupt
  property from 150 to 

[Qemu-devel] [PATCH] Fix TXE/TXEIE support in the STM32 USART model

2016-09-05 Thread Bill Paul
This commit attempts to fix the behavior of the TX FIFO Empty bit in
the STM32 USART driver. The two changes are:

1) After wrtiting to the data register, don't clear the TXE
bit in the status register. The way this model works, the FIFO is
effectively always empty. This is because we dump each character to
qemu_chr_fe_write_all() right away and unlike real hardware we don't
have to wait for the appropriate bits to be written to the I/O pins.

2) Implement support for the TXEIE (TXE interrupt enable) bit in CR1. When
OS driver code unmasks this bit and TXE is set, this should trigger an
interrupt to let the OS know the channel is now empty and it can send again.

ChibiOS depends on the correct behavior of the TXE and the TXEIE interrupt.
It checks to see if the TXE bit is set before trying to write any
characters. however at the outset TXE is clear, so it blocks forever
(or until you press a key at the serial console, which causes an RX
interrupt that unjams in).

Also once a character has been written, it waits for a TXEIE interrupt
before sending the next character in a string. With these two fixes, it can
now write to the serial port sucessfully.

Signed-off-by: Bill Paul <wp...@windriver.com>
Cc: Paolo Bonzini <pbonz...@redhat.com>
---
 hw/char/stm32f2xx_usart.c | 7 ++-
 include/hw/char/stm32f2xx_usart.h | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
index 15657ab..5671a7d 100644
--- a/hw/char/stm32f2xx_usart.c
+++ b/hw/char/stm32f2xx_usart.c
@@ -156,7 +156,6 @@ static void stm32f2xx_usart_write(void *opaque, hwaddr addr,
 qemu_chr_fe_write_all(s->chr, , 1);
 }
 s->usart_sr |= USART_SR_TC;
-s->usart_sr &= ~USART_SR_TXE;
 }
 return;
 case USART_BRR:
@@ -168,6 +167,12 @@ static void stm32f2xx_usart_write(void *opaque, hwaddr 
addr,
 s->usart_sr & USART_SR_RXNE) {
 qemu_set_irq(s->irq, 1);
 }
+
+if (s->usart_cr1 & USART_CR1_TXEIE &&
+s->usart_sr & USART_SR_TXE) {
+qemu_set_irq(s->irq, 1);
+}
+
 return;
 case USART_CR2:
 s->usart_cr2 = value;
diff --git a/include/hw/char/stm32f2xx_usart.h 
b/include/hw/char/stm32f2xx_usart.h
index b97f192..2820209 100644
--- a/include/hw/char/stm32f2xx_usart.h
+++ b/include/hw/char/stm32f2xx_usart.h
@@ -44,6 +44,7 @@
 #define USART_SR_RXNE (1 << 5)
 
 #define USART_CR1_UE  (1 << 13)
+#define USART_CR1_TXEIE (1 << 7)
 #define USART_CR1_RXNEIE  (1 << 5)
 #define USART_CR1_TE  (1 << 3)
 #define USART_CR1_RE  (1 << 2)
-- 
2.9.0




Re: [Qemu-devel] ARM Cortex-M issues

2016-08-29 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Peter Maydell had to 
walk into mine at 12:51:04 on Monday 29 August 2016 and say:

> On 29 August 2016 at 13:59, Bill Paul <wp...@windriver.com> wrote:
> > Unfortunately it's been a frustrating experience because there seem to be
> > several key places where QEMU's hardware emulation diverges from reality.
> > The ChibiOS examples often seem to depend on behavior that is valid for
> > actual hardware but which is either broken or just missing in QEMU. Some
> > of these issues are board-specific, but the last one seems a bit more
> > general.
> 
> Yes, our Cortex-M support is a bit undermaintained at the moment.
> If you'd like to write patches to fix some of the bugs you're
> encountering I'd be happy to review them, but I'm not aware of anybody
> actively working on M profile right now. We could really use a
> contributor who cares about it and has time to tackle improving it.
> (A-profile ARM emulation is in much better shape.)

I had a feeling you were going to say that. But I already fell for this trick 
once when I started using FreeBSD, and then I ended up being a developer for  
about 10 years. I'm older and wiser now. (Also I have a day job that consumes 
most of my time.)

The best I might be able to do is patch the STM32 SUART driver so that it 
supports the TX fifo empty interrupt. I'm really not sure how to fix the STM32 
timer driver (like I said, the ST Micro documentation is really hard to 
follow) and I'm not sure that any attempt to get the NMI to work would be any 
less of a hack then what's there now.

[...]
 
> The reason for this kind of thing is that the original support was
> done to support a specific RTOS, and so bugs which resulted in that
> RTOS not working were found and fixed. Bugs which weren't exercised
> by that RTOS remain lurking in the code, and if you try to use a
> different RTOS guest then you can run into them. (This is less
> obvious on the A profile cores because to a first approximation
> nobody runs anything but Linux on them, but in the embedded world
> there's still a fairly rich diversity of RTOSes which take different
> approaches to how they prod the hardware.)

In other words it's half-baked. :(

-Bill

> thanks
> -- PMM

-- 
=
-Bill Paul(510) 749-2329 | Senior Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   "I put a dollar in a change machine. Nothing changed." - George Carlin
=



Re: [Qemu-devel] ARM Cortex-M issues

2016-08-29 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Liviu Ionescu had to 
walk into mine at 12:19:42 on Monday 29 August 2016 and say:

> > On 29 Aug 2016, at 20:59, Bill Paul <wp...@windriver.com> wrote:
> > 
> > I recently started tinkering with ChibiOS as part of a small personal
> > project ...
> 
> I did most of the development for the µOS++/CMSIS++
> (http://micro-os-plus.github.io) on STM32F4DISCOVERY board, emulated by
> GNU ARM Eclipse QEMU, which implements even animated LEDs on a graphical
> image of the board.
> 
> FreeRTOS also works properly on the emulator, both the M0 and M3 ports.
> 
> As for Cortex-M implementation, there are many improvements in the GNU ARM
> Eclipse QEMU fork (http://gnuarmeclipse.github.io/qemu/), including an
> Eclipse debug plug-in to start it; it may be worth giving it a try for
> ChibiOS too.

I think I've been down this road already with Xilinx ARM support. ("We have 
our own fork of QEMU For the MPSoC parts!" "It seems to have diverged a lot of 
from the mainline. Also you've only been testing the ARM builds and those only 
on Linux hosts, and now the code has bitrotted." "Yeah... but... we're going 
to submit our changes to upstream Real Soon Now (tm).")

Note that I'm not suggesting the ARM Eclipse code suffers from bitrot. I'll 
give it a try. I just wish all of this was in once place.

Also, from a cursory look at the code, it doesn't look like this fork handles 
the NMI interrupt any better than the mainline.

The Cortex-M model has an explicit NMI vector in its vector table (#2). It's 
possible to trigger this interrupt via software by writing a 1 to the 
NMIPENDSET bit in the ICSR register in the System Control Block (which seems 
to be a Cortex-M-specific thing).

Currently this vector is treated just like any other IRQ. The problem is that 
means it is also subject to the case where CPSR_I is masked off in the CPU, 
which for the NMI is wrong. (How can you mask that which is unmaskabkle?)

From looking at how things are structured, I think the only way to make it 
work is to give the target-arm/cpu.c code a separate external NMI pin (e.g. 
CPU_INTERRUPT_NMI) and make the arm_gic.c smart enough to trigger that pin 
instead of the IRQ or FIQ pins when the NMI is triggered. The handling for 
that pin could then be special-cased not to ignore the state of CPSR_I.

But that was just from a quick look last night while I was experimenting. I 
don't know if maybe there's a better way. This is why I'm here asking 
questions. :)

-Bill

> 
> Regards,
> 
> Liviu

-- 
=
-Bill Paul(510) 749-2329 | Senior Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   "I put a dollar in a change machine. Nothing changed." - George Carlin
=



[Qemu-devel] ARM Cortex-M issues

2016-08-29 Thread Bill Paul
MI just work?

-Bill

-- 
=====
-Bill Paul(510) 749-2329 | Senior Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   "I put a dollar in a change machine. Nothing changed." - George Carlin
=



[Qemu-devel] [PATCH] hw/timer: Revert "hpet: inverse polarity when pin above ISA_NUM_IRQS"

2016-04-05 Thread Bill Paul
This reverts commit 0d63b2dd31464cfccc80bbeedc24e3863fe4c895.

This change was originally intended to correct the HPET behavior
in conjunction with Linux, however the behavior that it actually creates
doesn't match what happens with real hardware, the logic doesn't seem
compatible with the ioapic.c implementation either.

Signed-off-by: Bill Paul <wp...@windriver.com>
CC: Paolo Bonzini <pbonz...@redhat.com>
CC: Richard Henderson <r...@twiddle.net>
CC: Eduardo Habkost <ehabk...@redhat.com>
---
 hw/timer/hpet.c | 14 ++
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index 78140e6..a2c18b3 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -201,12 +201,7 @@ static void update_irq(struct HPETTimer *timer, int set)
 if (!set || !timer_enabled(timer) || !hpet_enabled(timer->state)) {
 s->isr &= ~mask;
 if (!timer_fsb_route(timer)) {
-/* fold the ICH PIRQ# pin's internal inversion logic into hpet */
-if (route >= ISA_NUM_IRQS) {
-qemu_irq_raise(s->irqs[route]);
-} else {
-qemu_irq_lower(s->irqs[route]);
-}
+qemu_irq_lower(s->irqs[route]);
 }
 } else if (timer_fsb_route(timer)) {
 address_space_stl_le(_space_memory, timer->fsb >> 32,
@@ -214,12 +209,7 @@ static void update_irq(struct HPETTimer *timer, int set)
  NULL);
 } else if (timer->config & HPET_TN_TYPE_LEVEL) {
 s->isr |= mask;
-/* fold the ICH PIRQ# pin's internal inversion logic into hpet */
-if (route >= ISA_NUM_IRQS) {
-qemu_irq_lower(s->irqs[route]);
-} else {
-qemu_irq_raise(s->irqs[route]);
-}
+qemu_irq_raise(s->irqs[route]);
 } else {
 s->isr &= ~mask;
 qemu_irq_pulse(s->irqs[route]);
-- 
2.4.6




Re: [Qemu-devel] Question about hw/timer/hpet.c, hw/intc/ioapic.c and polarity

2016-04-05 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Paolo Bonzini had to 
walk into mine at 06:20:05 on Tuesday 05 April 2016 and say:

> On 04/04/2016 23:42, Bill Paul wrote:
> > I'm testing some of the HPET handling code in VxWorks using QEMU 2.4.1
> > and I've encountered something which looks a little odd that I'm hoping
> > someone can clarify for me. First, some background:
> > 
> > The HPET timer supports three kinds of interrupt delivery:
> > 
> > Legacy: HPET can use the same IRQs as the old 8254 timer (IRQ2, IRQ8)
> > I/O APIC: HPET can use any of the first 32 I/O APIC IRQs in the system
> > FSB: HPET uses "front-side bus" mode, i.e interrupts are routed right to
> > the local APIC (I/O APIC is bypassed)
> > 
> > By default, VxWorks uses front-side bus mode, and that seems to work
> > fine. However I wanted to try I/O APIC mode too, and that seems to
> > behave in a funny
> > 
> > way. In particular, the following code in hw/timer/hpet.c puzzles me:
> > if (!set || !timer_enabled(timer) || !hpet_enabled(timer->state)) {
> > 
> > s->isr &= ~mask;
> > if (!timer_fsb_route(timer)) {
> > 
> > /* fold the ICH PIRQ# pin's internal inversion logic into
> > hpet */ if (route >= ISA_NUM_IRQS) {
> > 
> > qemu_irq_raise(s->irqs[route]);
> > 
> > } else {
> > 
> > qemu_irq_lower(s->irqs[route]);
> > 
> > }
> > 
> > }
> > 
> > } else if (timer_fsb_route(timer)) {
> > 
> > address_space_stl_le(_space_memory, timer->fsb >> 32,
> > 
> >  timer->fsb & 0x,
> >  MEMTXATTRS_UNSPECIFIED, NULL);
> > 
> > } else if (timer->config & HPET_TN_TYPE_LEVEL) {
> > 
> > s->isr |= mask;
> > /* fold the ICH PIRQ# pin's internal inversion logic into hpet */
> > if (route >= ISA_NUM_IRQS) {
> > 
> > qemu_irq_lower(s->irqs[route]);
> > 
> > } else {
> > 
> > qemu_irq_raise(s->irqs[route]);
> > 
> > }
> > 
> > } else {
> > 
> > s->isr &= ~mask;
> > qemu_irq_pulse(s->irqs[route]);
> > 
> > }
> > 
> > Note the part that inverts the interrupt handling logic for ICH PIRQ
> > pins. I don't understand how this is supposed to work.
> 
> I think t should be removed.
> 
>  If I use level triggered IRQ2
> 
> > or IRQ8 in VxWorks, then things work as expected. But if I use IRQ21, the
> > HPET timer interrupt service routine is immediately called, even though
> > the timer hasn't expired yet. The ISR reads 0 from the HPET status
> > register, indicating that no timers have events pending, so it just
> > returns. The first qemu_irq_raise() call is triggered because
> > hpet_enabled() returns true, but timer_enabled() returns false.
> > 
> > Researching the code history, I see that the inversion logic was added in
> > 2013 in order to fix a problem with HPET usage in Linux. However
> > something about the way this was done looks wrong to me. In the case
> > where we actually want to signal an interrupt because the timer has
> > expired, and the IRQ is larger than 15, the code calls qemu_irq_lower()
> > instead of qemu_irq_raise(). Eventually this results in ioapic_set_irq()
> > being called with level = 0. The problem is, ioapic_set_irq() will only
> > call ioapic_service() to notify the quest of an interrupt if level == 1.
> > 
> > Given this, I can't understand how this is supposed to work. The hpet.c
> > code seems to treat qemu_irq_raise() and qemu_irq_lower() as though they
> > can trigger active high or active low interrupts, but the ioapic.c code
> > doesn't support any polarity settings. The only way to actually trigger
> > an interrupt to the guest is to "raise" (assert) the interrupt by
> > calling qemu_irq_raise().
> 
> I think that commit 0d63b2d ("hpet: inverse polarity when pin above
> ISA_NUM_IRQS", 2013-12-11) can be reverted.  The code was probably
> tested on KVM only, but KVM now is *also* ignoring the IOAPIC polarity
> (commit 100943c54e09, "kvm: x86: ignore ioapic polarity", 2014-03-13).

I wonder how it worked on KVM.
 
> Does that work for you?  If so, can you

[Qemu-devel] Question about hw/timer/hpet.c, hw/intc/ioapic.c and polarity

2016-04-04 Thread Bill Paul
I'm testing some of the HPET handling code in VxWorks using QEMU 2.4.1 and 
I've encountered something which looks a little odd that I'm hoping someone 
can clarify for me. First, some background:

The HPET timer supports three kinds of interrupt delivery:

Legacy: HPET can use the same IRQs as the old 8254 timer (IRQ2, IRQ8)
I/O APIC: HPET can use any of the first 32 I/O APIC IRQs in the system
FSB: HPET uses "front-side bus" mode, i.e interrupts are routed right to the 
local APIC (I/O APIC is bypassed)

By default, VxWorks uses front-side bus mode, and that seems to work fine. 
However I wanted to try I/O APIC mode too, and that seems to behave in a funny 
way. In particular, the following code in hw/timer/hpet.c puzzles me:

if (!set || !timer_enabled(timer) || !hpet_enabled(timer->state)) {
s->isr &= ~mask;
if (!timer_fsb_route(timer)) {
/* fold the ICH PIRQ# pin's internal inversion logic into hpet */
if (route >= ISA_NUM_IRQS) {
qemu_irq_raise(s->irqs[route]);
} else {
qemu_irq_lower(s->irqs[route]);
}
}
} else if (timer_fsb_route(timer)) {
address_space_stl_le(_space_memory, timer->fsb >> 32,
 timer->fsb & 0x, MEMTXATTRS_UNSPECIFIED,
 NULL);
} else if (timer->config & HPET_TN_TYPE_LEVEL) {
s->isr |= mask;
/* fold the ICH PIRQ# pin's internal inversion logic into hpet */
if (route >= ISA_NUM_IRQS) {
qemu_irq_lower(s->irqs[route]);
} else {
qemu_irq_raise(s->irqs[route]);
}
} else {
s->isr &= ~mask;
qemu_irq_pulse(s->irqs[route]);
}

Note the part that inverts the interrupt handling logic for ICH PIRQ pins. I 
don't understand how this is supposed to work. If I use level triggered IRQ2 
or IRQ8 in VxWorks, then things work as expected. But if I use IRQ21, the HPET 
timer interrupt service routine is immediately called, even though the timer 
hasn't expired yet. The ISR reads 0 from the HPET status register, indicating 
that no timers have events pending, so it just returns. The first 
qemu_irq_raise() call is triggered because hpet_enabled() returns true, but 
timer_enabled() returns false.

Researching the code history, I see that the inversion logic was added in 2013 
in order to fix a problem with HPET usage in Linux. However something about 
the way this was done looks wrong to me. In the case where we actually want to 
signal an interrupt because the timer has expired, and the IRQ is larger than 
15, the code calls qemu_irq_lower() instead of qemu_irq_raise(). Eventually 
this results in ioapic_set_irq() being called with level = 0. The problem is, 
ioapic_set_irq() will only call ioapic_service() to notify the quest of an 
interrupt if level == 1.

Given this, I can't understand how this is supposed to work. The hpet.c code 
seems to treat qemu_irq_raise() and qemu_irq_lower() as though they can 
trigger active high or active low interrupts, but the ioapic.c code doesn't 
support any polarity settings. The only way to actually trigger an interrupt 
to the guest is to "raise" (assert) the interrupt by calling qemu_irq_raise().

Right now all I know is that VxWorks' usage of the HPET seems to work on real 
hardware, but not on QEMU. I suspect that the changes made to hpet.c here may 
have only "fixed" the problem with Linux by introducing some non-standard 
behavior that happens to pacify Linux's particular usage model.

Can someone comment on whether or not this inversion logic is really still 
necessary in Linux? Is there maybe a better way to handle this?

-Bill

-- 
=
-Bill Paul(510) 749-2329 | Senior Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   "I put a dollar in a change machine. Nothing changed." - George Carlin
=



Re: [Qemu-devel] Possible bug in target-i386/helper.c:do_cpu_init()?

2015-10-01 Thread Bill Paul
Ping?

> Consider the following circumstances:
> 
> - An x86-64 multicore system is running with all cores set for long mode
>   (EFER.LME and EFER.LMA set)
> - The OS decides to re-launch one of the AP CPUs using an INIT IPI
> 
> According to the Intel architecture manual, an INIT IPI should reset the
> CPU state (with a few small exceptions):
> 
> [...]
> 10.4.7.3   Local APIC State After an INIT Reset ("Wait-for-SIPI" State)
> 
> An INIT reset of the processor can be initiated in either of two ways:
> ·By asserting the processor's INIT# pin.
> ·By sending the processor an INIT IPI (an IPI with the delivery mode
> set to INIT).
> 
> Upon receiving an INIT through either of these mechanisms, the processor
> responds by beginning the initialization process of the processor core and
> the local APIC. The state of the local APIC following an INIT reset is the
> same as it is after a power-up or hardware reset, except that the APIC ID
> and arbitration ID registers are not affected. This state is also referred
> to at the "wait-for-SIPI" state (see also: Section 8.4.2, "MP
> Initialization Protocol Requirements and Restrictions").
> [...]
> 
> Note however that do_cpu_init() does this:
> 
> 1225 void do_cpu_init(X86CPU *cpu)
> 1226 {
> 1227 CPUState *cs = CPU(cpu);
> 1228 CPUX86State *env = >env;
> 1229 CPUX86State *save = g_new(CPUX86State, 1);
> 1230 int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
> 1231
> 1232 *save = *env;
> 1233
> 1234 cpu_reset(cs);
> 1235 cs->interrupt_request = sipi;
> 1236 memcpy(>start_init_save, >start_init_save,
> 1237offsetof(CPUX86State, end_init_save) -
> 1238offsetof(CPUX86State, start_init_save));
> 1239 g_free(save);
> 1240
> 1241 if (kvm_enabled()) {
> 1242 kvm_arch_do_init_vcpu(cpu);
> 1243 }
> 1244 apic_init_reset(cpu->apic_state);
> 1245 }
> 
> The CPU environment, which in this case includes the EFER state, is saved
> and restored when calling cpu_reset(). The x86_cpu_reset() function
> actually does clear all of the CPU environment, but this function puts it
> all back.
> 
> The result of this is that if the CPU was in long mode and you do an INIT
> IPI, the CPU still has the EFER.LMA and EFER.LME bits set, even though
> it's not actually running in long mode anymore. It doesn't seem possible
> for the guest to get the CPU out of this state, and one nasty side-effect
> is that trying to set the CR0 to enable paging never succeeds.
> 
> I added the following code at line 1240 above as a workaround:
> 
> #ifdef TARGET_X86_64
> /*
>  * The initial state of the CPU is not 64-bit mode. This being
>  * the case, don't leave the EFER.LME or EFER.LME bits set.
>  */
> 
> cpu_load_efer(env, 0);
> #endif
> 
> This seemed to fix the problem I was having, however I'm not certain this
> is the correct fix.
> 
> As background, I ran across this problem testing VxWorks with QEMU 2.3.0
> and OVMF firmware. The VxWorks BOOTX64.EFI loader is able to load and run
> 32-bit VxWorks images on 64-bit hardware by forcing the CPU back to 32-bit
> mode before handing control to the OS. However it only does this for the
> BSP (CPU 0). It turns out that the UEFI firmware puts the AP cores into
> long mode too. (This may be new in recent UEFI/OVMF versions, because I'm
> pretty sure tested this path before and didn't see a problem.) Everything
> works ok with uniprocessor images, but with SMP images, launching the
> first AP CPU fails due to the above condition (the CPU starts up, but is
> unable to enable paging and dies screaming in short order).
> 
> Booting with the 32-bit OVMF build and the VxWorks BOOTIA32.EFI loader
> works ok. The same VxWorks loader and kernel code also seems to run ok on
> real hardware.
> 
> I'm using QEMU 2.3.0 on FreeBSD/amd64 9.2-RELEASE. I'm not using KVM. It
> looks like the code is still the same in the git repo. Am I correct that
> do_cpu_init() should be clearing the EFER contents?
> 
> -Bill

-- 
=
-Bill Paul(510) 749-2329 | Senior Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   "I put a dollar in a change machine. Nothing changed." - George Carlin
=



[Qemu-devel] [PATCH] Correctly re-init EFER state during INIT IPI

2015-10-01 Thread Bill Paul
When doing a re-initialization of a CPU core, the default state is to _not_
have 64-bit long mode enabled. This means the LME (long mode enable) and LMA
(long mode active) bits in the EFER model-specific register should be cleared.

However, the EFER state is part of the CPU environment which is
preserved by do_cpu_init(), so if EFER.LME and EFER.LMA were set at the
time an INIT IPI was received, they will remain set after the init completes.

This is contrary to what the Intel architecture manual describes and what
happens on real hardware, and it leaves the CPU in a weird state that the
guest can't clear.

To fix this, the 'efer' member of the CPUX86State structure has been moved
to an area outside the region preserved by do_cpu_init(), so that it can
be properly re-initialized by x86_cpu_reset().

Signed-off-by: Bill Paul <wp...@windriver.com>
CC: Paolo Bonzini <pbonz...@redhat.com>
CC: Richard Henderson <r...@twiddle.net>
CC: Eduardo Habkost <ehabk...@redhat.com>
---
 target-i386/cpu.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 034fab6..fac773c 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -833,6 +833,7 @@ typedef struct CPUX86State {
 BNDReg bnd_regs[4];
 BNDCSReg bndcs_regs;
 uint64_t msr_bndcfgs;
+uint64_t efer;
 
 /* Beginning of state preserved by INIT (dummy marker).  */
 struct {} start_init_save;
@@ -865,7 +866,6 @@ typedef struct CPUX86State {
 uint32_t sysenter_cs;
 target_ulong sysenter_esp;
 target_ulong sysenter_eip;
-uint64_t efer;
 uint64_t star;
 
 uint64_t vm_hsave;
-- 
1.8.0




[Qemu-devel] Possible bug in target-i386/helper.c:do_cpu_init()?

2015-09-24 Thread Bill Paul
Consider the following circumstances:

- An x86-64 multicore system is running with all cores set for long mode
  (EFER.LME and EFER.LMA set)
- The OS decides to re-launch one of the AP CPUs using an INIT IPI

According to the Intel architecture manual, an INIT IPI should reset the CPU 
state (with a few small exceptions):

[...]
10.4.7.3   Local APIC State After an INIT Reset ("Wait-for-SIPI" State)

An INIT reset of the processor can be initiated in either of two ways:
·By asserting the processor's INIT# pin.
·By sending the processor an INIT IPI (an IPI with the delivery mode set 
to INIT).

Upon receiving an INIT through either of these mechanisms, the processor 
responds by beginning the initialization process of the processor core and the 
local APIC. The state of the local APIC following an INIT reset is the same as
it is after a power-up or hardware reset, except that the APIC ID and 
arbitration ID registers are not affected. This state is also referred to at 
the "wait-for-SIPI" state (see also: Section 8.4.2, "MP Initialization 
Protocol Requirements and Restrictions").
[...]

Note however that do_cpu_init() does this:

1225 void do_cpu_init(X86CPU *cpu)
1226 {
1227 CPUState *cs = CPU(cpu);
1228 CPUX86State *env = >env;
1229 CPUX86State *save = g_new(CPUX86State, 1);
1230 int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
1231 
1232 *save = *env;
1233 
1234 cpu_reset(cs);
1235 cs->interrupt_request = sipi;
1236 memcpy(>start_init_save, >start_init_save,
1237offsetof(CPUX86State, end_init_save) -
1238offsetof(CPUX86State, start_init_save));
1239 g_free(save);
1240 
1241 if (kvm_enabled()) {
1242 kvm_arch_do_init_vcpu(cpu);
1243 }
1244 apic_init_reset(cpu->apic_state);
1245 }

The CPU environment, which in this case includes the EFER state, is saved and 
restored when calling cpu_reset(). The x86_cpu_reset() function actually does 
clear all of the CPU environment, but this function puts it all back.

The result of this is that if the CPU was in long mode and you do an INIT IPI, 
the CPU still has the EFER.LMA and EFER.LME bits set, even though it's not 
actually running in long mode anymore. It doesn't seem possible for the guest 
to get the CPU out of this state, and one nasty side-effect is that trying to 
set the CR0 to enable paging never succeeds.

I added the following code at line 1240 above as a workaround:

#ifdef TARGET_X86_64
/*
 * The initial state of the CPU is not 64-bit mode. This being
 * the case, don't leave the EFER.LME or EFER.LME bits set.
 */
 
cpu_load_efer(env, 0);
#endif

This seemed to fix the problem I was having, however I'm not certain this is 
the correct fix.

As background, I ran across this problem testing VxWorks with QEMU 2.3.0 and 
OVMF firmware. The VxWorks BOOTX64.EFI loader is able to load and run 32-bit 
VxWorks images on 64-bit hardware by forcing the CPU back to 32-bit mode 
before handing control to the OS. However it only does this for the BSP (CPU 
0). It turns out that the UEFI firmware puts the AP cores into long mode too. 
(This may be new in recent UEFI/OVMF versions, because I'm pretty sure tested 
this path before and didn't see a problem.) Everything works ok with 
uniprocessor images, but with SMP images, launching the first AP CPU fails due 
to the above condition (the CPU starts up, but is unable to enable paging and 
dies screaming in short order).

Booting with the 32-bit OVMF build and the VxWorks BOOTIA32.EFI loader works 
ok. The same VxWorks loader and kernel code also seems to run ok on real 
hardware.

I'm using QEMU 2.3.0 on FreeBSD/amd64 9.2-RELEASE. I'm not using KVM. It looks 
like the code is still the same in the git repo. Am I correct that 
do_cpu_init() should be clearing the EFER contents?

-Bill

-- 
=====
-Bill Paul(510) 749-2329 | Senior Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   "I put a dollar in a change machine. Nothing changed." - George Carlin
=



Re: [Qemu-devel] [edk2] Windows does not support DataTableRegion at all [was: docs: describe QEMU's VMGenID design]

2015-09-14 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Laszlo Ersek had to 
walk into mine at 11:20:28 on Monday 14 September 2015 and say:

> On 09/14/15 18:53, Bill Paul wrote:
> > Of all the gin joints in all the towns in all the world, Laszlo Ersek had
> > to
> > 
> > walk into mine at 03:24:42 on Monday 14 September 2015 and say:
> >> On 09/14/15 10:24, Igor Mammedov wrote:
> >>> On Sun, 13 Sep 2015 15:34:51 +0300
> >>> 
> >>> "Michael S. Tsirkin" <m...@redhat.com> wrote:
> >>>> On Sun, Sep 13, 2015 at 01:56:44PM +0200, Laszlo Ersek wrote:
> >>>>> As the subject suggests, I have terrible news.
> >>>>> 
> >>>>> I'll preserve the full context here, so that it's easy to scroll back
> >>>>> to the ASL for reference.
> >>>>> 
> >>>>> I'm also CC'ing edk2-devel, because a number of BIOS developers
> >>>>> should be congregating there.
> >>>> 
> >>>> Wow, bravo! It does look like we need to go back to
> >>>> the drawing board.
> > 
> > I read your original post on this with great interest, and I applaud your
> > determination in tracking this down. Nice job.
> 
> Thank you!
> 
> > Sadly, it seems you too have
> > fallen victim to the "If It Works With Windows, It Must Be Ok" syndrome.
> 
> Well, I'd put it like this: we've fallen victim to a publicly
> undocumented feature gap / divergence from the ACPI spec in Windows'
> ACPI.SYS.
> 
> > Now, I realize that as far as this particular situation is concerned,
> > even if Microsoft decided to add support for DataTableRegion() tomorrow,
> > it wouldn't really help because there are too many different versions of
> > Windows in the field and there's no way to retroactively patch them all.
> > (Gee, that sounds familiar...)
> 
> Correct.
> 
> > Nevertheless, am I correct in saying that this is in fact a bug in
> > Microsoft's ACPI implementation (both in their ASL compiler and in the
> > AML parser)?
> 
> Absolutely. You are absolutely right.
> 
> We implemented the VMGENID spec with some undeniable creativity, but it
> broke down because the AML interpreter in Windows does not support an
> ACPI 2.0 feature.
> 
> (That interpreter is supposed to be ACPI 4.0 compliant, minimally; at
> least if we can judge it after the "matching" AML.exe's stated
> compatibility level, which is ACPI 4.0 in the standalone download, and
> 5.0 if you get it as part of the WDK.)
> 
> > Unless
> > DataTableRegion() is specified to be optional in some way (I don't know
> > if it is or not, but I doubt it),
> 
> It's not, to the best of my knowledge.
> 
> > this sounds like an clear cut case of non-
> > compliance with the ACPI spec.
> 
> Yes, it's precisely that.
> 
> > And if that's true, isn't there any way to get
> > Microsoft to fix it?
> 
> I don't know. Is there?

You would think that someone at Intel would know someone at Microsoft that 
could put some wheels in motion. (All this technology and still we have 
trouble communicating. :P )
 
> Microsoft continue to release updates (KB*) for Windows 7, Windows 8,
> Windows 10, and I think rolling a fix out for those would cover our
> needs quite okay.
> 
> But:
> - This would force QEMU/KVM host users to upgrade their Windows guest.
>   Maybe not such a big hurdle, but I reckon Windows sysadmins are
>   really conservative about installing updates. Perhaps we could solve
>   this issue but documentation.

I agree with you that it's a hassle, but so is patching any other Windows bug. 
And while this particular use of DataTableRegion() affects VMs, it has bearing 
on bare metal installations too.
 
> - More importantly, how do I even *report* this bug? How do I convince
>   Microsoft to implement a whole missing feature in their ACPI compiler
>   and interpreter? Can I demonstrate business justification?
>
>   I'm doubtful especially because DataTableRegion's usefulness is quite
>   apparent to the ACPI developer in search for parametrization options.
>   DataTableRegion was published as part of ACPI 2.0, on July 27, 2000
>   (more than fifteen years ago). I simply cannot imagine that in all
>   that time *no* physical platform's firmware developer tried to use
>   DataTableRegion.
> 
>   Therefore I can't help but assume that some big BIOS developer
>   company has already reported this to Microsoft, and the feature
>   request has been rejected. So what chance would I have?

I understand what you're saying. But, there has to be some way to deal with 
these sorts of 

Re: [Qemu-devel] [edk2] Windows does not support DataTableRegion at all [was: docs: describe QEMU's VMGenID design]

2015-09-14 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Laszlo Ersek had to 
walk into mine at 03:24:42 on Monday 14 September 2015 and say:

> On 09/14/15 10:24, Igor Mammedov wrote:
> > On Sun, 13 Sep 2015 15:34:51 +0300
> > 
> > "Michael S. Tsirkin" <m...@redhat.com> wrote:
> >> On Sun, Sep 13, 2015 at 01:56:44PM +0200, Laszlo Ersek wrote:
> >>> As the subject suggests, I have terrible news.
> >>> 
> >>> I'll preserve the full context here, so that it's easy to scroll back
> >>> to the ASL for reference.
> >>> 
> >>> I'm also CC'ing edk2-devel, because a number of BIOS developers should
> >>> be congregating there.
> >> 
> >> Wow, bravo! It does look like we need to go back to
> >> the drawing board.

I read your original post on this with great interest, and I applaud your 
determination in tracking this down. Nice job. Sadly, it seems you too have 
fallen victim to the "If It Works With Windows, It Must Be Ok" syndrome.

Now, I realize that as far as this particular situation is concerned, even if 
Microsoft decided to add support for DataTableRegion() tomorrow, it wouldn't 
really help because there are too many different versions of Windows in the 
field and there's no way to retroactively patch them all. (Gee, that sounds 
familiar...)

Nevertheless, am I correct in saying that this is in fact a bug in Microsoft's 
ACPI implementation (both in their ASL compiler and in the AML parser)? Unless 
DataTableRegion() is specified to be optional in some way (I don't know if it 
is or not, but I doubt it), this sounds like an clear cut case of non-
compliance with the ACPI spec. And if that's true, isn't there any way to get 
Microsoft to fix it?

-Bill

> > I suggest we go back to the last Gal's series
> > which is though not universal but a simple and
> > straightforward solution.
> > That series with comments addressed probably
> > is what we need in the end.
> 
> I agree (I commented the same on the RHBZ too). The only one requirement
> we might not satisfy with that is that the page containing the
> generation ID must always be mapped as cacheable. In practice it doesn't
> seem to cause issues.
> 
> We tried to play nice, but given that (a) the vmgenid doc doesn't
> mention a real requirement about the _CRS -- ie. no IO descriptors are
> allowed to be in it --, (b) Windows doesn't support DataTableRegion(), I
> doubt we could cover our bases 100% anyway. There can be any number of
> further hidden requirements, and hidden gaps in ACPI support too, so
> it's just business as usual with Windows: whatever works, works, don't
> ask why.
> 
> Just my opinion of course.
> 
> Laszlo
> 
> >> The only crazy thing you didn't try is to use
> >> an XSDT instead of the DSDT.
> >> I find it unlikely that this will help ...
> 
> ___
> edk2-devel mailing list
> edk2-de...@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel

-- 
=
-Bill Paul(510) 749-2329 | Senior Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   "I put a dollar in a change machine. Nothing changed." - George Carlin
=



[Qemu-devel] Fix for incorrect SYSRET instruction implementation -- anyone looked at this yet?

2015-03-09 Thread Bill Paul
Nobody has commented on this yet. According to my reading of the Intel 
documentation, the SYSRET instruction is supposed to force the RPL bits of the 
%ss register to 3 when returning to user mode. The actual sequence is:

SS.Selector -- (IA32_STAR[63:48]+8) OR 3; (* RPL forced to 3 *)

However, the code in helper_sysret() leaves them at 0 (in other words, the OR 
3 part of the above sequence is missing). It does set the privilege level 
bits of %cs correctly though.

This has caused me trouble with some of my VxWorks development: code that runs 
okay on real hardware will crash on QEMU, unless I apply the patch below.

Can someone confirm that this is in fact a real bug? The Intel architecture 
manual seems quite clear about the SYSRET behavior. The bug seems to have been 
around as far back as QEMU 0.10.5.

I am using QEMU 2.2.0 on FreeBSD/amd64 9.1-RELEASE.

-Bill

Signed-off-by: Bill Paul wp...@windriver.com

---
 target-i386/seg_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index fa374d0..2bc757a 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -1043,7 +1043,7 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
 env-eip = (uint32_t)env-regs[R_ECX];
 }
-cpu_x86_load_seg_cache(env, R_SS, selector + 8,
+cpu_x86_load_seg_cache(env, R_SS, (selector + 8) | 3,
0, 0x,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3  DESC_DPL_SHIFT) |
@@ -1056,7 +1056,7 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_S_MASK | (3  DESC_DPL_SHIFT) |
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
 env-eip = (uint32_t)env-regs[R_ECX];
-cpu_x86_load_seg_cache(env, R_SS, selector + 8,
+cpu_x86_load_seg_cache(env, R_SS, (selector + 8) | 3,
0, 0x,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3  DESC_DPL_SHIFT) |
-- 
1.8.0

-- 
=
-Bill Paul(510) 749-2329 | Senior Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   I put a dollar in a change machine. Nothing changed. - George Carlin
=


Re: [Qemu-devel] Fix for incorrect SYSRET instruction implementation -- anyone looked at this yet?

2015-03-09 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Stefan Weil had to 
walk into mine at 15:23:36 on Monday 09 March 2015 and say:

 Hi Bill,
 
 sending text only e-mails might help. Usually git send-email is better
 than using KMail or other mail software.

You know, I thought I was sending in plain text. Somewhere along the line 
KMail lied to me.

 Use tools like git gui to get a correct signature. Any optional personal
 comments should come directly after
 the line with ---.

After? Or before?

 Could you please re-send your patch? Check it before
 sending with scripts/checkpatch.pl.
 
 Maybe this looks like much regulations to fix a bug, but some rules are
 necessary to keep a project
 like QEMU alive.

I'm going to send it once more because it was entirely my fault that my stupid 
mailer kept sending in HTML mode, but that's it.

-Bill

--
=
-Bill Paul(510) 749-2329 | Senior Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   I put a dollar in a change machine. Nothing changed. - George Carlin
=



[Qemu-devel] Fix for incorrect SYSRET instruction implementation -- anyone looked at this yet?

2015-03-09 Thread Bill Paul
I'm certain I'm sending this in plain text mode this time. According to my 
reading of the Intel documentation, the SYSRET instruction is supposed to 
force the RPL bits of the %ss register to 3 when returning to user mode. The 
actual sequence is:

SS.Selector -- (IA32_STAR[63:48]+8) OR 3; (* RPL forced to 3 *)

However, the code in helper_sysret() leaves them at 0 (in other words, the OR 
3 part of the above sequence is missing). It does set the privilege level 
bits of %cs correctly though.

This has caused me trouble with some of my VxWorks development: code that runs 
okay on real hardware will crash on QEMU, unless I apply the patch below.

Can someone confirm that this is in fact a real bug? The Intel architecture 
manual seems quite clear about the SYSRET behavior. The bug seems to have been 
around as far back as QEMU 0.10.5.

I am using QEMU 2.2.0 on FreeBSD/amd64 9.1-RELEASE.

-Bill

Signed-off-by: Bill Paul wp...@windriver.com

---
 target-i386/seg_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index fa374d0..2bc757a 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -1043,7 +1043,7 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
 env-eip = (uint32_t)env-regs[R_ECX];
 }
-cpu_x86_load_seg_cache(env, R_SS, selector + 8,
+cpu_x86_load_seg_cache(env, R_SS, (selector + 8) | 3,
0, 0x,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3  DESC_DPL_SHIFT) |
@@ -1056,7 +1056,7 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_S_MASK | (3  DESC_DPL_SHIFT) |
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
 env-eip = (uint32_t)env-regs[R_ECX];
-cpu_x86_load_seg_cache(env, R_SS, selector + 8,
+cpu_x86_load_seg_cache(env, R_SS, (selector + 8) | 3,
0, 0x,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3  DESC_DPL_SHIFT) |
-- 
1.8.0



[Qemu-devel] Fix for bug in implementation of SYSRET instruction for x86-64

2015-03-04 Thread Bill Paul
(I tried sending this once earlier but it seems to have disappeared into the 
void. Apologies if it ends up showing up twice.)

Hi guys. I seem to have found a bug in the helper_systet() function in
target-i386/seg_helper.c. I downloaded the Intel architecture manual from 
here:

http://www.intel.com/content/www/us/en/processors/architectures-software-
developer-manuals.html

And it describes the behavior of SYSRET with regards to the stack selector 
(SS) as follows:

SS.Selector -- (IA32_STAR[63:48]+8) OR 3; (* RPL forced to 3 *)

In other words, the value of the SS register is supposed to be loaded from 
bits 63:48 of the IA32_STAR model-specific register (MSR), incremented by 8, 
_AND_ ORed with 3. ORing in the 3 sets the privilege level to 3 (user). This 
is done since SYSRET returns to user mode after a system call.

The code in helper_sysret() performs the increment by 8 step, but _NOT_ the 
OR with 3 step.

Here's another description of the SYSRET instruction which says basically the 
same thing, though in slightly different format:

http://tptp.cc/mirrors/siyobik.info/instruction/SYSRET.html

[...]
SS(SEL) = IA32_STAR[63:48] + 8;
SS(PL) = 0x3;
[...]

The effect of this bug is that when x86-64 code uses the SYSCALL instruction 
to enter kernel mode, the SYSRET instruction will return the CPU to user mode 
with the SS register incorrectly set (the privilege level bits will be 0). In 
my case, the original SS value for user mode was 0x2B, but after the return 
from SYSRET, it was changed to 0x28. It took me quite some time to realize 
this was due to a bug in QEMU rather than my own code.

This caused a problem later when the user-mode code was preempted by an 
interrupt. At the end of the interrupt handling, an IRET instruction was used 
to exit the interrupt context, and the IRET instruction would generate a 
general protection fault because it would attempt to validate the stack 
selector value and notice that it was set for PL 0 (supervisor) instead of PL 
3 (user).

From my reading, the code is quite clearly in error with respect to the Intel 
documentation, and fixing the bug in my local sources results in my test code 
(which runs correctly on real hardware) working correctly in QEMU. It seems 
this bug has been there for a long time -- I happened to have the sources for 
QEMU 0.10.5 and the bug is there too (in target-i386/op_helper.c). I'm puzzled 
as to how it's gone unnoticed for so long, which has me thinking that maybe 
I'm missing something. I'm pretty sure this is wrong though.

I'm attaching a patch for this below. It's a pretty simple fix. 
Comments/questions welcome.

-Bill

-- 
=
-Bill Paul(510) 749-2329 | Senior Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   I put a dollar in a change machine. Nothing changed. - George Carlin
=

Signed-off-by: Bill Paul wp...@windriver.com

---
 target-i386/seg_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index fa374d0..2bc757a 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -1043,7 +1043,7 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
 env-eip = (uint32_t)env-regs[R_ECX];
 }
-cpu_x86_load_seg_cache(env, R_SS, selector + 8,
+cpu_x86_load_seg_cache(env, R_SS, (selector + 8) | 3,
0, 0x,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3  DESC_DPL_SHIFT) |
@@ -1056,7 +1056,7 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_S_MASK | (3  DESC_DPL_SHIFT) |
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
 env-eip = (uint32_t)env-regs[R_ECX];
-cpu_x86_load_seg_cache(env, R_SS, selector + 8,
+cpu_x86_load_seg_cache(env, R_SS, (selector + 8) | 3,
0, 0x,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3  DESC_DPL_SHIFT) |
--
1.8.0
From e85d3d374594f6c31e1bf72f8912334194be8654 Mon Sep 17 00:00:00 2001
From: Bill Paul wp...@windriver.com
Date: Wed, 4 Mar 2015 09:19:03 -0800
Subject: [PATCH] This checkin corrects a bug in the implementation of the
 sysret instruction. Per the Intel architecture manual, the
 stack selector (SS) is to be loaded from the IA32_STAR
 register, incremented by 8, _AND_ ORed with 3 (this forces
 the privilege level to 3). The latter step (ORing in the 3)
 is missing. This breaks

[Qemu-devel] [PATCH] Fix bug in implementation of SYSRET instruction for x86-64

2015-03-04 Thread Bill Paul
Hi guys. I seem to have found a bug in the helper_systet() function in
target-i386/seg_helper.c. I downloaded the Intel architecture manual from 
here:

http://www.intel.com/content/www/us/en/processors/architectures-software-
developer-manuals.html

And it describes the behavior of SYSRET with regards to the stack selector 
(SS) as follows:

SS.Selector -- (IA32_STAR[63:48]+8) OR 3; (* RPL forced to 3 *)

In other words, the value of the SS register is supposed to be loaded from 
bits 63:48 of the IA32_STAR model-specific register (MSR), incremented by 8, 
_AND_ ORed with 3. ORing in the 3 sets the privilege level to 3 (user). This 
is done since SYSRET returns to user mode after a system call.

The code in helper_sysret() performs the increment by 8 step, but _NOT_ the 
OR with 3 step.

Here's another description of the SYSRET instruction which says basically the 
same thing, though in slightly different format:

http://tptp.cc/mirrors/siyobik.info/instruction/SYSRET.html

[...]
SS(SEL) = IA32_STAR[63:48] + 8;
SS(PL) = 0x3;
[...]

The effect of this bug is that when x86-64 code uses the SYSCALL instruction 
to enter kernel mode, the SYSRET instruction will return the CPU to user mode 
with the SS register incorrectly set (the privilege level bits will be 0). In 
my case, the original SS value for user mode was 0x2B, but after the return 
from SYSRET, it was changed to 0x28. It took me quite some time to realize 
this was due to a bug in QEMU rather than my own code.

This caused a problem later when the user-mode code was preempted by an 
interrupt. At the end of the interrupt handling, an IRET instruction was used 
to exit the interrupt context, and the IRET instruction would generate a 
general protection fault because it would attempt to validate the stack 
selector value and notice that it was set for PL 0 (supervisor) instead of PL 
3 (user).

From my reading, the code is quite clearly in error with respect to the Intel 
documentation, and fixing the bug in my local sources results in my test code 
(which runs correctly on real hardware) working correctly in QEMU. It seems 
this bug has been there for a long time -- I happened to have the sources for 
QEMU 0.10.5 and the bug is there too (in target-i386/op_helper.c). I'm puzzled 
as to how it's gone unnoticed for so long, which has me thinking that maybe 
I'm missing something. I'm pretty sure this is wrong though.

I'm including a patch to fix this below. It seems to fix the problem quite 
nicely on my QEMU 2.2.0 installation. I'm also attaching a separate copy in 
case my mail client mangles the formatting on the inline copy.

-Bill

-- 
=
-Bill Paul(510) 749-2329 | Senior Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   I put a dollar in a change machine. Nothing changed. - George Carlin
=

Signed-off-by: Bill Paul wp...@windriver.com

---
 target-i386/seg_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index fa374d0..2bc757a 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -1043,7 +1043,7 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
 env-eip = (uint32_t)env-regs[R_ECX];
 }
-cpu_x86_load_seg_cache(env, R_SS, selector + 8,
+cpu_x86_load_seg_cache(env, R_SS, (selector + 8) | 3,
0, 0x,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3  DESC_DPL_SHIFT) |
@@ -1056,7 +1056,7 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_S_MASK | (3  DESC_DPL_SHIFT) |
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
 env-eip = (uint32_t)env-regs[R_ECX];
-cpu_x86_load_seg_cache(env, R_SS, selector + 8,
+cpu_x86_load_seg_cache(env, R_SS, (selector + 8) | 3,
0, 0x,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3  DESC_DPL_SHIFT) |
--
1.8.0
From e85d3d374594f6c31e1bf72f8912334194be8654 Mon Sep 17 00:00:00 2001
From: Bill Paul wp...@windriver.com
Date: Wed, 4 Mar 2015 09:19:03 -0800
Subject: [PATCH] This checkin corrects a bug in the implementation of the
 sysret instruction. Per the Intel architecture manual, the
 stack selector (SS) is to be loaded from the IA32_STAR
 register, incremented by 8, _AND_ ORed with 3 (this forces
 the privilege level to 3). The latter step (ORing in the 3)
 is missing. This breaks the machine

[Qemu-devel] [Bug 1428352] [NEW] SYSRET instruction incorrectly implemented

2015-03-04 Thread Bill Paul
Public bug reported:

The Intel architecture manual states that when returning to user mode,
the SYSRET instruction will re-load the stack selector (%ss) from the
IA32_STAR model specific register using the following logic:

SS.Selector -- (IA32_STAR[63:48]+8) OR 3; (* RPL forced to 3 *)

Another description of the instruction behavior which shows the same
logic in a slightly different form can also be found here:

http://tptp.cc/mirrors/siyobik.info/instruction/SYSRET.html

[...]
SS(SEL) = IA32_STAR[63:48] + 8;
SS(PL) = 0x3;
[...]

In other words, the value of the %ss register is supposed to be loaded
from  bits 63:48 of the IA32_STAR model-specific register, incremented
by 8, and then ORed with 3. ORing in the 3 sets the privilege level to 3
(user). This is done since SYSRET returns to user mode after a system
call.

However, helper_sysret() in target-i386/seg_helper.c does not do the OR
3 step. The code looks like this:

cpu_x86_load_seg_cache(env, R_SS, selector + 8,
   0, 0x,
   DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   DESC_S_MASK | (3  DESC_DPL_SHIFT) |
   DESC_W_MASK | DESC_A_MASK);

It should look like this:

cpu_x86_load_seg_cache(env, R_SS, (selector + 8) | 3,
   0, 0x,
   DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   DESC_S_MASK | (3  DESC_DPL_SHIFT) |
   DESC_W_MASK | DESC_A_MASK);

The code does correctly set the privilege level bits for the code
selector register (%cs) but not for the stack selector (%ss).

The effect of this is that when SYSRET returns control to the user-mode
caller, %ss will be have the privilege level bits cleared. In my case,
it went from 0x2b to 0x28. This caused a crash later: when the user-mode
code was preempted by an interrupt, and the interrupt handler would do
an IRET, a general protection fault would occur because the %ss value
being loaded from the exception frame was not valid for user mode. (At
least, I think that's what happened.)

This behavior seems inconsistent with real hardware, and also appears to
be wrong with respect to the Intel documentation, so I'm pretty
confident in calling this a bug. :)

Note that this issue seems to have been around for a long time. I
discovered it while using QEMU 2.2.0, but I happened to have the sources
for QEMU 0.10.5, and the problem is there too (in os_helper.c). I am
using FreeBSD/amd64 9.1-RELEASE as my host system, without KVM.

The fix is fairly simple. I'm attaching a patch which worked for me.
Using this fix, the code that I'm testing now behaves the same on the
QEMU virtual machine as on real hardware.

- Bill (wp...@windriver.com)

** Affects: qemu
 Importance: Undecided
 Status: New

** Attachment added: Patch to correct helper_sysret()
   
https://bugs.launchpad.net/bugs/1428352/+attachment/4334723/+files/0001-This-checkin-corrects-a-bug-in-the-implementation-of.patch

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

Title:
  SYSRET instruction incorrectly implemented

Status in QEMU:
  New

Bug description:
  The Intel architecture manual states that when returning to user mode,
  the SYSRET instruction will re-load the stack selector (%ss) from the
  IA32_STAR model specific register using the following logic:

  SS.Selector -- (IA32_STAR[63:48]+8) OR 3; (* RPL forced to 3 *)

  Another description of the instruction behavior which shows the same
  logic in a slightly different form can also be found here:

  http://tptp.cc/mirrors/siyobik.info/instruction/SYSRET.html

  [...]
  SS(SEL) = IA32_STAR[63:48] + 8;
  SS(PL) = 0x3;
  [...]

  In other words, the value of the %ss register is supposed to be loaded
  from  bits 63:48 of the IA32_STAR model-specific register, incremented
  by 8, and then ORed with 3. ORing in the 3 sets the privilege level to
  3 (user). This is done since SYSRET returns to user mode after a
  system call.

  However, helper_sysret() in target-i386/seg_helper.c does not do the
  OR 3 step. The code looks like this:

  cpu_x86_load_seg_cache(env, R_SS, selector + 8,
 0, 0x,
 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
 DESC_S_MASK | (3  DESC_DPL_SHIFT) |
 DESC_W_MASK | DESC_A_MASK);

  It should look like this:

  cpu_x86_load_seg_cache(env, R_SS, (selector + 8) | 3,
 0, 0x,
 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
 DESC_S_MASK | (3  DESC_DPL_SHIFT) |
 DESC_W_MASK | DESC_A_MASK);

  The code does 

Re: [Qemu-devel] [PATCH] e1000: make ICS write-only

2013-01-09 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Michael S. Tsirkin 
had to walk into mine at 02:51:00 on Wednesday 09 January 2013 and say:

 Since commit b1332393cdd7d023de8f1f8aa136ee7866a18968,
 qemu started updating ICS register when interrupt
 is sent, with the intent to match spec better
 (guests do not actually read this register).
 However, the function set_interrupt_cause where ICS
 is updated is often called internally by
 device emulation so reading it does not produce the last value
 written by driver.  Looking closer at the spec,
 it documents ICS as write-only, so there's no need
 to update it at all. I conclude that while harmless this line is useless
 code so removing it is a bit cleaner than keeping it in.

You are wrong.

I know what the spec says. The spec lies (or at the very least, it doesn't 
agree with reality). With actual PRO/1000 hardware, the ICS register is 
readable. It provides a way to obtain the currently pending interrupt bits 
without the auto-clear behavior of the ICR register (which in some cases is 
actually detrimental).

The Intel 10GbE NICs (82598, 82599, x540) are the same way (they're very 
similar in design to the PRO/1000s, particularly the 82575, 82576, 82580 and 
later devices). The spes for the 10GbE devices _also_ say that ICS is read 
only. But if you look at the Intel drivers for those chips, you'll see they 
have actually implemented a workaround for a device errata (I think the for 
the 82598) that actually requires reading the ICS register. If you had 
implemented a PRO/10GbE virtual device based on the same chip and obeyed the 
spec the same way, I suspect Intel's driver would break.

I actually have in my possession real PRO/1000 silicon going all the way back 
to the 82543 and have tested every single one of them, and they all work like 
this. I've also asked the Intel LAN access division people about it and they 
said that in spite of it not being documented as readable, there's nothing 
particularly wrong with doing this.

The problem with using ICR is that the auto-clear behavior can sometimes 
result in some awkward interrupt handling code. You need to test ICR in 
interrupt context to see if there are events pending, and then schedule some 
other thread to handle them. But since reading ICR clears the bits, you need 
to save the events somewhere so that the other thread knows what events need 
servicing. Keeping the saved copy of pending events properly synchronized so 
that you don't lose any is actually big challenge. The VxWorks PRO/1000 driver 
used to have some very ugly code in it to deal with it, all of which became 
much simpler when using the ICS register instead.

I know what the spec says. But this is a case where the spec only says that 
because Intel decided not to disclose what the hardware actually does. They 
also don't tell you about all the hidden debug registers in the hardware 
either, but that doesn't mean they don't exist.

So pretty please, with sugar on top, leave this code alone.

-Bill

 Tested with windows and linux guests.
 
 Cc: Bill Paul wp...@windriver.com
 Reported-by: Yan Vugenfirer y...@daynix.com
 Signed-off-by: Michael S. Tsirkin m...@redhat.com
 ---
  hw/e1000.c | 1 -
  1 file changed, 1 deletion(-)
 
 diff --git a/hw/e1000.c b/hw/e1000.c
 index 92fb00a..928d804 100644
 --- a/hw/e1000.c
 +++ b/hw/e1000.c
 @@ -230,7 +230,6 @@ set_interrupt_cause(E1000State *s, int index, uint32_t
 val) val |= E1000_ICR_INT_ASSERTED;
  }
  s-mac_reg[ICR] = val;
 -s-mac_reg[ICS] = val;
  qemu_set_irq(s-dev.irq[0], (s-mac_reg[IMS]  s-mac_reg[ICR]) != 0);
  }

-- 
=
-Bill Paul(510) 749-2329 | Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   I put a dollar in a change machine. Nothing changed. - George Carlin
=



Re: [Qemu-devel] [PATCH] e1000: make ICS write-only

2013-01-09 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Michael S. Tsirkin 
had to walk into mine at 14:07:53 on Wednesday 09 January 2013 and say:

 On Wed, Jan 09, 2013 at 01:50:39PM -0600, Anthony Liguori wrote:
  I figured this would be the case but this is where a comment in the code
  or commit message would have helped a lot in avoiding future confusion.
  
  Regards,
  
  Anthony Liguori
 
 I just sent a documentation patch, please take a look.
 Thanks!

Well, strictly speaking, VxWorks doesn't rely on the ICS behavior anymore, but 
it prefers it. I ran into problems with VMware and Simics too, as they also 
don't emulate the ICS behavior, and getting that fixed was more of an uphill 
battle. So as a compromise I added a check to the driver to see if the ICS 
register has 'real hardware behavior' or 'emulated behavior' and made it use 
an alternate interrupt handling scheme in the emulated case. The alternate 
scheme is a little less efficient than the ICS scheme in some cases (mainly 
when the PRO/1000 device's interrupt is shared), but it still handles 
interrupts reliably.

That's a minor nit though. I'm fine with the comments as is. I just didn't 
want you do think VxWorks was completely brain damaged. :)

Note that I don't think VMware emulates the 'flexible RX mode' descriptor 
mechanism for the PRO/100 either, because the non-NDAed PRO/100 manual doesn't 
bother to mention it exists. I think this is something that was fixed in QEMU 
but I haven't had a chance to test it in a while. There's a similar problem 
with simulated the AMD PCnet/PCI devices (they only support the 'configuration 
block' setup method -- for the older non-PCI LANCE chips that was the only way 
to configure them but PCI devices starting with the am97c970 can be configured 
just by setting up registers).

Honestly I'm surprised I still have all my hair and that it's still the same 
color.

-Bill

-- 
=
-Bill Paul(510) 749-2329 | Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu - Wind River Systems
=
   I put a dollar in a change machine. Nothing changed. - George Carlin
=



Re: [Qemu-devel] [PATCH] e1000: make ICS write-only

2013-01-09 Thread Bill Paul
Of all the gin joints in all the towns in all the world, Michael S. Tsirkin 
had to walk into mine at 13:44:38 on Wednesday 09 January 2013 and say:

 On Wed, Jan 09, 2013 at 09:30:43AM -0800, Bill Paul wrote:
  Of all the gin joints in all the towns in all the world, Michael S.
  Tsirkin
  
  had to walk into mine at 02:51:00 on Wednesday 09 January 2013 and say:
   Since commit b1332393cdd7d023de8f1f8aa136ee7866a18968,
   qemu started updating ICS register when interrupt
   is sent, with the intent to match spec better
   (guests do not actually read this register).
   However, the function set_interrupt_cause where ICS
   is updated is often called internally by
   device emulation so reading it does not produce the last value
   written by driver.  Looking closer at the spec,
   it documents ICS as write-only, so there's no need
   to update it at all. I conclude that while harmless this line is
   useless code so removing it is a bit cleaner than keeping it in.
  
  You are wrong.
  
  I know what the spec says. The spec lies (or at the very least, it
  doesn't agree with reality). With actual PRO/1000 hardware, the ICS
  register is readable. It provides a way to obtain the currently pending
  interrupt bits without the auto-clear behavior of the ICR register
  (which in some cases is actually detrimental).
  
  The Intel 10GbE NICs (82598, 82599, x540) are the same way (they're very
  similar in design to the PRO/1000s, particularly the 82575, 82576, 82580
  and later devices). The spes for the 10GbE devices _also_ say that ICS
  is read only. But if you look at the Intel drivers for those chips,
  you'll see they have actually implemented a workaround for a device
  errata (I think the for the 82598) that actually requires reading the
  ICS register. If you had implemented a PRO/10GbE virtual device based on
  the same chip and obeyed the spec the same way, I suspect Intel's driver
  would break.
  
  I actually have in my possession real PRO/1000 silicon going all the way
  back to the 82543 and have tested every single one of them, and they all
  work like this. I've also asked the Intel LAN access division people
  about it and they said that in spite of it not being documented as
  readable, there's nothing particularly wrong with doing this.
  
  The problem with using ICR is that the auto-clear behavior can sometimes
  result in some awkward interrupt handling code. You need to test ICR in
  interrupt context to see if there are events pending, and then schedule
  some other thread to handle them. But since reading ICR clears the bits,
  you need to save the events somewhere so that the other thread knows
  what events need servicing. Keeping the saved copy of pending events
  properly synchronized so that you don't lose any is actually big
  challenge. The VxWorks PRO/1000 driver used to have some very ugly code
  in it to deal with it, all of which became much simpler when using the
  ICS register instead.
  
  I know what the spec says. But this is a case where the spec only says
  that because Intel decided not to disclose what the hardware actually
  does. They also don't tell you about all the hidden debug registers in
  the hardware either, but that doesn't mean they don't exist.
  
  So pretty please, with sugar on top, leave this code alone.
  
  -Bill
 
 OK now since there's no spec, I'd like to find out how does the
 register behave. Let's assume I read ICR. This clears ICR - does it
 also clear ICS?

Yes.

ICS mirrors ICR: reading ICS lets you peek at the contents of ICR without 
auto-clearing them. If you read ICR, you're acknowledging any events that may 
be pending.

Let's say the LSC (link state change) becomes set, because you unplugged the 
cable. The LSC bit becomes set in both ICR and in ICS.

If you read ICS first, then you'll see the LSC bit is set, and it'll stay set 
(the event stays unacked).

If you read ICR first, then you'll see the LSC bit is set, and you'll clear it 
(the event is acked).

If you read ICS _after_ you read ICR, then LSC will be clear (because reading 
ICR first acked it).

-Bill


 Thanks,
 MST
 
   Tested with windows and linux guests.
   
   Cc: Bill Paul wp...@windriver.com
   Reported-by: Yan Vugenfirer y...@daynix.com
   Signed-off-by: Michael S. Tsirkin m...@redhat.com
   ---
   
hw/e1000.c | 1 -
1 file changed, 1 deletion(-)
   
   diff --git a/hw/e1000.c b/hw/e1000.c
   index 92fb00a..928d804 100644
   --- a/hw/e1000.c
   +++ b/hw/e1000.c
   @@ -230,7 +230,6 @@ set_interrupt_cause(E1000State *s, int index,
   uint32_t val) val |= E1000_ICR_INT_ASSERTED;
   
}
s-mac_reg[ICR] = val;
   
   -s-mac_reg[ICS] = val;
   
qemu_set_irq(s-dev.irq[0], (s-mac_reg[IMS]  s-mac_reg[ICR]) !=
0);

}

-- 
=
-Bill Paul(510) 749-2329 | Member of Technical Staff,
 wp...@windriver.com | Master of Unix-Fu