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

Generated on Fri Feb 28 2020 16:27:01 for gem5 by doxygen 1.8.13