/*
 * Copyright (c) 2014, 2016-2017 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __DEV_VIRTIO_BASE_HH__
#define __DEV_VIRTIO_BASE_HH__

#include <functional>

#include "base/bitunion.hh"
#include "dev/virtio/virtio_ring.h"
#include "mem/port_proxy.hh"
#include "sim/sim_object.hh"

struct VirtIODeviceBaseParams;
struct VirtIODummyDeviceParams;

class VirtQueue;

/** @{
 * @name VirtIO endian conversion helpers
 *
 * VirtIO prior to version 1.0 (legacy versions) normally send values
 * to the host in the guest systems native byte order. This is going
 * to change in version 1.0 which mandates little endian. We currently
 * only support the legacy version of VirtIO (the new and shiny
 * standard is still in a draft state and not implemented by the
 * kernel). Once we support the new standard, we should negotiate the
 * VirtIO version with the guest and automatically use the right type
 * of byte swapping.
 */


template <> inline vring_used_elem
swap_byte(vring_used_elem v) {
    v.id = swap_byte(v.id);
    v.len = swap_byte(v.len);
    return v;
}

template <> inline vring_desc
swap_byte(vring_desc v) {
    v.addr = swap_byte(v.addr);
    v.len = swap_byte(v.len);
    v.flags = swap_byte(v.flags);
    v.next = swap_byte(v.next);
    return v;
}

/** @} */

/**
 * VirtIO descriptor (chain) wrapper
 *
 * Communication in VirtIO takes place by sending and receiving chains
 * of so called descriptors using device queues. The queue is
 * responsible for sending a descriptor chain from the guest to the
 * host and later sending it back to the guest. The descriptor chain
 * itself can be thought of as a linked list of buffers (descriptors)
 * that are read only (isIncoming() is true) or write only
 * (isOutgoing() is true). A single chain may contain any mix of input
 * and output buffers.
 *
 * The descriptor wrapper is normally <i>only</i> instantiated by the
 * virtqueue wrapper (VirtQueue) and should never be instantiated in
 * device models. The VirtQueue also ensures that the descriptor
 * wrapper is re-populated with new data from the guest by calling
 * updateChain() whenever a new descriptor chain is passed to the host
 * (VirtQueue::consumeDescriptor()). The updateChain() method
 * automatically does some sanity checks on the descriptor chain to
 * detect loops.
 */
class VirtDescriptor
{
  public:
    /** Descriptor index in virtqueue */
    typedef uint16_t Index;

    /** @{
     * @name VirtIO Descriptor <-> Queue Interface
     */
    /**
     * Create a descriptor wrapper.
     *
     * @param memProxy Proxy to the guest physical memory.
     * @param queue Queue owning this descriptor.
     * @param index Index within the queue.
     */
    VirtDescriptor(PortProxy &memProxy, ByteOrder bo,
            VirtQueue &queue, Index index);
    // WORKAROUND: The noexcept declaration works around a bug where
    // gcc 4.7 tries to call the wrong constructor when emplacing
    // something into a vector.
    VirtDescriptor(VirtDescriptor &&other) noexcept;
    ~VirtDescriptor() noexcept;

    VirtDescriptor &operator=(VirtDescriptor &&rhs) noexcept;

    /** Get the descriptor's index into the virtqueue. */
    Index index() const { return _index; }

    /** Populate this descriptor with data from the guest. */
    void update();

    /** Populate this descriptor chain with data from the guest. */
    void updateChain();
    /** @} */

    /** @{
     * @name Debug interfaces
     */
    /**
     * Dump the contents of a descriptor
     */
    void dump() const;
    /**
     * Dump the contents of a descriptor chain starting at this
     * descriptor.
     */
    void dumpChain() const;
    /** @} */


    /** @{
     * @name Device Model Interfaces
     */
    /**
     * Read the contents of a descriptor.
     *
     * This method copies the contents of a descriptor into a buffer
     * within gem5. Devices should typically use chainRead() instead
     * as it automatically follows the descriptor chain to read the
     * desired number of bytes.
     *
     * @see chainRead
     *
     * @param offset Offset into the descriptor.
     * @param dst Destination buffer.
     * @param size Amount of data to read (in bytes).
     */
    void read(size_t offset, uint8_t *dst, size_t size) const;
    /**
     * Write to the contents of a descriptor.
     *
     * This method copies the contents of a descriptor into a buffer
     * within gem5. Devices should typically use chainWrite() instead
     * as it automatically follows the descriptor chain to read the
     * desired number of bytes.
     *
     * @see chainWrite
     *
     * @param offset Offset into the descriptor.
     * @param src Source buffer.
     * @param size Amount of data to read (in bytes).
     */
    void write(size_t offset, const uint8_t *src, size_t size);
    /**
     * Retrieve the size of this descriptor.
     *
     * This method gets the size of a single descriptor. For incoming
     * data, it corresponds to the amount of data that can be read
     * from the descriptor. For outgoing data, it corresponds to the
     * amount of data that can be written to it.
     *
     * @see chainSize
     *
     * @return Size of descriptor in bytes.
     */
    size_t size() const { return desc.len; }

    /**
     * Is this descriptor chained to another descriptor?
     *
     * @return true if there is a next pointer, false otherwise.
     */
    bool hasNext() const { return desc.flags & VRING_DESC_F_NEXT; }
    /**
     * Get the pointer to the next descriptor in a chain.
     *
     * @return Pointer to the next descriptor or NULL if this is the
     * last element in a chain.
     */
    VirtDescriptor *next() const;

    /** Check if this is a read-only descriptor (incoming data). */
    bool isIncoming() const { return !isOutgoing(); }
    /** Check if this is a write-only descriptor (outgoing data). */
    bool isOutgoing() const { return desc.flags & VRING_DESC_F_WRITE; }


    /**
     * Read the contents of a descriptor chain.
     *
     * This method reads the specified number of bytes from a
     * descriptor chain starting at the this descriptor plus an offset
     * in bytes. The method automatically follows the links in the
     * descriptor chain.
     *
     * @param offset Offset into the chain (in bytes).
     * @param dst Pointer to destination buffer.
     * @param size Size (in bytes).
     */
    void chainRead(size_t offset, uint8_t *dst, size_t size) const;
    /**
     * Write to a descriptor chain.
     *
     * This method writes the specified number of bytes to a
     * descriptor chain starting at the this descriptor plus an offset
     * in bytes. The method automatically follows the links in the
     * descriptor chain.
     *
     * @param offset Offset into the chain (in bytes).
     * @param src Pointer to source buffer.
     * @param size Size (in bytes).
     */
    void chainWrite(size_t offset, const uint8_t *src, size_t size);
    /**
     * Retrieve the size of this descriptor chain.
     *
     * This method gets the size of a descriptor chain starting at
     * this descriptor.
     *
     * @return Size of descriptor chain in bytes.
     */
    size_t chainSize() const;
    /** @} */

  private:
    // Remove default constructor
    VirtDescriptor();
    // Prevent copying
    VirtDescriptor(const VirtDescriptor &other);

    /** Pointer to memory proxy */
    PortProxy *memProxy;
    /** Pointer to virtqueue owning this descriptor */
    VirtQueue *queue;

    /** The byte order the descriptor is stored in. */
    ByteOrder byteOrder;

    /** Index in virtqueue */
    Index _index;

    /** Underlying descriptor */
    vring_desc desc;
};

/**
 * Base wrapper around a virtqueue.
 *
 * VirtIO device models typically need to extend this class to
 * implement their own device queues.
 *
 * @note Queues must be registered with
 * VirtIODeviceBase::registerQueue() to be active.
 */
class VirtQueue : public Serializable {
public:
    virtual ~VirtQueue() {};

    /** @{
     * @name Checkpointing Interface
     */
    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;

    /** @{
     * @name Low-level Device Interface
     */
    /**
     * Set the base address of this queue.
     *
     * @param address Guest physical base address of the queue.
     */
    void setAddress(Addr address);
    /**
     * Get the guest physical address of this queue.
     *
     * @return Physical address in guest where this queue resides.
     */
    Addr getAddress() const { return _address; }

    /**
     * Get the number of descriptors available in this queue.
     *
     * @return Size of queue in descriptors.
     */
     uint16_t getSize() const { return _size; }

    /**
     * Get a pointer to a specific descriptor in the queue.
     *
     * @note This interfaces is normally only used by VirtDescriptor
     * to follow descriptor chains. Device models typically don't need
     * to use it.
     *
     * @return Pointer to a VirtDescriptor.
     */
    VirtDescriptor *getDescriptor(VirtDescriptor::Index index) {
        return &descriptors[index];
    }
    /** @} */

    /** @{
     * @name Device Model Interfaces
     */
    /**
     * Get an incoming descriptor chain from the queue.
     *
     * @return Pointer to descriptor on success, NULL if no pending
     * descriptors are available.
     */
    VirtDescriptor *consumeDescriptor();
    /**
     * Send a descriptor chain to the guest.
     *
     * This method posts a descriptor chain to the guest after a
     * device model has finished processing it. The device model
     * typically needs to call VirtIODeviceBase::kick() to deliver
     * notify tell the guest that the queue has been updated.
     *
     * @note The desc parameter must refer to the first descriptor in
     * a chain that has been retrieved using consumeDescriptor().
     *
     * @note The len parameter specified the amount of data produced
     * by the device model. It seems to be ignored by Linux and it is
     * not well defined.
     *
     * @param desc Start of descriptor chain.
     * @param len Length of the produced data.
     */
    void produceDescriptor(VirtDescriptor *desc, uint32_t len);
    /** @} */

    /** @{
     * @name Device Model Callbacks
     */
    /**
     * Notify queue of pending events.
     *
     * This method is called by VirtIODeviceBase::onNotify() to notify
     * the device model of pending data in a virtqueue. The default
     * implementation of this method iterates over the available
     * descriptor chains and calls onNotifyDescriptor() for every new
     * incoming chain.
     *
     * Device models should normally overload one of onNotify() and
     * onNotifyDescriptor().
     */
    virtual void onNotify();
    /**
     * Notify queue of pending incoming descriptor.
     *
     * This method is called by the default implementation of
     * onNotify() to notify the device model of pending data in a
     * descriptor chain.
     *
     * Device models should normally overload one of onNotify() and
     * onNotifyDescriptor().
     */
    virtual void onNotifyDescriptor(VirtDescriptor *desc) {};
    /** @} */

    /** @{
     * @name Debug interfaces
     */
    /** Dump the contents of a queue */
    void dump() const;
    /** @} */

    /** @{ */
    /**
     * Page size used by VirtIO.\ It's hard-coded to 4096 bytes in
     * the spec for historical reasons.
     */
    static const Addr ALIGN_BITS = 12;
    static const Addr ALIGN_SIZE = 1 << ALIGN_BITS;
    /** @} */

  protected:
    /**
     * Instantiate a new virtqueue.
     *
     * Instantiate a virtqueue with a fixed size. The size is
     * specified in descriptors which are defined as 4096 bytes each.
     *
     * @param proxy Proxy to the guest physical memory.
     * @param size Size in descriptors/pages.
     */
    VirtQueue(PortProxy &proxy, ByteOrder bo, uint16_t size);

    /** Byte order in this queue */
    ByteOrder byteOrder;

  private:
    VirtQueue();

    /** Queue size in terms of number of descriptors */
    const uint16_t _size;
    /** Base address of the queue */
    Addr _address;
    /** Guest physical memory proxy */
    PortProxy &memProxy;

  private:
    /**
     * VirtIO ring buffer wrapper.
     *
     * This class wraps a VirtIO ring buffer. The template parameter T
     * is used to select the data type for the items in the ring (used
     * or available descriptors).
     */
    template<typename T>
    class VirtRing
    {
      public:
        typedef uint16_t Flags;
        typedef uint16_t Index;

        struct Header {
            Flags flags;
            Index index;
        } M5_ATTR_PACKED;

        VirtRing<T>(PortProxy &proxy, ByteOrder bo, uint16_t size) :
            header{0, 0}, ring(size), _proxy(proxy), _base(0), byteOrder(bo)
        {}

        /**
         * Set the base address of the VirtIO ring buffer.
         *
         * @param addr New host physical address
         */
        void setAddress(Addr addr) { _base = addr; }

        /** Update the ring buffer header with data from the guest. */
        void
        readHeader()
        {
            assert(_base != 0);
            _proxy.readBlob(_base, &header, sizeof(header));
            header.flags = gtoh(header.flags, byteOrder);
            header.index = gtoh(header.index, byteOrder);
        }

        void
        writeHeader()
        {
            Header out;
            assert(_base != 0);
            out.flags = htog(header.flags, byteOrder);
            out.index = htog(header.index, byteOrder);
            _proxy.writeBlob(_base, &out, sizeof(out));
        }

        void
        read()
        {
            readHeader();

            /* Read and byte-swap the elements in the ring */
            T temp[ring.size()];
            _proxy.readBlob(_base + sizeof(header),
                            temp, sizeof(T) * ring.size());
            for (int i = 0; i < ring.size(); ++i)
                ring[i] = gtoh(temp[i], byteOrder);
        }

        void
        write()
        {
            assert(_base != 0);
            /* Create a byte-swapped copy of the ring and write it to
             * guest memory. */
            T temp[ring.size()];
            for (int i = 0; i < ring.size(); ++i)
                temp[i] = htog(ring[i], byteOrder);
            _proxy.writeBlob(_base + sizeof(header),
                             temp, sizeof(T) * ring.size());
            writeHeader();
        }

        /** Ring buffer header in host byte order */
        Header header;
        /** Elements in ring in host byte order */
        std::vector<T> ring;

      private:
        // Remove default constructor
        VirtRing<T>();

        /** Guest physical memory proxy */
        PortProxy &_proxy;
        /** Guest physical base address of the ring buffer */
        Addr _base;
        /** Byte order in the ring */
        ByteOrder byteOrder;
    };

    /** Ring of available (incoming) descriptors */
    VirtRing<VirtDescriptor::Index> avail;
    /** Ring of used (outgoing) descriptors */
    VirtRing<struct vring_used_elem> used;

    /** Offset of last consumed descriptor in the VirtQueue::avail
     * ring */
    uint16_t _last_avail;

    /** Vector of pre-created descriptors indexed by their index into
     * the queue. */
    std::vector<VirtDescriptor> descriptors;
};

/**
 * Base class for all VirtIO-based devices.
 *
 * This class implements the functionality of the VirtIO 0.9.5
 * specification. This version of VirtIO is also known as "legacy" in
 * the VirtIO 1.0 specification from OASIS.
 *
 * @see https://github.com/rustyrussell/virtio-spec
 * @see http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.html
 */
class VirtIODeviceBase : public SimObject
{
  public:
    typedef uint16_t QueueID;
    typedef uint32_t FeatureBits;
    /** This is a VirtQueue address as exposed through the low-level
     * interface.\ The address needs to be multiplied by the page size
     * (seems to be hardcoded to 4096 in the spec) to get the real
     * physical address.
     */
    typedef uint16_t VirtAddress;
    /** Device Type (sometimes known as subsystem ID) */
    typedef uint16_t DeviceId;

    BitUnion8(DeviceStatus)
        Bitfield<7> failed;
        Bitfield<2> driver_ok;
        Bitfield<1> driver;
        Bitfield<0> acknowledge;
    EndBitUnion(DeviceStatus)

    typedef VirtIODeviceBaseParams Params;
    VirtIODeviceBase(Params *params, DeviceId id, size_t config_size,
                     FeatureBits features);
    virtual ~VirtIODeviceBase();

  public:
    /** @{
     * @name SimObject Interfaces
     */
    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;
    /** @} */


  protected:
    /** @{
     * @name Device Model Interfaces
     */

    /**
     * Inform the guest of available buffers.
     *
     * When a device model has finished processing incoming buffers
     * (after onNotify has been called), it typically needs to inform
     * the guest that there are new pending outgoing buffers. The
     * method used to inform the guest is transport dependent, but is
     * typically through an interrupt. Device models call this method
     * to tell the transport interface to notify the guest.
     */
    void
    kick()
    {
        assert(transKick);
        transKick();
    };

    /**
     * Register a new VirtQueue with the device model.
     *
     * Devices typically register at least one VirtQueue to use for
     * communication with the guest. This <i>must</i> be done from the
     * constructor since the number of queues are assumed to be
     * constant throughout the lifetime of the device.
     *
     * @warning This method may only be called from the device model
     * constructor.
     */
    void registerQueue(VirtQueue &queue);


    /**
     * Feature set accepted by the guest.
     *
     * When the guest starts the driver for the device, it starts by
     * negotiating features. The device first offers a set of features
     * (see deviceFeatures), the driver then notifies the device of
     * which features it accepted. The base class will automatically
     * accept any feature set that is a subset of the features offered
     * by the device.
     */
    FeatureBits guestFeatures;
    /** @} */

  public:
    /** @{
     * @name Optional VirtIO Interfaces
     */
    /**
     * Read from the configuration space of a device.
     *
     * This method is called by the transport interface to read data
     * from a device model's configuration space. The device model
     * should use the cfgOffset parameter as the offset into its
     * configuration space.
     *
     * @warning The address in the packet should not be used to
     * determine the offset into a device's configuration space.
     *
     * @param pkt Read request packet.
     * @param cfgOffset Offset into the device's configuration space.
     */
    virtual void readConfig(PacketPtr pkt, Addr cfgOffset);
    /**
     * Write to the configuration space of a device.
     *
     * This method is called by the transport interface to write data
     * into a device model's configuration space. The device model
     * should use the cfgOffset parameter as the offset into its
     * configuration space.
     *
     * @warning The address in the packet should not be used to
     * determine the offset into a device's configuration space.
     *
     * @param pkt Write request packet.
     * @param cfgOffset Offset into the device's configuration space.
     */
    virtual void writeConfig(PacketPtr pkt, Addr cfgOffset);

    /**
     * Driver-request device reset.
     *
     * The device driver may reset a device by writing zero to the
     * device status register (using setDeviceStatus()), which causes
     * this method to be called. Device models overriding this method
     * <i>must</i> ensure that the reset method of the base class is
     * called when the device is reset.
     *
     * @note Always call the reset method of the base class from
     * device-specific reset methods.
     */
    virtual void reset();
    /** @} */

  protected:
    /** @{
     * @name Device Model Helpers
     */

    /**
     * Read configuration data from a device structure.
     *
     * @param pkt Read request packet.
     * @param cfgOffset Offset into the device's configuration space.
     * @param cfg Device configuration
     */
    void readConfigBlob(PacketPtr pkt, Addr cfgOffset, const uint8_t *cfg);

    /**
     * Write configuration data to a device structure.
     *
     * @param pkt Write request packet.
     * @param cfgOffset Offset into the device's configuration space.
     * @param cfg Device configuration
     */
    void writeConfigBlob(PacketPtr pkt, Addr cfgOffset, uint8_t *cfg);

    /**
     * The byte order of the queues, descriptors, etc.
     */
    ByteOrder byteOrder;

    /** @} */

  public:
    /** @{
     * @name VirtIO Transport Interfaces
     */
     /**
      * Register a callback to kick the guest through the transport
      * interface.
      *
      * @param callback Callback into transport interface.
      */
    void
    registerKickCallback(const std::function<void()> &callback)
    {
        assert(!transKick);
        transKick = callback;
    }


    /**
     * Driver is requesting service.
     *
     * This method is called by the underlying hardware interface
     * (e.g., PciVirtIO or MmmioVirtIO) to notify a device of pending
     * incoming descriptors.
     *
     * @param index ID of the queue with pending actions.
     */
    void onNotify(QueueID index);


    /**
     * Change currently active queue.
     *
     * The transport interface works on a queue at a time. The
     * currently active queue is decided by the value of the queue
     * select field in a device.
     *
     * @param idx ID of the queue to select.
     */
    void setQueueSelect(QueueID idx) { _queueSelect = idx; }
    /**
     * Get the currently active queue.
     *
     * The transport interface works on a queue at a time. The
     * currently active queue is decided by the value of the queue
     * select field in a device.
     *
     * @return The ID of the currently active queue.
     */
    QueueID getQueueSelect() const { return _queueSelect; }

    /**
     * Change the host physical address of the currently active queue.
     *
     * @note The new address is specified in multiples of the page
     * size (fixed to 4096 bytes in the standard). For example, if the
     * address 10 is selected, the actual host physical address will
     * be 40960.
     *
     * @see setQueueSelect
     * @see getQueueSelect
     *
     * @param address New address of the currently active queue (in
     * pages).
     */
    void setQueueAddress(uint32_t address);
    /**
     * Get the host physical address of the currently active queue.
     *
     * @note The new address is specified in multiples of the page
     * size (fixed to 4096 bytes in the standard). For example, if the
     * address 10 is selected, the actual host physical address will
     * be 40960.
     *
     * @see setQueueSelect
     * @see getQueueSelect
     *
     * @return Address of the currently active queue (in pages).
     */
    uint32_t getQueueAddress() const;

    /**
     * Get the size (descriptors) of the currently active queue.
     *
     * @return Size of the currently active queue in number of
     * descriptors.
     */
    uint16_t getQueueSize() const { return getCurrentQueue().getSize(); }

    /**
     * Update device status and optionally reset device.
     *
     * The special device status of 0 is used to reset the device by
     * calling reset().
     *
     * @param status New device status.
     */
    void setDeviceStatus(DeviceStatus status);

    /**
     * Retrieve the device status.
     *
     * @return Device status.
     */
    DeviceStatus getDeviceStatus() const { return _deviceStatus; }

    /**
     * Set feature bits accepted by the guest driver.
     *
     * This enables a subset of the features offered by the device
     * model through the getGuestFeatures() interface.
     */
    void setGuestFeatures(FeatureBits features);

    /**
     * Get features accepted by the guest driver.
     *
     * @return Currently active features.
     */
    FeatureBits getGuestFeatures() const { return guestFeatures; }

    /** Device ID (sometimes known as subsystem ID) */
    const DeviceId deviceId;

    /** Size of the device's configuration space */
    const size_t configSize;

    /** Feature set offered by the device */
    const FeatureBits deviceFeatures;
    /** @} */

  private:
    /** Convenience method to get the currently selected queue */
    const VirtQueue &getCurrentQueue() const;
    /** Convenience method to get the currently selected queue */
    VirtQueue &getCurrentQueue();

    /**
     * Status of the device
     *
     * @see getDeviceStatus
     * @see setDeviceStatus
     */
    DeviceStatus _deviceStatus;

    /** Queue select register (set by guest) */
    QueueID _queueSelect;

    /** List of virtual queues supported by this device */
    std::vector<VirtQueue *> _queues;

    /** Callbacks to kick the guest through the transport layer  */
    std::function<void()> transKick;
};

class VirtIODummyDevice : public VirtIODeviceBase
{
  public:
    VirtIODummyDevice(VirtIODummyDeviceParams *params);

  protected:
    /** VirtIO device ID */
    static const DeviceId ID_INVALID = 0x00;
};

#endif // __DEV_VIRTIO_BASE_HH__
