42 #include "debug/VIO.hh"
43 #include "params/VirtIODeviceBase.hh"
44 #include "params/VirtIODummyDevice.hh"
48 : memProxy(&_memProxy), queue(&_queue), _index(descIndex),
55 *
this = std::forward<VirtDescriptor>(other);
66 queue = std::move(rhs.queue);
67 _index = std::move(rhs._index);
68 desc = std::move(rhs.desc);
81 assert(_index < queue->getSize());
87 "VirtDescriptor(%i): Addr: 0x%x, Len: %i, Flags: 0x%x, "
98 }
while ((desc = desc->
next()) != NULL && desc !=
this);
101 panic(
"Loop in descriptor chain!\n");
110 DPRINTF(VIO,
"Descriptor[%i]: "
111 "Addr: 0x%x, Len: %i, Flags: 0x%x, Next: 0x%x\n",
130 }
while ((desc = desc->
next()) != NULL);
146 DPRINTF(VIO,
"VirtDescriptor(%p, 0x%x, %i)::read: offset: %i, dst: 0x%x, size: %i\n",
148 assert(size <=
desc.
len - offset);
150 panic(
"Trying to read from outgoing buffer\n");
158 DPRINTF(VIO,
"VirtDescriptor(%p, 0x%x, %i)::write: offset: %i, src: 0x%x, size: %i\n",
160 assert(size <=
desc.
len - offset);
162 panic(
"Trying to write to incoming buffer\n");
171 const size_t full_size(size);
173 if (offset < desc->
size()) {
175 desc->
read(offset, dst, chunk_size);
180 offset -= desc->
size();
182 }
while ((desc = desc->
next()) != NULL && desc->
isIncoming() && size > 0);
185 panic(
"Failed to read %i bytes from chain of %i bytes @ offset %i\n",
194 const size_t full_size(size);
196 if (offset < desc->
size()) {
198 desc->
write(offset, src, chunk_size);
203 offset -= desc->
size();
205 }
while ((desc = desc->
next()) != NULL && size > 0);
208 panic(
"Failed to write %i bytes into chain of %i bytes @ offset %i\n",
219 size += desc->
size();
220 }
while ((desc = desc->
next()) != NULL);
228 : _size(size), _address(0), memProxy(proxy),
229 avail(proxy, size), used(proxy, size),
249 paramIn(cp,
"_address", addr_in);
262 _size *
sizeof(uint16_t));
263 const Addr addr_used((addr_avail_end +
sizeof(uint16_t) +
274 DPRINTF(VIO,
"consumeDescriptor: _last_avail: %i, avail.idx: %i (->%i)\n",
293 DPRINTF(VIO,
"produceDescriptor: dscIdx: %i, len: %i, used.idx: %i\n",
329 deviceId(id), configSize(config_size), deviceFeatures(features),
330 _deviceStatus(0), _queueSelect(0),
374 DPRINTF(VIO,
"onNotify: idx: %i\n", idx);
376 panic(
"Guest tried to notify queue (%i), but only %i "
377 "queues registered.\n",
386 DPRINTF(VIO,
"Setting guest features: 0x%x\n", features);
388 panic(
"Guest tried to enable unsupported features:\n"
389 "Device features: 0x%x\n"
390 "Requested features: 0x%x\n",
401 DPRINTF(VIO,
"ACK: %i, DRIVER: %i, DRIVER_OK: %i, FAILED: %i\n",
402 status.acknowledge, status.driver, status.driver_ok, status.failed);
410 panic(
"Unhandled device config read (offset: 0x%x).\n", cfgOffset);
416 panic(
"Unhandled device config write (offset: 0x%x).\n", cfgOffset);
425 panic(
"Config read out of bounds.\n");
428 pkt->
setData(const_cast<uint8_t *>(cfg) + cfgOffset);
437 panic(
"Config write out of bounds.\n");
440 pkt->
writeData((uint8_t *)cfg + cfgOffset);
489 VirtIODummyDeviceParams::create()
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 & operator=(VirtDescriptor &&rhs) noexcept
void dump() const
Dump the contents of a queue.
void setAddress(Addr address)
Set the base address of this queue.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
~VirtDescriptor() noexcept
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
bool hasNext() const
Is this descriptor chained to another descriptor?
#define DDUMP(x, data, count)
Index index() const
Get the descriptor's index into the virtqueue.
static const unsigned ALIGN_BITS
Page size used by VirtIO. It's hard-coded to 4096 bytes in the spec for historical reasons...
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 setAddress(Addr addr)
Set the base address of the VirtIO ring buffer.
void dumpChain() const
Dump the contents of a descriptor chain starting at this descriptor.
void setDeviceStatus(DeviceStatus status)
Update device status and optionally reset device.
bool isIncoming() const
Check if this is a read-only descriptor (incoming data).
void writeData(uint8_t *p) const
Copy data from the packet to the provided block pointer, which is aligned to the given block size...
virtual ~VirtIODeviceBase()
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 descriptor.
void produceDescriptor(VirtDescriptor *desc, uint32_t len)
Send a descriptor chain to the guest.
Addr _address
Base address of the queue.
#define UNSERIALIZE_SCALAR(scalar)
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.
void setData(const uint8_t *p)
Copy data into the packet from the provided pointer.
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 chainRead(size_t offset, uint8_t *dst, size_t size) const
Read the contents of a descriptor chain.
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.
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
virtual void writeConfig(PacketPtr pkt, Addr cfgOffset)
Write to the configuration space of a device.
VirtIO descriptor (chain) wrapper.
Addr getAddress() const
Get the guest physical address of this queue.
virtual void reset()
Driver-request device reset.
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.
const VirtQueue & getCurrentQueue() const
Convenience method to get the currently selected queue.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
virtual void onNotify()
Notify queue of pending events.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
VirtQueue * queue
Pointer to virtqueue owning this descriptor.
size_t size() const
Retrieve the size of this descriptor.
#define SERIALIZE_SCALAR(scalar)
virtual void readBlob(Addr addr, uint8_t *p, int size) const
Read size bytes memory at address and store in p.
FeatureBits guestFeatures
Feature set accepted by the guest.
uint32_t getQueueAddress() const
Get the host physical address of the currently active queue.
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 structural port, to be used for debug accesses.
VirtIODummyDevice(VirtIODummyDeviceParams *params)
VirtDescriptor * next() const
Get the pointer to the next descriptor in a chain.
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)
void read(size_t offset, uint8_t *dst, size_t size) const
Read the contents of a descriptor.
const FeatureBits deviceFeatures
Feature set offered by the device.
std::ostream CheckpointOut
VirtIODeviceBase(Params *params, DeviceId id, size_t config_size, FeatureBits features)
void setQueueAddress(uint32_t address)
Change the host physical address of the currently active queue.
uint16_t Index
Descriptor index in virtqueue.
virtual void writeBlob(Addr addr, const uint8_t *p, int size) const
Write size bytes from p to address.
T vtoh_legacy(T v)
Convert legacy VirtIO endianness to host endianness.
size_t chainSize() const
Retrieve the size of this descriptor chain.
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.
bool isOutgoing() const
Check if this is a write-only descriptor (outgoing data).
static const unsigned ALIGN_SIZE
void serialize(CheckpointOut &cp) const override
Serialize an object.
Base wrapper around a virtqueue.
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.