[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-discuss] quick pointer on adding a new chardev

From: Peter Maydell
Subject: Re: [Qemu-discuss] quick pointer on adding a new chardev
Date: Fri, 17 Feb 2017 16:36:56 +0000

On 17 February 2017 at 15:47, Herb Peyerl <address@hidden> wrote:
> I’ve managed to get a basic qemu device written that responds to register 
> reads/writes and inserts writes from the guest Linux instance into a Qemu 
> Fifo.  Now I’m trying to hook the device up to a TCP socket listening on 
> another host  (nc -l).
> In essence, I’m trying to do this:
>         -chardev socket,host=,port=5000,id=myfoo0 \
>         -device myfoo,chardev=myfoo0
> What I seem to be unclear on at this point is how to create a chardev device 
> that qemu recognizes as a ‘myfoo’  (instead of ‘serial’ or ‘usb-serial’) …

* the chardev is the "backend" part which defines the
  communications channel (socket, terminal, filedescriptor...)
  on the host OS
* the bit of emulated hardware that appears to the guest
  and which uses the backend is usually just called
  a "device".

> I understand on the receive side I need to do ‘qemu_chr_add_handlers()’
> but I’m unclear on how a new chardev becomes instantiated.

It's the presence of the command line option '-chardev ....' that
says "instantiate a chardev".
(Similarly, the -device option is what says "instantiate the
device". Board models may also automatically instantiate
some devices, and for non-pluggable devices which are
hardwired to certain IRQs and memory ranges that's the only
way to create a device.)

>  I’ve looked at other device emulations like xilinx_uart.c and
> cadence_uart.c which appear to do that but I can’t seem to get
> my device to be acceptable to ‘-device …..’

xilinx_uart.c seems as good a thing to look at as any.
Your device has to define a property:

static Property xilinx_uartlite_properties[] = {
    DEFINE_PROP_CHR("chardev", XilinxUARTLite, chr),

Then the commandline -device myfoo option will accept
chardev=something. When the property is set this fills
in the specified structure field (in this case 'chr' in
the XilinxUARTLite struct -- use the right field and
struct names for your device). You can then use it in
your code. (If you can't work without a chardev backend
then you should make sure your device's realize method
fails with a suitable error if the property is unset.)

Your realize method also needs to call
qemu_chr_fe_set_handlers() to register hooks to be called
to handle received data from the chardev.

PS: this all assumes the device is a pluggable one
like a PCI device. If it's hardwired into the board
model then you can't use -device to create it, and the
syntax for giving it its chardev will be different
(something involving -global I think).

> As a side note, it appears that the API has changed in recent
> versions of qemu (CharBackend, and        DEFINE_PROP_CHR) but
> the version of Qemu I’m using from the Xilinx Qemu tree hasn’t
> been keeping up, as a result ‘CharBackend’ is not defined….

I think this comes under the heading of "you should probably
talk to Xilinx"...

>   The old way appears to be " s->chr = qemu_char_get_next_serial();” which is 
> failing for me and as a result qemu_chr_add_handlers() gets a SEGV.     ( 
> https://github.com/Xilinx/qemu/blob/master/hw/char/cadence_uart.c#L479 )

the get_next_serial() method is an old thing which
(a) is specific to serial devices and (b) gets you
the next chardev that was specified for serial in particular.
On the command line that looks like
 -serial chardev:mychardevid
(or any of a number of other ways to specify the backend
to -serial), and calling get_next_serial() gets you the
next unused one if there are multiple -serial command
line options.

It should still (even before that function went away)
be possible to do this via -chardev, though.

>> qemu-system-aarch64: Option ‘-device myfoo’ cannot be handled by this machine

This is saying "I don't know about this device at all", and
doesn't have anything to do with chardevs. I would
start by checking that your code is really being built
(ie you have the makefile syntax right and have specified
in the right default-configs/ file that it should be
built for this target architecture, and that you have
the right syntax to register the device (the type_init
macro and associated boilerplate).

-- PMM

reply via email to

[Prev in Thread] Current Thread [Next in Thread]