qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* simple serial device emulation
@ 2021-09-10 19:35 Hinko Kocevar
  2021-09-10 21:49 ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 4+ messages in thread
From: Hinko Kocevar @ 2021-09-10 19:35 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 897 bytes --]

I have an emulated MMIO area holding couple of registers that deal with
serial UART. Very simple access to the Tx and Rx registers from the
userspace point of view involves polling for a bit in one register and then
writing another; when there is room for another character. When the guest
app does write to a MMIO Tx register, as expected, io_writex() is invoked
and my handler is invoked. At the moment it does not do much. I'm thinking
now that the character needs to be fed to the serial device instance or
something.

Where should I look for suitable examples in the qemu code? I reckon that
other machines exist that do the similar. I found lots of serial_mm_init()
and sysbus_mmio_map() uses around serial port instances but I'm not sure
how to couple my "serial ops" to the "bus" or SerialMM (if that is the way
to go).

Thanks!
//hinko

-- 
.. the more I see the less I believe.., AE AoR

[-- Attachment #2: Type: text/html, Size: 1116 bytes --]

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

* Re: simple serial device emulation
  2021-09-10 19:35 simple serial device emulation Hinko Kocevar
@ 2021-09-10 21:49 ` Philippe Mathieu-Daudé
  2021-09-11 15:23   ` Peter Maydell
  0 siblings, 1 reply; 4+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-10 21:49 UTC (permalink / raw)
  To: Hinko Kocevar, qemu-devel

On 9/10/21 9:35 PM, Hinko Kocevar wrote:
> I have an emulated MMIO area holding couple of registers that deal with
> serial UART. Very simple access to the Tx and Rx registers from the
> userspace point of view involves polling for a bit in one register and
> then writing another; when there is room for another character. When the
> guest app does write to a MMIO Tx register, as expected, io_writex() is
> invoked and my handler is invoked. At the moment it does not do much.
> I'm thinking now that the character needs to be fed to the serial device
> instance or something.
> 
> Where should I look for suitable examples in the qemu code? I reckon
> that other machines exist that do the similar. I found lots of
> serial_mm_init() and sysbus_mmio_map() uses around serial port instances
> but I'm not sure how to couple my "serial ops" to the "bus" or SerialMM
> (if that is the way to go).

Your device is a "character device frontend". See the API in
include/chardev/char-fe.h. Frontends can be connected to various
backends. The simplest backend is the standard input/output
(named 'stdio').

To be useful your frontend have to implement some handlers:
IOEventHandler, IOCanReadHandler, IOReadHandler. The frontend
register these handlers by calling qemu_chr_fe_set_handlers()
(usually in the DeviceRealize() handler).

The backends will interact with your device via this API.

I recommend you to look at the hw/char/digic-uart.c model which is
quite simple, it returns the last char received, and only transmit
one char per I/O.

Then for a more complete (and up to date) model you can look at
hw/char/goldfish_tty.c, it uses a FIFO to receive chars, but still
transmit one char at a time.

Finally the hw/char/serial.c is probably the most complete models,
with 2 FIFOs (RX & TX) and try to respect timings.

Regards,

Phil.


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

* Re: simple serial device emulation
  2021-09-10 21:49 ` Philippe Mathieu-Daudé
@ 2021-09-11 15:23   ` Peter Maydell
  2021-09-11 16:08     ` Hinko Kocevar
  0 siblings, 1 reply; 4+ messages in thread
From: Peter Maydell @ 2021-09-11 15:23 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé; +Cc: Hinko Kocevar, QEMU Developers

On Fri, 10 Sept 2021 at 22:51, Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>
> On 9/10/21 9:35 PM, Hinko Kocevar wrote:
> > I have an emulated MMIO area holding couple of registers that deal with
> > serial UART. Very simple access to the Tx and Rx registers from the
> > userspace point of view involves polling for a bit in one register and
> > then writing another; when there is room for another character. When the
> > guest app does write to a MMIO Tx register, as expected, io_writex() is
> > invoked and my handler is invoked. At the moment it does not do much.
> > I'm thinking now that the character needs to be fed to the serial device
> > instance or something.
> >
> > Where should I look for suitable examples in the qemu code? I reckon
> > that other machines exist that do the similar. I found lots of
> > serial_mm_init() and sysbus_mmio_map() uses around serial port instances
> > but I'm not sure how to couple my "serial ops" to the "bus" or SerialMM
> > (if that is the way to go).
>
> Your device is a "character device frontend". See the API in
> include/chardev/char-fe.h. Frontends can be connected to various
> backends. The simplest backend is the standard input/output
> (named 'stdio').

More specifically, it's a UART model. All of our UART models
are in hw/char/.

> I recommend you to look at the hw/char/digic-uart.c model which is
> quite simple, it returns the last char received, and only transmit
> one char per I/O.

digic-uart does still use the old qemu_chr_fe_write_all() blocking
API, though (there is an XXX comment about that). If you want an
example of the non-blocking approach, try hw/char/cmsdk-apb-uart.c.

> Finally the hw/char/serial.c is probably the most complete models,
> with 2 FIFOs (RX & TX) and try to respect timings.

hw/char/serial.c is kind of complicated though, both because
it's quite old code that's been gradually modernized, and also
because it has to support both mmio and io port type serial ports.
So I'm not sure I'd recommend it as an example to learn from.

-- PMM


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

* Re: simple serial device emulation
  2021-09-11 15:23   ` Peter Maydell
@ 2021-09-11 16:08     ` Hinko Kocevar
  0 siblings, 0 replies; 4+ messages in thread
From: Hinko Kocevar @ 2021-09-11 16:08 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Philippe Mathieu-Daudé, QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 2613 bytes --]

On Sat, 11 Sep 2021 at 17:24, Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Fri, 10 Sept 2021 at 22:51, Philippe Mathieu-Daudé <f4bug@amsat.org>
> wrote:
> >
> > On 9/10/21 9:35 PM, Hinko Kocevar wrote:
> > > I have an emulated MMIO area holding couple of registers that deal with
> > > serial UART. Very simple access to the Tx and Rx registers from the
> > > userspace point of view involves polling for a bit in one register and
> > > then writing another; when there is room for another character. When
> the
> > > guest app does write to a MMIO Tx register, as expected, io_writex() is
> > > invoked and my handler is invoked. At the moment it does not do much.
> > > I'm thinking now that the character needs to be fed to the serial
> device
> > > instance or something.
> > >
> > > Where should I look for suitable examples in the qemu code? I reckon
> > > that other machines exist that do the similar. I found lots of
> > > serial_mm_init() and sysbus_mmio_map() uses around serial port
> instances
> > > but I'm not sure how to couple my "serial ops" to the "bus" or SerialMM
> > > (if that is the way to go).
> >
> > Your device is a "character device frontend". See the API in
> > include/chardev/char-fe.h. Frontends can be connected to various
> > backends. The simplest backend is the standard input/output
> > (named 'stdio').
>
> More specifically, it's a UART model. All of our UART models
> are in hw/char/.
>
> > I recommend you to look at the hw/char/digic-uart.c model which is
> > quite simple, it returns the last char received, and only transmit
> > one char per I/O.


Phil, that was perfect. Just something someone like me with no prior
experience in hacking qemu can use. I have my chars on stdout as we speak.
I took the digic code as a starting point.


>
> digic-uart does still use the old qemu_chr_fe_write_all() blocking
> API, though (there is an XXX comment about that). If you want an
> example of the non-blocking approach, try hw/char/cmsdk-apb-uart.c.


Peter, thanks for the input. I’ll look into the improved handling, too!


>
> > Finally the hw/char/serial.c is probably the most complete models,
> > with 2 FIFOs (RX & TX) and try to respect timings.
>
> hw/char/serial.c is kind of complicated though, both because
> it's quite old code that's been gradually modernized, and also
> because it has to support both mmio and io port type serial ports.
> So I'm not sure I'd recommend it as an example to learn from.


Good to know!

//hinko
-- 
.. the more I see the less I believe.., AE AoR

[-- Attachment #2: Type: text/html, Size: 3767 bytes --]

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

end of thread, other threads:[~2021-09-11 16:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-10 19:35 simple serial device emulation Hinko Kocevar
2021-09-10 21:49 ` Philippe Mathieu-Daudé
2021-09-11 15:23   ` Peter Maydell
2021-09-11 16:08     ` Hinko Kocevar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).