block.cc revision 14239
12689Sktlim@umich.edu/* 22689Sktlim@umich.edu * Copyright (c) 2014 ARM Limited 32689Sktlim@umich.edu * All rights reserved 42689Sktlim@umich.edu * 52689Sktlim@umich.edu * The license below extends only to copyright in the software and shall 62689Sktlim@umich.edu * not be construed as granting a license to any other intellectual 72689Sktlim@umich.edu * property including but not limited to intellectual property relating 82689Sktlim@umich.edu * to a hardware implementation of the functionality of the software 92689Sktlim@umich.edu * licensed hereunder. You may use the software subject to the license 102689Sktlim@umich.edu * terms below provided that you ensure that this notice is replicated 112689Sktlim@umich.edu * unmodified and in its entirety in all distributions of the software, 122689Sktlim@umich.edu * modified or unmodified, in source code or in binary form. 132689Sktlim@umich.edu * 142689Sktlim@umich.edu * Redistribution and use in source and binary forms, with or without 152689Sktlim@umich.edu * modification, are permitted provided that the following conditions are 162689Sktlim@umich.edu * met: redistributions of source code must retain the above copyright 172689Sktlim@umich.edu * notice, this list of conditions and the following disclaimer; 182689Sktlim@umich.edu * redistributions in binary form must reproduce the above copyright 192689Sktlim@umich.edu * notice, this list of conditions and the following disclaimer in the 202689Sktlim@umich.edu * documentation and/or other materials provided with the distribution; 212689Sktlim@umich.edu * neither the name of the copyright holders nor the names of its 222689Sktlim@umich.edu * contributors may be used to endorse or promote products derived from 232689Sktlim@umich.edu * this software without specific prior written permission. 242689Sktlim@umich.edu * 252689Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 262689Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 272689Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 282689Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 292689Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 302689Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 312689Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 322689Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 332689Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 342521SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 353960Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 364194Ssaidi@eecs.umich.edu * 371070SN/A * Authors: Andreas Sandberg 381070SN/A */ 392521SN/A 402680Sktlim@umich.edu#include "dev/virtio/block.hh" 412521SN/A 422522SN/A#include "debug/VIOBlock.hh" 432037SN/A#include "params/VirtIOBlock.hh" 4456SN/A#include "sim/system.hh" 452378SN/A 462521SN/AVirtIOBlock::VirtIOBlock(Params *params) 472378SN/A : VirtIODeviceBase(params, ID_BLOCK, sizeof(Config), 0), 484762Snate@binkert.org qRequests(params->system->physProxy, params->queueSize, *this), 494762Snate@binkert.org image(*params->image) 502378SN/A{ 512SN/A registerQueue(qRequests); 522SN/A 532107SN/A config.capacity = image.size(); 542SN/A} 552SN/A 562SN/A 572SN/AVirtIOBlock::~VirtIOBlock() 582SN/A{ 591070SN/A} 602378SN/A 612378SN/Avoid 622521SN/AVirtIOBlock::readConfig(PacketPtr pkt, Addr cfgOffset) 632640Sstever@eecs.umich.edu{ 642640Sstever@eecs.umich.edu Config cfg_out; 652378SN/A cfg_out.capacity = htov_legacy(config.capacity); 662378SN/A 672378SN/A readConfigBlob(pkt, cfgOffset, (uint8_t *)&cfg_out); 682902Ssaidi@eecs.umich.edu} 692SN/A 701070SN/AVirtIOBlock::Status 711070SN/AVirtIOBlock::read(const BlkRequest &req, VirtDescriptor *desc_chain, 721070SN/A size_t off_data, size_t size) 732378SN/A{ 741070SN/A std::vector<uint8_t> data(size); 754838Ssaidi@eecs.umich.edu uint64_t sector(req.sector); 764838Ssaidi@eecs.umich.edu 771070SN/A DPRINTF(VIOBlock, "Read request starting @ sector %i (size: %i)\n", 782520SN/A sector, size); 792520SN/A 802520SN/A if (size % SectorSize != 0) 812520SN/A panic("Unexpected request/sector size relationship\n"); 822520SN/A 832520SN/A for (Addr offset = 0; offset < size; offset += SectorSize) { 842520SN/A if (image.read(&data[offset], sector) != SectorSize) { 852520SN/A warn("Failed to read sector %i\n", sector); 862520SN/A return S_IOERR; 872521SN/A } 882521SN/A ++sector; 892521SN/A } 902521SN/A 912520SN/A desc_chain->chainWrite(off_data, &data[0], size); 921070SN/A 932158SN/A return S_OK; 941070SN/A} 954762Snate@binkert.org 963812Ssaidi@eecs.umich.eduVirtIOBlock::Status 973812Ssaidi@eecs.umich.eduVirtIOBlock::write(const BlkRequest &req, VirtDescriptor *desc_chain, 983812Ssaidi@eecs.umich.edu size_t off_data, size_t size) 993812Ssaidi@eecs.umich.edu{ 1004762Snate@binkert.org std::vector<uint8_t> data(size); 1013812Ssaidi@eecs.umich.edu uint64_t sector(req.sector); 1024762Snate@binkert.org 1031070SN/A DPRINTF(VIOBlock, "Write request starting @ sector %i (size: %i)\n", 1043812Ssaidi@eecs.umich.edu sector, size); 1053812Ssaidi@eecs.umich.edu 1061070SN/A if (size % SectorSize != 0) 1073812Ssaidi@eecs.umich.edu panic("Unexpected request/sector size relationship\n"); 1083812Ssaidi@eecs.umich.edu 1093812Ssaidi@eecs.umich.edu 1103812Ssaidi@eecs.umich.edu desc_chain->chainRead(off_data, &data[0], size); 1111070SN/A 1123812Ssaidi@eecs.umich.edu for (Addr offset = 0; offset < size; offset += SectorSize) { 1133812Ssaidi@eecs.umich.edu if (image.write(&data[offset], sector) != SectorSize) { 1143812Ssaidi@eecs.umich.edu warn("Failed to write sector %i\n", sector); 1151070SN/A return S_IOERR; 1163812Ssaidi@eecs.umich.edu } 1173812Ssaidi@eecs.umich.edu ++sector; 1181070SN/A } 1193812Ssaidi@eecs.umich.edu 1203812Ssaidi@eecs.umich.edu return S_OK; 1211074SN/A 1223812Ssaidi@eecs.umich.edu} 1233812Ssaidi@eecs.umich.edu 1241074SN/Avoid 1253812Ssaidi@eecs.umich.eduVirtIOBlock::RequestQueue::onNotifyDescriptor(VirtDescriptor *desc) 1263812Ssaidi@eecs.umich.edu{ 1273812Ssaidi@eecs.umich.edu DPRINTF(VIOBlock, "Got input data descriptor (len: %i)\n", 1283812Ssaidi@eecs.umich.edu desc->size()); 1293812Ssaidi@eecs.umich.edu /* 1302378SN/A * Read the request structure and do endian conversion if 1312378SN/A * necessary. 1321070SN/A */ 133878SN/A BlkRequest req; 1342SN/A desc->chainRead(0, (uint8_t *)&req, sizeof(req)); 1352SN/A req.type = htov_legacy(req.type); 1362SN/A req.sector = htov_legacy(req.sector); 1372SN/A 1382378SN/A Status status; 1391070SN/A const size_t data_size(desc->chainSize() 1401070SN/A - sizeof(BlkRequest) - sizeof(Status)); 1412378SN/A 1422378SN/A switch (req.type) { 1432378SN/A case T_IN: 1442378SN/A status = parent.read(req, desc, sizeof(BlkRequest), data_size); 1452SN/A break; 1462SN/A 1471808SN/A case T_OUT: 1484095Sbinkertn@umich.edu status = parent.write(req, desc, sizeof(BlkRequest), data_size); 1491808SN/A break; 1502901Ssaidi@eecs.umich.edu 1514762Snate@binkert.org case T_FLUSH: 1522901Ssaidi@eecs.umich.edu status = S_OK; 1532901Ssaidi@eecs.umich.edu break; 1542901Ssaidi@eecs.umich.edu 1552901Ssaidi@eecs.umich.edu default: 1562901Ssaidi@eecs.umich.edu warn("Unsupported IO request: %i\n", req.type); 1573960Sgblack@eecs.umich.edu status = S_UNSUPP; 1583960Sgblack@eecs.umich.edu break; 1594095Sbinkertn@umich.edu } 1604095Sbinkertn@umich.edu 1614095Sbinkertn@umich.edu desc->chainWrite(sizeof(BlkRequest) + data_size, 1623960Sgblack@eecs.umich.edu &status, sizeof(status)); 1633960Sgblack@eecs.umich.edu 164180SN/A // Tell the guest that we are done with this descriptor. 1652680Sktlim@umich.edu produceDescriptor(desc, sizeof(BlkRequest) + data_size + sizeof(Status)); 1662SN/A parent.kick(); 1671806SN/A} 1682680Sktlim@umich.edu 1692680Sktlim@umich.eduVirtIOBlock * 1701806SN/AVirtIOBlockParams::create() 1711806SN/A{ 1721806SN/A return new VirtIOBlock(this); 1731806SN/A} 1742680Sktlim@umich.edu