gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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, params->queueSize, *this),
49  image(*params->image)
50 {
52 
54 }
55 
56 
58 {
59 }
60 
61 void
63 {
64  Config cfg_out;
66 
67  readConfigBlob(pkt, cfgOffset, (uint8_t *)&cfg_out);
68 }
69 
72  size_t off_data, size_t size)
73 {
74  uint8_t data[size];
75  uint64_t sector(req.sector);
76 
77  DPRINTF(VIOBlock, "Read request starting @ sector %i (size: %i)\n",
78  sector, size);
79 
80  if (size % SectorSize != 0)
81  panic("Unexpected request/sector size relationship\n");
82 
83  for (Addr offset = 0; offset < size; offset += SectorSize) {
84  if (image.read(data + offset, sector) != SectorSize) {
85  warn("Failed to read sector %i\n", sector);
86  return S_IOERR;
87  }
88  ++sector;
89  }
90 
91  desc_chain->chainWrite(off_data, data, size);
92 
93  return S_OK;
94 }
95 
98  size_t off_data, size_t size)
99 {
100  uint8_t data[size];
101  uint64_t sector(req.sector);
102 
103  DPRINTF(VIOBlock, "Write request starting @ sector %i (size: %i)\n",
104  sector, size);
105 
106  if (size % SectorSize != 0)
107  panic("Unexpected request/sector size relationship\n");
108 
109 
110  desc_chain->chainRead(off_data, data, size);
111 
112  for (Addr offset = 0; offset < size; offset += SectorSize) {
113  if (image.write(data + offset, sector) != SectorSize) {
114  warn("Failed to write sector %i\n", sector);
115  return S_IOERR;
116  }
117  ++sector;
118  }
119 
120  return S_OK;
121 
122 }
123 
124 void
126 {
127  DPRINTF(VIOBlock, "Got input data descriptor (len: %i)\n",
128  desc->size());
129  /*
130  * Read the request structure and do endian conversion if
131  * necessary.
132  */
133  BlkRequest req;
134  desc->chainRead(0, (uint8_t *)&req, sizeof(req));
135  req.type = htov_legacy(req.type);
136  req.sector = htov_legacy(req.sector);
137 
138  Status status;
139  const size_t data_size(desc->chainSize()
140  - sizeof(BlkRequest) - sizeof(Status));
141 
142  switch (req.type) {
143  case T_IN:
144  status = parent.read(req, desc, sizeof(BlkRequest), data_size);
145  break;
146 
147  case T_OUT:
148  status = parent.write(req, desc, sizeof(BlkRequest), data_size);
149  break;
150 
151  case T_FLUSH:
152  status = S_OK;
153  break;
154 
155  default:
156  warn("Unsupported IO request: %i\n", req.type);
157  status = S_UNSUPP;
158  break;
159  }
160 
161  desc->chainWrite(sizeof(BlkRequest) + data_size,
162  &status, sizeof(status));
163 
164  // Tell the guest that we are done with this descriptor.
165  produceDescriptor(desc, sizeof(BlkRequest) + data_size + sizeof(Status));
166  parent.kick();
167 }
168 
169 VirtIOBlock *
170 VirtIOBlockParams::create()
171 {
172  return new VirtIOBlock(this);
173 }
#define DPRINTF(x,...)
Definition: trace.hh:212
VirtIOBlock & parent
Definition: block.hh:176
Base class for all VirtIO-based devices.
Definition: base.hh:570
Status read(const BlkRequest &req, VirtDescriptor *desc_chain, size_t off_data, size_t size)
Device read request.
Definition: block.cc:71
virtual ~VirtIOBlock()
Definition: block.cc:57
VirtIOBlock(Params *params)
Definition: block.cc:46
#define panic(...)
Definition: misc.hh:153
DiskImage & image
Image backing this device.
Definition: block.hh:183
VirtIOBlockParams Params
Definition: block.hh:72
static const RequestType T_FLUSH
Flush device buffers.
Definition: block.hh:112
Block device configuration structure.
Definition: block.hh:87
Bitfield< 23, 0 > offset
Definition: types.hh:149
uint8_t Status
Definition: block.hh:118
Status write(const BlkRequest &req, VirtDescriptor *desc_chain, size_t off_data, size_t size)
Device write request.
Definition: block.cc:97
static const RequestType T_OUT
Write request.
Definition: block.hh:110
const char data[]
Definition: circlebuf.cc:43
VirtIO block device request as sent by guest.
Definition: block.hh:128
#define warn(...)
Definition: misc.hh:219
Bitfield< 5, 0 > status
Definition: miscregs.hh:1604
void produceDescriptor(VirtDescriptor *desc, uint32_t len)
Send a descriptor chain to the guest.
Definition: base.cc:290
virtual std::streampos size() const =0
Config config
Definition: block.hh:90
system
Definition: isa.cc:226
T htov_legacy(T v)
Convert host endianness to legacy VirtIO endianness.
Definition: base.hh:76
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
static const RequestType T_IN
Read request.
Definition: block.hh:108
void chainWrite(size_t offset, const uint8_t *src, size_t size)
Write to a descriptor chain.
Definition: base.cc:191
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:136
uint64_t capacity
Definition: block.hh:88
void onNotifyDescriptor(VirtDescriptor *desc)
Notify queue of pending incoming descriptor.
Definition: block.cc:125
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:245
size_t size() const
Retrieve the size of this descriptor.
Definition: base.hh:231
void readConfig(PacketPtr pkt, Addr cfgOffset)
Read from the configuration space of a device.
Definition: block.cc:62
void registerQueue(VirtQueue &queue)
Register a new VirtQueue with the device model.
Definition: base.cc:477
static const Status S_IOERR
Request failed due to a device error.
Definition: block.hh:122
int size()
Definition: pagetable.hh:146
virtual std::streampos read(uint8_t *data, std::streampos offset) const =0
size_t chainSize() const
Retrieve the size of this descriptor chain.
Definition: base.cc:214
VirtIO block device.
Definition: block.hh:69
static const Status S_OK
Request succeeded.
Definition: block.hh:120
RequestQueue qRequests
Device I/O request queue.
Definition: block.hh:180
static const Status S_UNSUPP
Request not supported.
Definition: block.hh:124
void readConfigBlob(PacketPtr pkt, Addr cfgOffset, const uint8_t *cfg)
Read configuration data from a device structure.
Definition: base.cc:420

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