disk_image.cc revision 9637
16019Shines@cs.fsu.edu/* 212495Sgiacomo.travaglini@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 37111Sgblack@eecs.umich.edu * All rights reserved. 47111Sgblack@eecs.umich.edu * 57111Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67111Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77111Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87111Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97111Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107111Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117111Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127111Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137111Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 146019Shines@cs.fsu.edu * this software without specific prior written permission. 156019Shines@cs.fsu.edu * 166019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276019Shines@cs.fsu.edu * 286019Shines@cs.fsu.edu * Authors: Nathan Binkert 296019Shines@cs.fsu.edu */ 306019Shines@cs.fsu.edu 316019Shines@cs.fsu.edu/** @file 326019Shines@cs.fsu.edu * Disk Image Definitions 336019Shines@cs.fsu.edu */ 346019Shines@cs.fsu.edu 356019Shines@cs.fsu.edu#include <sys/types.h> 366019Shines@cs.fsu.edu#include <sys/uio.h> 376019Shines@cs.fsu.edu#include <unistd.h> 386019Shines@cs.fsu.edu 396019Shines@cs.fsu.edu#include <cerrno> 406019Shines@cs.fsu.edu#include <cstring> 416019Shines@cs.fsu.edu#include <fstream> 426019Shines@cs.fsu.edu#include <string> 436019Shines@cs.fsu.edu 446019Shines@cs.fsu.edu#include "base/callback.hh" 456019Shines@cs.fsu.edu#include "base/misc.hh" 466019Shines@cs.fsu.edu#include "base/trace.hh" 476019Shines@cs.fsu.edu#include "debug/DiskImageRead.hh" 487692SAli.Saidi@ARM.com#include "debug/DiskImageWrite.hh" 496242Sgblack@eecs.umich.edu#include "dev/disk_image.hh" 506019Shines@cs.fsu.edu#include "sim/byteswap.hh" 5112334Sgabeblack@google.com#include "sim/sim_exit.hh" 527408Sgblack@eecs.umich.edu 536216Snate@binkert.orgusing namespace std; 547720Sgblack@eecs.umich.edu 556019Shines@cs.fsu.edu//////////////////////////////////////////////////////////////////////// 566019Shines@cs.fsu.edu// 5710037SARM gem5 Developers// Raw Disk image 5810037SARM gem5 Developers// 596019Shines@cs.fsu.eduRawDiskImage::RawDiskImage(const Params* p) 606019Shines@cs.fsu.edu : DiskImage(p), disk_size(0) 617751SAli.Saidi@ARM.com{ open(p->image_file, p->read_only); } 627751SAli.Saidi@ARM.com 637751SAli.Saidi@ARM.comRawDiskImage::~RawDiskImage() 647751SAli.Saidi@ARM.com{ close(); } 657751SAli.Saidi@ARM.com 667751SAli.Saidi@ARM.comvoid 677751SAli.Saidi@ARM.comRawDiskImage::open(const string &filename, bool rd_only) 687751SAli.Saidi@ARM.com{ 697751SAli.Saidi@ARM.com if (!filename.empty()) { 708303SAli.Saidi@ARM.com initialized = true; 717751SAli.Saidi@ARM.com readonly = rd_only; 728303SAli.Saidi@ARM.com file = filename; 738303SAli.Saidi@ARM.com 748303SAli.Saidi@ARM.com ios::openmode mode = ios::in | ios::binary; 757751SAli.Saidi@ARM.com if (!readonly) 767720Sgblack@eecs.umich.edu mode |= ios::out; 778303SAli.Saidi@ARM.com stream.open(file.c_str(), mode); 788303SAli.Saidi@ARM.com if (!stream.is_open()) 798303SAli.Saidi@ARM.com panic("Error opening %s", filename); 808303SAli.Saidi@ARM.com } 818303SAli.Saidi@ARM.com} 828303SAli.Saidi@ARM.com 838303SAli.Saidi@ARM.comvoid 848303SAli.Saidi@ARM.comRawDiskImage::close() 858303SAli.Saidi@ARM.com{ 868303SAli.Saidi@ARM.com stream.close(); 878303SAli.Saidi@ARM.com} 888303SAli.Saidi@ARM.com 898303SAli.Saidi@ARM.comstd::streampos 908303SAli.Saidi@ARM.comRawDiskImage::size() const 917751SAli.Saidi@ARM.com{ 927751SAli.Saidi@ARM.com if (disk_size == 0) { 937751SAli.Saidi@ARM.com if (!stream.is_open()) 947751SAli.Saidi@ARM.com panic("file not open!\n"); 957720Sgblack@eecs.umich.edu stream.seekg(0, ios::end); 967751SAli.Saidi@ARM.com disk_size = stream.tellg(); 977720Sgblack@eecs.umich.edu } 987751SAli.Saidi@ARM.com 997751SAli.Saidi@ARM.com return disk_size / SectorSize; 1007751SAli.Saidi@ARM.com} 1017751SAli.Saidi@ARM.com 1027751SAli.Saidi@ARM.comstd::streampos 1037751SAli.Saidi@ARM.comRawDiskImage::read(uint8_t *data, std::streampos offset) const 1046242Sgblack@eecs.umich.edu{ 1057751SAli.Saidi@ARM.com if (!initialized) 1067751SAli.Saidi@ARM.com panic("RawDiskImage not initialized"); 10710407Smitch.hayenga@arm.com 1087751SAli.Saidi@ARM.com if (!stream.is_open()) 1096019Shines@cs.fsu.edu panic("file not open!\n"); 1107751SAli.Saidi@ARM.com 1116246Sgblack@eecs.umich.edu stream.seekg(offset * SectorSize, ios::beg); 1127751SAli.Saidi@ARM.com if (!stream.good()) 1137751SAli.Saidi@ARM.com panic("Could not seek to location in file"); 1147751SAli.Saidi@ARM.com 1157751SAli.Saidi@ARM.com streampos pos = stream.tellg(); 1167751SAli.Saidi@ARM.com stream.read((char *)data, SectorSize); 1176329Sgblack@eecs.umich.edu 1187751SAli.Saidi@ARM.com DPRINTF(DiskImageRead, "read: offset=%d\n", (uint64_t)offset); 1196757SAli.Saidi@ARM.com DDUMP(DiskImageRead, data, SectorSize); 1207751SAli.Saidi@ARM.com 1217751SAli.Saidi@ARM.com return stream.tellg() - pos; 1227751SAli.Saidi@ARM.com} 12310037SARM gem5 Developers 1247751SAli.Saidi@ARM.comstd::streampos 1257638Sgblack@eecs.umich.eduRawDiskImage::write(const uint8_t *data, std::streampos offset) 1267751SAli.Saidi@ARM.com{ 1277751SAli.Saidi@ARM.com if (!initialized) 1287751SAli.Saidi@ARM.com panic("RawDiskImage not initialized"); 1297751SAli.Saidi@ARM.com 1307751SAli.Saidi@ARM.com if (readonly) 1317638Sgblack@eecs.umich.edu panic("Cannot write to a read only disk image"); 1327751SAli.Saidi@ARM.com 1337751SAli.Saidi@ARM.com if (!stream.is_open()) 1347751SAli.Saidi@ARM.com panic("file not open!\n"); 1357751SAli.Saidi@ARM.com 1367751SAli.Saidi@ARM.com stream.seekp(offset * SectorSize, ios::beg); 1377638Sgblack@eecs.umich.edu if (!stream.good()) 1387751SAli.Saidi@ARM.com panic("Could not seek to location in file"); 1397751SAli.Saidi@ARM.com 1407751SAli.Saidi@ARM.com DPRINTF(DiskImageWrite, "write: offset=%d\n", (uint64_t)offset); 1417751SAli.Saidi@ARM.com DDUMP(DiskImageWrite, data, SectorSize); 1427751SAli.Saidi@ARM.com 1436757SAli.Saidi@ARM.com streampos pos = stream.tellp(); 14410037SARM gem5 Developers stream.write((const char *)data, SectorSize); 14510037SARM gem5 Developers return stream.tellp() - pos; 14610037SARM gem5 Developers} 14710037SARM gem5 Developers 1487751SAli.Saidi@ARM.comRawDiskImage * 14910037SARM gem5 DevelopersRawDiskImageParams::create() 15010037SARM gem5 Developers{ 1517751SAli.Saidi@ARM.com return new RawDiskImage(this); 1527640Sgblack@eecs.umich.edu} 15310037SARM gem5 Developers 15410037SARM gem5 Developers//////////////////////////////////////////////////////////////////////// 1557751SAli.Saidi@ARM.com// 15610037SARM gem5 Developers// Copy on Write Disk image 15710037SARM gem5 Developers// 1587751SAli.Saidi@ARM.comconst uint32_t CowDiskImage::VersionMajor = 1; 1597640Sgblack@eecs.umich.educonst uint32_t CowDiskImage::VersionMinor = 0; 16012496Sgiacomo.travaglini@arm.com 16112496Sgiacomo.travaglini@arm.comclass CowDiskCallback : public Callback 16212496Sgiacomo.travaglini@arm.com{ 16312496Sgiacomo.travaglini@arm.com private: 16412496Sgiacomo.travaglini@arm.com CowDiskImage *image; 16512496Sgiacomo.travaglini@arm.com 16612496Sgiacomo.travaglini@arm.com public: 16712496Sgiacomo.travaglini@arm.com CowDiskCallback(CowDiskImage *i) : image(i) {} 16812496Sgiacomo.travaglini@arm.com void process() { image->save(); delete this; } 16912496Sgiacomo.travaglini@arm.com}; 17012496Sgiacomo.travaglini@arm.com 17112496Sgiacomo.travaglini@arm.comCowDiskImage::CowDiskImage(const Params *p) 17212496Sgiacomo.travaglini@arm.com : DiskImage(p), filename(p->image_file), child(p->child), table(NULL) 17312496Sgiacomo.travaglini@arm.com{ 17412496Sgiacomo.travaglini@arm.com if (filename.empty()) { 17512496Sgiacomo.travaglini@arm.com initSectorTable(p->table_size); 17612496Sgiacomo.travaglini@arm.com } else { 17712496Sgiacomo.travaglini@arm.com if (!open(filename)) { 17812494Schuan.zhu@arm.com if (p->read_only) 17912494Schuan.zhu@arm.com fatal("could not open read-only file"); 18010037SARM gem5 Developers initSectorTable(p->table_size); 18110037SARM gem5 Developers } 18213759Sgiacomo.gabrielli@arm.com 18313759Sgiacomo.gabrielli@arm.com if (!p->read_only) 18413759Sgiacomo.gabrielli@arm.com registerExitCallback(new CowDiskCallback(this)); 18513759Sgiacomo.gabrielli@arm.com } 18613759Sgiacomo.gabrielli@arm.com} 18713759Sgiacomo.gabrielli@arm.com 18810037SARM gem5 DevelopersCowDiskImage::~CowDiskImage() 18910037SARM gem5 Developers{ 19012788Sgiacomo.travaglini@arm.com SectorTable::iterator i = table->begin(); 19112788Sgiacomo.travaglini@arm.com SectorTable::iterator end = table->end(); 19212788Sgiacomo.travaglini@arm.com 19312788Sgiacomo.travaglini@arm.com while (i != end) { 19412788Sgiacomo.travaglini@arm.com delete (*i).second; 19512788Sgiacomo.travaglini@arm.com ++i; 19612788Sgiacomo.travaglini@arm.com } 19712788Sgiacomo.travaglini@arm.com} 19812788Sgiacomo.travaglini@arm.com 19912788Sgiacomo.travaglini@arm.comvoid 20012788Sgiacomo.travaglini@arm.comSafeRead(ifstream &stream, void *data, int count) 20112788Sgiacomo.travaglini@arm.com{ 20212788Sgiacomo.travaglini@arm.com stream.read((char *)data, count); 20312788Sgiacomo.travaglini@arm.com if (!stream.is_open()) 20412788Sgiacomo.travaglini@arm.com panic("file not open"); 20512788Sgiacomo.travaglini@arm.com 20612788Sgiacomo.travaglini@arm.com if (stream.eof()) 20712788Sgiacomo.travaglini@arm.com panic("premature end-of-file"); 20812788Sgiacomo.travaglini@arm.com 20912788Sgiacomo.travaglini@arm.com if (stream.bad() || stream.fail()) 21011514Sandreas.sandberg@arm.com panic("error reading cowdisk image"); 21111514Sandreas.sandberg@arm.com} 21211514Sandreas.sandberg@arm.com 21311514Sandreas.sandberg@arm.comtemplate<class T> 21411514Sandreas.sandberg@arm.comvoid 21511514Sandreas.sandberg@arm.comSafeRead(ifstream &stream, T &data) 21611514Sandreas.sandberg@arm.com{ 21711514Sandreas.sandberg@arm.com SafeRead(stream, &data, sizeof(data)); 21811514Sandreas.sandberg@arm.com} 21911514Sandreas.sandberg@arm.com 22010037SARM gem5 Developerstemplate<class T> 22110037SARM gem5 Developersvoid 22210037SARM gem5 DevelopersSafeReadSwap(ifstream &stream, T &data) 22310037SARM gem5 Developers{ 22410037SARM gem5 Developers SafeRead(stream, &data, sizeof(data)); 22510037SARM gem5 Developers data = letoh(data); //is this the proper byte order conversion? 22610037SARM gem5 Developers} 22710854SNathanael.Premillieu@arm.com 22810854SNathanael.Premillieu@arm.combool 22910037SARM gem5 DevelopersCowDiskImage::open(const string &file) 23010037SARM gem5 Developers{ 2317751SAli.Saidi@ARM.com ifstream stream(file.c_str()); 23210037SARM gem5 Developers if (!stream.is_open()) 2337751SAli.Saidi@ARM.com return false; 23410037SARM gem5 Developers 23510037SARM gem5 Developers if (stream.fail() || stream.bad()) 23610037SARM gem5 Developers panic("Error opening %s", file); 23710037SARM gem5 Developers 23810037SARM gem5 Developers uint64_t magic; 23910037SARM gem5 Developers SafeRead(stream, magic); 24010037SARM gem5 Developers 24110037SARM gem5 Developers if (memcmp(&magic, "COWDISK!", sizeof(magic)) != 0) 24210037SARM gem5 Developers panic("Could not open %s: Invalid magic", file); 24310037SARM gem5 Developers 24410037SARM gem5 Developers uint32_t major, minor; 24510037SARM gem5 Developers SafeReadSwap(stream, major); 2467751SAli.Saidi@ARM.com SafeReadSwap(stream, minor); 2477640Sgblack@eecs.umich.edu 24812495Sgiacomo.travaglini@arm.com if (major != VersionMajor && minor != VersionMinor) 24912495Sgiacomo.travaglini@arm.com panic("Could not open %s: invalid version %d.%d != %d.%d", 25012495Sgiacomo.travaglini@arm.com file, major, minor, VersionMajor, VersionMinor); 25112495Sgiacomo.travaglini@arm.com 25212495Sgiacomo.travaglini@arm.com uint64_t sector_count; 25312495Sgiacomo.travaglini@arm.com SafeReadSwap(stream, sector_count); 25412495Sgiacomo.travaglini@arm.com table = new SectorTable(sector_count); 25512495Sgiacomo.travaglini@arm.com 25612495Sgiacomo.travaglini@arm.com 25710037SARM gem5 Developers for (uint64_t i = 0; i < sector_count; i++) { 25810037SARM gem5 Developers uint64_t offset; 25913550Sgiacomo.travaglini@arm.com SafeReadSwap(stream, offset); 26013550Sgiacomo.travaglini@arm.com 26113550Sgiacomo.travaglini@arm.com Sector *sector = new Sector; 26213585Sgabeblack@google.com SafeRead(stream, sector, sizeof(Sector)); 26313550Sgiacomo.travaglini@arm.com 26413550Sgiacomo.travaglini@arm.com assert(table->find(offset) == table->end()); 26513585Sgabeblack@google.com (*table)[offset] = sector; 26610037SARM gem5 Developers } 26710037SARM gem5 Developers 26810037SARM gem5 Developers stream.close(); 26910037SARM gem5 Developers 27010037SARM gem5 Developers initialized = true; 27110037SARM gem5 Developers return true; 27210037SARM gem5 Developers} 27310037SARM gem5 Developers 27410037SARM gem5 Developersvoid 27510037SARM gem5 DevelopersCowDiskImage::initSectorTable(int hash_size) 27610037SARM gem5 Developers{ 27710037SARM gem5 Developers table = new SectorTable(hash_size); 27810037SARM gem5 Developers 27910037SARM gem5 Developers initialized = true; 28010037SARM gem5 Developers} 28110037SARM gem5 Developers 28210037SARM gem5 Developersvoid 28310037SARM gem5 DevelopersSafeWrite(ofstream &stream, const void *data, int count) 28410037SARM gem5 Developers{ 28510037SARM gem5 Developers stream.write((const char *)data, count); 28610037SARM gem5 Developers if (!stream.is_open()) 28710037SARM gem5 Developers panic("file not open"); 28810037SARM gem5 Developers 28910037SARM gem5 Developers if (stream.eof()) 29010037SARM gem5 Developers panic("premature end-of-file"); 29110037SARM gem5 Developers 29210037SARM gem5 Developers if (stream.bad() || stream.fail()) 29310037SARM gem5 Developers panic("error reading cowdisk image"); 29410037SARM gem5 Developers} 29510037SARM gem5 Developers 29610037SARM gem5 Developerstemplate<class T> 29710037SARM gem5 Developersvoid 29810037SARM gem5 DevelopersSafeWrite(ofstream &stream, const T &data) 29910037SARM gem5 Developers{ 30010037SARM gem5 Developers SafeWrite(stream, &data, sizeof(data)); 30110037SARM gem5 Developers} 30210037SARM gem5 Developers 30310037SARM gem5 Developerstemplate<class T> 30410037SARM gem5 Developersvoid 30510037SARM gem5 DevelopersSafeWriteSwap(ofstream &stream, const T &data) 30610037SARM gem5 Developers{ 30710037SARM gem5 Developers T swappeddata = letoh(data); //is this the proper byte order conversion? 30810037SARM gem5 Developers SafeWrite(stream, &swappeddata, sizeof(data)); 30910037SARM gem5 Developers} 31010037SARM gem5 Developersvoid 31110037SARM gem5 DevelopersCowDiskImage::save() 31210037SARM gem5 Developers{ 31310037SARM gem5 Developers save(filename); 31410037SARM gem5 Developers} 31510037SARM gem5 Developers 31613999Sgiacomo.travaglini@arm.comvoid 31713999Sgiacomo.travaglini@arm.comCowDiskImage::save(const string &file) 31810037SARM gem5 Developers{ 31910037SARM gem5 Developers if (!initialized) 32010037SARM gem5 Developers panic("RawDiskImage not initialized"); 32110037SARM gem5 Developers 32210037SARM gem5 Developers ofstream stream(file.c_str()); 32310037SARM gem5 Developers if (!stream.is_open() || stream.fail() || stream.bad()) 32410037SARM gem5 Developers panic("Error opening %s", file); 32510037SARM gem5 Developers 32610037SARM gem5 Developers uint64_t magic; 3277707Sgblack@eecs.umich.edu memcpy(&magic, "COWDISK!", sizeof(magic)); 3286757SAli.Saidi@ARM.com SafeWrite(stream, magic); 3297693SAli.Saidi@ARM.com 3307693SAli.Saidi@ARM.com SafeWriteSwap(stream, (uint32_t)VersionMajor); 3317720Sgblack@eecs.umich.edu SafeWriteSwap(stream, (uint32_t)VersionMinor); 33210417Sandreas.hansson@arm.com SafeWriteSwap(stream, (uint64_t)table->size()); 3337720Sgblack@eecs.umich.edu 3347720Sgblack@eecs.umich.edu uint64_t size = table->size(); 3357720Sgblack@eecs.umich.edu SectorTable::iterator iter = table->begin(); 3367720Sgblack@eecs.umich.edu SectorTable::iterator end = table->end(); 3377752SWilliam.Wang@arm.com 3387752SWilliam.Wang@arm.com for (uint64_t i = 0; i < size; i++) { 3397752SWilliam.Wang@arm.com if (iter == end) 3408300Schander.sudanthi@arm.com panic("Incorrect Table Size during save of COW disk image"); 3418300Schander.sudanthi@arm.com 3428300Schander.sudanthi@arm.com SafeWriteSwap(stream, (uint64_t)(*iter).first); 3438300Schander.sudanthi@arm.com SafeWrite(stream, (*iter).second->data, sizeof(Sector)); 3448300Schander.sudanthi@arm.com ++iter; 3458300Schander.sudanthi@arm.com } 34610037SARM gem5 Developers 34710037SARM gem5 Developers stream.close(); 34810037SARM gem5 Developers} 34910037SARM gem5 Developers 35010037SARM gem5 Developersvoid 35110037SARM gem5 DevelopersCowDiskImage::writeback() 35210037SARM gem5 Developers{ 35310037SARM gem5 Developers SectorTable::iterator i = table->begin(); 35410037SARM gem5 Developers SectorTable::iterator end = table->end(); 35510037SARM gem5 Developers 35610037SARM gem5 Developers while (i != end) { 35710037SARM gem5 Developers child->write((*i).second->data, (*i).first); 35810037SARM gem5 Developers ++i; 35910037SARM gem5 Developers } 36010037SARM gem5 Developers} 36110037SARM gem5 Developers 36210037SARM gem5 Developersstd::streampos 36310037SARM gem5 DevelopersCowDiskImage::size() const 36410037SARM gem5 Developers{ return child->size(); } 36510037SARM gem5 Developers 36610037SARM gem5 Developersstd::streampos 36710037SARM gem5 DevelopersCowDiskImage::read(uint8_t *data, std::streampos offset) const 36810037SARM gem5 Developers{ 36910037SARM gem5 Developers if (!initialized) 37010037SARM gem5 Developers panic("CowDiskImage not initialized"); 37110037SARM gem5 Developers 37210037SARM gem5 Developers if (offset > size()) 37310037SARM gem5 Developers panic("access out of bounds"); 37410037SARM gem5 Developers 37510037SARM gem5 Developers SectorTable::const_iterator i = table->find(offset); 37612526Schuan.zhu@arm.com if (i == table->end()) 37712526Schuan.zhu@arm.com return child->read(data, offset); 37812526Schuan.zhu@arm.com else { 37912526Schuan.zhu@arm.com memcpy(data, (*i).second->data, SectorSize); 38012526Schuan.zhu@arm.com DPRINTF(DiskImageRead, "read: offset=%d\n", (uint64_t)offset); 3818902Sandreas.hansson@arm.com DDUMP(DiskImageRead, data, SectorSize); 3826019Shines@cs.fsu.edu return SectorSize; 3836019Shines@cs.fsu.edu } 384} 385 386std::streampos 387CowDiskImage::write(const uint8_t *data, std::streampos offset) 388{ 389 if (!initialized) 390 panic("RawDiskImage not initialized"); 391 392 if (offset > size()) 393 panic("access out of bounds"); 394 395 SectorTable::iterator i = table->find(offset); 396 if (i == table->end()) { 397 Sector *sector = new Sector; 398 memcpy(sector, data, SectorSize); 399 table->insert(make_pair(offset, sector)); 400 } else { 401 memcpy((*i).second->data, data, SectorSize); 402 } 403 404 DPRINTF(DiskImageWrite, "write: offset=%d\n", (uint64_t)offset); 405 DDUMP(DiskImageWrite, data, SectorSize); 406 407 return SectorSize; 408} 409 410void 411CowDiskImage::serialize(ostream &os) 412{ 413 string cowFilename = name() + ".cow"; 414 SERIALIZE_SCALAR(cowFilename); 415 save(Checkpoint::dir() + "/" + cowFilename); 416} 417 418void 419CowDiskImage::unserialize(Checkpoint *cp, const string §ion) 420{ 421 string cowFilename; 422 UNSERIALIZE_SCALAR(cowFilename); 423 cowFilename = cp->cptDir + "/" + cowFilename; 424 open(cowFilename); 425} 426 427CowDiskImage * 428CowDiskImageParams::create() 429{ 430 return new CowDiskImage(this); 431} 432