#include "debug/VIO.hh"
#include "params/VirtIODeviceBase.hh"
#include "params/VirtIODummyDevice.hh"
+#include "sim/system.hh"
-VirtDescriptor::VirtDescriptor(PortProxy &_memProxy, VirtQueue &_queue,
- Index descIndex)
- : memProxy(&_memProxy), queue(&_queue), _index(descIndex),
+VirtDescriptor::VirtDescriptor(PortProxy &_memProxy, ByteOrder bo,
+ VirtQueue &_queue, Index descIndex)
+ : memProxy(&_memProxy), queue(&_queue), byteOrder(bo), _index(descIndex),
desc{0, 0, 0, 0}
{
}
{
memProxy = std::move(rhs.memProxy);
queue = std::move(rhs.queue);
+ byteOrder = std::move(rhs.byteOrder);
_index = std::move(rhs._index);
desc = std::move(rhs.desc);
const Addr desc_addr(vq_addr + sizeof(desc) * _index);
vring_desc guest_desc;
memProxy->readBlob(desc_addr, &guest_desc, sizeof(guest_desc));
- desc = vtoh_legacy(guest_desc);
+ desc = gtoh(guest_desc, byteOrder);
DPRINTF(VIO,
"VirtDescriptor(%i): Addr: 0x%x, Len: %i, Flags: 0x%x, "
"Next: 0x%x\n",
-VirtQueue::VirtQueue(PortProxy &proxy, uint16_t size)
- : _size(size), _address(0), memProxy(proxy),
- avail(proxy, size), used(proxy, size),
+VirtQueue::VirtQueue(PortProxy &proxy, ByteOrder bo, uint16_t size)
+ : byteOrder(bo), _size(size), _address(0), memProxy(proxy),
+ avail(proxy, bo, size), used(proxy, bo, size),
_last_avail(0)
{
descriptors.reserve(_size);
for (int i = 0; i < _size; ++i)
- descriptors.emplace_back(proxy, *this, i);
+ descriptors.emplace_back(proxy, bo, *this, i);
}
void
size_t config_size, FeatureBits features)
: SimObject(params),
guestFeatures(0),
+ byteOrder(params->system->getGuestByteOrder()),
deviceId(id), configSize(config_size), deviceFeatures(features),
_deviceStatus(0), _queueSelect(0),
transKick(NULL)
* of byte swapping.
*/
-/** Convert legacy VirtIO endianness to host endianness. */
-template <typename T> inline T
-vtoh_legacy(T v) {
- return TheISA::gtoh(v);
-}
-
-/** Convert host endianness to legacy VirtIO endianness. */
-template <typename T> inline T
-htov_legacy(T v) {
- return TheISA::htog(v);
-}
-
template <> inline vring_used_elem
-vtoh_legacy(vring_used_elem v) {
- v.id = vtoh_legacy(v.id);
- v.len = vtoh_legacy(v.len);
- return v;
-}
-
-template <> inline vring_used_elem
-htov_legacy(vring_used_elem v) {
- v.id = htov_legacy(v.id);
- v.len = htov_legacy(v.len);
+swap_byte(vring_used_elem v) {
+ v.id = swap_byte(v.id);
+ v.len = swap_byte(v.len);
return v;
}
template <> inline vring_desc
-vtoh_legacy(vring_desc v) {
- v.addr = vtoh_legacy(v.addr);
- v.len = vtoh_legacy(v.len);
- v.flags = vtoh_legacy(v.flags);
- v.next = vtoh_legacy(v.next);
- return v;
-}
-
-template <> inline vring_desc
-htov_legacy(vring_desc v) {
- v.addr = htov_legacy(v.addr);
- v.len = htov_legacy(v.len);
- v.flags = htov_legacy(v.flags);
- v.next = htov_legacy(v.next);
+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;
}
* @param queue Queue owning this descriptor.
* @param index Index within the queue.
*/
- VirtDescriptor(PortProxy &memProxy, VirtQueue &queue, Index index);
+ 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.
/** Pointer to virtqueue owning this descriptor */
VirtQueue *queue;
+ /** The byte order the descriptor is stored in. */
+ ByteOrder byteOrder;
+
/** Index in virtqueue */
Index _index;
* @param proxy Proxy to the guest physical memory.
* @param size Size in descriptors/pages.
*/
- VirtQueue(PortProxy &proxy, uint16_t size);
+ VirtQueue(PortProxy &proxy, ByteOrder bo, uint16_t size);
+
+ /** Byte order in this queue */
+ ByteOrder byteOrder;
private:
VirtQueue();
Index index;
} M5_ATTR_PACKED;
- VirtRing<T>(PortProxy &proxy, uint16_t size)
- : header{0, 0}, ring(size), _proxy(proxy), _base(0) {}
+ 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.
void setAddress(Addr addr) { _base = addr; }
/** Update the ring buffer header with data from the guest. */
- void readHeader() {
+ void
+ readHeader()
+ {
assert(_base != 0);
_proxy.readBlob(_base, &header, sizeof(header));
- header.flags = vtoh_legacy(header.flags);
- header.index = vtoh_legacy(header.index);
+ header.flags = gtoh(header.flags, byteOrder);
+ header.index = gtoh(header.index, byteOrder);
}
- void writeHeader() {
+ void
+ writeHeader()
+ {
Header out;
assert(_base != 0);
- out.flags = htov_legacy(header.flags);
- out.index = htov_legacy(header.index);
+ out.flags = htog(header.flags, byteOrder);
+ out.index = htog(header.index, byteOrder);
_proxy.writeBlob(_base, &out, sizeof(out));
}
- void read() {
+ void
+ read()
+ {
readHeader();
/* Read and byte-swap the elements in the ring */
_proxy.readBlob(_base + sizeof(header),
temp, sizeof(T) * ring.size());
for (int i = 0; i < ring.size(); ++i)
- ring[i] = vtoh_legacy(temp[i]);
+ ring[i] = gtoh(temp[i], byteOrder);
}
- void write() {
+ 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] = htov_legacy(ring[i]);
+ temp[i] = htog(ring[i], byteOrder);
_proxy.writeBlob(_base + sizeof(header),
temp, sizeof(T) * ring.size());
writeHeader();
PortProxy &_proxy;
/** Guest physical base address of the ring buffer */
Addr _base;
+ /** Byte order in the ring */
+ ByteOrder byteOrder;
};
/** Ring of available (incoming) descriptors */
*/
void writeConfigBlob(PacketPtr pkt, Addr cfgOffset, uint8_t *cfg);
+ /**
+ * The byte order of the queues, descriptors, etc.
+ */
+ ByteOrder byteOrder;
+
/** @} */
public:
VirtIOBlock::VirtIOBlock(Params *params)
: VirtIODeviceBase(params, ID_BLOCK, sizeof(Config), 0),
- qRequests(params->system->physProxy, params->queueSize, *this),
+ qRequests(params->system->physProxy, byteOrder,
+ params->queueSize, *this),
image(*params->image)
{
registerQueue(qRequests);
VirtIOBlock::readConfig(PacketPtr pkt, Addr cfgOffset)
{
Config cfg_out;
- cfg_out.capacity = htov_legacy(config.capacity);
+ cfg_out.capacity = htog(config.capacity, byteOrder);
readConfigBlob(pkt, cfgOffset, (uint8_t *)&cfg_out);
}
*/
BlkRequest req;
desc->chainRead(0, (uint8_t *)&req, sizeof(req));
- req.type = htov_legacy(req.type);
- req.sector = htov_legacy(req.sector);
+ req.type = htog(req.type, byteOrder);
+ req.sector = htog(req.sector, byteOrder);
Status status;
const size_t data_size(desc->chainSize()
: public VirtQueue
{
public:
- RequestQueue(PortProxy &proxy, uint16_t size, VirtIOBlock &_parent)
- : VirtQueue(proxy, size), parent(_parent) {}
+ RequestQueue(PortProxy &proxy, ByteOrder bo,
+ uint16_t size, VirtIOBlock &_parent)
+ : VirtQueue(proxy, bo, size), parent(_parent) {}
virtual ~RequestQueue() {}
void onNotifyDescriptor(VirtDescriptor *desc);
VirtIOConsole::VirtIOConsole(Params *params)
: VirtIODeviceBase(params, ID_CONSOLE, sizeof(Config), F_SIZE),
- qRecv(params->system->physProxy, params->qRecvSize, *this),
- qTrans(params->system->physProxy, params->qTransSize, *this),
+ qRecv(params->system->physProxy, byteOrder, params->qRecvSize, *this),
+ qTrans(params->system->physProxy, byteOrder, params->qTransSize, *this),
device(*params->device), callbackDataAvail(qRecv)
{
registerQueue(qRecv);
VirtIOConsole::readConfig(PacketPtr pkt, Addr cfgOffset)
{
Config cfg_out;
- cfg_out.rows = htov_legacy(config.rows);
- cfg_out.cols = htov_legacy(config.cols);
+ cfg_out.rows = htog(config.rows, byteOrder);
+ cfg_out.cols = htog(config.cols, byteOrder);
readConfigBlob(pkt, cfgOffset, (uint8_t *)&cfg_out);
}
: public VirtQueue
{
public:
- TermRecvQueue(PortProxy &proxy, uint16_t size, VirtIOConsole &_parent)
- : VirtQueue(proxy, size), parent(_parent) {}
+ TermRecvQueue(PortProxy &proxy, ByteOrder bo,
+ uint16_t size, VirtIOConsole &_parent)
+ : VirtQueue(proxy, bo, size), parent(_parent) {}
virtual ~TermRecvQueue() {}
void onNotify() { trySend(); }
: public VirtQueue
{
public:
- TermTransQueue(PortProxy &proxy, uint16_t size, VirtIOConsole &_parent)
- : VirtQueue(proxy, size), parent(_parent) {}
+ TermTransQueue(PortProxy &proxy, ByteOrder bo,
+ uint16_t size, VirtIOConsole &_parent)
+ : VirtQueue(proxy, bo, size), parent(_parent) {}
virtual ~TermTransQueue() {}
void onNotifyDescriptor(VirtDescriptor *desc);
: VirtIODeviceBase(params, ID_9P,
sizeof(Config) + params->tag.size(),
F_MOUNT_TAG),
- queue(params->system->physProxy, params->queueSize, *this)
+ queue(params->system->physProxy, byteOrder, params->queueSize, *this)
{
config.reset((Config *)
operator new(configSize));
- config->len = htov_legacy(params->tag.size());
+ config->len = htog(params->tag.size(), byteOrder);
memcpy(config->tag, params->tag.c_str(), params->tag.size());
registerQueue(queue);
class FSQueue : public VirtQueue
{
public:
- FSQueue(PortProxy &proxy, uint16_t size, VirtIO9PBase &_parent)
- : VirtQueue(proxy, size), parent(_parent) {}
+ FSQueue(PortProxy &proxy, ByteOrder bo,
+ uint16_t size, VirtIO9PBase &_parent)
+ : VirtQueue(proxy, bo, size), parent(_parent) {}
virtual ~FSQueue() {}
void onNotifyDescriptor(VirtDescriptor *desc);