block.hh revision 10390
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#ifndef __DEV_VIRTIO_BLOCK_HH__ 41#define __DEV_VIRTIO_BLOCK_HH__ 42 43#include "dev/virtio/base.hh" 44#include "dev/disk_image.hh" 45#include "dev/terminal.hh" 46 47struct VirtIOBlockParams; 48 49/** 50 * VirtIO block device 51 * 52 * The block device uses the following queues: 53 * -# Requests 54 * 55 * A guest issues a request by creating a descriptor chain that starts 56 * with a BlkRequest. Immediately after the BlkRequest follows the 57 * data for the request. The data buffer(s) are either input or output 58 * descriptors depending on the request type. The last byte in the 59 * descriptor chain should always be writable by the host and contains 60 * the request status code (OK/Error). 61 * 62 * The protocol supports asynchronous request completion by returning 63 * descriptor chains when they have been populated by the backing 64 * store. However, there is little point in doing so here. 65 * 66 * @see https://github.com/rustyrussell/virtio-spec 67 * @see http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.html 68 */ 69class VirtIOBlock : public VirtIODeviceBase 70{ 71 public: 72 typedef VirtIOBlockParams Params; 73 VirtIOBlock(Params *params); 74 virtual ~VirtIOBlock(); 75 76 void readConfig(PacketPtr pkt, Addr cfgOffset); 77 78 protected: 79 static const DeviceId ID_BLOCK = 0x02; 80 81 /** 82 * Block device configuration structure 83 * 84 * @note This needs to be changed if the supported feature set 85 * changes! 86 */ 87 struct Config { 88 uint64_t capacity; 89 } M5_ATTR_PACKED; 90 Config config; 91 92 /** @{ 93 * @name Feature bits 94 */ 95 static const FeatureBits F_SIZE_MAX = (1 << 1); 96 static const FeatureBits F_SEG_MAX = (1 << 2); 97 static const FeatureBits F_GEOMETRY = (1 << 4); 98 static const FeatureBits F_RO = (1 << 5); 99 static const FeatureBits F_BLK_SIZE = (1 << 6); 100 static const FeatureBits F_TOPOLOGY = (1 << 10); 101 /** @} */ 102 103 /** @{ 104 * @name VirtIO block requests 105 */ 106 typedef uint32_t RequestType; 107 /** Read request */ 108 static const RequestType T_IN = 0; 109 /** Write request */ 110 static const RequestType T_OUT = 1; 111 /** Flush device buffers */ 112 static const RequestType T_FLUSH = 4; 113 /** @} */ 114 115 /** @{ 116 * @name VirtIO block request status 117 */ 118 typedef uint8_t Status; 119 /** Request succeeded */ 120 static const Status S_OK = 0; 121 /** Request failed due to a device error */ 122 static const Status S_IOERR = 1; 123 /** Request not supported */ 124 static const Status S_UNSUPP = 2; 125 /** @} */ 126 127 /** VirtIO block device request as sent by guest */ 128 struct BlkRequest { 129 RequestType type; 130 uint32_t reserved; 131 uint64_t sector; 132 } M5_ATTR_PACKED; 133 134 /** 135 * Device read request. 136 * 137 * @param req Disk request from guest. 138 * @param desc_chain Request descriptor chain (from start of 139 * request) 140 * @param off_data Offset into the descriptor chain where data 141 * should be written. 142 * @param size Request data size. 143 */ 144 Status read(const BlkRequest &req, VirtDescriptor *desc_chain, 145 size_t off_data, size_t size); 146 /** 147 * Device write request. 148 * 149 * @param req Disk request from guest. 150 * @param desc_chain Request descriptor chain (from start of 151 * request) 152 * @param off_data Offset into the descriptor chain where data 153 * should be read. 154 * @param size Request data size. 155 */ 156 Status write(const BlkRequest &req, VirtDescriptor *desc_chain, 157 size_t off_data, size_t size); 158 159 protected: 160 /** 161 * Virtqueue for disk requests. 162 */ 163 class RequestQueue 164 : public VirtQueue 165 { 166 public: 167 RequestQueue(PortProxy &proxy, uint16_t size, VirtIOBlock &_parent) 168 : VirtQueue(proxy, size), parent(_parent) {} 169 virtual ~RequestQueue() {} 170 171 void onNotifyDescriptor(VirtDescriptor *desc); 172 173 std::string name() const { return parent.name() + ".qRequests"; } 174 175 protected: 176 VirtIOBlock &parent; 177 }; 178 179 /** Device I/O request queue */ 180 RequestQueue qRequests; 181 182 /** Image backing this device */ 183 DiskImage ℑ 184}; 185 186#endif // __DEV_VIRTIO_BLOCK_HH__ 187