On 2020/6/3 1:54, Alistair Francis wrote:
On Tue, Jun 2, 2020 at 5:28 AM LIU Zhiwei<zhiwei_...@c-sky.com>  wrote:
Hi Alistair,

There are still some questions I don't understand.

1. Is the baud rate  or fifo a necessary feature to simulate?
As you can see, qemu_chr_fe_write will send the byte as soon as possible.
When you want to transmit a byte through WDATA,  you can call
qemu_chr_fe_write directly.
So qemu_chr_fe_write() will send the data straight away. This doesn't
match what teh hardware does though. So by modelling a FIFO and a
delay in sending we can better match the hardware.
I see many UARTs have similar features. Does the software really care about
these features? Usually I just want to print something to the terminal through UART. Most simulation in QEMU is for running software, not exactly the details of hardware.
For example, we will not simulate the 16x oversamples in this UART.

There is no error here. Personally I  think it is necessary to simulate the FIFO and baud rate,
maybe for supporting some backends.

Can someone give a reasonable answer for this question?
2.  The baud rate calculation method is not strictly right.
I think when a byte write to FIFO,  char_tx_time * 8 is the correct time
to send the byte instead of
char_tx_time * 4.
Do you mind explaining why 8 is correct instead of 4?
Usually write a byte to WDATA will trigger a uart_write_tx_fifo. Translate a bit will take
char_tx_time. So it will take char_tx_time * 8 to transmit a byte.
3.  Why add a watch here?
This is based on the Cadence UART implementation in QEMU (which does
the same thing). This will trigger a callback when we can write more
data or when the backend has hung up.
Many other serials do the same thing, like virtio-console and serial. So it may be a common
interface here. I will try to understand it(Not yet).

Zhiwei
Alistair

+        s->uart_status |= UART_STATUS_TXEMPTY;
+        s->uart_intr_state |= INTR_STATE_TX_EMPTY;
+        s->uart_intr_state &= ~INTR_STATE_TX_WATERMARK;
+        ibex_uart_update_irqs(s);
+        return FALSE;
+    }
+
+    ret = qemu_chr_fe_write(&s->chr, s->tx_fifo, s->tx_level);
+
+    if (ret >= 0) {
+        s->tx_level -= ret;
+        memmove(s->tx_fifo, s->tx_fifo + ret, s->tx_level);
+    }
+
+    if (s->tx_level) {
+        guint r = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
+                                        ibex_uart_xmit, s);
+        if (!r) {
+            s->tx_level = 0;
+            return FALSE;
+        }
+    }
+
Zhiwei




Reply via email to