42 #include "debug/VIO.hh" 43 #include "params/VirtIODeviceBase.hh" 44 #include "params/VirtIODummyDevice.hh" 49 : memProxy(&_memProxy), queue(&_queue),
byteOrder(bo), _index(descIndex),
56 *
this = std::forward<VirtDescriptor>(other);
67 queue = std::move(rhs.queue);
69 _index = std::move(rhs._index);
70 desc = std::move(rhs.desc);
83 assert(_index < queue->getSize());
89 "VirtDescriptor(%i): Addr: 0x%x, Len: %i, Flags: 0x%x, " 100 }
while ((desc = desc->
next()) != NULL && desc !=
this);
103 panic(
"Loop in descriptor chain!\n");
112 DPRINTF(VIO,
"Descriptor[%i]: " 113 "Addr: 0x%x, Len: %i, Flags: 0x%x, Next: 0x%x\n",
132 }
while ((desc = desc->
next()) != NULL);
148 DPRINTF(VIO,
"VirtDescriptor(%p, 0x%x, %i)::read: offset: %i, dst: 0x%x, size: %i\n",
150 assert(size <=
desc.
len - offset);
152 panic(
"Trying to read from outgoing buffer\n");
160 DPRINTF(VIO,
"VirtDescriptor(%p, 0x%x, %i)::write: offset: %i, src: 0x%x, size: %i\n",
162 assert(size <=
desc.
len - offset);
164 panic(
"Trying to write to incoming buffer\n");
173 const size_t full_size(size);
175 if (offset < desc->
size()) {
177 desc->
read(offset, dst, chunk_size);
182 offset -= desc->
size();
184 }
while ((desc = desc->
next()) != NULL && desc->
isIncoming() && size > 0);
187 panic(
"Failed to read %i bytes from chain of %i bytes @ offset %i\n",
196 const size_t full_size(size);
198 if (offset < desc->
size()) {
200 desc->
write(offset, src, chunk_size);
205 offset -= desc->
size();
207 }
while ((desc = desc->
next()) != NULL && size > 0);
210 panic(
"Failed to write %i bytes into chain of %i bytes @ offset %i\n",
221 size += desc->
size();
222 }
while ((desc = desc->
next()) != NULL);
231 avail(proxy, bo, size), used(proxy, bo, size),
251 paramIn(cp,
"_address", addr_in);
264 _size *
sizeof(uint16_t));
265 const Addr addr_used((addr_avail_end +
sizeof(uint16_t) +
276 DPRINTF(VIO,
"consumeDescriptor: _last_avail: %i, avail.idx: %i (->%i)\n",
295 DPRINTF(VIO,
"produceDescriptor: dscIdx: %i, len: %i, used.idx: %i\n",
332 deviceId(id), configSize(config_size), deviceFeatures(features),
333 _deviceStatus(0), _queueSelect(0),
377 DPRINTF(VIO,
"onNotify: idx: %i\n", idx);
379 panic(
"Guest tried to notify queue (%i), but only %i " 380 "queues registered.\n",
389 DPRINTF(VIO,
"Setting guest features: 0x%x\n", features);
391 panic(
"Guest tried to enable unsupported features:\n" 392 "Device features: 0x%x\n" 393 "Requested features: 0x%x\n",
404 DPRINTF(VIO,
"ACK: %i, DRIVER: %i, DRIVER_OK: %i, FAILED: %i\n",
405 status.acknowledge, status.driver, status.driver_ok, status.failed);
413 panic(
"Unhandled device config read (offset: 0x%x).\n", cfgOffset);
419 panic(
"Unhandled device config write (offset: 0x%x).\n", cfgOffset);
425 const unsigned size(pkt->
getSize());
428 panic(
"Config read out of bounds.\n");
431 pkt->
setData(const_cast<uint8_t *>(cfg) + cfgOffset);
437 const unsigned size(pkt->
getSize());
440 panic(
"Config write out of bounds.\n");
443 pkt->
writeData((uint8_t *)cfg + cfgOffset);
492 VirtIODummyDeviceParams::create()
#define panic(...)
This implements a cprintf based panic() function.
Base class for all VirtIO-based devices.
void write(size_t offset, const uint8_t *src, size_t size)
Write to the contents of a descriptor.
VirtDescriptor * next() const
Get the pointer to the next descriptor in a chain.
VirtDescriptor & operator=(VirtDescriptor &&rhs) noexcept
void setAddress(Addr address)
Set the base address of this queue.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
T gtoh(T value, ByteOrder guest_byte_order)
~VirtDescriptor() noexcept
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
static const Addr ALIGN_SIZE
#define DDUMP(x, data, count)
void setGuestFeatures(FeatureBits features)
Set feature bits accepted by the guest driver.
VirtDescriptor * getDescriptor(VirtDescriptor::Index index)
Get a pointer to a specific descriptor in the queue.
void dumpChain() const
Dump the contents of a descriptor chain starting at this descriptor.
void setAddress(Addr addr)
Set the base address of the VirtIO ring buffer.
void setDeviceStatus(DeviceStatus status)
Update device status and optionally reset device.
virtual ~VirtIODeviceBase()
size_t size() const
Retrieve the size of this descriptor.
void serialize(CheckpointOut &cp) const override
Serialize an object.
void readHeader()
Update the ring buffer header with data from the guest.
VirtDescriptor * consumeDescriptor()
Get an incoming descriptor chain from the queue.
void dump() const
Dump the contents of a queue.
void produceDescriptor(VirtDescriptor *desc, uint32_t len)
Send a descriptor chain to the guest.
void chainRead(size_t offset, uint8_t *dst, size_t size) const
Read the contents of a descriptor chain.
Addr _address
Base address of the queue.
#define UNSERIALIZE_SCALAR(scalar)
ByteOrder byteOrder
The byte order the descriptor is stored in.
void writeConfigBlob(PacketPtr pkt, Addr cfgOffset, uint8_t *cfg)
Write configuration data to a device structure.
std::string csprintf(const char *format, const Args &...args)
DeviceStatus _deviceStatus
Status of the device.
ByteOrder byteOrder(ThreadContext *tc)
void setData(const uint8_t *p)
Copy data into the packet from the provided pointer.
void writeBlob(Addr addr, const void *p, int size) const
Same as tryWriteBlob, but insists on success.
bool isIncoming() const
Check if this is a read-only descriptor (incoming data).
const Params * params() const
void read(size_t offset, uint8_t *dst, size_t size) const
Read the contents of a descriptor.
size_t chainSize() const
Retrieve the size of this descriptor chain.
QueueID _queueSelect
Queue select register (set by guest)
std::vector< VirtDescriptor > descriptors
Vector of pre-created descriptors indexed by their index into the queue.
void chainWrite(size_t offset, const uint8_t *src, size_t size)
Write to a descriptor chain.
std::vector< VirtQueue * > _queues
List of virtual queues supported by this device.
Header header
Ring buffer header in host byte order.
virtual void writeConfig(PacketPtr pkt, Addr cfgOffset)
Write to the configuration space of a device.
VirtIO descriptor (chain) wrapper.
void writeData(uint8_t *p) const
Copy data from the packet to the memory at the provided pointer.
virtual void reset()
Driver-request device reset.
void dump() const
Dump the contents of a descriptor.
void onNotify(QueueID index)
Driver is requesting service.
Index _index
Index in virtqueue.
virtual void readConfig(PacketPtr pkt, Addr cfgOffset)
Read from the configuration space of a device.
VirtRing< VirtDescriptor::Index > avail
Ring of available (incoming) descriptors.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
virtual void onNotify()
Notify queue of pending events.
Index index() const
Get the descriptor's index into the virtqueue.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
VirtQueue * queue
Pointer to virtqueue owning this descriptor.
#define SERIALIZE_SCALAR(scalar)
FeatureBits guestFeatures
Feature set accepted by the guest.
const uint16_t _size
Queue size in terms of number of descriptors.
void updateChain()
Populate this descriptor chain with data from the guest.
This object is a proxy for a port or other object which implements the functional response protocol...
VirtIODummyDevice(VirtIODummyDeviceParams *params)
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
void registerQueue(VirtQueue &queue)
Register a new VirtQueue with the device model.
uint16_t DeviceId
Device Type (sometimes known as subsystem ID)
const VirtQueue & getCurrentQueue() const
Convenience method to get the currently selected queue.
const FeatureBits deviceFeatures
Feature set offered by the device.
Addr getAddress() const
Get the guest physical address of this queue.
std::ostream CheckpointOut
VirtIODeviceBase(Params *params, DeviceId id, size_t config_size, FeatureBits features)
bool isOutgoing() const
Check if this is a write-only descriptor (outgoing data).
void setQueueAddress(uint32_t address)
Change the host physical address of the currently active queue.
uint16_t Index
Descriptor index in virtqueue.
uint32_t getQueueAddress() const
Get the host physical address of the currently active queue.
void update()
Populate this descriptor with data from the guest.
VirtRing< struct vring_used_elem > used
Ring of used (outgoing) descriptors.
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
std::vector< T > ring
Elements in ring in host byte order.
ByteOrder byteOrder
Byte order in this queue.
static const Addr ALIGN_BITS
Page size used by VirtIO. It's hard-coded to 4096 bytes in the spec for historical reasons...
void serialize(CheckpointOut &cp) const override
Serialize an object.
Base wrapper around a virtqueue.
bool hasNext() const
Is this descriptor chained to another descriptor?
void unserialize(CheckpointIn &cp) override
Unserialize an object.
uint16_t _last_avail
Offset of last consumed descriptor in the VirtQueue::avail ring.
void readConfigBlob(PacketPtr pkt, Addr cfgOffset, const uint8_t *cfg)
Read configuration data from a device structure.
vring_desc desc
Underlying descriptor.
Abstract superclass for simulation objects.
const size_t configSize
Size of the device's configuration space.
virtual void onNotifyDescriptor(VirtDescriptor *desc)
Notify queue of pending incoming descriptor.
PortProxy * memProxy
Pointer to memory proxy.