All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2] hw/char/escc: Lower irq when transmit buffer is filled
@ 2019-04-17  0:50 Stephen Checkoway
  2019-04-18 12:13 ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 4+ messages in thread
From: Stephen Checkoway @ 2019-04-17  0:50 UTC (permalink / raw)
  To: Paolo Bonzini, Stephen Checkoway, QEMU Developers,
	Artyom Tarasenko, Laurent Vivier, qemu-trivial,
	Marc-André Lureau, Mark Cave-Ayland

The SCC/ESCC will briefly stop asserting an interrupt when the
transmit FIFO is filled.

This code doesn't model the transmit FIFO/shift register so the
pending transmit interrupt is never deasserted which means that an
edge-triggered interrupt controller will never see the low-to-high
transition it needs to raise another interrupt. The practical
consequence of this is that guest firmware with an interrupt service
routine for the ESCC that does not send all of the data it has
immediately will stop sending data if the following sequence of
events occurs:
1. Disable processor interrupts
2. Write a character to the ESCC
3. Add additional characters to a buffer which is drained by the ISR
4. Enable processor interrupts

In this case, the first character will be sent, the interrupt will
fire and the ISR will output the second character. Since the pending
transmit interrupt remains asserted, no additional interrupts will
ever fire.

This fixes that situation by explicitly lowering the IRQ when a
character is written to the buffer and no other interrupts are currently
pending.

Signed-off-by: Stephen Checkoway <stephen.checkoway@oberlin.edu>
---
 hw/char/escc.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/hw/char/escc.c b/hw/char/escc.c
index 628f5f81f7..c5b05a63f1 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -509,6 +509,13 @@ static void escc_mem_write(void *opaque, hwaddr addr,
         break;
     case SERIAL_DATA:
         trace_escc_mem_writeb_data(CHN_C(s), val);
+        /*
+         * Lower the irq when data is written to the Tx buffer and no other
+         * interrupts are currently pending. The irq will be raised again once
+         * the Tx buffer becomes empty below.
+         */
+        s->txint = 0;
+        escc_update_irq(s);
         s->tx = val;
         if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
             if (qemu_chr_fe_backend_connected(&s->chr)) {
-- 
2.20.1 (Apple Git-117)

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH v2] hw/char/escc: Lower irq when transmit buffer is filled
  2019-04-17  0:50 [Qemu-devel] [PATCH v2] hw/char/escc: Lower irq when transmit buffer is filled Stephen Checkoway
@ 2019-04-18 12:13 ` Philippe Mathieu-Daudé
  2019-04-19 15:42     ` Stephen Checkoway
  0 siblings, 1 reply; 4+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-04-18 12:13 UTC (permalink / raw)
  To: Stephen Checkoway, Paolo Bonzini, QEMU Developers,
	Artyom Tarasenko, Laurent Vivier, qemu-trivial,
	Marc-André Lureau, Mark Cave-Ayland

On 4/17/19 2:50 AM, Stephen Checkoway wrote:
> The SCC/ESCC will briefly stop asserting an interrupt when the
> transmit FIFO is filled.
> 
> This code doesn't model the transmit FIFO/shift register so the
> pending transmit interrupt is never deasserted which means that an
> edge-triggered interrupt controller will never see the low-to-high
> transition it needs to raise another interrupt. The practical
> consequence of this is that guest firmware with an interrupt service
> routine for the ESCC that does not send all of the data it has
> immediately will stop sending data if the following sequence of
> events occurs:
> 1. Disable processor interrupts
> 2. Write a character to the ESCC
> 3. Add additional characters to a buffer which is drained by the ISR
> 4. Enable processor interrupts
> 
> In this case, the first character will be sent, the interrupt will
> fire and the ISR will output the second character. Since the pending
> transmit interrupt remains asserted, no additional interrupts will
> ever fire.

You might want to add a line expliciting the chipset model which forced
you to do that patch (Z85C30).

> This fixes that situation by explicitly lowering the IRQ when a
> character is written to the buffer and no other interrupts are currently
> pending.

> 
> Signed-off-by: Stephen Checkoway <stephen.checkoway@oberlin.edu>
> ---
>  hw/char/escc.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/hw/char/escc.c b/hw/char/escc.c
> index 628f5f81f7..c5b05a63f1 100644
> --- a/hw/char/escc.c
> +++ b/hw/char/escc.c
> @@ -509,6 +509,13 @@ static void escc_mem_write(void *opaque, hwaddr addr,
>          break;
>      case SERIAL_DATA:
>          trace_escc_mem_writeb_data(CHN_C(s), val);
> +        /*
> +         * Lower the irq when data is written to the Tx buffer and no other
> +         * interrupts are currently pending. The irq will be raised again once
> +         * the Tx buffer becomes empty below.
> +         */
> +        s->txint = 0;
> +        escc_update_irq(s);

Way better, thanks :)

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

Note: the Z85C30 has a 1-byte transmit FIFO and 3-byte receive FIFO.
Our model default is the ESCC, and we use ESCC_SERIO_QUEUE_SIZE=256 byte
for rx FIFO... If needed we can add properties and use a white list of
chipset with their tx/rx FIFO size.

>          s->tx = val;
>          if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
>              if (qemu_chr_fe_backend_connected(&s->chr)) {
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH v2] hw/char/escc: Lower irq when transmit buffer is filled
@ 2019-04-19 15:42     ` Stephen Checkoway
  0 siblings, 0 replies; 4+ messages in thread
From: Stephen Checkoway @ 2019-04-19 15:42 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: Paolo Bonzini, QEMU Developers, Artyom Tarasenko, Laurent Vivier,
	qemu-trivial, Marc-André Lureau, Mark Cave-Ayland



> On Apr 18, 2019, at 08:13, Philippe Mathieu-Daudé <philmd@redhat.com> wrote:
> 
> On 4/17/19 2:50 AM, Stephen Checkoway wrote:
>> The SCC/ESCC will briefly stop asserting an interrupt when the
>> transmit FIFO is filled.
>> 
>> This code doesn't model the transmit FIFO/shift register so the
>> pending transmit interrupt is never deasserted which means that an
>> edge-triggered interrupt controller will never see the low-to-high
>> transition it needs to raise another interrupt. The practical
>> consequence of this is that guest firmware with an interrupt service
>> routine for the ESCC that does not send all of the data it has
>> immediately will stop sending data if the following sequence of
>> events occurs:
>> 1. Disable processor interrupts
>> 2. Write a character to the ESCC
>> 3. Add additional characters to a buffer which is drained by the ISR
>> 4. Enable processor interrupts
>> 
>> In this case, the first character will be sent, the interrupt will
>> fire and the ISR will output the second character. Since the pending
>> transmit interrupt remains asserted, no additional interrupts will
>> ever fire.
> 
> You might want to add a line expliciting the chipset model which forced
> you to do that patch (Z85C30).

Done.

Thanks for looking at this.

-- 
Stephen Checkoway

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH v2] hw/char/escc: Lower irq when transmit buffer is filled
@ 2019-04-19 15:42     ` Stephen Checkoway
  0 siblings, 0 replies; 4+ messages in thread
From: Stephen Checkoway @ 2019-04-19 15:42 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: qemu-trivial, Mark Cave-Ayland, QEMU Developers, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, Artyom Tarasenko



> On Apr 18, 2019, at 08:13, Philippe Mathieu-Daudé <philmd@redhat.com> wrote:
> 
> On 4/17/19 2:50 AM, Stephen Checkoway wrote:
>> The SCC/ESCC will briefly stop asserting an interrupt when the
>> transmit FIFO is filled.
>> 
>> This code doesn't model the transmit FIFO/shift register so the
>> pending transmit interrupt is never deasserted which means that an
>> edge-triggered interrupt controller will never see the low-to-high
>> transition it needs to raise another interrupt. The practical
>> consequence of this is that guest firmware with an interrupt service
>> routine for the ESCC that does not send all of the data it has
>> immediately will stop sending data if the following sequence of
>> events occurs:
>> 1. Disable processor interrupts
>> 2. Write a character to the ESCC
>> 3. Add additional characters to a buffer which is drained by the ISR
>> 4. Enable processor interrupts
>> 
>> In this case, the first character will be sent, the interrupt will
>> fire and the ISR will output the second character. Since the pending
>> transmit interrupt remains asserted, no additional interrupts will
>> ever fire.
> 
> You might want to add a line expliciting the chipset model which forced
> you to do that patch (Z85C30).

Done.

Thanks for looking at this.

-- 
Stephen Checkoway







^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-04-19 15:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-17  0:50 [Qemu-devel] [PATCH v2] hw/char/escc: Lower irq when transmit buffer is filled Stephen Checkoway
2019-04-18 12:13 ` Philippe Mathieu-Daudé
2019-04-19 15:42   ` Stephen Checkoway
2019-04-19 15:42     ` Stephen Checkoway

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.