12#include <l4/l4virtio/server/l4virtio>
15namespace L4virtio {
namespace Svr {
namespace Console {
72 Driver_mem_region *
mem;
127 enum { Control_queue_size = 0x10 };
136 Port &operator = (
Port const &) =
delete;
138 virtual ~Port() =
default;
193 struct Serial_config_space
199 } __attribute__((packed));
211 explicit Virtio_con(
unsigned max_ports,
bool enable_multiport)
213 _num_ports(enable_multiport ? max_ports : 1),
215 enable_multiport ? max_ports * 2 + 2 : 2)
224 _dev_config.host_features(0) = hf.
raw;
226 if (enable_multiport)
227 _dev_config.priv_config()->max_nr_ports = _num_ports;
228 _dev_config.reset_hdr();
231 void reset_queue_configs()
233 for (
unsigned q = 0; q < _dev_config.num_queues(); ++q)
239 if (index >= _dev_config.num_queues())
242 if (
setup_queue(get_queue(index), index, max_queue_size(index)))
255 && _dev_config.num_queues() > Ctrl_rx;
258 bool ctrl_queue_ready()
const
259 {
return _ctrl_port.
is_open(); }
263 _negotiated_features =
Features(_dev_config.negotiated_features(0));
396 if (!ctrl_queue_ready())
409 rp.
start(
this, r, &req);
416 memcpy(req.
msg, &msg,
sizeof(msg));
420 size_t name_len = cxx::min(req.
len -
sizeof(msg), strlen(name));
421 memcpy(
reinterpret_cast<char*
>(req.
msg) +
sizeof(msg), name, name_len);
422 q->
finish(r,
this,
sizeof(msg) + name_len);
425 q->
finish(r,
this,
sizeof(msg));
449 Virtqueue::Request r;
455 rp.
start(
this, r, &req);
458 if (req.
len <
sizeof(msg))
465 memcpy(&msg, req.
msg,
sizeof(msg));
481 if (!ctrl_queue_ready())
488 if (msg.
id >= max_ports())
501 if (msg.
id >= max_ports())
524 this->
_mem_info.load_desc(desc, proc, table);
530 Control_request *data)
536 data->msg =
reinterpret_cast<Control_message *
>(region->local(desc.
addr));
537 data->len = desc.
len;
543 for (
unsigned p = 0; p < _num_ports; ++p)
547 reset_queue_configs();
548 _dev_config.reset_hdr();
638 unsigned max_ports()
const
639 {
return _num_ports; }
642 bool is_control_queue(
unsigned q)
const
643 {
return q == Ctrl_rx || q == Ctrl_tx; }
645 unsigned queue_to_port(
unsigned q)
const
646 {
return (q == 0 || q == 1) ? 0 : (q / 2) - 1; }
656 unsigned max_queue_size(
unsigned q)
const
658 if (is_control_queue(q))
672 Virtqueue *get_queue(
unsigned q)
675 if (is_control_queue(q))
678 p =
port(queue_to_port(q));
689 Dev_config_t<Serial_config_space> _dev_config;
691 Features _negotiated_features{0};
Base class implementing a virtio console device with L4Re-based notification handling.
Base class implementing a virtio console functionality.
virtual void process_port_open(l4_uint32_t id, l4_uint16_t value)=0
Callback called on PORT_OPEN event.
bool check_queues() override
callback for checking if the queues at DRIVER_OK transition
virtual void reset_device()
Reset the state of the actual console device.
bool multiport_enabled() const
Return true if the multiport feature is enabled and control queues are available.
bool check_features(void) override
callback for checking the subset of accepted features
virtual void notify_queue(Virtqueue *queue)=0
Notify queue of available data.
void reset() override
reset callback, called for doing a device reset
int port_open(unsigned idx, bool open)
Send a PORT_OPEN message and update the internal state.
virtual void process_port_ready(l4_uint32_t id, l4_uint16_t value)
Callback called on PORT_READY event.
int port_remove(unsigned idx)
Send a DEVICE_REMOVE message and update the internal state.
virtual void process_device_ready(l4_uint16_t value)=0
Callback called on DEVICE_READY event.
int port_add(unsigned idx)
Send a DEVICE_ADD message and update the internal state.
int reconfig_queue(unsigned index) override
callback for client queue-config request
Virtio_con(unsigned max_ports, bool enable_multiport)
Create a new multiport console device.
virtual Port * port(unsigned port)=0
Return the specified port.
int handle_control_message()
Handle control message received from the driver.
int send_control_message(l4_uint32_t idx, l4_uint16_t event, l4_uint16_t value=0, const char *name=0)
Send control message to driver.
Server-side L4-VIRTIO device stub.
Mem_list _mem_info
Memory region list.
bool setup_queue(Virtqueue *q, unsigned qn, unsigned num_max)
Enable/disable the specified queue.
void reset_queue_config(unsigned idx, unsigned num_max, bool inc_generation=false)
Trigger reset for the configuration space for queue idx.
Encapsulate the state for processing a VIRTIO request.
void start(DESC_MAN *dm, Virtqueue *ring, Virtqueue::Head_desc const &request, ARGS... args)
Start processing a new request.
Virtqueue implementation for the device.
Request next_avail()
Get the next available descriptor from the available ring.
void finish(Head_desc &d, QUEUE_OBSERVER *o, l4_uint32_t len=0)
Add a descriptor to the used ring, and notify an observer.
void consumed(Head_desc const &r, l4_uint32_t len=0)
Put the given descriptor into the used ring.
Descriptor in the descriptor table.
l4_uint32_t len
Length of described buffer.
Ptr< void > addr
Address stored in descriptor.
bool ready() const
Test if this queue is in working state.
unsigned int l4_uint32_t
Unsigned 32bit value.
unsigned short int l4_uint16_t
Unsigned 16bit value.
@ L4_EINVAL
Invalid argument.
@ L4_EBUSY
Object currently busy, try later.
@ L4_ENODEV
No such thing.
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
@ L4VIRTIO_ID_CONSOLE
Simple device for data IO via ports.
long chksys(long err, char const *extra="", long ret=0)
Generate C++ exception on error.
L4-VIRTIO Transport C++ API.
Exception used by Queue to indicate descriptor errors.
@ Bad_address
Address cannot be translated.
Virtio console control message.
Events
Possible control events.
@ Device_ready
Sent by driver at initialization.
@ Console_port
Sent by device to nominate port as console port.
@ Port_open
Sent by device and driver to indicate whether a port is open.
@ Port_name
Sent by device to tag a port.
@ Device_remove
Sent by device to remove added ports.
@ Device_add
Sent by device to create new ports.
@ Port_ready
Sent by driver as response to Device_add.
@ Resize
Sent by device to indicate a console size change.
l4_uint16_t value
Extra information.
l4_uint32_t id
Port number.
l4_uint16_t event
Control event, see Events.
Specialised Virtqueue::Request providing access to control message payload.
Control_message * msg
Virtual address of the data block (in device space).
l4_uint32_t len
Length of datablock in bytes.
Driver_mem_region * mem
Pointer to driver memory region.
Virtio console specific feature bits.
constexpr emerg_write_bfm_t::Val emerg_write() const
Get the emerg_write bits ( 2 to 2 ) of raw.
constexpr console_multiport_bfm_t::Val console_multiport() const
Get the console_multiport bits ( 1 to 1 ) of raw.
constexpr console_size_bfm_t::Val console_size() const
Get the console_size bits ( 0 to 0 ) of raw.
Representation of a Virtio console port.
Port_status status
State the port is in.
Virtqueue rx
Transmitq of the port.
unsigned vq_max
Maximum queue sizes for this port.
virtual void reset()
Reset the port to the initial state and disable its virtqueues.
Virtqueue tx
Receiveq of the port.
bool is_open() const
Check that the port is open.
bool rx_ready() const
Check that device implementation may write to receive queues.
bool tx_ready() const
Check that device implementation may read from transmit queues.
Port_status
Possible states of a virtio console port.
@ Port_added
Port has been added by device, waiting for ready message.
@ Port_ready
Port is ready but still closed.
@ Port_open
Port is in a working state.
@ Port_disabled
Reset state, waiting for port to be added.
@ Port_failed
Device failure, port unusable.
bool queues_ready() const
Check that both virtqueues are set up correctly.
Type for device feature bitmap.
l4_uint32_t raw
The raw value of the features bitmap.