gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
base.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, 2016 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  * Authors: Andreas Sandberg
38  */
39 
40 #ifndef __DEV_VIRTIO_BASE_HH__
41 #define __DEV_VIRTIO_BASE_HH__
42 
43 #include "arch/isa_traits.hh"
44 #include "base/bitunion.hh"
45 #include "base/callback.hh"
46 #include "dev/virtio/virtio_ring.h"
47 #include "mem/port_proxy.hh"
48 #include "sim/sim_object.hh"
49 
50 struct VirtIODeviceBaseParams;
51 struct VirtIODummyDeviceParams;
52 
53 class VirtQueue;
54 
69 template <typename T> inline T
71  return TheISA::gtoh(v);
72 }
73 
75 template <typename T> inline T
77  return TheISA::htog(v);
78 }
79 
80 
81 template <> inline vring_used_elem
83  v.id = vtoh_legacy(v.id);
84  v.len = vtoh_legacy(v.len);
85  return v;
86 }
87 
88 template <> inline vring_used_elem
90  v.id = htov_legacy(v.id);
91  v.len = htov_legacy(v.len);
92  return v;
93 }
94 
95 template <> inline vring_desc
97  v.addr = vtoh_legacy(v.addr);
98  v.len = vtoh_legacy(v.len);
99  v.flags = vtoh_legacy(v.flags);
100  v.next = vtoh_legacy(v.next);
101  return v;
102 }
103 
104 template <> inline vring_desc
106  v.addr = htov_legacy(v.addr);
107  v.len = htov_legacy(v.len);
108  v.flags = htov_legacy(v.flags);
109  v.next = htov_legacy(v.next);
110  return v;
111 }
112 
137 {
138  public:
140  typedef uint16_t Index;
141 
153  // WORKAROUND: The noexcept declaration works around a bug where
154  // gcc 4.7 tries to call the wrong constructor when emplacing
155  // something into a vector.
156  VirtDescriptor(VirtDescriptor &&other) noexcept;
157  ~VirtDescriptor() noexcept;
158 
159  VirtDescriptor &operator=(VirtDescriptor &&rhs) noexcept;
160 
162  Index index() const { return _index; }
163 
165  void update();
166 
168  void updateChain();
177  void dump() const;
182  void dumpChain() const;
203  void read(size_t offset, uint8_t *dst, size_t size) const;
218  void write(size_t offset, const uint8_t *src, size_t size);
231  size_t size() const { return desc.len; }
232 
238  bool hasNext() const { return desc.flags & VRING_DESC_F_NEXT; }
245  VirtDescriptor *next() const;
246 
248  bool isIncoming() const { return !isOutgoing(); }
250  bool isOutgoing() const { return desc.flags & VRING_DESC_F_WRITE; }
251 
252 
265  void chainRead(size_t offset, uint8_t *dst, size_t size) const;
278  void chainWrite(size_t offset, const uint8_t *src, size_t size);
287  size_t chainSize() const;
290  private:
291  // Remove default constructor
292  VirtDescriptor();
293  // Prevent copying
294  VirtDescriptor(const VirtDescriptor &other);
295 
300 
303 
306 };
307 
317 class VirtQueue : public Serializable {
318 public:
319  virtual ~VirtQueue() {};
320 
324  void serialize(CheckpointOut &cp) const override;
325  void unserialize(CheckpointIn &cp) override;
326 
335  void setAddress(Addr address);
341  Addr getAddress() const { return _address; }
342 
348  uint16_t getSize() const { return _size; }
349 
360  return &descriptors[index];
361  }
392  void produceDescriptor(VirtDescriptor *desc, uint32_t len);
410  virtual void onNotify();
421  virtual void onNotifyDescriptor(VirtDescriptor *desc) {};
428  void dump() const;
436  static const unsigned ALIGN_BITS = 12;
437  static const unsigned ALIGN_SIZE = 1 << ALIGN_BITS;
440  protected:
450  VirtQueue(PortProxy &proxy, uint16_t size);
451 
452  private:
453  VirtQueue();
454 
456  const uint16_t _size;
461 
462  private:
470  template<typename T>
471  class VirtRing
472  {
473  public:
474  typedef uint16_t Flags;
475  typedef uint16_t Index;
476 
477  struct Header {
480  } M5_ATTR_PACKED;
481 
482  VirtRing<T>(PortProxy &proxy, uint16_t size)
483  : header{0, 0}, ring(size), _proxy(proxy), _base(0) {}
484 
491 
493  void readHeader() {
494  assert(_base != 0);
495  _proxy.readBlob(_base, (uint8_t *)&header, sizeof(header));
498  }
499 
500  void writeHeader() {
501  Header out;
502  assert(_base != 0);
503  out.flags = htov_legacy(header.flags);
504  out.index = htov_legacy(header.index);
505  _proxy.writeBlob(_base, (uint8_t *)&out, sizeof(out));
506  }
507 
508  void read() {
509  readHeader();
510 
511  /* Read and byte-swap the elements in the ring */
512  T temp[ring.size()];
513  _proxy.readBlob(_base + sizeof(header),
514  (uint8_t *)temp, sizeof(T) * ring.size());
515  for (int i = 0; i < ring.size(); ++i)
516  ring[i] = vtoh_legacy(temp[i]);
517  }
518 
519  void write() {
520  assert(_base != 0);
521  /* Create a byte-swapped copy of the ring and write it to
522  * guest memory. */
523  T temp[ring.size()];
524  for (int i = 0; i < ring.size(); ++i)
525  temp[i] = htov_legacy(ring[i]);
526  _proxy.writeBlob(_base + sizeof(header),
527  (uint8_t *)temp, sizeof(T) * ring.size());
528  writeHeader();
529  }
530 
532  Header header;
535 
536  private:
537  // Remove default constructor
538  VirtRing<T>();
539 
544  };
545 
550 
553  uint16_t _last_avail;
554 
558 };
559 
571 {
572  public:
573  typedef uint16_t QueueID;
574  typedef uint32_t FeatureBits;
580  typedef uint16_t VirtAddress;
582  typedef uint16_t DeviceId;
583 
584  BitUnion8(DeviceStatus)
585  Bitfield<7> failed;
586  Bitfield<2> driver_ok;
587  Bitfield<1> driver;
588  Bitfield<0> acknowledge;
589  EndBitUnion(DeviceStatus)
590 
591  typedef VirtIODeviceBaseParams Params;
592  VirtIODeviceBase(Params *params, DeviceId id, size_t config_size,
593  FeatureBits features);
594  virtual ~VirtIODeviceBase();
595 
596  public:
600  void serialize(CheckpointOut &cp) const override;
601  void unserialize(CheckpointIn &cp) override;
605  protected:
620  void kick() {
621  assert(transKick);
622  transKick->process();
623  };
624 
636  void registerQueue(VirtQueue &queue);
637 
638 
652  public:
670  virtual void readConfig(PacketPtr pkt, Addr cfgOffset);
685  virtual void writeConfig(PacketPtr pkt, Addr cfgOffset);
686 
699  virtual void reset();
702  protected:
714  void readConfigBlob(PacketPtr pkt, Addr cfgOffset, const uint8_t *cfg);
715 
723  void writeConfigBlob(PacketPtr pkt, Addr cfgOffset, uint8_t *cfg);
724 
727  public:
738  assert(!transKick);
739  transKick = c;
740  }
741 
742 
752  void onNotify(QueueID index);
753 
754 
764  void setQueueSelect(QueueID idx) { _queueSelect = idx; }
774  QueueID getQueueSelect() const { return _queueSelect; }
775 
790  void setQueueAddress(uint32_t address);
804  uint32_t getQueueAddress() const;
805 
812  uint16_t getQueueSize() const { return getCurrentQueue().getSize(); }
813 
822  void setDeviceStatus(DeviceStatus status);
823 
829  DeviceStatus getDeviceStatus() const { return _deviceStatus; }
830 
837  void setGuestFeatures(FeatureBits features);
838 
845 
848 
850  const size_t configSize;
851 
856  private:
858  const VirtQueue &getCurrentQueue() const;
861 
868  DeviceStatus _deviceStatus;
869 
872 
875 
878 };
879 
881 {
882  public:
883  VirtIODummyDevice(VirtIODummyDeviceParams *params);
884 
885  protected:
887  static const DeviceId ID_INVALID = 0x00;
888 };
889 
890 #endif // __DEV_VIRTIO_BASE_HH__
Base class for all VirtIO-based devices.
Definition: base.hh:570
void write(size_t offset, const uint8_t *src, size_t size)
Write to the contents of a descriptor.
Definition: base.cc:156
void dump() const
Dump the contents of a queue.
Definition: base.cc:304
Bitfield< 30, 0 > index
virtual void process()=0
virtual process function that is invoked when the callback queue is executed.
void setAddress(Addr address)
Set the base address of this queue.
Definition: base.cc:258
T htog(T value)
Definition: byteswap.hh:177
Bitfield< 28 > v
Definition: miscregs.hh:1366
uint16_t VirtAddress
This is a VirtQueue address as exposed through the low-level interface. The address needs to be multi...
Definition: base.hh:580
Generic callback class.
Definition: callback.hh:41
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: base.cc:245
void writeHeader()
Definition: base.hh:500
Bitfield< 7 > i
Definition: miscregs.hh:1378
BitUnion8(DeviceStatus) Bitfield< 7 > failed
SimObjectParams Params
Definition: sim_object.hh:110
uint16_t Index
Definition: base.hh:475
void setQueueSelect(QueueID idx)
Change currently active queue.
Definition: base.hh:764
ip6_addr_t addr
Definition: inet.hh:335
Bitfield< 1 > driver
Definition: base.hh:587
#define VRING_DESC_F_WRITE
Definition: virtio_ring.h:39
bool hasNext() const
Is this descriptor chained to another descriptor?
Definition: base.hh:238
Index index() const
Get the descriptor's index into the virtqueue.
Definition: base.hh:162
const Params * params() const
Definition: sim_object.hh:111
DeviceStatus getDeviceStatus() const
Retrieve the device status.
Definition: base.hh:829
static const unsigned ALIGN_BITS
Page size used by VirtIO. It's hard-coded to 4096 bytes in the spec for historical reasons...
Definition: base.hh:436
void setGuestFeatures(FeatureBits features)
Set feature bits accepted by the guest driver.
Definition: base.cc:384
VirtDescriptor * getDescriptor(VirtDescriptor::Index index)
Get a pointer to a specific descriptor in the queue.
Definition: base.hh:359
void setAddress(Addr addr)
Set the base address of the VirtIO ring buffer.
Definition: base.hh:490
Bitfield< 23, 0 > offset
Definition: types.hh:149
const DeviceId deviceId
Device ID (sometimes known as subsystem ID)
Definition: base.hh:847
void dumpChain() const
Dump the contents of a descriptor chain starting at this descriptor.
Definition: base.cc:122
void setDeviceStatus(DeviceStatus status)
Update device status and optionally reset device.
Definition: base.cc:398
bool isIncoming() const
Check if this is a read-only descriptor (incoming data).
Definition: base.hh:248
static const DeviceId ID_INVALID
VirtIO device ID.
Definition: base.hh:887
STL vector class.
Definition: stl.hh:40
T gtoh(T value)
Definition: byteswap.hh:179
struct VirtQueue::VirtRing::Header M5_ATTR_PACKED
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: base.cc:341
void readHeader()
Update the ring buffer header with data from the guest.
Definition: base.hh:493
VirtDescriptor * consumeDescriptor()
Get an incoming descriptor chain from the queue.
Definition: base.cc:271
Bitfield< 5, 0 > status
Definition: miscregs.hh:1604
void dump() const
Dump the contents of a descriptor.
Definition: base.cc:105
void produceDescriptor(VirtDescriptor *desc, uint32_t len)
Send a descriptor chain to the guest.
Definition: base.cc:290
Addr _address
Base address of the queue.
Definition: base.hh:458
uint16_t getQueueSize() const
Get the size (descriptors) of the currently active queue.
Definition: base.hh:812
PortProxy Object Declaration.
Bitfield< 0 > acknowledge
Definition: base.hh:588
T htov_legacy(T v)
Convert host endianness to legacy VirtIO endianness.
Definition: base.hh:76
void writeConfigBlob(PacketPtr pkt, Addr cfgOffset, uint8_t *cfg)
Write configuration data to a device structure.
Definition: base.cc:432
DeviceStatus _deviceStatus
Status of the device.
Definition: base.hh:868
QueueID getQueueSelect() const
Get the currently active queue.
Definition: base.hh:774
PortProxy & memProxy
Guest physical memory proxy.
Definition: base.hh:460
#define VRING_DESC_F_NEXT
Definition: virtio_ring.h:37
Definition: flags.hh:35
QueueID _queueSelect
Queue select register (set by guest)
Definition: base.hh:871
std::vector< VirtDescriptor > descriptors
Vector of pre-created descriptors indexed by their index into the queue.
Definition: base.hh:557
void chainRead(size_t offset, uint8_t *dst, size_t size) const
Read the contents of a descriptor chain.
Definition: base.cc:168
void kick()
Inform the guest of available buffers.
Definition: base.hh:620
uint64_t addr
Definition: virtio_ring.h:64
uint16_t getSize() const
Get the number of descriptors available in this queue.
Definition: base.hh:348
uint16_t next
Definition: virtio_ring.h:70
void chainWrite(size_t offset, const uint8_t *src, size_t size)
Write to a descriptor chain.
Definition: base.cc:191
std::vector< VirtQueue * > _queues
List of virtual queues supported by this device.
Definition: base.hh:874
Header header
Ring buffer header in host byte order.
Definition: base.hh:532
Bitfield< 2 > driver_ok
Definition: base.hh:586
virtual void writeConfig(PacketPtr pkt, Addr cfgOffset)
Write to the configuration space of a device.
Definition: base.cc:414
VirtIO descriptor (chain) wrapper.
Definition: base.hh:136
Addr getAddress() const
Get the guest physical address of this queue.
Definition: base.hh:341
PortProxy & _proxy
Guest physical memory proxy.
Definition: base.hh:541
virtual void reset()
Driver-request device reset.
Definition: base.cc:361
EndBitUnion(DeviceStatus) typedef VirtIODeviceBaseParams Params
void onNotify(QueueID index)
Driver is requesting service.
Definition: base.cc:372
Index _index
Index in virtqueue.
Definition: base.hh:302
virtual void readConfig(PacketPtr pkt, Addr cfgOffset)
Read from the configuration space of a device.
Definition: base.cc:408
Callback * transKick
Callbacks to kick the guest through the transport layer.
Definition: base.hh:877
uint32_t len
Definition: virtio_ring.h:84
uint16_t Flags
Definition: base.hh:474
VirtRing< VirtDescriptor::Index > avail
Ring of available (incoming) descriptors.
Definition: base.hh:547
const VirtQueue & getCurrentQueue() const
Convenience method to get the currently selected queue.
Definition: base.cc:445
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
virtual void onNotify()
Notify queue of pending events.
Definition: base.cc:314
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
Basic support for object serialization.
Definition: serialize.hh:220
VirtQueue * queue
Pointer to virtqueue owning this descriptor.
Definition: base.hh:299
size_t size() const
Retrieve the size of this descriptor.
Definition: base.hh:231
virtual void readBlob(Addr addr, uint8_t *p, int size) const
Read size bytes memory at address and store in p.
Definition: port_proxy.cc:45
FeatureBits guestFeatures
Feature set accepted by the guest.
Definition: base.hh:649
uint32_t getQueueAddress() const
Get the host physical address of the currently active queue.
Definition: base.cc:469
const uint16_t _size
Queue size in terms of number of descriptors.
Definition: base.hh:456
void updateChain()
Populate this descriptor chain with data from the guest.
Definition: base.cc:93
This object is a proxy for a structural port, to be used for debug accesses.
Definition: port_proxy.hh:84
VirtIODummyDevice(VirtIODummyDeviceParams *params)
Definition: base.cc:483
VirtDescriptor * next() const
Get the pointer to the next descriptor in a chain.
Definition: base.cc:134
void registerQueue(VirtQueue &queue)
Register a new VirtQueue with the device model.
Definition: base.cc:477
int size()
Definition: pagetable.hh:146
Bitfield< 29 > c
Definition: miscregs.hh:1365
uint16_t DeviceId
Device Type (sometimes known as subsystem ID)
Definition: base.hh:582
void read(size_t offset, uint8_t *dst, size_t size) const
Read the contents of a descriptor.
Definition: base.cc:144
const FeatureBits deviceFeatures
Feature set offered by the device.
Definition: base.hh:853
std::ostream CheckpointOut
Definition: serialize.hh:67
void setQueueAddress(uint32_t address)
Change the host physical address of the currently active queue.
Definition: base.cc:463
uint16_t Index
Descriptor index in virtqueue.
Definition: base.hh:140
virtual void writeBlob(Addr addr, const uint8_t *p, int size) const
Write size bytes from p to address.
Definition: port_proxy.cc:58
T vtoh_legacy(T v)
Convert legacy VirtIO endianness to host endianness.
Definition: base.hh:70
Bitfield< 18, 16 > len
Definition: miscregs.hh:1626
nomali_config_t cfg
Definition: gpu_nomali.cc:66
size_t chainSize() const
Retrieve the size of this descriptor chain.
Definition: base.cc:214
void update()
Populate this descriptor with data from the guest.
Definition: base.cc:74
VirtRing< struct vring_used_elem > used
Ring of used (outgoing) descriptors.
Definition: base.hh:549
VirtIO ring buffer wrapper.
Definition: base.hh:471
uint16_t flags
Definition: virtio_ring.h:68
std::vector< T > ring
Elements in ring in host byte order.
Definition: base.hh:534
bool isOutgoing() const
Check if this is a write-only descriptor (outgoing data).
Definition: base.hh:250
static const unsigned ALIGN_SIZE
Definition: base.hh:437
void registerKickCallback(Callback *c)
Register a callback to kick the guest through the transport interface.
Definition: base.hh:737
virtual ~VirtQueue()
Definition: base.hh:319
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: base.cc:238
Base wrapper around a virtqueue.
Definition: base.hh:317
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: base.cc:351
uint16_t _last_avail
Offset of last consumed descriptor in the VirtQueue::avail ring.
Definition: base.hh:553
FeatureBits getGuestFeatures() const
Get features accepted by the guest driver.
Definition: base.hh:844
void readConfigBlob(PacketPtr pkt, Addr cfgOffset, const uint8_t *cfg)
Read configuration data from a device structure.
Definition: base.cc:420
vring_desc desc
Underlying descriptor.
Definition: base.hh:305
Abstract superclass for simulation objects.
Definition: sim_object.hh:94
uint32_t len
Definition: virtio_ring.h:66
const size_t configSize
Size of the device's configuration space.
Definition: base.hh:850
Addr _base
Guest physical base address of the ring buffer.
Definition: base.hh:543
uint32_t FeatureBits
Definition: base.hh:574
uint16_t QueueID
Definition: base.hh:573
virtual void onNotifyDescriptor(VirtDescriptor *desc)
Notify queue of pending incoming descriptor.
Definition: base.hh:421
PortProxy * memProxy
Pointer to memory proxy.
Definition: base.hh:297

Generated on Fri Jun 9 2017 13:03:41 for gem5 by doxygen 1.8.6