xref: /openbmc/qemu/include/hw/virtio/virtio-serial.h (revision 4dad0a9aa818698e0735c8352bf7925a1660df6f)
10d09e41aSPaolo Bonzini /*
20d09e41aSPaolo Bonzini  * Virtio Serial / Console Support
30d09e41aSPaolo Bonzini  *
40d09e41aSPaolo Bonzini  * Copyright IBM, Corp. 2008
50d09e41aSPaolo Bonzini  * Copyright Red Hat, Inc. 2009, 2010
60d09e41aSPaolo Bonzini  *
70d09e41aSPaolo Bonzini  * Authors:
80d09e41aSPaolo Bonzini  *  Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
90d09e41aSPaolo Bonzini  *  Amit Shah <amit.shah@redhat.com>
100d09e41aSPaolo Bonzini  *
110d09e41aSPaolo Bonzini  * This work is licensed under the terms of the GNU GPL, version 2.  See
120d09e41aSPaolo Bonzini  * the COPYING file in the top-level directory.
130d09e41aSPaolo Bonzini  *
140d09e41aSPaolo Bonzini  */
152a6a4076SMarkus Armbruster 
162a6a4076SMarkus Armbruster #ifndef QEMU_VIRTIO_SERIAL_H
172a6a4076SMarkus Armbruster #define QEMU_VIRTIO_SERIAL_H
180d09e41aSPaolo Bonzini 
199b70c179SMichael S. Tsirkin #include "standard-headers/linux/virtio_console.h"
200d09e41aSPaolo Bonzini #include "hw/virtio/virtio.h"
21db1015e9SEduardo Habkost #include "qom/object.h"
220d09e41aSPaolo Bonzini 
230d09e41aSPaolo Bonzini struct virtio_serial_conf {
240d09e41aSPaolo Bonzini     /* Max. number of ports we can have for a virtio-serial device */
250d09e41aSPaolo Bonzini     uint32_t max_virtserial_ports;
260d09e41aSPaolo Bonzini };
270d09e41aSPaolo Bonzini 
280d09e41aSPaolo Bonzini #define TYPE_VIRTIO_SERIAL_PORT "virtio-serial-port"
29c821774aSEduardo Habkost OBJECT_DECLARE_TYPE(VirtIOSerialPort, VirtIOSerialPortClass,
3030b5707cSEduardo Habkost                     VIRTIO_SERIAL_PORT)
310d09e41aSPaolo Bonzini 
320d09e41aSPaolo Bonzini typedef struct VirtIOSerial VirtIOSerial;
33b28b8037SEduardo Habkost 
34b28b8037SEduardo Habkost #define TYPE_VIRTIO_SERIAL_BUS "virtio-serial-bus"
35*8063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(VirtIOSerialBus, VIRTIO_SERIAL_BUS)
36b28b8037SEduardo Habkost 
370d09e41aSPaolo Bonzini 
38db1015e9SEduardo Habkost struct VirtIOSerialPortClass {
390d09e41aSPaolo Bonzini     DeviceClass parent_class;
400d09e41aSPaolo Bonzini 
410d09e41aSPaolo Bonzini     /* Is this a device that binds with hvc in the guest? */
420d09e41aSPaolo Bonzini     bool is_console;
430d09e41aSPaolo Bonzini 
440d09e41aSPaolo Bonzini     /*
452ef66625SAndreas Färber      * The per-port (or per-app) realize function that's called when a
460d09e41aSPaolo Bonzini      * new device is found on the bus.
470d09e41aSPaolo Bonzini      */
482ef66625SAndreas Färber     DeviceRealize realize;
490d09e41aSPaolo Bonzini     /*
502ef66625SAndreas Färber      * Per-port unrealize function that's called when a port gets
510d09e41aSPaolo Bonzini      * hot-unplugged or removed.
520d09e41aSPaolo Bonzini      */
532ef66625SAndreas Färber     DeviceUnrealize unrealize;
540d09e41aSPaolo Bonzini 
550d09e41aSPaolo Bonzini     /* Callbacks for guest events */
560d09e41aSPaolo Bonzini         /* Guest opened/closed device. */
570d09e41aSPaolo Bonzini     void (*set_guest_connected)(VirtIOSerialPort *port, int guest_connected);
580d09e41aSPaolo Bonzini 
5955289fb0SPavel Butsykin     /* Enable/disable backend for virtio serial port */
6055289fb0SPavel Butsykin     void (*enable_backend)(VirtIOSerialPort *port, bool enable);
6155289fb0SPavel Butsykin 
620d09e41aSPaolo Bonzini         /* Guest is now ready to accept data (virtqueues set up). */
630d09e41aSPaolo Bonzini     void (*guest_ready)(VirtIOSerialPort *port);
640d09e41aSPaolo Bonzini 
650d09e41aSPaolo Bonzini         /*
664add73aaSAmit Shah          * Guest has enqueued a buffer for the host to write into.
674add73aaSAmit Shah          * Called each time a buffer is enqueued by the guest;
684add73aaSAmit Shah          * irrespective of whether there already were free buffers the
694add73aaSAmit Shah          * host could have consumed.
704add73aaSAmit Shah          *
714add73aaSAmit Shah          * This is dependent on both the guest and host end being
724add73aaSAmit Shah          * connected.
734add73aaSAmit Shah          */
744add73aaSAmit Shah     void (*guest_writable)(VirtIOSerialPort *port);
754add73aaSAmit Shah 
764add73aaSAmit Shah     /*
770d09e41aSPaolo Bonzini      * Guest wrote some data to the port. This data is handed over to
780d09e41aSPaolo Bonzini      * the app via this callback.  The app can return a size less than
790d09e41aSPaolo Bonzini      * 'len'.  In this case, throttling will be enabled for this port.
800d09e41aSPaolo Bonzini      */
810d09e41aSPaolo Bonzini     ssize_t (*have_data)(VirtIOSerialPort *port, const uint8_t *buf,
82f9fb0532SHans de Goede                          ssize_t len);
83db1015e9SEduardo Habkost };
840d09e41aSPaolo Bonzini 
850d09e41aSPaolo Bonzini /*
860d09e41aSPaolo Bonzini  * This is the state that's shared between all the ports.  Some of the
870d09e41aSPaolo Bonzini  * state is configurable via command-line options. Some of it can be
880d09e41aSPaolo Bonzini  * set by individual devices in their initfn routines. Some of the
890d09e41aSPaolo Bonzini  * state is set by the generic qdev device init routine.
900d09e41aSPaolo Bonzini  */
910d09e41aSPaolo Bonzini struct VirtIOSerialPort {
920d09e41aSPaolo Bonzini     DeviceState dev;
930d09e41aSPaolo Bonzini 
940d09e41aSPaolo Bonzini     QTAILQ_ENTRY(VirtIOSerialPort) next;
950d09e41aSPaolo Bonzini 
960d09e41aSPaolo Bonzini     /*
970d09e41aSPaolo Bonzini      * This field gives us the virtio device as well as the qdev bus
980d09e41aSPaolo Bonzini      * that we are associated with
990d09e41aSPaolo Bonzini      */
1000d09e41aSPaolo Bonzini     VirtIOSerial *vser;
1010d09e41aSPaolo Bonzini 
1020d09e41aSPaolo Bonzini     VirtQueue *ivq, *ovq;
1030d09e41aSPaolo Bonzini 
1040d09e41aSPaolo Bonzini     /*
1050d09e41aSPaolo Bonzini      * This name is sent to the guest and exported via sysfs.
1060d09e41aSPaolo Bonzini      * The guest could create symlinks based on this information.
1070d09e41aSPaolo Bonzini      * The name is in the reverse fqdn format, like org.qemu.console.0
1080d09e41aSPaolo Bonzini      */
1090d09e41aSPaolo Bonzini     char *name;
1100d09e41aSPaolo Bonzini 
1110d09e41aSPaolo Bonzini     /*
1120d09e41aSPaolo Bonzini      * This id helps identify ports between the guest and the host.
1130d09e41aSPaolo Bonzini      * The guest sends a "header" with this id with each data packet
1140d09e41aSPaolo Bonzini      * that it sends and the host can then find out which associated
1150d09e41aSPaolo Bonzini      * device to send out this data to
1160d09e41aSPaolo Bonzini      */
1170d09e41aSPaolo Bonzini     uint32_t id;
1180d09e41aSPaolo Bonzini 
1190d09e41aSPaolo Bonzini     /*
1200d09e41aSPaolo Bonzini      * This is the elem that we pop from the virtqueue.  A slow
1210d09e41aSPaolo Bonzini      * backend that consumes guest data (e.g. the file backend for
1220d09e41aSPaolo Bonzini      * qemu chardevs) can cause the guest to block till all the output
1230d09e41aSPaolo Bonzini      * is flushed.  This isn't desired, so we keep a note of the last
1240d09e41aSPaolo Bonzini      * element popped and continue consuming it once the backend
1250d09e41aSPaolo Bonzini      * becomes writable again.
1260d09e41aSPaolo Bonzini      */
12751b19ebeSPaolo Bonzini     VirtQueueElement *elem;
1280d09e41aSPaolo Bonzini 
1290d09e41aSPaolo Bonzini     /*
1300d09e41aSPaolo Bonzini      * The index and the offset into the iov buffer that was popped in
1310d09e41aSPaolo Bonzini      * elem above.
1320d09e41aSPaolo Bonzini      */
1330d09e41aSPaolo Bonzini     uint32_t iov_idx;
1340d09e41aSPaolo Bonzini     uint64_t iov_offset;
1350d09e41aSPaolo Bonzini 
1360d09e41aSPaolo Bonzini     /*
1370d09e41aSPaolo Bonzini      * When unthrottling we use a bottom-half to call flush_queued_data.
1380d09e41aSPaolo Bonzini      */
1390d09e41aSPaolo Bonzini     QEMUBH *bh;
1400d09e41aSPaolo Bonzini 
1410d09e41aSPaolo Bonzini     /* Is the corresponding guest device open? */
1420d09e41aSPaolo Bonzini     bool guest_connected;
1430d09e41aSPaolo Bonzini     /* Is this device open for IO on the host? */
1440d09e41aSPaolo Bonzini     bool host_connected;
1450d09e41aSPaolo Bonzini     /* Do apps not want to receive data? */
1460d09e41aSPaolo Bonzini     bool throttled;
1470d09e41aSPaolo Bonzini };
1480d09e41aSPaolo Bonzini 
1490d09e41aSPaolo Bonzini /* The virtio-serial bus on top of which the ports will ride as devices */
1500d09e41aSPaolo Bonzini struct VirtIOSerialBus {
1510d09e41aSPaolo Bonzini     BusState qbus;
1520d09e41aSPaolo Bonzini 
1530d09e41aSPaolo Bonzini     /* This is the parent device that provides the bus for ports. */
1540d09e41aSPaolo Bonzini     VirtIOSerial *vser;
1550d09e41aSPaolo Bonzini 
1560d09e41aSPaolo Bonzini     /* The maximum number of ports that can ride on top of this bus */
1570d09e41aSPaolo Bonzini     uint32_t max_nr_ports;
1580d09e41aSPaolo Bonzini };
1590d09e41aSPaolo Bonzini 
1600d09e41aSPaolo Bonzini typedef struct VirtIOSerialPostLoad {
1610d09e41aSPaolo Bonzini     QEMUTimer *timer;
1620d09e41aSPaolo Bonzini     uint32_t nr_active_ports;
1630d09e41aSPaolo Bonzini     struct {
1640d09e41aSPaolo Bonzini         VirtIOSerialPort *port;
1650d09e41aSPaolo Bonzini         uint8_t host_connected;
1660d09e41aSPaolo Bonzini     } *connected;
1670d09e41aSPaolo Bonzini } VirtIOSerialPostLoad;
1680d09e41aSPaolo Bonzini 
1690d09e41aSPaolo Bonzini struct VirtIOSerial {
17076017fd2SKONRAD Frederic     VirtIODevice parent_obj;
1710d09e41aSPaolo Bonzini 
1720d09e41aSPaolo Bonzini     VirtQueue *c_ivq, *c_ovq;
1730d09e41aSPaolo Bonzini     /* Arrays of ivqs and ovqs: one per port */
1740d09e41aSPaolo Bonzini     VirtQueue **ivqs, **ovqs;
1750d09e41aSPaolo Bonzini 
1760d09e41aSPaolo Bonzini     VirtIOSerialBus bus;
1770d09e41aSPaolo Bonzini 
1780d09e41aSPaolo Bonzini     QTAILQ_HEAD(, VirtIOSerialPort) ports;
1790d09e41aSPaolo Bonzini 
180a1857ad1SAmit Shah     QLIST_ENTRY(VirtIOSerial) next;
181a1857ad1SAmit Shah 
1820d09e41aSPaolo Bonzini     /* bitmap for identifying active ports */
1830d09e41aSPaolo Bonzini     uint32_t *ports_map;
1840d09e41aSPaolo Bonzini 
1850d09e41aSPaolo Bonzini     struct VirtIOSerialPostLoad *post_load;
1862cd2b016SKONRAD Frederic 
1872cd2b016SKONRAD Frederic     virtio_serial_conf serial;
188a06b1daeSSascha Silbe 
189a06b1daeSSascha Silbe     uint64_t host_features;
1900d09e41aSPaolo Bonzini };
1910d09e41aSPaolo Bonzini 
1920d09e41aSPaolo Bonzini /* Interface to the virtio-serial bus */
1930d09e41aSPaolo Bonzini 
1940d09e41aSPaolo Bonzini /*
1950d09e41aSPaolo Bonzini  * Open a connection to the port
1960d09e41aSPaolo Bonzini  *   Returns 0 on success (always).
1970d09e41aSPaolo Bonzini  */
1980d09e41aSPaolo Bonzini int virtio_serial_open(VirtIOSerialPort *port);
1990d09e41aSPaolo Bonzini 
2000d09e41aSPaolo Bonzini /*
2010d09e41aSPaolo Bonzini  * Close the connection to the port
2020d09e41aSPaolo Bonzini  *   Returns 0 on success (always).
2030d09e41aSPaolo Bonzini  */
2040d09e41aSPaolo Bonzini int virtio_serial_close(VirtIOSerialPort *port);
2050d09e41aSPaolo Bonzini 
2060d09e41aSPaolo Bonzini /*
2070d09e41aSPaolo Bonzini  * Send data to Guest
2080d09e41aSPaolo Bonzini  */
2090d09e41aSPaolo Bonzini ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,
2100d09e41aSPaolo Bonzini                             size_t size);
2110d09e41aSPaolo Bonzini 
2120d09e41aSPaolo Bonzini /*
2130d09e41aSPaolo Bonzini  * Query whether a guest is ready to receive data.
2140d09e41aSPaolo Bonzini  */
2150d09e41aSPaolo Bonzini size_t virtio_serial_guest_ready(VirtIOSerialPort *port);
2160d09e41aSPaolo Bonzini 
2170d09e41aSPaolo Bonzini /*
2180d09e41aSPaolo Bonzini  * Flow control: Ports can signal to the virtio-serial core to stop
2190d09e41aSPaolo Bonzini  * sending data or re-start sending data, depending on the 'throttle'
2200d09e41aSPaolo Bonzini  * value here.
2210d09e41aSPaolo Bonzini  */
2220d09e41aSPaolo Bonzini void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle);
2230d09e41aSPaolo Bonzini 
2242cd2b016SKONRAD Frederic #define TYPE_VIRTIO_SERIAL "virtio-serial-device"
225*8063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(VirtIOSerial, VIRTIO_SERIAL)
2262cd2b016SKONRAD Frederic 
2270d09e41aSPaolo Bonzini #endif
228