gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
base.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, 2016-2017 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 <> inline vring_used_elem
71  v.id = swap_byte(v.id);
72  v.len = swap_byte(v.len);
73  return v;
74 }
75 
76 template <> inline vring_desc
78  v.addr = swap_byte(v.addr);
79  v.len = swap_byte(v.len);
80  v.flags = swap_byte(v.flags);
81  v.next = swap_byte(v.next);
82  return v;
83 }
84 
109 {
110  public:
112  typedef uint16_t Index;
113 
125  VirtQueue &queue, Index index);
126  // WORKAROUND: The noexcept declaration works around a bug where
127  // gcc 4.7 tries to call the wrong constructor when emplacing
128  // something into a vector.
129  VirtDescriptor(VirtDescriptor &&other) noexcept;
130  ~VirtDescriptor() noexcept;
131 
132  VirtDescriptor &operator=(VirtDescriptor &&rhs) noexcept;
133 
135  Index index() const { return _index; }
136 
138  void update();
139 
141  void updateChain();
150  void dump() const;
155  void dumpChain() const;
176  void read(size_t offset, uint8_t *dst, size_t size) const;
191  void write(size_t offset, const uint8_t *src, size_t size);
204  size_t size() const { return desc.len; }
205 
211  bool hasNext() const { return desc.flags & VRING_DESC_F_NEXT; }
218  VirtDescriptor *next() const;
219 
221  bool isIncoming() const { return !isOutgoing(); }
223  bool isOutgoing() const { return desc.flags & VRING_DESC_F_WRITE; }
224 
225 
238  void chainRead(size_t offset, uint8_t *dst, size_t size) const;
251  void chainWrite(size_t offset, const uint8_t *src, size_t size);
260  size_t chainSize() const;
263  private:
264  // Remove default constructor
265  VirtDescriptor();
266  // Prevent copying
267  VirtDescriptor(const VirtDescriptor &other);
268 
273 
276 
278  Index _index;
279 
282 };
283 
293 class VirtQueue : public Serializable {
294 public:
295  virtual ~VirtQueue() {};
296 
300  void serialize(CheckpointOut &cp) const override;
301  void unserialize(CheckpointIn &cp) override;
302 
311  void setAddress(Addr address);
317  Addr getAddress() const { return _address; }
318 
324  uint16_t getSize() const { return _size; }
325 
336  return &descriptors[index];
337  }
349  VirtDescriptor *consumeDescriptor();
368  void produceDescriptor(VirtDescriptor *desc, uint32_t len);
386  virtual void onNotify();
397  virtual void onNotifyDescriptor(VirtDescriptor *desc) {};
404  void dump() const;
412  static const Addr ALIGN_BITS = 12;
413  static const Addr ALIGN_SIZE = 1 << ALIGN_BITS;
416  protected:
426  VirtQueue(PortProxy &proxy, ByteOrder bo, uint16_t size);
427 
430 
431  private:
432  VirtQueue();
433 
435  const uint16_t _size;
440 
441  private:
449  template<typename T>
450  class VirtRing
451  {
452  public:
453  typedef uint16_t Flags;
454  typedef uint16_t Index;
455 
456  struct Header {
457  Flags flags;
458  Index index;
459  } M5_ATTR_PACKED;
460 
461  VirtRing<T>(PortProxy &proxy, ByteOrder bo, uint16_t size) :
462  header{0, 0}, ring(size), _proxy(proxy), _base(0), byteOrder(bo)
463  {}
464 
470  void setAddress(Addr addr) { _base = addr; }
471 
473  void
475  {
476  assert(_base != 0);
477  _proxy.readBlob(_base, &header, sizeof(header));
478  header.flags = gtoh(header.flags, byteOrder);
479  header.index = gtoh(header.index, byteOrder);
480  }
481 
482  void
484  {
485  Header out;
486  assert(_base != 0);
487  out.flags = htog(header.flags, byteOrder);
488  out.index = htog(header.index, byteOrder);
489  _proxy.writeBlob(_base, &out, sizeof(out));
490  }
491 
492  void
494  {
495  readHeader();
496 
497  /* Read and byte-swap the elements in the ring */
498  T temp[ring.size()];
499  _proxy.readBlob(_base + sizeof(header),
500  temp, sizeof(T) * ring.size());
501  for (int i = 0; i < ring.size(); ++i)
502  ring[i] = gtoh(temp[i], byteOrder);
503  }
504 
505  void
507  {
508  assert(_base != 0);
509  /* Create a byte-swapped copy of the ring and write it to
510  * guest memory. */
511  T temp[ring.size()];
512  for (int i = 0; i < ring.size(); ++i)
513  temp[i] = htog(ring[i], byteOrder);
514  _proxy.writeBlob(_base + sizeof(header),
515  temp, sizeof(T) * ring.size());
516  writeHeader();
517  }
518 
520  Header header;
523 
524  private:
525  // Remove default constructor
526  VirtRing<T>();
527 
534  };
535 
540 
543  uint16_t _last_avail;
544 
548 };
549 
561 {
562  public:
563  typedef uint16_t QueueID;
564  typedef uint32_t FeatureBits;
570  typedef uint16_t VirtAddress;
572  typedef uint16_t DeviceId;
573 
574  BitUnion8(DeviceStatus)
575  Bitfield<7> failed;
576  Bitfield<2> driver_ok;
577  Bitfield<1> driver;
578  Bitfield<0> acknowledge;
579  EndBitUnion(DeviceStatus)
580 
581  typedef VirtIODeviceBaseParams Params;
582  VirtIODeviceBase(Params *params, DeviceId id, size_t config_size,
583  FeatureBits features);
584  virtual ~VirtIODeviceBase();
585 
586  public:
590  void serialize(CheckpointOut &cp) const override;
591  void unserialize(CheckpointIn &cp) override;
595  protected:
610  void kick() {
611  assert(transKick);
612  transKick->process();
613  };
614 
626  void registerQueue(VirtQueue &queue);
627 
628 
639  FeatureBits guestFeatures;
642  public:
660  virtual void readConfig(PacketPtr pkt, Addr cfgOffset);
675  virtual void writeConfig(PacketPtr pkt, Addr cfgOffset);
676 
689  virtual void reset();
692  protected:
704  void readConfigBlob(PacketPtr pkt, Addr cfgOffset, const uint8_t *cfg);
705 
713  void writeConfigBlob(PacketPtr pkt, Addr cfgOffset, uint8_t *cfg);
714 
719 
722  public:
733  assert(!transKick);
734  transKick = c;
735  }
736 
737 
747  void onNotify(QueueID index);
748 
749 
759  void setQueueSelect(QueueID idx) { _queueSelect = idx; }
769  QueueID getQueueSelect() const { return _queueSelect; }
770 
785  void setQueueAddress(uint32_t address);
799  uint32_t getQueueAddress() const;
800 
807  uint16_t getQueueSize() const { return getCurrentQueue().getSize(); }
808 
817  void setDeviceStatus(DeviceStatus status);
818 
824  DeviceStatus getDeviceStatus() const { return _deviceStatus; }
825 
832  void setGuestFeatures(FeatureBits features);
833 
839  FeatureBits getGuestFeatures() const { return guestFeatures; }
840 
842  const DeviceId deviceId;
843 
845  const size_t configSize;
846 
848  const FeatureBits deviceFeatures;
851  private:
853  const VirtQueue &getCurrentQueue() const;
855  VirtQueue &getCurrentQueue();
856 
863  DeviceStatus _deviceStatus;
864 
866  QueueID _queueSelect;
867 
870 
873 };
874 
876 {
877  public:
878  VirtIODummyDevice(VirtIODummyDeviceParams *params);
879 
880  protected:
882  static const DeviceId ID_INVALID = 0x00;
883 };
884 
885 #endif // __DEV_VIRTIO_BASE_HH__
Base class for all VirtIO-based devices.
Definition: base.hh:560
void write(size_t offset, const uint8_t *src, size_t size)
Write to the contents of a descriptor.
Definition: base.cc:158
VirtDescriptor * next() const
Get the pointer to the next descriptor in a chain.
Definition: base.cc:136
output header
Definition: nop.cc:39
uint16_t getSize() const
Get the number of descriptors available in this queue.
Definition: base.hh:324
Bitfield< 28 > v
uint16_t VirtAddress
This is a VirtQueue address as exposed through the low-level interface. The address needs to be multi...
Definition: base.hh:570
Generic callback class.
Definition: callback.hh:41
EndBitUnion(UserDescFlags) struct UserDesc32
Definition: process.cc:160
uint16_t getQueueSize() const
Get the size (descriptors) of the currently active queue.
Definition: base.hh:807
void writeHeader()
Definition: base.hh:483
T gtoh(T value, ByteOrder guest_byte_order)
Definition: byteswap.hh:166
Bitfield< 7 > i
~VirtDescriptor() noexcept
Definition: base.cc:59
SimObjectParams Params
Definition: sim_object.hh:113
uint16_t Index
Definition: base.hh:454
void setQueueSelect(QueueID idx)
Change currently active queue.
Definition: base.hh:759
ip6_addr_t addr
Definition: inet.hh:335
Bitfield< 1 > driver
Definition: base.hh:577
#define VRING_DESC_F_WRITE
Definition: virtio_ring.h:39
VirtDescriptor * getDescriptor(VirtDescriptor::Index index)
Get a pointer to a specific descriptor in the queue.
Definition: base.hh:335
void dumpChain() const
Dump the contents of a descriptor chain starting at this descriptor.
Definition: base.cc:124
void reset()
Definition: statistics.cc:570
void setAddress(Addr addr)
Set the base address of the VirtIO ring buffer.
Definition: base.hh:470
Bitfield< 23, 0 > offset
Definition: types.hh:154
Definition: cprintf.cc:42
const DeviceId deviceId
Device ID (sometimes known as subsystem ID)
Definition: base.hh:842
STL vector class.
Definition: stl.hh:40
size_t size() const
Retrieve the size of this descriptor.
Definition: base.hh:204
void readHeader()
Update the ring buffer header with data from the guest.
Definition: base.hh:474
Bitfield< 5, 0 > status
void chainRead(size_t offset, uint8_t *dst, size_t size) const
Read the contents of a descriptor chain.
Definition: base.cc:170
Addr _address
Base address of the queue.
Definition: base.hh:437
ByteOrder byteOrder
The byte order of the queues, descriptors, etc.
Definition: base.hh:718
PortProxy Object Declaration.
Bitfield< 0 > acknowledge
Definition: base.hh:578
ByteOrder byteOrder
The byte order the descriptor is stored in.
Definition: base.hh:275
DeviceStatus _deviceStatus
Status of the device.
Definition: base.hh:863
PortProxy & memProxy
Guest physical memory proxy.
Definition: base.hh:439
T htog(T value, ByteOrder guest_byte_order)
Definition: byteswap.hh:159
#define VRING_DESC_F_NEXT
Definition: virtio_ring.h:37
bool isIncoming() const
Check if this is a read-only descriptor (incoming data).
Definition: base.hh:221
void read(size_t offset, uint8_t *dst, size_t size) const
Read the contents of a descriptor.
Definition: base.cc:146
size_t chainSize() const
Retrieve the size of this descriptor chain.
Definition: base.cc:216
QueueID _queueSelect
Queue select register (set by guest)
Definition: base.hh:866
std::vector< VirtDescriptor > descriptors
Vector of pre-created descriptors indexed by their index into the queue.
Definition: base.hh:547
void kick()
Inform the guest of available buffers.
Definition: base.hh:610
uint64_t addr
Definition: virtio_ring.h:64
ByteOrder byteOrder
Byte order in the ring.
Definition: base.hh:533
uint16_t next
Definition: virtio_ring.h:70
ByteOrder
Definition: types.hh:247
void chainWrite(size_t offset, const uint8_t *src, size_t size)
Write to a descriptor chain.
Definition: base.cc:193
std::vector< VirtQueue * > _queues
List of virtual queues supported by this device.
Definition: base.hh:869
Header header
Ring buffer header in host byte order.
Definition: base.hh:520
Bitfield< 18, 16 > len
Bitfield< 2 > driver_ok
Definition: base.hh:576
void serialize(const ThreadContext &tc, CheckpointOut &cp)
Thread context serialization helpers.
VirtIO descriptor (chain) wrapper.
Definition: base.hh:108
PortProxy & _proxy
Guest physical memory proxy.
Definition: base.hh:529
void dump() const
Dump the contents of a descriptor.
Definition: base.cc:107
Index _index
Index in virtqueue.
Definition: base.hh:278
Callback * transKick
Callbacks to kick the guest through the transport layer.
Definition: base.hh:872
uint32_t len
Definition: virtio_ring.h:84
uint16_t Flags
Definition: base.hh:453
VirtRing< VirtDescriptor::Index > avail
Ring of available (incoming) descriptors.
Definition: base.hh:537
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Index index() const
Get the descriptor&#39;s index into the virtqueue.
Definition: base.hh:135
DeviceStatus getDeviceStatus() const
Retrieve the device status.
Definition: base.hh:824
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:255
Basic support for object serialization.
Definition: serialize.hh:153
VirtQueue * queue
Pointer to virtqueue owning this descriptor.
Definition: base.hh:272
#define BitUnion8(name)
Definition: bitunion.hh:379
struct FXSave M5_ATTR_PACKED
FeatureBits guestFeatures
Feature set accepted by the guest.
Definition: base.hh:639
const uint16_t _size
Queue size in terms of number of descriptors.
Definition: base.hh:435
void updateChain()
Populate this descriptor chain with data from the guest.
Definition: base.cc:95
This object is a proxy for a port or other object which implements the functional response protocol...
Definition: port_proxy.hh:82
FeatureBits getGuestFeatures() const
Get features accepted by the guest driver.
Definition: base.hh:839
Bitfield< 29 > c
Bitfield< 25, 21 > bo
Definition: types.hh:64
uint16_t DeviceId
Device Type (sometimes known as subsystem ID)
Definition: base.hh:572
const FeatureBits deviceFeatures
Feature set offered by the device.
Definition: base.hh:848
Addr getAddress() const
Get the guest physical address of this queue.
Definition: base.hh:317
std::ostream CheckpointOut
Definition: serialize.hh:68
bool isOutgoing() const
Check if this is a write-only descriptor (outgoing data).
Definition: base.hh:223
uint16_t Index
Descriptor index in virtqueue.
Definition: base.hh:112
vring_used_elem swap_byte(vring_used_elem v)
Definition: base.hh:70
void update()
Populate this descriptor with data from the guest.
Definition: base.cc:76
VirtRing< struct vring_used_elem > used
Ring of used (outgoing) descriptors.
Definition: base.hh:539
VirtIO ring buffer wrapper.
Definition: base.hh:450
uint16_t flags
Definition: virtio_ring.h:68
std::vector< T > ring
Elements in ring in host byte order.
Definition: base.hh:522
ByteOrder byteOrder
Byte order in this queue.
Definition: base.hh:429
void unserialize(ThreadContext &tc, CheckpointIn &cp)
void registerKickCallback(Callback *c)
Register a callback to kick the guest through the transport interface.
Definition: base.hh:732
virtual ~VirtQueue()
Definition: base.hh:295
Base wrapper around a virtqueue.
Definition: base.hh:293
QueueID getQueueSelect() const
Get the currently active queue.
Definition: base.hh:769
bool hasNext() const
Is this descriptor chained to another descriptor?
Definition: base.hh:211
uint16_t _last_avail
Offset of last consumed descriptor in the VirtQueue::avail ring.
Definition: base.hh:543
vring_desc desc
Underlying descriptor.
Definition: base.hh:281
Abstract superclass for simulation objects.
Definition: sim_object.hh:96
uint32_t len
Definition: virtio_ring.h:66
const size_t configSize
Size of the device&#39;s configuration space.
Definition: base.hh:845
Addr _base
Guest physical base address of the ring buffer.
Definition: base.hh:531
uint32_t FeatureBits
Definition: base.hh:564
uint16_t QueueID
Definition: base.hh:563
virtual void onNotifyDescriptor(VirtDescriptor *desc)
Notify queue of pending incoming descriptor.
Definition: base.hh:397
PortProxy * memProxy
Pointer to memory proxy.
Definition: base.hh:270

Generated on Fri Feb 28 2020 16:26:58 for gem5 by doxygen 1.8.13