2 * Copyright (c) 2014 ARM Limited
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.
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.
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.
37 * Authors: Andreas Sandberg
40 #include "dev/virtio/block.hh"
42 #include "debug/VIOBlock.hh"
43 #include "params/VirtIOBlock.hh"
44 #include "sim/system.hh"
46 VirtIOBlock::VirtIOBlock(Params
*params
)
47 : VirtIODeviceBase(params
, ID_BLOCK
, sizeof(Config
), 0),
48 qRequests(params
->system
->physProxy
, params
->queueSize
, *this),
51 registerQueue(qRequests
);
53 config
.capacity
= image
.size();
57 VirtIOBlock::~VirtIOBlock()
62 VirtIOBlock::readConfig(PacketPtr pkt
, Addr cfgOffset
)
65 cfg_out
.capacity
= htov_legacy(config
.capacity
);
67 readConfigBlob(pkt
, cfgOffset
, (uint8_t *)&cfg_out
);
71 VirtIOBlock::read(const BlkRequest
&req
, VirtDescriptor
*desc_chain
,
72 size_t off_data
, size_t size
)
75 uint64_t sector(req
.sector
);
77 DPRINTF(VIOBlock
, "Read request starting @ sector %i (size: %i)\n",
80 if (size
% SectorSize
!= 0)
81 panic("Unexpected request/sector size relationship\n");
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
);
91 desc_chain
->chainWrite(off_data
, data
, size
);
97 VirtIOBlock::write(const BlkRequest
&req
, VirtDescriptor
*desc_chain
,
98 size_t off_data
, size_t size
)
101 uint64_t sector(req
.sector
);
103 DPRINTF(VIOBlock
, "Write request starting @ sector %i (size: %i)\n",
106 if (size
% SectorSize
!= 0)
107 panic("Unexpected request/sector size relationship\n");
110 desc_chain
->chainRead(off_data
, data
, size
);
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
);
125 VirtIOBlock::RequestQueue::onNotifyDescriptor(VirtDescriptor
*desc
)
127 DPRINTF(VIOBlock
, "Got input data descriptor (len: %i)\n",
130 * Read the request structure and do endian conversion if
134 desc
->chainRead(0, (uint8_t *)&req
, sizeof(req
));
135 req
.type
= htov_legacy(req
.type
);
136 req
.sector
= htov_legacy(req
.sector
);
139 const size_t data_size(desc
->chainSize()
140 - sizeof(BlkRequest
) - sizeof(Status
));
144 status
= parent
.read(req
, desc
, sizeof(BlkRequest
), data_size
);
148 status
= parent
.write(req
, desc
, sizeof(BlkRequest
), data_size
);
156 warn("Unsupported IO request: %i\n", req
.type
);
161 desc
->chainWrite(sizeof(BlkRequest
) + data_size
,
162 &status
, sizeof(status
));
164 // Tell the guest that we are done with this descriptor.
165 produceDescriptor(desc
, sizeof(BlkRequest
) + data_size
+ sizeof(Status
));
170 VirtIOBlockParams::create()
172 return new VirtIOBlock(this);