abstract_mem.cc revision 3170
17404SAli.Saidi@ARM.com/* 212709Sgiacomo.travaglini@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 37404SAli.Saidi@ARM.com * All rights reserved. 47404SAli.Saidi@ARM.com * 57404SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 67404SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 77404SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright 87404SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer; 97404SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright 107404SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the 117404SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution; 127404SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 137404SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 147404SAli.Saidi@ARM.com * this software without specific prior written permission. 157404SAli.Saidi@ARM.com * 167404SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177404SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187404SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197404SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207404SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217404SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227404SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237404SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247404SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257404SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267404SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277404SAli.Saidi@ARM.com * 287404SAli.Saidi@ARM.com * Authors: Ron Dreslinski 297404SAli.Saidi@ARM.com * Ali Saidi 307404SAli.Saidi@ARM.com */ 317404SAli.Saidi@ARM.com 327404SAli.Saidi@ARM.com#include <sys/types.h> 337404SAli.Saidi@ARM.com#include <sys/mman.h> 347404SAli.Saidi@ARM.com#include <errno.h> 357404SAli.Saidi@ARM.com#include <fcntl.h> 367404SAli.Saidi@ARM.com#include <unistd.h> 377404SAli.Saidi@ARM.com#include <zlib.h> 3810037SARM gem5 Developers 397404SAli.Saidi@ARM.com#include <iostream> 4010873Sandreas.sandberg@arm.com#include <string> 417404SAli.Saidi@ARM.com 4210474Sandreas.hansson@arm.com 4310474Sandreas.hansson@arm.com#include "base/misc.hh" 447404SAli.Saidi@ARM.com#include "config/full_system.hh" 4510037SARM gem5 Developers#include "mem/packet_impl.hh" 4610037SARM gem5 Developers#include "mem/physical.hh" 477404SAli.Saidi@ARM.com#include "sim/host.hh" 487728SAli.Saidi@ARM.com#include "sim/builder.hh" 497404SAli.Saidi@ARM.com#include "sim/eventq.hh" 508245Snate@binkert.org#include "arch/isa_traits.hh" 519152Satgutier@umich.edu 528245Snate@binkert.org 538245Snate@binkert.orgusing namespace std; 5410873Sandreas.sandberg@arm.comusing namespace TheISA; 557748SAli.Saidi@ARM.com 567404SAli.Saidi@ARM.com 577404SAli.Saidi@ARM.comPhysicalMemory::PhysicalMemory(Params *p) 587404SAli.Saidi@ARM.com : MemObject(p->name), pmemAddr(NULL), port(NULL), lat(p->latency), _params(p) 597404SAli.Saidi@ARM.com{ 6013892Sgabeblack@google.com if (params()->addrRange.size() % TheISA::PageBytes != 0) 6110717Sandreas.hansson@arm.com panic("Memory Size not divisible by page size\n"); 6210717Sandreas.hansson@arm.com 6310717Sandreas.hansson@arm.com int map_flags = MAP_ANON | MAP_PRIVATE; 649258SAli.Saidi@ARM.com pmemAddr = (uint8_t *)mmap(NULL, params()->addrRange.size(), PROT_READ | PROT_WRITE, 6510621SCurtis.Dunham@arm.com map_flags, -1, 0); 6610621SCurtis.Dunham@arm.com 6712086Sspwilson2@wisc.edu if (pmemAddr == (void *)MAP_FAILED) { 6812086Sspwilson2@wisc.edu perror("mmap"); 6912086Sspwilson2@wisc.edu fatal("Could not mmap!\n"); 7012086Sspwilson2@wisc.edu } 7112086Sspwilson2@wisc.edu 7212086Sspwilson2@wisc.edu pagePtr = 0; 7311588SCurtis.Dunham@arm.com} 7411588SCurtis.Dunham@arm.com 7512086Sspwilson2@wisc.eduvoid 767439Sdam.sunwoo@arm.comPhysicalMemory::init() 777576SAli.Saidi@ARM.com{ 7810037SARM gem5 Developers if (!port) 7910037SARM gem5 Developers panic("PhysicalMemory not connected to anything!"); 8010037SARM gem5 Developers port->sendStatusChange(Port::RangeChange); 8110717Sandreas.hansson@arm.com} 8210037SARM gem5 Developers 8310037SARM gem5 DevelopersPhysicalMemory::~PhysicalMemory() 8410037SARM gem5 Developers{ 8510037SARM gem5 Developers if (pmemAddr) 8610037SARM gem5 Developers munmap(pmemAddr, params()->addrRange.size()); 8710037SARM gem5 Developers //Remove memPorts? 8810037SARM gem5 Developers} 8910037SARM gem5 Developers 9010037SARM gem5 DevelopersAddr 9110037SARM gem5 DevelopersPhysicalMemory::new_page() 9210037SARM gem5 Developers{ 9310037SARM gem5 Developers Addr return_addr = pagePtr << LogVMPageSize; 947439Sdam.sunwoo@arm.com return_addr += params()->addrRange.start; 957404SAli.Saidi@ARM.com 967404SAli.Saidi@ARM.com ++pagePtr; 977404SAli.Saidi@ARM.com return return_addr; 987404SAli.Saidi@ARM.com} 997404SAli.Saidi@ARM.com 1007404SAli.Saidi@ARM.comint 10110717Sandreas.hansson@arm.comPhysicalMemory::deviceBlockSize() 10210717Sandreas.hansson@arm.com{ 10310717Sandreas.hansson@arm.com //Can accept anysize request 10410717Sandreas.hansson@arm.com return 0; 10513795SAndrea.Mondelli@ucf.edu} 10610717Sandreas.hansson@arm.com 10710717Sandreas.hansson@arm.comTick 10810717Sandreas.hansson@arm.comPhysicalMemory::calculateLatency(Packet *pkt) 10910717Sandreas.hansson@arm.com{ 11010717Sandreas.hansson@arm.com return lat; 11110717Sandreas.hansson@arm.com} 11210717Sandreas.hansson@arm.com 11310717Sandreas.hansson@arm.com 11410717Sandreas.hansson@arm.com 11510717Sandreas.hansson@arm.com// Add load-locked to tracking list. Should only be called if the 11610717Sandreas.hansson@arm.com// operation is a load and the LOCKED flag is set. 11713784Sgabeblack@google.comvoid 11813784Sgabeblack@google.comPhysicalMemory::trackLoadLocked(Request *req) 11910717Sandreas.hansson@arm.com{ 12010717Sandreas.hansson@arm.com Addr paddr = LockedAddr::mask(req->getPaddr()); 12110717Sandreas.hansson@arm.com 12210717Sandreas.hansson@arm.com // first we check if we already have a locked addr for this 12310717Sandreas.hansson@arm.com // xc. Since each xc only gets one, we just update the 12410717Sandreas.hansson@arm.com // existing record with the new address. 12510717Sandreas.hansson@arm.com list<LockedAddr>::iterator i; 12610717Sandreas.hansson@arm.com 12713892Sgabeblack@google.com for (i = lockedAddrList.begin(); i != lockedAddrList.end(); ++i) { 12810717Sandreas.hansson@arm.com if (i->matchesContext(req)) { 12910717Sandreas.hansson@arm.com DPRINTF(LLSC, "Modifying lock record: cpu %d thread %d addr %#x\n", 13010537Sandreas.hansson@arm.com req->getCpuNum(), req->getThreadNum(), paddr); 13110537Sandreas.hansson@arm.com i->addr = paddr; 13210537Sandreas.hansson@arm.com return; 13314040Sgiacomo.travaglini@arm.com } 13414040Sgiacomo.travaglini@arm.com } 13514040Sgiacomo.travaglini@arm.com 13614040Sgiacomo.travaglini@arm.com // no record for this xc: need to allocate a new one 13710537Sandreas.hansson@arm.com DPRINTF(LLSC, "Adding lock record: cpu %d thread %d addr %#x\n", 13812738Sandreas.sandberg@arm.com req->getCpuNum(), req->getThreadNum(), paddr); 13910537Sandreas.hansson@arm.com lockedAddrList.push_front(LockedAddr(req)); 14010537Sandreas.hansson@arm.com} 14110537Sandreas.hansson@arm.com 14210037SARM gem5 Developers 14310037SARM gem5 Developers// Called on *writes* only... both regular stores and 14410037SARM gem5 Developers// store-conditional operations. Check for conventional stores which 1459152Satgutier@umich.edu// conflict with locked addresses, and for success/failure of store 1469152Satgutier@umich.edu// conditionals. 1479152Satgutier@umich.edubool 14810913Sandreas.sandberg@arm.comPhysicalMemory::checkLockedAddrList(Request *req) 14911588SCurtis.Dunham@arm.com{ 15011588SCurtis.Dunham@arm.com Addr paddr = LockedAddr::mask(req->getPaddr()); 1519152Satgutier@umich.edu bool isLocked = req->isLocked(); 15210913Sandreas.sandberg@arm.com 1539152Satgutier@umich.edu // Initialize return value. Non-conditional stores always 15410913Sandreas.sandberg@arm.com // succeed. Assume conditional stores will fail until proven 1559152Satgutier@umich.edu // otherwise. 1569152Satgutier@umich.edu bool success = !isLocked; 1579152Satgutier@umich.edu 15810913Sandreas.sandberg@arm.com // Iterate over list. Note that there could be multiple matching 15910913Sandreas.sandberg@arm.com // records, as more than one context could have done a load locked 1607404SAli.Saidi@ARM.com // to this location. 16110037SARM gem5 Developers list<LockedAddr>::iterator i = lockedAddrList.begin(); 1629152Satgutier@umich.edu 16310037SARM gem5 Developers while (i != lockedAddrList.end()) { 16410037SARM gem5 Developers 16510037SARM gem5 Developers if (i->addr == paddr) { 16610037SARM gem5 Developers // we have a matching address 16710037SARM gem5 Developers 16810037SARM gem5 Developers if (isLocked && i->matchesContext(req)) { 16910037SARM gem5 Developers // it's a store conditional, and as far as the memory 17010037SARM gem5 Developers // system can tell, the requesting context's lock is 1719152Satgutier@umich.edu // still valid. 17210913Sandreas.sandberg@arm.com DPRINTF(LLSC, "StCond success: cpu %d thread %d addr %#x\n", 17310037SARM gem5 Developers req->getCpuNum(), req->getThreadNum(), paddr); 17410037SARM gem5 Developers success = true; 17510913Sandreas.sandberg@arm.com } 1767733SAli.Saidi@ARM.com 1777404SAli.Saidi@ARM.com // Get rid of our record of this lock and advance to next 1787404SAli.Saidi@ARM.com DPRINTF(LLSC, "Erasing lock record: cpu %d thread %d addr %#x\n", 1797748SAli.Saidi@ARM.com i->cpuNum, i->threadNum, paddr); 1809342SAndreas.Sandberg@arm.com i = lockedAddrList.erase(i); 1817748SAli.Saidi@ARM.com } 1829524SAndreas.Sandberg@ARM.com else { 1839152Satgutier@umich.edu // no match: advance to next record 1849152Satgutier@umich.edu ++i; 18510621SCurtis.Dunham@arm.com } 1867748SAli.Saidi@ARM.com } 1877748SAli.Saidi@ARM.com 1887748SAli.Saidi@ARM.com if (isLocked) { 1897404SAli.Saidi@ARM.com req->setScResult(success ? 1 : 0); 19012749Sgiacomo.travaglini@arm.com } 19110037SARM gem5 Developers 19210037SARM gem5 Developers return success; 19311580SDylan.Johnson@ARM.com} 19411580SDylan.Johnson@ARM.com 1957404SAli.Saidi@ARM.comvoid 1968733Sgeoffrey.blake@arm.comPhysicalMemory::doFunctionalAccess(Packet *pkt) 19710621SCurtis.Dunham@arm.com{ 19810621SCurtis.Dunham@arm.com assert(pkt->getAddr() + pkt->getSize() < params()->addrRange.size()); 19910109SGeoffrey.Blake@arm.com 20010037SARM gem5 Developers switch (pkt->cmd) { 20110109SGeoffrey.Blake@arm.com case Packet::ReadReq: 2027439Sdam.sunwoo@arm.com if (pkt->req->isLocked()) { 2037439Sdam.sunwoo@arm.com trackLoadLocked(pkt->req); 2047439Sdam.sunwoo@arm.com } 2057439Sdam.sunwoo@arm.com memcpy(pkt->getPtr<uint8_t>(), 2067404SAli.Saidi@ARM.com pmemAddr + pkt->getAddr() - params()->addrRange.start, 2077439Sdam.sunwoo@arm.com pkt->getSize()); 2087439Sdam.sunwoo@arm.com break; 20910109SGeoffrey.Blake@arm.com case Packet::WriteReq: 21010109SGeoffrey.Blake@arm.com if (writeOK(pkt->req)) { 21110109SGeoffrey.Blake@arm.com memcpy(pmemAddr + pkt->getAddr() - params()->addrRange.start, 21210109SGeoffrey.Blake@arm.com pkt->getPtr<uint8_t>(), pkt->getSize()); 21310109SGeoffrey.Blake@arm.com } 21410109SGeoffrey.Blake@arm.com break; 21510109SGeoffrey.Blake@arm.com default: 21610109SGeoffrey.Blake@arm.com panic("unimplemented"); 2178202SAli.Saidi@ARM.com } 2188202SAli.Saidi@ARM.com 2198202SAli.Saidi@ARM.com pkt->result = Packet::Success; 2208202SAli.Saidi@ARM.com} 2218202SAli.Saidi@ARM.com 2228202SAli.Saidi@ARM.comPort * 2238202SAli.Saidi@ARM.comPhysicalMemory::getPort(const std::string &if_name, int idx) 22410037SARM gem5 Developers{ 22510621SCurtis.Dunham@arm.com if (if_name == "port" && idx == -1) { 22610474Sandreas.hansson@arm.com if (port != NULL) 2278202SAli.Saidi@ARM.com panic("PhysicalMemory::getPort: additional port requested to memory!"); 2287439Sdam.sunwoo@arm.com port = new MemoryPort(name() + "-port", this); 22910621SCurtis.Dunham@arm.com return port; 2307439Sdam.sunwoo@arm.com } else if (if_name == "functional") { 23110621SCurtis.Dunham@arm.com /* special port for functional writes at startup. */ 2327439Sdam.sunwoo@arm.com return new MemoryPort(name() + "-funcport", this); 23311517SCurtis.Dunham@arm.com } else { 23411517SCurtis.Dunham@arm.com panic("PhysicalMemory::getPort: unknown port %s requested", if_name); 23511517SCurtis.Dunham@arm.com } 23612735Sandreas.sandberg@arm.com} 23712735Sandreas.sandberg@arm.com 23812735Sandreas.sandberg@arm.comvoid 23912735Sandreas.sandberg@arm.comPhysicalMemory::recvStatusChange(Port::Status status) 24012735Sandreas.sandberg@arm.com{ 24112735Sandreas.sandberg@arm.com} 24212735Sandreas.sandberg@arm.com 24312735Sandreas.sandberg@arm.comPhysicalMemory::MemoryPort::MemoryPort(const std::string &_name, 24412735Sandreas.sandberg@arm.com PhysicalMemory *_memory) 2457439Sdam.sunwoo@arm.com : SimpleTimingPort(_name), memory(_memory) 2467439Sdam.sunwoo@arm.com{ } 2477439Sdam.sunwoo@arm.com 24810037SARM gem5 Developersvoid 24910037SARM gem5 DevelopersPhysicalMemory::MemoryPort::recvStatusChange(Port::Status status) 25010037SARM gem5 Developers{ 2517439Sdam.sunwoo@arm.com memory->recvStatusChange(status); 2528733Sgeoffrey.blake@arm.com} 2537439Sdam.sunwoo@arm.com 25410037SARM gem5 Developersvoid 25510037SARM gem5 DevelopersPhysicalMemory::MemoryPort::getDeviceAddressRanges(AddrRangeList &resp, 25610037SARM gem5 Developers AddrRangeList &snoop) 2577404SAli.Saidi@ARM.com{ 2587436Sdam.sunwoo@arm.com memory->getAddressRanges(resp, snoop); 2597436Sdam.sunwoo@arm.com} 26010037SARM gem5 Developers 26110037SARM gem5 Developersvoid 26210037SARM gem5 DevelopersPhysicalMemory::getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) 26310037SARM gem5 Developers{ 26410037SARM gem5 Developers snoop.clear(); 26510037SARM gem5 Developers resp.clear(); 26610037SARM gem5 Developers resp.push_back(RangeSize(params()->addrRange.start, 26710037SARM gem5 Developers params()->addrRange.size())); 26811575SDylan.Johnson@ARM.com} 26911575SDylan.Johnson@ARM.com 27011575SDylan.Johnson@ARM.comint 27111575SDylan.Johnson@ARM.comPhysicalMemory::MemoryPort::deviceBlockSize() 27210037SARM gem5 Developers{ 27310037SARM gem5 Developers return memory->deviceBlockSize(); 27410037SARM gem5 Developers} 27510324SCurtis.Dunham@arm.com 27610037SARM gem5 DevelopersTick 27711574SCurtis.Dunham@arm.comPhysicalMemory::MemoryPort::recvAtomic(Packet *pkt) 27811574SCurtis.Dunham@arm.com{ 27911574SCurtis.Dunham@arm.com memory->doFunctionalAccess(pkt); 28011574SCurtis.Dunham@arm.com return memory->calculateLatency(pkt); 28111574SCurtis.Dunham@arm.com} 28210037SARM gem5 Developers 28310037SARM gem5 Developersvoid 28410037SARM gem5 DevelopersPhysicalMemory::MemoryPort::recvFunctional(Packet *pkt) 28510324SCurtis.Dunham@arm.com{ 28610037SARM gem5 Developers // Default implementation of SimpleTimingPort::recvFunctional() 28710037SARM gem5 Developers // calls recvAtomic() and throws away the latency; we can save a 28810037SARM gem5 Developers // little here by just not calculating the latency. 28910037SARM gem5 Developers memory->doFunctionalAccess(pkt); 29010037SARM gem5 Developers} 29111575SDylan.Johnson@ARM.com 29210037SARM gem5 Developersunsigned int 29312499Sgiacomo.travaglini@arm.comPhysicalMemory::drain(Event *de) 29410037SARM gem5 Developers{ 29512499Sgiacomo.travaglini@arm.com int count = port->drain(de); 29610037SARM gem5 Developers if (count) 29710037SARM gem5 Developers changeState(Draining); 29810037SARM gem5 Developers else 29910037SARM gem5 Developers changeState(Drained); 30010037SARM gem5 Developers return count; 3017439Sdam.sunwoo@arm.com} 3027439Sdam.sunwoo@arm.com 3037439Sdam.sunwoo@arm.comvoid 3047439Sdam.sunwoo@arm.comPhysicalMemory::serialize(ostream &os) 3057439Sdam.sunwoo@arm.com{ 30610621SCurtis.Dunham@arm.com gzFile compressedMem; 30710621SCurtis.Dunham@arm.com string filename = name() + ".physmem"; 30811580SDylan.Johnson@ARM.com 3097728SAli.Saidi@ARM.com SERIALIZE_SCALAR(filename); 31011517SCurtis.Dunham@arm.com 31111517SCurtis.Dunham@arm.com // write memory file 31210037SARM gem5 Developers string thefile = Checkpoint::dir() + "/" + filename.c_str(); 31310037SARM gem5 Developers int fd = creat(thefile.c_str(), 0664); 31410037SARM gem5 Developers if (fd < 0) { 31510037SARM gem5 Developers perror("creat"); 31610037SARM gem5 Developers fatal("Can't open physical memory checkpoint file '%s'\n", filename); 31710037SARM gem5 Developers } 31810037SARM gem5 Developers 31910037SARM gem5 Developers compressedMem = gzdopen(fd, "wb"); 32010621SCurtis.Dunham@arm.com if (compressedMem == NULL) 32110621SCurtis.Dunham@arm.com fatal("Insufficient memory to allocate compression state for %s\n", 32210621SCurtis.Dunham@arm.com filename); 32310621SCurtis.Dunham@arm.com 32410037SARM gem5 Developers if (gzwrite(compressedMem, pmemAddr, params()->addrRange.size()) != params()->addrRange.size()) { 32510037SARM gem5 Developers fatal("Write failed on physical memory checkpoint file '%s'\n", 32610037SARM gem5 Developers filename); 32710109SGeoffrey.Blake@arm.com } 32810037SARM gem5 Developers 32910109SGeoffrey.Blake@arm.com if (gzclose(compressedMem)) 33010037SARM gem5 Developers fatal("Close failed on physical memory checkpoint file '%s'\n", 33110109SGeoffrey.Blake@arm.com filename); 33210037SARM gem5 Developers} 33310109SGeoffrey.Blake@arm.com 33410109SGeoffrey.Blake@arm.comvoid 33510109SGeoffrey.Blake@arm.comPhysicalMemory::unserialize(Checkpoint *cp, const string §ion) 33610109SGeoffrey.Blake@arm.com{ 33710109SGeoffrey.Blake@arm.com gzFile compressedMem; 33810109SGeoffrey.Blake@arm.com long *tempPage; 33910109SGeoffrey.Blake@arm.com long *pmem_current; 34010109SGeoffrey.Blake@arm.com uint64_t curSize; 34110109SGeoffrey.Blake@arm.com uint32_t bytesRead; 34210037SARM gem5 Developers const int chunkSize = 16384; 3437728SAli.Saidi@ARM.com 3448067SAli.Saidi@ARM.com 3457728SAli.Saidi@ARM.com string filename; 3467728SAli.Saidi@ARM.com 34710621SCurtis.Dunham@arm.com UNSERIALIZE_SCALAR(filename); 3487728SAli.Saidi@ARM.com 3497728SAli.Saidi@ARM.com filename = cp->cptDir + "/" + filename; 35010621SCurtis.Dunham@arm.com 35110037SARM gem5 Developers // mmap memoryfile 35210037SARM gem5 Developers int fd = open(filename.c_str(), O_RDONLY); 35310037SARM gem5 Developers if (fd < 0) { 35410037SARM gem5 Developers perror("open"); 35510037SARM gem5 Developers fatal("Can't open physical memory checkpoint file '%s'", filename); 35610037SARM gem5 Developers } 3577728SAli.Saidi@ARM.com 3587728SAli.Saidi@ARM.com compressedMem = gzdopen(fd, "rb"); 3597728SAli.Saidi@ARM.com if (compressedMem == NULL) 3607728SAli.Saidi@ARM.com fatal("Insufficient memory to allocate compression state for %s\n", 3617728SAli.Saidi@ARM.com filename); 3627728SAli.Saidi@ARM.com 3637728SAli.Saidi@ARM.com // unmap file that was mmaped in the constructor 3647728SAli.Saidi@ARM.com // This is done here to make sure that gzip and open don't muck with our 3657728SAli.Saidi@ARM.com // nice large space of memory before we reallocate it 3667728SAli.Saidi@ARM.com munmap(pmemAddr, params()->addrRange.size()); 36710621SCurtis.Dunham@arm.com 3687728SAli.Saidi@ARM.com pmemAddr = (uint8_t *)mmap(NULL, params()->addrRange.size(), PROT_READ | PROT_WRITE, 3699258SAli.Saidi@ARM.com MAP_ANON | MAP_PRIVATE, -1, 0); 3709535Smrinmoy.ghosh@arm.com 37110037SARM gem5 Developers if (pmemAddr == (void *)MAP_FAILED) { 37210037SARM gem5 Developers perror("mmap"); 37310037SARM gem5 Developers fatal("Could not mmap physical memory!\n"); 37412735Sandreas.sandberg@arm.com } 3759258SAli.Saidi@ARM.com 3769535Smrinmoy.ghosh@arm.com curSize = 0; 3779535Smrinmoy.ghosh@arm.com tempPage = (long*)malloc(chunkSize); 3789535Smrinmoy.ghosh@arm.com if (tempPage == NULL) 3799535Smrinmoy.ghosh@arm.com fatal("Unable to malloc memory to read file %s\n", filename); 3809535Smrinmoy.ghosh@arm.com 3819535Smrinmoy.ghosh@arm.com /* Only copy bytes that are non-zero, so we don't give the VM system hell */ 3829258SAli.Saidi@ARM.com while (curSize < params()->addrRange.size()) { 3839258SAli.Saidi@ARM.com bytesRead = gzread(compressedMem, tempPage, chunkSize); 3849258SAli.Saidi@ARM.com if (bytesRead != chunkSize && bytesRead != params()->addrRange.size() - curSize) 38510579SAndrew.Bardsley@arm.com fatal("Read failed on physical memory checkpoint file '%s'" 38610579SAndrew.Bardsley@arm.com " got %d bytes, expected %d or %d bytes\n", 38710579SAndrew.Bardsley@arm.com filename, bytesRead, chunkSize, params()->addrRange.size()-curSize); 38810037SARM gem5 Developers 38910579SAndrew.Bardsley@arm.com assert(bytesRead % sizeof(long) == 0); 39011517SCurtis.Dunham@arm.com 39111517SCurtis.Dunham@arm.com for (int x = 0; x < bytesRead/sizeof(long); x++) 39210579SAndrew.Bardsley@arm.com { 39310037SARM gem5 Developers if (*(tempPage+x) != 0) { 39410579SAndrew.Bardsley@arm.com pmem_current = (long*)(pmemAddr + curSize + x * sizeof(long)); 39510579SAndrew.Bardsley@arm.com *pmem_current = *(tempPage+x); 39610579SAndrew.Bardsley@arm.com } 39710579SAndrew.Bardsley@arm.com } 39810579SAndrew.Bardsley@arm.com curSize += bytesRead; 39910579SAndrew.Bardsley@arm.com } 40010579SAndrew.Bardsley@arm.com 40110579SAndrew.Bardsley@arm.com free(tempPage); 4029258SAli.Saidi@ARM.com 4039258SAli.Saidi@ARM.com if (gzclose(compressedMem)) 4049258SAli.Saidi@ARM.com fatal("Close failed on physical memory checkpoint file '%s'\n", 4059258SAli.Saidi@ARM.com filename); 4069258SAli.Saidi@ARM.com 4079258SAli.Saidi@ARM.com} 4089258SAli.Saidi@ARM.com 4099258SAli.Saidi@ARM.com 4109258SAli.Saidi@ARM.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory) 4119535Smrinmoy.ghosh@arm.com 4129258SAli.Saidi@ARM.com Param<string> file; 4139258SAli.Saidi@ARM.com Param<Range<Addr> > range; 41410621SCurtis.Dunham@arm.com Param<Tick> latency; 4159258SAli.Saidi@ARM.com 41610037SARM gem5 DevelopersEND_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory) 41710037SARM gem5 Developers 4189258SAli.Saidi@ARM.comBEGIN_INIT_SIM_OBJECT_PARAMS(PhysicalMemory) 4199535Smrinmoy.ghosh@arm.com 4209535Smrinmoy.ghosh@arm.com INIT_PARAM_DFLT(file, "memory mapped file", ""), 42110474Sandreas.hansson@arm.com INIT_PARAM(range, "Device Address Range"), 42210474Sandreas.hansson@arm.com INIT_PARAM(latency, "Memory access latency") 42310474Sandreas.hansson@arm.com 4249535Smrinmoy.ghosh@arm.comEND_INIT_SIM_OBJECT_PARAMS(PhysicalMemory) 4259535Smrinmoy.ghosh@arm.com 42610621SCurtis.Dunham@arm.comCREATE_SIM_OBJECT(PhysicalMemory) 42710037SARM gem5 Developers{ 42810037SARM gem5 Developers PhysicalMemory::Params *p = new PhysicalMemory::Params; 42910037SARM gem5 Developers p->name = getInstanceName(); 4309535Smrinmoy.ghosh@arm.com p->addrRange = range; 4319258SAli.Saidi@ARM.com p->latency = latency; 4329258SAli.Saidi@ARM.com return new PhysicalMemory(p); 4339258SAli.Saidi@ARM.com} 4349258SAli.Saidi@ARM.com 4359258SAli.Saidi@ARM.comREGISTER_SIM_OBJECT("PhysicalMemory", PhysicalMemory) 4369535Smrinmoy.ghosh@arm.com