1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #pragma once
26 
27 #include <stdint.h>
28 #include <virtio.h>
29 
30 /*
31  * VirtIO Console Feature Flags
32  */
33 #define VIRTIO_CONSOLE_F_SIZE (1U << 0)
34 #define VIRTIO_CONSOLE_F_MULTIPORT (1U << 1)
35 #define VIRTIO_CONSOLE_F_EMERG_WRITE (1U << 2)
36 
37 /**
38  * enum virtio_console_event - Message types for VirtIO console control events.
39  * @VIRTIO_CONSOLE_DEVICE_READY:  Guest->Host Acknowledge driver is ready to
40  *                                speak control protocol
41  * @VIRTIO_CONSOLE_DEVICE_ADD:    Host->Guest Sent when the host connects a
42  *                                port
43  * @VIRTIO_CONSOLE_DEVICE_REMOVE: Host->Guest Sent when the host disconnects a
44  *                                port
45  * @VIRTIO_CONSOLE_PORT_READY:    Guest->Host Acknowledge a DEVICE_ADD has been
46  *                                processed by the driver
47  * @VIRTIO_CONSOLE_CONSOLE_PORT:  Host->Guest label a port as being the primary
48  *                                console (as opposed to a serial port)
49  * @VIRTIO_CONSOLE_RESIZE:        Host->Guest one of the consoles has resized
50  * @VIRTIO_CONSOLE_PORT_OPEN:     Bidirectional, whether the port is available
51  *                                in "software". In theory, this is application
52  *                                defined, but QEMU requires that we open the
53  *                                port to begin receiving messages on it.
54  * @VIRTIO_CONSOLE_PORT_NAME:     Host->Guest to indicate the name of a port.
55  *                                The name is contained in the rest of the
56  *                                virtio buffer after the event header.
57  */
58 enum virtio_console_event {
59     VIRTIO_CONSOLE_DEVICE_READY = 0,
60     VIRTIO_CONSOLE_DEVICE_ADD = 1,
61     VIRTIO_CONSOLE_DEVICE_REMOVE = 2,
62     VIRTIO_CONSOLE_PORT_READY = 3,
63     VIRTIO_CONSOLE_CONSOLE_PORT = 4,
64     VIRTIO_CONSOLE_RESIZE = 5,
65     VIRTIO_CONSOLE_PORT_OPEN = 6,
66     VIRTIO_CONSOLE_PORT_NAME = 7,
67 };
68 
69 /* Queue IDs for the control queues */
70 #define VIRTIO_CONSOLE_CTRL_RX 2
71 #define VIRTIO_CONSOLE_CTRL_TX 3
72 
73 /* Offset from the base of a port for the RX/TX queues */
74 #define VIRTIO_CONSOLE_RX_OFFSET 0
75 #define VIRTIO_CONSOLE_TX_OFFSET 1
76 
77 /* Maximum number of ports we support in multiport */
78 #define MAX_PORTS 16
79 
80 /* Maximum name size we support for a port */
81 #define MAX_PORT_NAME_SIZE 64
82 
83 /**
84  * struct port - Bookkeeping for port state
85  * @host_connected:  Whether the host enabled this port
86  * @guest_connected: Whether we enabled this port
87  * @name:            Port name (provided by host), optional. Will be an empty
88  *                   string if unspecified.
89  */
90 struct port {
91     bool host_connected;
92     bool guest_connected;
93     char name[MAX_PORT_NAME_SIZE];
94 };
95 
96 /**
97  * struct virtio_console - A virtio serial/console bus
98  * @vio:   VirtIO device being used
99  * @ports: Current port state
100  */
101 struct virtio_console {
102     struct virtio_config* vio;
103     struct port ports[MAX_PORTS];
104 };
105 
106 /**
107  * init_virtio_console() - Initializes a single VirtIO console device
108  * Returns: The initialized console, or NULL in the event of a failure.
109  *
110  * We currently support a single legacy VirtIO console, in multiport
111  * configuration. Any additional consoles will be ignored.
112  *
113  * Note that at VirtIO console device in multiport configuration may have
114  * multiple attached serial ports, some of which are consoles.
115  * We support driving any number of these, but they must stem from the same
116  * VirtIO console.
117  */
118 struct virtio_console* init_virtio_console(void);
119 
120 /**
121  * virtio_console_connect_port() - Hook up queues to a specific port.
122  * @console: The console bus to hook up to.
123  * @port_id: Which port to hook up to.
124  * @vq_in:   Host->Guest virtq
125  * @vq_out:  Guest->Host virtq
126  */
127 void virtio_console_connect_port(struct virtio_console* console,
128                                  size_t port_id,
129                                  struct virtq* vq_in,
130                                  struct virtq* vq_out);
131