disk_image.cc revision 8232
111988Sandreas.sandberg@arm.com/* 28839Sandreas.hansson@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 38839Sandreas.hansson@arm.com * All rights reserved. 48839Sandreas.hansson@arm.com * 58839Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68839Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 78839Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 88839Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 98839Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 108839Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 118839Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 128839Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 133101Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from 148579Ssteve.reinhardt@amd.com * this software without specific prior written permission. 153101Sstever@eecs.umich.edu * 163101Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173101Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183101Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193101Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203101Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213101Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223101Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233101Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243101Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253101Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263101Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273101Sstever@eecs.umich.edu * 283101Sstever@eecs.umich.edu * Authors: Nathan Binkert 293101Sstever@eecs.umich.edu */ 303101Sstever@eecs.umich.edu 313101Sstever@eecs.umich.edu/** @file 323101Sstever@eecs.umich.edu * Disk Image Definitions 333101Sstever@eecs.umich.edu */ 343101Sstever@eecs.umich.edu 353101Sstever@eecs.umich.edu#include <sys/types.h> 363101Sstever@eecs.umich.edu#include <sys/uio.h> 373101Sstever@eecs.umich.edu#include <unistd.h> 383101Sstever@eecs.umich.edu 393101Sstever@eecs.umich.edu#include <cerrno> 403101Sstever@eecs.umich.edu#include <cstring> 413101Sstever@eecs.umich.edu#include <fstream> 427778Sgblack@eecs.umich.edu#include <string> 438839Sandreas.hansson@arm.com 443101Sstever@eecs.umich.edu#include "base/callback.hh" 453101Sstever@eecs.umich.edu#include "base/misc.hh" 463101Sstever@eecs.umich.edu#include "base/trace.hh" 473101Sstever@eecs.umich.edu#include "debug/DiskImageRead.hh" 483101Sstever@eecs.umich.edu#include "debug/DiskImageWrite.hh" 493101Sstever@eecs.umich.edu#include "dev/disk_image.hh" 503101Sstever@eecs.umich.edu#include "sim/byteswap.hh" 513101Sstever@eecs.umich.edu#include "sim/sim_exit.hh" 523101Sstever@eecs.umich.edu 533101Sstever@eecs.umich.eduusing namespace std; 543101Sstever@eecs.umich.edu 553101Sstever@eecs.umich.edu//////////////////////////////////////////////////////////////////////// 563101Sstever@eecs.umich.edu// 573101Sstever@eecs.umich.edu// Raw Disk image 583101Sstever@eecs.umich.edu// 593101Sstever@eecs.umich.eduRawDiskImage::RawDiskImage(const Params* p) 603101Sstever@eecs.umich.edu : DiskImage(p), disk_size(0) 613101Sstever@eecs.umich.edu{ open(p->image_file, p->read_only); } 6212563Sgabeblack@google.com 6312563Sgabeblack@google.comRawDiskImage::~RawDiskImage() 643885Sbinkertn@umich.edu{ close(); } 653885Sbinkertn@umich.edu 664762Snate@binkert.orgvoid 673885Sbinkertn@umich.eduRawDiskImage::open(const string &filename, bool rd_only) 683885Sbinkertn@umich.edu{ 697528Ssteve.reinhardt@amd.com if (!filename.empty()) { 703885Sbinkertn@umich.edu initialized = true; 714380Sbinkertn@umich.edu readonly = rd_only; 724167Sbinkertn@umich.edu file = filename; 733102Sstever@eecs.umich.edu 743101Sstever@eecs.umich.edu ios::openmode mode = ios::in | ios::binary; 754762Snate@binkert.org if (!readonly) 764762Snate@binkert.org mode |= ios::out; 774762Snate@binkert.org stream.open(file.c_str(), mode); 784762Snate@binkert.org if (!stream.is_open()) 794762Snate@binkert.org panic("Error opening %s", filename); 804762Snate@binkert.org } 814762Snate@binkert.org} 824762Snate@binkert.org 834762Snate@binkert.orgvoid 845033Smilesck@eecs.umich.eduRawDiskImage::close() 855033Smilesck@eecs.umich.edu{ 865033Smilesck@eecs.umich.edu stream.close(); 875033Smilesck@eecs.umich.edu} 885033Smilesck@eecs.umich.edu 895033Smilesck@eecs.umich.eduoff_t 905033Smilesck@eecs.umich.eduRawDiskImage::size() const 915033Smilesck@eecs.umich.edu{ 925033Smilesck@eecs.umich.edu if (disk_size == 0) { 935033Smilesck@eecs.umich.edu if (!stream.is_open()) 943101Sstever@eecs.umich.edu panic("file not open!\n"); 953101Sstever@eecs.umich.edu stream.seekg(0, ios::end); 963101Sstever@eecs.umich.edu disk_size = stream.tellg(); 975033Smilesck@eecs.umich.edu } 9810267SGeoffrey.Blake@arm.com 998596Ssteve.reinhardt@amd.com return disk_size / SectorSize; 1008596Ssteve.reinhardt@amd.com} 1018596Ssteve.reinhardt@amd.com 1028596Ssteve.reinhardt@amd.comoff_t 1037673Snate@binkert.orgRawDiskImage::read(uint8_t *data, off_t offset) const 1047673Snate@binkert.org{ 1057673Snate@binkert.org if (!initialized) 1067673Snate@binkert.org panic("RawDiskImage not initialized"); 10711988Sandreas.sandberg@arm.com 10811988Sandreas.sandberg@arm.com if (!stream.is_open()) 10911988Sandreas.sandberg@arm.com panic("file not open!\n"); 11011988Sandreas.sandberg@arm.com 1113101Sstever@eecs.umich.edu if (stream.seekg(offset * SectorSize, ios::beg) < 0) 1123101Sstever@eecs.umich.edu panic("Could not seek to location in file"); 1133101Sstever@eecs.umich.edu 1143101Sstever@eecs.umich.edu streampos pos = stream.tellg(); 1153101Sstever@eecs.umich.edu stream.read((char *)data, SectorSize); 11610380SAndrew.Bardsley@arm.com 11710380SAndrew.Bardsley@arm.com DPRINTF(DiskImageRead, "read: offset=%d\n", (uint64_t)offset); 11810380SAndrew.Bardsley@arm.com DDUMP(DiskImageRead, data, SectorSize); 11910380SAndrew.Bardsley@arm.com 12010380SAndrew.Bardsley@arm.com return stream.tellg() - pos; 12110380SAndrew.Bardsley@arm.com} 12210458Sandreas.hansson@arm.com 12310458Sandreas.hansson@arm.comoff_t 12410458Sandreas.hansson@arm.comRawDiskImage::write(const uint8_t *data, off_t offset) 12510458Sandreas.hansson@arm.com{ 12610458Sandreas.hansson@arm.com if (!initialized) 12710458Sandreas.hansson@arm.com panic("RawDiskImage not initialized"); 12810458Sandreas.hansson@arm.com 12910458Sandreas.hansson@arm.com if (readonly) 13010458Sandreas.hansson@arm.com panic("Cannot write to a read only disk image"); 13110458Sandreas.hansson@arm.com 13210458Sandreas.hansson@arm.com if (!stream.is_open()) 13310458Sandreas.hansson@arm.com panic("file not open!\n"); 1343101Sstever@eecs.umich.edu 1353101Sstever@eecs.umich.edu if (stream.seekp(offset * SectorSize, ios::beg) < 0) 1363101Sstever@eecs.umich.edu panic("Could not seek to location in file"); 1373101Sstever@eecs.umich.edu 1383101Sstever@eecs.umich.edu DPRINTF(DiskImageWrite, "write: offset=%d\n", (uint64_t)offset); 13910267SGeoffrey.Blake@arm.com DDUMP(DiskImageWrite, data, SectorSize); 14010267SGeoffrey.Blake@arm.com 14110267SGeoffrey.Blake@arm.com streampos pos = stream.tellp(); 14210267SGeoffrey.Blake@arm.com stream.write((const char *)data, SectorSize); 1433101Sstever@eecs.umich.edu return stream.tellp() - pos; 1443101Sstever@eecs.umich.edu} 1453101Sstever@eecs.umich.edu 1463101Sstever@eecs.umich.eduRawDiskImage * 1473101Sstever@eecs.umich.eduRawDiskImageParams::create() 1483101Sstever@eecs.umich.edu{ 1493101Sstever@eecs.umich.edu return new RawDiskImage(this); 1503101Sstever@eecs.umich.edu} 1513101Sstever@eecs.umich.edu 1523101Sstever@eecs.umich.edu//////////////////////////////////////////////////////////////////////// 1533101Sstever@eecs.umich.edu// 1543101Sstever@eecs.umich.edu// Copy on Write Disk image 1553101Sstever@eecs.umich.edu// 1563101Sstever@eecs.umich.educonst uint32_t CowDiskImage::VersionMajor = 1; 1573101Sstever@eecs.umich.educonst uint32_t CowDiskImage::VersionMinor = 0; 1583101Sstever@eecs.umich.edu 1593101Sstever@eecs.umich.educlass CowDiskCallback : public Callback 1603101Sstever@eecs.umich.edu{ 1613101Sstever@eecs.umich.edu private: 1623101Sstever@eecs.umich.edu CowDiskImage *image; 1633101Sstever@eecs.umich.edu 1643101Sstever@eecs.umich.edu public: 1653101Sstever@eecs.umich.edu CowDiskCallback(CowDiskImage *i) : image(i) {} 1663101Sstever@eecs.umich.edu void process() { image->save(); delete this; } 1673101Sstever@eecs.umich.edu}; 1683101Sstever@eecs.umich.edu 1693101Sstever@eecs.umich.eduCowDiskImage::CowDiskImage(const Params *p) 1703101Sstever@eecs.umich.edu : DiskImage(p), filename(p->image_file), child(p->child), table(NULL) 1713101Sstever@eecs.umich.edu{ 1723101Sstever@eecs.umich.edu if (filename.empty()) { 1733101Sstever@eecs.umich.edu init(p->table_size); 1743101Sstever@eecs.umich.edu } else { 1753101Sstever@eecs.umich.edu if (!open(filename)) { 1763101Sstever@eecs.umich.edu if (p->read_only) 1773101Sstever@eecs.umich.edu fatal("could not open read-only file"); 1785033Smilesck@eecs.umich.edu init(p->table_size); 1796656Snate@binkert.org } 1805033Smilesck@eecs.umich.edu 1815033Smilesck@eecs.umich.edu if (!p->read_only) 1825033Smilesck@eecs.umich.edu registerExitCallback(new CowDiskCallback(this)); 1833101Sstever@eecs.umich.edu } 1843101Sstever@eecs.umich.edu} 1853101Sstever@eecs.umich.edu 18610267SGeoffrey.Blake@arm.comCowDiskImage::~CowDiskImage() 18710267SGeoffrey.Blake@arm.com{ 18810267SGeoffrey.Blake@arm.com SectorTable::iterator i = table->begin(); 18910267SGeoffrey.Blake@arm.com SectorTable::iterator end = table->end(); 19010267SGeoffrey.Blake@arm.com 19110267SGeoffrey.Blake@arm.com while (i != end) { 19210267SGeoffrey.Blake@arm.com delete (*i).second; 19310267SGeoffrey.Blake@arm.com ++i; 19410267SGeoffrey.Blake@arm.com } 19510267SGeoffrey.Blake@arm.com} 19610267SGeoffrey.Blake@arm.com 19710267SGeoffrey.Blake@arm.comvoid 19810267SGeoffrey.Blake@arm.comSafeRead(ifstream &stream, void *data, int count) 1993101Sstever@eecs.umich.edu{ 2003101Sstever@eecs.umich.edu stream.read((char *)data, count); 2013101Sstever@eecs.umich.edu if (!stream.is_open()) 2023101Sstever@eecs.umich.edu panic("file not open"); 2033101Sstever@eecs.umich.edu 2043101Sstever@eecs.umich.edu if (stream.eof()) 2053101Sstever@eecs.umich.edu panic("premature end-of-file"); 2063101Sstever@eecs.umich.edu 2073101Sstever@eecs.umich.edu if (stream.bad() || stream.fail()) 2083101Sstever@eecs.umich.edu panic("error reading cowdisk image"); 2093102Sstever@eecs.umich.edu} 2103101Sstever@eecs.umich.edu 2113101Sstever@eecs.umich.edutemplate<class T> 2123101Sstever@eecs.umich.eduvoid 21310267SGeoffrey.Blake@arm.comSafeRead(ifstream &stream, T &data) 21410267SGeoffrey.Blake@arm.com{ 21510267SGeoffrey.Blake@arm.com SafeRead(stream, &data, sizeof(data)); 21610267SGeoffrey.Blake@arm.com} 21710267SGeoffrey.Blake@arm.com 21810267SGeoffrey.Blake@arm.comtemplate<class T> 21910267SGeoffrey.Blake@arm.comvoid 2207673Snate@binkert.orgSafeReadSwap(ifstream &stream, T &data) 2218607Sgblack@eecs.umich.edu{ 2227673Snate@binkert.org SafeRead(stream, &data, sizeof(data)); 2233101Sstever@eecs.umich.edu data = letoh(data); //is this the proper byte order conversion? 22411988Sandreas.sandberg@arm.com} 22511988Sandreas.sandberg@arm.com 22611988Sandreas.sandberg@arm.combool 2277673Snate@binkert.orgCowDiskImage::open(const string &file) 2287673Snate@binkert.org{ 2293101Sstever@eecs.umich.edu ifstream stream(file.c_str()); 2303101Sstever@eecs.umich.edu if (!stream.is_open()) 2313101Sstever@eecs.umich.edu return false; 2323101Sstever@eecs.umich.edu 2333101Sstever@eecs.umich.edu if (stream.fail() || stream.bad()) 2343101Sstever@eecs.umich.edu panic("Error opening %s", file); 2355033Smilesck@eecs.umich.edu 2365475Snate@binkert.org uint64_t magic; 2375475Snate@binkert.org SafeRead(stream, magic); 2385475Snate@binkert.org 2395475Snate@binkert.org if (memcmp(&magic, "COWDISK!", sizeof(magic)) != 0) 24010380SAndrew.Bardsley@arm.com panic("Could not open %s: Invalid magic", file); 24110380SAndrew.Bardsley@arm.com 24210380SAndrew.Bardsley@arm.com uint32_t major, minor; 2433101Sstever@eecs.umich.edu SafeReadSwap(stream, major); 2443101Sstever@eecs.umich.edu SafeReadSwap(stream, minor); 2453101Sstever@eecs.umich.edu 2464762Snate@binkert.org if (major != VersionMajor && minor != VersionMinor) 2474762Snate@binkert.org panic("Could not open %s: invalid version %d.%d != %d.%d", 2484762Snate@binkert.org file, major, minor, VersionMajor, VersionMinor); 2493101Sstever@eecs.umich.edu 25012050Snikos.nikoleris@arm.com uint64_t sector_count; 25112050Snikos.nikoleris@arm.com SafeReadSwap(stream, sector_count); 25212050Snikos.nikoleris@arm.com table = new SectorTable(sector_count); 2538459SAli.Saidi@ARM.com 2548459SAli.Saidi@ARM.com 25512050Snikos.nikoleris@arm.com for (uint64_t i = 0; i < sector_count; i++) { 2563101Sstever@eecs.umich.edu uint64_t offset; 2577528Ssteve.reinhardt@amd.com SafeReadSwap(stream, offset); 2587528Ssteve.reinhardt@amd.com 2597528Ssteve.reinhardt@amd.com Sector *sector = new Sector; 2607528Ssteve.reinhardt@amd.com SafeRead(stream, sector, sizeof(Sector)); 2617528Ssteve.reinhardt@amd.com 2627528Ssteve.reinhardt@amd.com assert(table->find(offset) == table->end()); 2633101Sstever@eecs.umich.edu (*table)[offset] = sector; 2647528Ssteve.reinhardt@amd.com } 2657528Ssteve.reinhardt@amd.com 2667528Ssteve.reinhardt@amd.com stream.close(); 2677528Ssteve.reinhardt@amd.com 2687528Ssteve.reinhardt@amd.com initialized = true; 2697528Ssteve.reinhardt@amd.com return true; 2707528Ssteve.reinhardt@amd.com} 2717528Ssteve.reinhardt@amd.com 2727528Ssteve.reinhardt@amd.comvoid 2737528Ssteve.reinhardt@amd.comCowDiskImage::init(int hash_size) 2748321Ssteve.reinhardt@amd.com{ 27512194Sgabeblack@google.com table = new SectorTable(hash_size); 2767528Ssteve.reinhardt@amd.com 2777528Ssteve.reinhardt@amd.com initialized = true; 2787528Ssteve.reinhardt@amd.com} 2797528Ssteve.reinhardt@amd.com 2807528Ssteve.reinhardt@amd.comvoid 2817528Ssteve.reinhardt@amd.comSafeWrite(ofstream &stream, const void *data, int count) 2827528Ssteve.reinhardt@amd.com{ 2837528Ssteve.reinhardt@amd.com stream.write((const char *)data, count); 2847528Ssteve.reinhardt@amd.com if (!stream.is_open()) 2857528Ssteve.reinhardt@amd.com panic("file not open"); 2867528Ssteve.reinhardt@amd.com 2877528Ssteve.reinhardt@amd.com if (stream.eof()) 2887528Ssteve.reinhardt@amd.com panic("premature end-of-file"); 2893101Sstever@eecs.umich.edu 2908664SAli.Saidi@ARM.com if (stream.bad() || stream.fail()) 2918664SAli.Saidi@ARM.com panic("error reading cowdisk image"); 2928664SAli.Saidi@ARM.com} 2938664SAli.Saidi@ARM.com 2948664SAli.Saidi@ARM.comtemplate<class T> 2958664SAli.Saidi@ARM.comvoid 2969953Sgeoffrey.blake@arm.comSafeWrite(ofstream &stream, const T &data) 2979953Sgeoffrey.blake@arm.com{ 2989953Sgeoffrey.blake@arm.com SafeWrite(stream, &data, sizeof(data)); 2999953Sgeoffrey.blake@arm.com} 3009953Sgeoffrey.blake@arm.com 3019953Sgeoffrey.blake@arm.comtemplate<class T> 3029953Sgeoffrey.blake@arm.comvoid 3039953Sgeoffrey.blake@arm.comSafeWriteSwap(ofstream &stream, const T &data) 3049953Sgeoffrey.blake@arm.com{ 3059953Sgeoffrey.blake@arm.com T swappeddata = letoh(data); //is this the proper byte order conversion? 3069953Sgeoffrey.blake@arm.com SafeWrite(stream, &swappeddata, sizeof(data)); 3079953Sgeoffrey.blake@arm.com} 3089953Sgeoffrey.blake@arm.comvoid 30910267SGeoffrey.Blake@arm.comCowDiskImage::save() 31010267SGeoffrey.Blake@arm.com{ 31110267SGeoffrey.Blake@arm.com save(filename); 31210267SGeoffrey.Blake@arm.com} 31310267SGeoffrey.Blake@arm.com 31410267SGeoffrey.Blake@arm.comvoid 31510267SGeoffrey.Blake@arm.comCowDiskImage::save(const string &file) 31612563Sgabeblack@google.com{ 31710267SGeoffrey.Blake@arm.com if (!initialized) 31810267SGeoffrey.Blake@arm.com panic("RawDiskImage not initialized"); 31910267SGeoffrey.Blake@arm.com 32010267SGeoffrey.Blake@arm.com ofstream stream(file.c_str()); 32110267SGeoffrey.Blake@arm.com if (!stream.is_open() || stream.fail() || stream.bad()) 32210267SGeoffrey.Blake@arm.com panic("Error opening %s", file); 32310267SGeoffrey.Blake@arm.com 32410267SGeoffrey.Blake@arm.com uint64_t magic; 32510267SGeoffrey.Blake@arm.com memcpy(&magic, "COWDISK!", sizeof(magic)); 32610267SGeoffrey.Blake@arm.com SafeWrite(stream, magic); 32710267SGeoffrey.Blake@arm.com 32810267SGeoffrey.Blake@arm.com SafeWriteSwap(stream, (uint32_t)VersionMajor); 3293101Sstever@eecs.umich.edu SafeWriteSwap(stream, (uint32_t)VersionMinor); 3303101Sstever@eecs.umich.edu SafeWriteSwap(stream, (uint64_t)table->size()); 3313101Sstever@eecs.umich.edu 3323101Sstever@eecs.umich.edu uint64_t size = table->size(); 3333101Sstever@eecs.umich.edu SectorTable::iterator iter = table->begin(); 3343101Sstever@eecs.umich.edu SectorTable::iterator end = table->end(); 3353101Sstever@eecs.umich.edu 33610364SGeoffrey.Blake@arm.com for (uint64_t i = 0; i < size; i++) { 33710364SGeoffrey.Blake@arm.com if (iter == end) 33810364SGeoffrey.Blake@arm.com panic("Incorrect Table Size during save of COW disk image"); 33910364SGeoffrey.Blake@arm.com 3403101Sstever@eecs.umich.edu SafeWriteSwap(stream, (uint64_t)(*iter).first); 3414762Snate@binkert.org SafeWrite(stream, (*iter).second->data, sizeof(Sector)); 3424762Snate@binkert.org ++iter; 3434762Snate@binkert.org } 3444762Snate@binkert.org 3457528Ssteve.reinhardt@amd.com stream.close(); 3464762Snate@binkert.org} 3474762Snate@binkert.org 3484762Snate@binkert.orgvoid 34910267SGeoffrey.Blake@arm.comCowDiskImage::writeback() 35010267SGeoffrey.Blake@arm.com{ 35110267SGeoffrey.Blake@arm.com SectorTable::iterator i = table->begin(); 35210267SGeoffrey.Blake@arm.com SectorTable::iterator end = table->end(); 35310267SGeoffrey.Blake@arm.com 35410267SGeoffrey.Blake@arm.com while (i != end) { 35510267SGeoffrey.Blake@arm.com child->write((*i).second->data, (*i).first); 35610267SGeoffrey.Blake@arm.com ++i; 35710267SGeoffrey.Blake@arm.com } 35810267SGeoffrey.Blake@arm.com} 35910267SGeoffrey.Blake@arm.com 36010267SGeoffrey.Blake@arm.comoff_t 36110267SGeoffrey.Blake@arm.comCowDiskImage::size() const 36210267SGeoffrey.Blake@arm.com{ return child->size(); } 36310267SGeoffrey.Blake@arm.com 36410267SGeoffrey.Blake@arm.comoff_t 36510267SGeoffrey.Blake@arm.comCowDiskImage::read(uint8_t *data, off_t offset) const 36610267SGeoffrey.Blake@arm.com{ 36710267SGeoffrey.Blake@arm.com if (!initialized) 36810267SGeoffrey.Blake@arm.com panic("CowDiskImage not initialized"); 36910267SGeoffrey.Blake@arm.com 37010267SGeoffrey.Blake@arm.com if (offset > size()) 37110267SGeoffrey.Blake@arm.com panic("access out of bounds"); 37210267SGeoffrey.Blake@arm.com 37310267SGeoffrey.Blake@arm.com SectorTable::const_iterator i = table->find(offset); 37410267SGeoffrey.Blake@arm.com if (i == table->end()) 37510364SGeoffrey.Blake@arm.com return child->read(data, offset); 37610364SGeoffrey.Blake@arm.com else { 37710267SGeoffrey.Blake@arm.com memcpy(data, (*i).second->data, SectorSize); 37810267SGeoffrey.Blake@arm.com DPRINTF(DiskImageRead, "read: offset=%d\n", (uint64_t)offset); 37910267SGeoffrey.Blake@arm.com DDUMP(DiskImageRead, data, SectorSize); 38010267SGeoffrey.Blake@arm.com return SectorSize; 38110267SGeoffrey.Blake@arm.com } 38210267SGeoffrey.Blake@arm.com} 3837673Snate@binkert.org 3847673Snate@binkert.orgoff_t 3857673Snate@binkert.orgCowDiskImage::write(const uint8_t *data, off_t offset) 3863101Sstever@eecs.umich.edu{ 38711988Sandreas.sandberg@arm.com if (!initialized) 38811988Sandreas.sandberg@arm.com panic("RawDiskImage not initialized"); 38911988Sandreas.sandberg@arm.com 39011988Sandreas.sandberg@arm.com if (offset > size()) 3917673Snate@binkert.org panic("access out of bounds"); 3927673Snate@binkert.org 3933101Sstever@eecs.umich.edu SectorTable::iterator i = table->find(offset); 3943101Sstever@eecs.umich.edu if (i == table->end()) { 3953101Sstever@eecs.umich.edu Sector *sector = new Sector; 3963101Sstever@eecs.umich.edu memcpy(sector, data, SectorSize); 3973101Sstever@eecs.umich.edu table->insert(make_pair(offset, sector)); 3983101Sstever@eecs.umich.edu } else { 3993101Sstever@eecs.umich.edu memcpy((*i).second->data, data, SectorSize); 4003101Sstever@eecs.umich.edu } 4013101Sstever@eecs.umich.edu 4023101Sstever@eecs.umich.edu DPRINTF(DiskImageWrite, "write: offset=%d\n", (uint64_t)offset); 4033101Sstever@eecs.umich.edu DDUMP(DiskImageWrite, data, SectorSize); 4043101Sstever@eecs.umich.edu 4053101Sstever@eecs.umich.edu return SectorSize; 4063101Sstever@eecs.umich.edu} 4073101Sstever@eecs.umich.edu 4085033Smilesck@eecs.umich.eduvoid 4095033Smilesck@eecs.umich.eduCowDiskImage::serialize(ostream &os) 4103101Sstever@eecs.umich.edu{ 4113101Sstever@eecs.umich.edu string cowFilename = name() + ".cow"; 4123101Sstever@eecs.umich.edu SERIALIZE_SCALAR(cowFilename); 4133101Sstever@eecs.umich.edu save(Checkpoint::dir() + "/" + cowFilename); 4143101Sstever@eecs.umich.edu} 4153101Sstever@eecs.umich.edu 4163101Sstever@eecs.umich.eduvoid 4173101Sstever@eecs.umich.eduCowDiskImage::unserialize(Checkpoint *cp, const string §ion) 4183101Sstever@eecs.umich.edu{ 4193101Sstever@eecs.umich.edu string cowFilename; 4203101Sstever@eecs.umich.edu UNSERIALIZE_SCALAR(cowFilename); 4213101Sstever@eecs.umich.edu cowFilename = cp->cptDir + "/" + cowFilename; 4223101Sstever@eecs.umich.edu open(cowFilename); 4233101Sstever@eecs.umich.edu} 4243101Sstever@eecs.umich.edu 4253101Sstever@eecs.umich.eduCowDiskImage * 4263101Sstever@eecs.umich.eduCowDiskImageParams::create() 4273101Sstever@eecs.umich.edu{ 4283101Sstever@eecs.umich.edu return new CowDiskImage(this); 4293101Sstever@eecs.umich.edu} 4303101Sstever@eecs.umich.edu