gem5  v20.1.0.0
block.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 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 
38 #include "dev/virtio/block.hh"
39 
40 #include "debug/VIOBlock.hh"
41 #include "params/VirtIOBlock.hh"
42 #include "sim/system.hh"
43 
45  : VirtIODeviceBase(params, ID_BLOCK, sizeof(Config), 0),
46  qRequests(params->system->physProxy, byteOrder,
47  params->queueSize, *this),
48  image(*params->image)
49 {
51 
53 }
54 
55 
57 {
58 }
59 
60 void
62 {
63  Config cfg_out;
65 
66  readConfigBlob(pkt, cfgOffset, (uint8_t *)&cfg_out);
67 }
68 
71  size_t off_data, size_t size)
72 {
74  uint64_t sector(req.sector);
75 
76  DPRINTF(VIOBlock, "Read request starting @ sector %i (size: %i)\n",
77  sector, size);
78 
79  if (size % SectorSize != 0)
80  panic("Unexpected request/sector size relationship\n");
81 
82  for (Addr offset = 0; offset < size; offset += SectorSize) {
83  if (image.read(&data[offset], sector) != SectorSize) {
84  warn("Failed to read sector %i\n", sector);
85  return S_IOERR;
86  }
87  ++sector;
88  }
89 
90  desc_chain->chainWrite(off_data, &data[0], size);
91 
92  return S_OK;
93 }
94 
97  size_t off_data, size_t size)
98 {
100  uint64_t sector(req.sector);
101 
102  DPRINTF(VIOBlock, "Write request starting @ sector %i (size: %i)\n",
103  sector, size);
104 
105  if (size % SectorSize != 0)
106  panic("Unexpected request/sector size relationship\n");
107 
108 
109  desc_chain->chainRead(off_data, &data[0], size);
110 
111  for (Addr offset = 0; offset < size; offset += SectorSize) {
112  if (image.write(&data[offset], sector) != SectorSize) {
113  warn("Failed to write sector %i\n", sector);
114  return S_IOERR;
115  }
116  ++sector;
117  }
118 
119  return S_OK;
120 
121 }
122 
123 void
125 {
126  DPRINTF(VIOBlock, "Got input data descriptor (len: %i)\n",
127  desc->size());
128  /*
129  * Read the request structure and do endian conversion if
130  * necessary.
131  */
132  BlkRequest req;
133  desc->chainRead(0, (uint8_t *)&req, sizeof(req));
134  req.type = htog(req.type, byteOrder);
135  req.sector = htog(req.sector, byteOrder);
136 
137  Status status;
138  const size_t data_size(desc->chainSize()
139  - sizeof(BlkRequest) - sizeof(Status));
140 
141  switch (req.type) {
142  case T_IN:
143  status = parent.read(req, desc, sizeof(BlkRequest), data_size);
144  break;
145 
146  case T_OUT:
147  status = parent.write(req, desc, sizeof(BlkRequest), data_size);
148  break;
149 
150  case T_FLUSH:
151  status = S_OK;
152  break;
153 
154  default:
155  warn("Unsupported IO request: %i\n", req.type);
156  status = S_UNSUPP;
157  break;
158  }
159 
160  desc->chainWrite(sizeof(BlkRequest) + data_size,
161  &status, sizeof(status));
162 
163  // Tell the guest that we are done with this descriptor.
164  produceDescriptor(desc, sizeof(BlkRequest) + data_size + sizeof(Status));
165  parent.kick();
166 }
167 
168 VirtIOBlock *
169 VirtIOBlockParams::create()
170 {
171  return new VirtIOBlock(this);
172 }
VirtIOBlock::Config::capacity
uint64_t capacity
Definition: block.hh:85
VirtDescriptor::size
size_t size() const
Retrieve the size of this descriptor.
Definition: base.hh:202
ArmISA::status
Bitfield< 5, 0 > status
Definition: miscregs_types.hh:417
VirtIOBlock::VirtIOBlock
VirtIOBlock(Params *params)
Definition: block.cc:44
VirtIOBlock::Config
Block device configuration structure.
Definition: block.hh:84
DiskImage::write
virtual std::streampos write(const uint8_t *data, std::streampos offset)=0
VirtIOBlock::S_OK
static const Status S_OK
Request succeeded.
Definition: block.hh:117
warn
#define warn(...)
Definition: logging.hh:239
VirtQueue::produceDescriptor
void produceDescriptor(VirtDescriptor *desc, uint32_t len)
Send a descriptor chain to the guest.
Definition: base.cc:290
system.hh
VirtIOBlock::qRequests
RequestQueue qRequests
Device I/O request queue.
Definition: block.hh:178
VirtIOBlock::read
Status read(const BlkRequest &req, VirtDescriptor *desc_chain, size_t off_data, size_t size)
Device read request.
Definition: block.cc:70
data
const char data[]
Definition: circlebuf.test.cc:42
VirtIOBlock::~VirtIOBlock
virtual ~VirtIOBlock()
Definition: block.cc:56
VirtIOBlock::BlkRequest
VirtIO block device request as sent by guest.
Definition: block.hh:125
block.hh
ArmISA::byteOrder
ByteOrder byteOrder(const ThreadContext *tc)
Definition: utility.hh:449
VirtIOBlock
VirtIO block device.
Definition: block.hh:66
VirtIOBlock::T_FLUSH
static const RequestType T_FLUSH
Flush device buffers.
Definition: block.hh:109
VirtIODeviceBase::registerQueue
void registerQueue(VirtQueue &queue)
Register a new VirtQueue with the device model.
Definition: base.cc:477
SectorSize
#define SectorSize
Definition: disk_image.hh:44
VirtIOBlock::Status
uint8_t Status
Definition: block.hh:115
VirtIODeviceBase
Base class for all VirtIO-based devices.
Definition: base.hh:558
VirtIOBlock::RequestQueue::parent
VirtIOBlock & parent
Definition: block.hh:174
std::vector< uint8_t >
VirtIOBlock::image
DiskImage & image
Image backing this device.
Definition: block.hh:181
VirtIOBlock::Params
VirtIOBlockParams Params
Definition: block.hh:69
DiskImage::size
virtual std::streampos size() const =0
X86ISA::system
Bitfield< 15 > system
Definition: misc.hh:997
VirtIOBlock::write
Status write(const BlkRequest &req, VirtDescriptor *desc_chain, size_t off_data, size_t size)
Device write request.
Definition: block.cc:96
VirtIOBlock::T_IN
static const RequestType T_IN
Read request.
Definition: block.hh:105
VirtIOBlock::config
Config config
Definition: block.hh:87
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
VirtIOBlock::T_OUT
static const RequestType T_OUT
Write request.
Definition: block.hh:107
htog
T htog(T value, ByteOrder guest_byte_order)
Definition: byteswap.hh:155
VirtIODeviceBase::readConfigBlob
void readConfigBlob(PacketPtr pkt, Addr cfgOffset, const uint8_t *cfg)
Read configuration data from a device structure.
Definition: base.cc:420
VirtIOBlock::readConfig
void readConfig(PacketPtr pkt, Addr cfgOffset)
Read from the configuration space of a device.
Definition: block.cc:61
VirtQueue::byteOrder
ByteOrder byteOrder
Byte order in this queue.
Definition: base.hh:427
VirtDescriptor::chainWrite
void chainWrite(size_t offset, const uint8_t *src, size_t size)
Write to a descriptor chain.
Definition: base.cc:191
VirtDescriptor::chainSize
size_t chainSize() const
Retrieve the size of this descriptor chain.
Definition: base.cc:214
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
VirtDescriptor::chainRead
void chainRead(size_t offset, uint8_t *dst, size_t size) const
Read the contents of a descriptor chain.
Definition: base.cc:168
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
VirtIOBlock::S_UNSUPP
static const Status S_UNSUPP
Request not supported.
Definition: block.hh:121
VirtIOBlock::RequestQueue::onNotifyDescriptor
void onNotifyDescriptor(VirtDescriptor *desc)
Notify queue of pending incoming descriptor.
Definition: block.cc:124
VirtIOBlock::BlkRequest::sector
uint64_t sector
Definition: block.hh:128
DiskImage::read
virtual std::streampos read(uint8_t *data, std::streampos offset) const =0
VirtIOBlock::S_IOERR
static const Status S_IOERR
Request failed due to a device error.
Definition: block.hh:119
VirtIODeviceBase::kick
void kick()
Inform the guest of available buffers.
Definition: base.hh:609
VirtIODeviceBase::byteOrder
ByteOrder byteOrder
The byte order of the queues, descriptors, etc.
Definition: base.hh:718
VirtDescriptor
VirtIO descriptor (chain) wrapper.
Definition: base.hh:106
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:153

Generated on Wed Sep 30 2020 14:02:11 for gem5 by doxygen 1.8.17