abstract_mem.cc revision 2665
12810SN/A/* 212599Snikos.nikoleris@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 39663Suri.wiener@arm.com * All rights reserved. 49663Suri.wiener@arm.com * 59663Suri.wiener@arm.com * Redistribution and use in source and binary forms, with or without 69663Suri.wiener@arm.com * modification, are permitted provided that the following conditions are 79663Suri.wiener@arm.com * met: redistributions of source code must retain the above copyright 89663Suri.wiener@arm.com * notice, this list of conditions and the following disclaimer; 99663Suri.wiener@arm.com * redistributions in binary form must reproduce the above copyright 109663Suri.wiener@arm.com * notice, this list of conditions and the following disclaimer in the 119663Suri.wiener@arm.com * documentation and/or other materials provided with the distribution; 129663Suri.wiener@arm.com * neither the name of the copyright holders nor the names of its 139663Suri.wiener@arm.com * contributors may be used to endorse or promote products derived from 142810SN/A * this software without specific prior written permission. 152810SN/A * 162810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272810SN/A * 282810SN/A * Authors: Ron Dreslinski 292810SN/A */ 302810SN/A 312810SN/A#include <sys/types.h> 322810SN/A#include <sys/mman.h> 332810SN/A#include <errno.h> 342810SN/A#include <fcntl.h> 352810SN/A#include <unistd.h> 362810SN/A#include <zlib.h> 372810SN/A 382810SN/A#include <iostream> 392810SN/A#include <string> 402810SN/A 4113349Snikos.nikoleris@arm.com 422810SN/A#include "base/misc.hh" 432810SN/A#include "config/full_system.hh" 442810SN/A#include "mem/packet_impl.hh" 452810SN/A#include "mem/physical.hh" 462810SN/A#include "sim/host.hh" 472810SN/A#include "sim/builder.hh" 482810SN/A#include "sim/eventq.hh" 4910764Sandreas.hansson@arm.com#include "arch/isa_traits.hh" 5010764Sandreas.hansson@arm.com 512810SN/A 5212727Snikos.nikoleris@arm.comusing namespace std; 5312727Snikos.nikoleris@arm.comusing namespace TheISA; 544626SN/A 5512727Snikos.nikoleris@arm.comPhysicalMemory::MemResponseEvent::MemResponseEvent(Packet *pkt, MemoryPort* _m) 5613349Snikos.nikoleris@arm.com : Event(&mainEventQueue, CPU_Tick_Pri), pkt(pkt), memoryPort(_m) 574626SN/A{ 585314SN/A 5912727Snikos.nikoleris@arm.com this->setFlags(AutoDelete); 6011375Sandreas.hansson@arm.com} 6112727Snikos.nikoleris@arm.com 6213349Snikos.nikoleris@arm.comvoid 6312727Snikos.nikoleris@arm.comPhysicalMemory::MemResponseEvent::process() 642810SN/A{ 6512724Snikos.nikoleris@arm.com memoryPort->sendTiming(pkt); 662810SN/A} 672810SN/A 682810SN/Aconst char * 693374SN/APhysicalMemory::MemResponseEvent::description() 709264Sdjordje.kovacevic@arm.com{ 712810SN/A return "Physical Memory Timing Access respnse event"; 7211375Sandreas.hansson@arm.com} 734626SN/A 744626SN/APhysicalMemory::PhysicalMemory(const string &n, Tick latency) 759725Sandreas.hansson@arm.com : MemObject(n),base_addr(0), pmem_addr(NULL), port(NULL), lat(latency) 7611375Sandreas.hansson@arm.com{ 779725Sandreas.hansson@arm.com // Hardcoded to 128 MB for now. 7811375Sandreas.hansson@arm.com pmem_size = 1 << 27; 7911375Sandreas.hansson@arm.com 809725Sandreas.hansson@arm.com if (pmem_size % TheISA::PageBytes != 0) 819725Sandreas.hansson@arm.com panic("Memory Size not divisible by page size\n"); 829725Sandreas.hansson@arm.com 839725Sandreas.hansson@arm.com int map_flags = MAP_ANON | MAP_PRIVATE; 849725Sandreas.hansson@arm.com pmem_addr = (uint8_t *)mmap(NULL, pmem_size, PROT_READ | PROT_WRITE, 859725Sandreas.hansson@arm.com map_flags, -1, 0); 869725Sandreas.hansson@arm.com 8711284Sandreas.hansson@arm.com if (pmem_addr == (void *)MAP_FAILED) { 8811284Sandreas.hansson@arm.com perror("mmap"); 8911284Sandreas.hansson@arm.com fatal("Could not mmap!\n"); 9011284Sandreas.hansson@arm.com } 9111284Sandreas.hansson@arm.com 9211284Sandreas.hansson@arm.com page_ptr = 0; 9311284Sandreas.hansson@arm.com} 9411284Sandreas.hansson@arm.com 9511284Sandreas.hansson@arm.comvoid 9611284Sandreas.hansson@arm.comPhysicalMemory::init() 9711284Sandreas.hansson@arm.com{ 9811284Sandreas.hansson@arm.com if (!port) 9911284Sandreas.hansson@arm.com panic("PhysicalMemory not connected to anything!"); 10011284Sandreas.hansson@arm.com port->sendStatusChange(Port::RangeChange); 10111284Sandreas.hansson@arm.com} 10211284Sandreas.hansson@arm.com 10311284Sandreas.hansson@arm.comPhysicalMemory::~PhysicalMemory() 10411284Sandreas.hansson@arm.com{ 10511284Sandreas.hansson@arm.com if (pmem_addr) 10611284Sandreas.hansson@arm.com munmap(pmem_addr, pmem_size); 10711284Sandreas.hansson@arm.com //Remove memPorts? 10811284Sandreas.hansson@arm.com} 10911284Sandreas.hansson@arm.com 11011284Sandreas.hansson@arm.comAddr 11111284Sandreas.hansson@arm.comPhysicalMemory::new_page() 1129725Sandreas.hansson@arm.com{ 1139725Sandreas.hansson@arm.com Addr return_addr = page_ptr << LogVMPageSize; 1149725Sandreas.hansson@arm.com return_addr += base_addr; 1159725Sandreas.hansson@arm.com 1169725Sandreas.hansson@arm.com ++page_ptr; 1179725Sandreas.hansson@arm.com return return_addr; 1189725Sandreas.hansson@arm.com} 1192810SN/A 1204626SN/Aint 12113349Snikos.nikoleris@arm.comPhysicalMemory::deviceBlockSize() 12213349Snikos.nikoleris@arm.com{ 12313349Snikos.nikoleris@arm.com //Can accept anysize request 12411375Sandreas.hansson@arm.com return 0; 12511375Sandreas.hansson@arm.com} 12611375Sandreas.hansson@arm.com 12713859Sodanrc@yahoo.com.brbool 1284626SN/APhysicalMemory::doTimingAccess (Packet *pkt, MemoryPort* memoryPort) 1295875Ssteve.reinhardt@amd.com{ 1305875Ssteve.reinhardt@amd.com doFunctionalAccess(pkt); 1315875Ssteve.reinhardt@amd.com 1325875Ssteve.reinhardt@amd.com // turn packet around to go back to requester 1335875Ssteve.reinhardt@amd.com pkt->makeTimingResponse(); 1345875Ssteve.reinhardt@amd.com MemResponseEvent* response = new MemResponseEvent(pkt, memoryPort); 1355875Ssteve.reinhardt@amd.com response->schedule(curTick + lat); 13610766Sandreas.hansson@arm.com 13711742Snikos.nikoleris@arm.com return true; 13811742Snikos.nikoleris@arm.com} 13911742Snikos.nikoleris@arm.com 14011742Snikos.nikoleris@arm.comTick 14111742Snikos.nikoleris@arm.comPhysicalMemory::doAtomicAccess(Packet *pkt) 14211742Snikos.nikoleris@arm.com{ 14311742Snikos.nikoleris@arm.com doFunctionalAccess(pkt); 14411742Snikos.nikoleris@arm.com return lat; 14511742Snikos.nikoleris@arm.com} 14611742Snikos.nikoleris@arm.com 14711742Snikos.nikoleris@arm.comvoid 14811742Snikos.nikoleris@arm.comPhysicalMemory::doFunctionalAccess(Packet *pkt) 14911742Snikos.nikoleris@arm.com{ 15011742Snikos.nikoleris@arm.com assert(pkt->getAddr() + pkt->getSize() < pmem_size); 15111742Snikos.nikoleris@arm.com 15211742Snikos.nikoleris@arm.com switch (pkt->cmd) { 15311742Snikos.nikoleris@arm.com case Packet::ReadReq: 15411742Snikos.nikoleris@arm.com memcpy(pkt->getPtr<uint8_t>(), 15511741Snikos.nikoleris@arm.com pmem_addr + pkt->getAddr() - base_addr, 15611741Snikos.nikoleris@arm.com pkt->getSize()); 1574626SN/A break; 1585318SN/A case Packet::WriteReq: 15911741Snikos.nikoleris@arm.com memcpy(pmem_addr + pkt->getAddr() - base_addr, 16013859Sodanrc@yahoo.com.br pkt->getPtr<uint8_t>(), 16113859Sodanrc@yahoo.com.br pkt->getSize()); 1624626SN/A // temporary hack: will need to add real LL/SC implementation 1634626SN/A // for cacheless systems later. 1644626SN/A if (pkt->req->getFlags() & LOCKED) { 1654903SN/A pkt->req->setScResult(1); 1664903SN/A } 1674903SN/A break; 16811284Sandreas.hansson@arm.com default: 1694903SN/A panic("unimplemented"); 17011741Snikos.nikoleris@arm.com } 17111741Snikos.nikoleris@arm.com 17212715Snikos.nikoleris@arm.com pkt->result = Packet::Success; 17312715Snikos.nikoleris@arm.com} 17412715Snikos.nikoleris@arm.com 17512715Snikos.nikoleris@arm.comPort * 17612715Snikos.nikoleris@arm.comPhysicalMemory::getPort(const std::string &if_name) 1774903SN/A{ 1784903SN/A if (if_name == "") { 17911740Snikos.nikoleris@arm.com if (port != NULL) 18011740Snikos.nikoleris@arm.com panic("PhysicalMemory::getPort: additional port requested to memory!"); 18111740Snikos.nikoleris@arm.com port = new MemoryPort(name() + "-port", this); 18211740Snikos.nikoleris@arm.com return port; 18311740Snikos.nikoleris@arm.com } else if (if_name == "functional") { 18411740Snikos.nikoleris@arm.com /* special port for functional writes at startup. */ 18511740Snikos.nikoleris@arm.com return new MemoryPort(name() + "-funcport", this); 18611741Snikos.nikoleris@arm.com } else { 18711740Snikos.nikoleris@arm.com panic("PhysicalMemory::getPort: unknown port %s requested", if_name); 18811741Snikos.nikoleris@arm.com } 18911741Snikos.nikoleris@arm.com} 19011740Snikos.nikoleris@arm.com 19113349Snikos.nikoleris@arm.comvoid 19213349Snikos.nikoleris@arm.comPhysicalMemory::recvStatusChange(Port::Status status) 19313349Snikos.nikoleris@arm.com{ 19413349Snikos.nikoleris@arm.com} 19513349Snikos.nikoleris@arm.com 19613349Snikos.nikoleris@arm.comPhysicalMemory::MemoryPort::MemoryPort(const std::string &_name, 19713349Snikos.nikoleris@arm.com PhysicalMemory *_memory) 19813349Snikos.nikoleris@arm.com : Port(_name), memory(_memory) 19913349Snikos.nikoleris@arm.com{ } 20013349Snikos.nikoleris@arm.com 20113349Snikos.nikoleris@arm.comvoid 20213349Snikos.nikoleris@arm.comPhysicalMemory::MemoryPort::recvStatusChange(Port::Status status) 20313349Snikos.nikoleris@arm.com{ 20413349Snikos.nikoleris@arm.com memory->recvStatusChange(status); 20512715Snikos.nikoleris@arm.com} 20613349Snikos.nikoleris@arm.com 20713349Snikos.nikoleris@arm.comvoid 20813349Snikos.nikoleris@arm.comPhysicalMemory::MemoryPort::getDeviceAddressRanges(AddrRangeList &resp, 20912715Snikos.nikoleris@arm.com AddrRangeList &snoop) 21012715Snikos.nikoleris@arm.com{ 21112715Snikos.nikoleris@arm.com memory->getAddressRanges(resp, snoop); 21212715Snikos.nikoleris@arm.com} 21312715Snikos.nikoleris@arm.com 21411740Snikos.nikoleris@arm.comvoid 21511740Snikos.nikoleris@arm.comPhysicalMemory::getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) 21611740Snikos.nikoleris@arm.com{ 21711740Snikos.nikoleris@arm.com snoop.clear(); 21811740Snikos.nikoleris@arm.com resp.clear(); 21911740Snikos.nikoleris@arm.com resp.push_back(RangeSize(base_addr, pmem_size)); 22011740Snikos.nikoleris@arm.com} 22111740Snikos.nikoleris@arm.com 22211740Snikos.nikoleris@arm.comint 22311741Snikos.nikoleris@arm.comPhysicalMemory::MemoryPort::deviceBlockSize() 22413349Snikos.nikoleris@arm.com{ 22513349Snikos.nikoleris@arm.com return memory->deviceBlockSize(); 22613349Snikos.nikoleris@arm.com} 22713349Snikos.nikoleris@arm.com 22813349Snikos.nikoleris@arm.combool 22913349Snikos.nikoleris@arm.comPhysicalMemory::MemoryPort::recvTiming(Packet *pkt) 23013349Snikos.nikoleris@arm.com{ 23113349Snikos.nikoleris@arm.com return memory->doTimingAccess(pkt, this); 23213349Snikos.nikoleris@arm.com} 23313349Snikos.nikoleris@arm.com 23413349Snikos.nikoleris@arm.comTick 23513349Snikos.nikoleris@arm.comPhysicalMemory::MemoryPort::recvAtomic(Packet *pkt) 23613349Snikos.nikoleris@arm.com{ 23713349Snikos.nikoleris@arm.com return memory->doAtomicAccess(pkt); 23813349Snikos.nikoleris@arm.com} 23913349Snikos.nikoleris@arm.com 24013349Snikos.nikoleris@arm.comvoid 24113349Snikos.nikoleris@arm.comPhysicalMemory::MemoryPort::recvFunctional(Packet *pkt) 24213349Snikos.nikoleris@arm.com{ 24313349Snikos.nikoleris@arm.com memory->doFunctionalAccess(pkt); 24413349Snikos.nikoleris@arm.com} 24513349Snikos.nikoleris@arm.com 24613349Snikos.nikoleris@arm.com 24713349Snikos.nikoleris@arm.com 24813349Snikos.nikoleris@arm.comvoid 24913349Snikos.nikoleris@arm.comPhysicalMemory::serialize(ostream &os) 25013349Snikos.nikoleris@arm.com{ 25113349Snikos.nikoleris@arm.com gzFile compressedMem; 25213349Snikos.nikoleris@arm.com string filename = name() + ".physmem"; 25313349Snikos.nikoleris@arm.com 25411741Snikos.nikoleris@arm.com SERIALIZE_SCALAR(pmem_size); 25511741Snikos.nikoleris@arm.com SERIALIZE_SCALAR(filename); 25613349Snikos.nikoleris@arm.com 25713349Snikos.nikoleris@arm.com // write memory file 25811741Snikos.nikoleris@arm.com string thefile = Checkpoint::dir() + "/" + filename.c_str(); 25911741Snikos.nikoleris@arm.com int fd = creat(thefile.c_str(), 0664); 26012715Snikos.nikoleris@arm.com if (fd < 0) { 26113349Snikos.nikoleris@arm.com perror("creat"); 26211741Snikos.nikoleris@arm.com fatal("Can't open physical memory checkpoint file '%s'\n", filename); 26311741Snikos.nikoleris@arm.com } 26411741Snikos.nikoleris@arm.com 26511741Snikos.nikoleris@arm.com compressedMem = gzdopen(fd, "wb"); 26611741Snikos.nikoleris@arm.com if (compressedMem == NULL) 26711741Snikos.nikoleris@arm.com fatal("Insufficient memory to allocate compression state for %s\n", 26811741Snikos.nikoleris@arm.com filename); 26911741Snikos.nikoleris@arm.com 27011741Snikos.nikoleris@arm.com if (gzwrite(compressedMem, pmem_addr, pmem_size) != pmem_size) { 27111741Snikos.nikoleris@arm.com fatal("Write failed on physical memory checkpoint file '%s'\n", 27211741Snikos.nikoleris@arm.com filename); 27311741Snikos.nikoleris@arm.com } 27411741Snikos.nikoleris@arm.com 27511741Snikos.nikoleris@arm.com if (gzclose(compressedMem)) 2765318SN/A fatal("Close failed on physical memory checkpoint file '%s'\n", 27713349Snikos.nikoleris@arm.com filename); 27811357Sstephan.diestelhorst@arm.com} 27911357Sstephan.diestelhorst@arm.com 28011357Sstephan.diestelhorst@arm.comvoid 28111357Sstephan.diestelhorst@arm.comPhysicalMemory::unserialize(Checkpoint *cp, const string §ion) 28211357Sstephan.diestelhorst@arm.com{ 2834903SN/A gzFile compressedMem; 28411357Sstephan.diestelhorst@arm.com long *tempPage; 2854908SN/A long *pmem_current; 28612791Snikos.nikoleris@arm.com uint64_t curSize; 28712823Srmk35@cl.cam.ac.uk uint32_t bytesRead; 2885314SN/A const int chunkSize = 16384; 2895314SN/A 29013349Snikos.nikoleris@arm.com 29113349Snikos.nikoleris@arm.com // unmap file that was mmaped in the constructor 29213349Snikos.nikoleris@arm.com munmap(pmem_addr, pmem_size); 29313349Snikos.nikoleris@arm.com 29413349Snikos.nikoleris@arm.com string filename; 29513349Snikos.nikoleris@arm.com 29613349Snikos.nikoleris@arm.com UNSERIALIZE_SCALAR(pmem_size); 29713349Snikos.nikoleris@arm.com UNSERIALIZE_SCALAR(filename); 29813349Snikos.nikoleris@arm.com 29913349Snikos.nikoleris@arm.com filename = cp->cptDir + "/" + filename; 30013349Snikos.nikoleris@arm.com 30113349Snikos.nikoleris@arm.com // mmap memoryfile 30213349Snikos.nikoleris@arm.com int fd = open(filename.c_str(), O_RDONLY); 30313349Snikos.nikoleris@arm.com if (fd < 0) { 30413349Snikos.nikoleris@arm.com perror("open"); 30513349Snikos.nikoleris@arm.com fatal("Can't open physical memory checkpoint file '%s'", filename); 30613349Snikos.nikoleris@arm.com } 30713349Snikos.nikoleris@arm.com 30813349Snikos.nikoleris@arm.com compressedMem = gzdopen(fd, "rb"); 30913349Snikos.nikoleris@arm.com if (compressedMem == NULL) 31013349Snikos.nikoleris@arm.com fatal("Insufficient memory to allocate compression state for %s\n", 31113349Snikos.nikoleris@arm.com filename); 31213349Snikos.nikoleris@arm.com 31313349Snikos.nikoleris@arm.com 31413349Snikos.nikoleris@arm.com pmem_addr = (uint8_t *)mmap(NULL, pmem_size, PROT_READ | PROT_WRITE, 31513349Snikos.nikoleris@arm.com MAP_ANON | MAP_PRIVATE, -1, 0); 31613349Snikos.nikoleris@arm.com 31713349Snikos.nikoleris@arm.com if (pmem_addr == (void *)MAP_FAILED) { 31813349Snikos.nikoleris@arm.com perror("mmap"); 31913349Snikos.nikoleris@arm.com fatal("Could not mmap physical memory!\n"); 32013349Snikos.nikoleris@arm.com } 32113349Snikos.nikoleris@arm.com 32213349Snikos.nikoleris@arm.com curSize = 0; 3234903SN/A tempPage = (long*)malloc(chunkSize); 3244903SN/A if (tempPage == NULL) 3252810SN/A fatal("Unable to malloc memory to read file %s\n", filename); 3262810SN/A 3272810SN/A /* Only copy bytes that are non-zero, so we don't give the VM system hell */ 3282810SN/A while (curSize < pmem_size) { 3294903SN/A bytesRead = gzread(compressedMem, tempPage, chunkSize); 3307667Ssteve.reinhardt@amd.com if (bytesRead != chunkSize && bytesRead != pmem_size - curSize) 3317667Ssteve.reinhardt@amd.com fatal("Read failed on physical memory checkpoint file '%s'" 3327667Ssteve.reinhardt@amd.com " got %d bytes, expected %d or %d bytes\n", 3337667Ssteve.reinhardt@amd.com filename, bytesRead, chunkSize, pmem_size-curSize); 3347667Ssteve.reinhardt@amd.com 33511284Sandreas.hansson@arm.com assert(bytesRead % sizeof(long) == 0); 33611284Sandreas.hansson@arm.com 3379725Sandreas.hansson@arm.com for (int x = 0; x < bytesRead/sizeof(long); x++) 33812599Snikos.nikoleris@arm.com { 33912599Snikos.nikoleris@arm.com if (*(tempPage+x) != 0) { 34012599Snikos.nikoleris@arm.com pmem_current = (long*)(pmem_addr + curSize + x * sizeof(long)); 34112599Snikos.nikoleris@arm.com *pmem_current = *(tempPage+x); 34212599Snikos.nikoleris@arm.com } 34311284Sandreas.hansson@arm.com } 34411284Sandreas.hansson@arm.com curSize += bytesRead; 3457667Ssteve.reinhardt@amd.com } 3467667Ssteve.reinhardt@amd.com 3477667Ssteve.reinhardt@amd.com free(tempPage); 3487667Ssteve.reinhardt@amd.com 3497667Ssteve.reinhardt@amd.com if (gzclose(compressedMem)) 3507667Ssteve.reinhardt@amd.com fatal("Close failed on physical memory checkpoint file '%s'\n", 3517667Ssteve.reinhardt@amd.com filename); 3527667Ssteve.reinhardt@amd.com 3537667Ssteve.reinhardt@amd.com} 3544665SN/A 35513875SAndrea.Mondelli@ucf.edu 35611375Sandreas.hansson@arm.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory) 35711741Snikos.nikoleris@arm.com 35811741Snikos.nikoleris@arm.com Param<string> file; 35911741Snikos.nikoleris@arm.com Param<Range<Addr> > range; 36012715Snikos.nikoleris@arm.com Param<Tick> latency; 36112715Snikos.nikoleris@arm.com 36212715Snikos.nikoleris@arm.comEND_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory) 36312715Snikos.nikoleris@arm.com 36412715Snikos.nikoleris@arm.comBEGIN_INIT_SIM_OBJECT_PARAMS(PhysicalMemory) 36512715Snikos.nikoleris@arm.com 36612715Snikos.nikoleris@arm.com INIT_PARAM_DFLT(file, "memory mapped file", ""), 36712715Snikos.nikoleris@arm.com INIT_PARAM(range, "Device Address Range"), 36812715Snikos.nikoleris@arm.com INIT_PARAM(latency, "Memory access latency") 36912715Snikos.nikoleris@arm.com 3709725Sandreas.hansson@arm.comEND_INIT_SIM_OBJECT_PARAMS(PhysicalMemory) 37112793Snikos.nikoleris@arm.com 37212793Snikos.nikoleris@arm.comCREATE_SIM_OBJECT(PhysicalMemory) 37312793Snikos.nikoleris@arm.com{ 37412793Snikos.nikoleris@arm.com 37512793Snikos.nikoleris@arm.com return new PhysicalMemory(getInstanceName(), latency); 37612793Snikos.nikoleris@arm.com} 37712793Snikos.nikoleris@arm.com 37812793Snikos.nikoleris@arm.comREGISTER_SIM_OBJECT("PhysicalMemory", PhysicalMemory) 37912793Snikos.nikoleris@arm.com