mm_disk.cc revision 10905:a6ca6831e775
15615Sgblack@eecs.umich.edu/* 25615Sgblack@eecs.umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 35615Sgblack@eecs.umich.edu * All rights reserved. 47087Snate@binkert.org * 57087Snate@binkert.org * Redistribution and use in source and binary forms, with or without 67087Snate@binkert.org * modification, are permitted provided that the following conditions are 77087Snate@binkert.org * met: redistributions of source code must retain the above copyright 87087Snate@binkert.org * notice, this list of conditions and the following disclaimer; 97087Snate@binkert.org * redistributions in binary form must reproduce the above copyright 107087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 117087Snate@binkert.org * documentation and/or other materials provided with the distribution; 125615Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137087Snate@binkert.org * contributors may be used to endorse or promote products derived from 147087Snate@binkert.org * this software without specific prior written permission. 157087Snate@binkert.org * 167087Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177087Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187087Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197087Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207087Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215615Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227087Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235615Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245615Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255615Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265615Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275615Sgblack@eecs.umich.edu * 285615Sgblack@eecs.umich.edu * Authors: Ali Saidi 295615Sgblack@eecs.umich.edu */ 305615Sgblack@eecs.umich.edu 315615Sgblack@eecs.umich.edu/** @file 325615Sgblack@eecs.umich.edu * This device acts as a disk similar to the memory mapped disk device 335615Sgblack@eecs.umich.edu * in legion. Any access is translated to an offset in the disk image. 345615Sgblack@eecs.umich.edu */ 355615Sgblack@eecs.umich.edu 365615Sgblack@eecs.umich.edu#include <cstring> 375615Sgblack@eecs.umich.edu 385615Sgblack@eecs.umich.edu#include "base/trace.hh" 395615Sgblack@eecs.umich.edu#include "debug/IdeDisk.hh" 405615Sgblack@eecs.umich.edu#include "dev/sparc/mm_disk.hh" 415615Sgblack@eecs.umich.edu#include "dev/platform.hh" 425615Sgblack@eecs.umich.edu#include "mem/packet_access.hh" 435615Sgblack@eecs.umich.edu#include "mem/port.hh" 449338SAndreas.Sandberg@arm.com#include "sim/byteswap.hh" 455615Sgblack@eecs.umich.edu#include "sim/system.hh" 465615Sgblack@eecs.umich.edu 475615Sgblack@eecs.umich.eduMmDisk::MmDisk(const Params *p) 485615Sgblack@eecs.umich.edu : BasicPioDevice(p, p->image->size() * SectorSize), 495615Sgblack@eecs.umich.edu image(p->image), curSector((off_t)-1), dirty(false) 505615Sgblack@eecs.umich.edu{ 515615Sgblack@eecs.umich.edu std::memset(&diskData, 0, SectorSize); 525615Sgblack@eecs.umich.edu} 535615Sgblack@eecs.umich.edu 545615Sgblack@eecs.umich.eduTick 555615Sgblack@eecs.umich.eduMmDisk::read(PacketPtr pkt) 565615Sgblack@eecs.umich.edu{ 575615Sgblack@eecs.umich.edu Addr accessAddr; 585615Sgblack@eecs.umich.edu off_t sector; 595615Sgblack@eecs.umich.edu uint16_t d16; 605615Sgblack@eecs.umich.edu uint32_t d32; 615615Sgblack@eecs.umich.edu uint64_t d64; 625615Sgblack@eecs.umich.edu 635615Sgblack@eecs.umich.edu assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 645615Sgblack@eecs.umich.edu accessAddr = pkt->getAddr() - pioAddr; 655615Sgblack@eecs.umich.edu 665615Sgblack@eecs.umich.edu sector = accessAddr / SectorSize; 675615Sgblack@eecs.umich.edu 685615Sgblack@eecs.umich.edu if (sector != curSector) { 695615Sgblack@eecs.umich.edu if (dirty) { 705615Sgblack@eecs.umich.edu#ifndef NDEBUG 715615Sgblack@eecs.umich.edu off_t bytes_written = 725615Sgblack@eecs.umich.edu#endif 735615Sgblack@eecs.umich.edu image->write(diskData, curSector); 745615Sgblack@eecs.umich.edu assert(bytes_written == SectorSize); 755615Sgblack@eecs.umich.edu } 765615Sgblack@eecs.umich.edu#ifndef NDEBUG 775615Sgblack@eecs.umich.edu off_t bytes_read = 785615Sgblack@eecs.umich.edu#endif 795615Sgblack@eecs.umich.edu image->read(diskData, sector); 805615Sgblack@eecs.umich.edu assert(bytes_read == SectorSize); 815615Sgblack@eecs.umich.edu curSector = sector; 825615Sgblack@eecs.umich.edu } 835615Sgblack@eecs.umich.edu switch (pkt->getSize()) { 845615Sgblack@eecs.umich.edu case sizeof(uint8_t): 855615Sgblack@eecs.umich.edu pkt->set(diskData[accessAddr % SectorSize]); 865615Sgblack@eecs.umich.edu DPRINTF(IdeDisk, "reading byte %#x value= %#x\n", accessAddr, diskData[accessAddr % 875615Sgblack@eecs.umich.edu SectorSize]); 885615Sgblack@eecs.umich.edu break; 895615Sgblack@eecs.umich.edu case sizeof(uint16_t): 905615Sgblack@eecs.umich.edu memcpy(&d16, diskData + (accessAddr % SectorSize), 2); 915615Sgblack@eecs.umich.edu pkt->set(htobe(d16)); 925615Sgblack@eecs.umich.edu DPRINTF(IdeDisk, "reading word %#x value= %#x\n", accessAddr, d16); 935615Sgblack@eecs.umich.edu break; 945615Sgblack@eecs.umich.edu case sizeof(uint32_t): 955615Sgblack@eecs.umich.edu memcpy(&d32, diskData + (accessAddr % SectorSize), 4); 965615Sgblack@eecs.umich.edu pkt->set(htobe(d32)); 979338SAndreas.Sandberg@arm.com DPRINTF(IdeDisk, "reading dword %#x value= %#x\n", accessAddr, d32); 985615Sgblack@eecs.umich.edu break; 995615Sgblack@eecs.umich.edu case sizeof(uint64_t): 1005615Sgblack@eecs.umich.edu memcpy(&d64, diskData + (accessAddr % SectorSize), 8); 1015615Sgblack@eecs.umich.edu pkt->set(htobe(d64)); 1025615Sgblack@eecs.umich.edu DPRINTF(IdeDisk, "reading qword %#x value= %#x\n", accessAddr, d64); 1035615Sgblack@eecs.umich.edu break; 1045615Sgblack@eecs.umich.edu default: 1055615Sgblack@eecs.umich.edu panic("Invalid access size\n"); 1065615Sgblack@eecs.umich.edu } 1075615Sgblack@eecs.umich.edu 1085615Sgblack@eecs.umich.edu pkt->makeAtomicResponse(); 1095615Sgblack@eecs.umich.edu return pioDelay; 1105615Sgblack@eecs.umich.edu} 1115615Sgblack@eecs.umich.edu 1125615Sgblack@eecs.umich.eduTick 1135615Sgblack@eecs.umich.eduMmDisk::write(PacketPtr pkt) 1145615Sgblack@eecs.umich.edu{ 1155615Sgblack@eecs.umich.edu Addr accessAddr; 1165615Sgblack@eecs.umich.edu off_t sector; 1175615Sgblack@eecs.umich.edu uint16_t d16; 1185615Sgblack@eecs.umich.edu uint32_t d32; 1195615Sgblack@eecs.umich.edu uint64_t d64; 1209338SAndreas.Sandberg@arm.com 1215615Sgblack@eecs.umich.edu assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 1225615Sgblack@eecs.umich.edu accessAddr = pkt->getAddr() - pioAddr; 1235615Sgblack@eecs.umich.edu 1245615Sgblack@eecs.umich.edu sector = accessAddr / SectorSize; 1255615Sgblack@eecs.umich.edu 126 if (sector != curSector) { 127 if (dirty) { 128#ifndef NDEBUG 129 off_t bytes_written = 130#endif 131 image->write(diskData, curSector); 132 assert(bytes_written == SectorSize); 133 } 134#ifndef NDEBUG 135 off_t bytes_read = 136#endif 137 image->read(diskData, sector); 138 assert(bytes_read == SectorSize); 139 curSector = sector; 140 } 141 dirty = true; 142 143 switch (pkt->getSize()) { 144 case sizeof(uint8_t): 145 diskData[accessAddr % SectorSize] = htobe(pkt->get<uint8_t>()); 146 DPRINTF(IdeDisk, "writing byte %#x value= %#x\n", accessAddr, diskData[accessAddr % 147 SectorSize]); 148 break; 149 case sizeof(uint16_t): 150 d16 = htobe(pkt->get<uint16_t>()); 151 memcpy(diskData + (accessAddr % SectorSize), &d16, 2); 152 DPRINTF(IdeDisk, "writing word %#x value= %#x\n", accessAddr, d16); 153 break; 154 case sizeof(uint32_t): 155 d32 = htobe(pkt->get<uint32_t>()); 156 memcpy(diskData + (accessAddr % SectorSize), &d32, 4); 157 DPRINTF(IdeDisk, "writing dword %#x value= %#x\n", accessAddr, d32); 158 break; 159 case sizeof(uint64_t): 160 d64 = htobe(pkt->get<uint64_t>()); 161 memcpy(diskData + (accessAddr % SectorSize), &d64, 8); 162 DPRINTF(IdeDisk, "writing qword %#x value= %#x\n", accessAddr, d64); 163 break; 164 default: 165 panic("Invalid access size\n"); 166 } 167 168 pkt->makeAtomicResponse(); 169 return pioDelay; 170} 171 172void 173MmDisk::serialize(CheckpointOut &cp) const 174{ 175 // just write any dirty changes to the cow layer it will take care of 176 // serialization 177 if (dirty) { 178#ifndef NDEBUG 179 int bytes_read = 180#endif 181 image->write(diskData, curSector); 182 assert(bytes_read == SectorSize); 183 } 184} 185 186MmDisk * 187MmDiskParams::create() 188{ 189 return new MmDisk(this); 190} 191