physical.cc revision 2592
19646SChris.Emmons@arm.com/* 210839Sandreas.sandberg@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 39646SChris.Emmons@arm.com * All rights reserved. 49646SChris.Emmons@arm.com * 59646SChris.Emmons@arm.com * Redistribution and use in source and binary forms, with or without 69646SChris.Emmons@arm.com * modification, are permitted provided that the following conditions are 79646SChris.Emmons@arm.com * met: redistributions of source code must retain the above copyright 89646SChris.Emmons@arm.com * notice, this list of conditions and the following disclaimer; 99646SChris.Emmons@arm.com * redistributions in binary form must reproduce the above copyright 109646SChris.Emmons@arm.com * notice, this list of conditions and the following disclaimer in the 119646SChris.Emmons@arm.com * documentation and/or other materials provided with the distribution; 129646SChris.Emmons@arm.com * neither the name of the copyright holders nor the names of its 139646SChris.Emmons@arm.com * contributors may be used to endorse or promote products derived from 149646SChris.Emmons@arm.com * this software without specific prior written permission. 159646SChris.Emmons@arm.com * 169646SChris.Emmons@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179646SChris.Emmons@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189646SChris.Emmons@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199646SChris.Emmons@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209646SChris.Emmons@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219646SChris.Emmons@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229646SChris.Emmons@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239646SChris.Emmons@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249646SChris.Emmons@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259646SChris.Emmons@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269646SChris.Emmons@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279646SChris.Emmons@arm.com */ 289646SChris.Emmons@arm.com 299646SChris.Emmons@arm.com#include <sys/types.h> 309646SChris.Emmons@arm.com#include <sys/mman.h> 319646SChris.Emmons@arm.com#include <errno.h> 329646SChris.Emmons@arm.com#include <fcntl.h> 339646SChris.Emmons@arm.com#include <unistd.h> 349646SChris.Emmons@arm.com#include <zlib.h> 359646SChris.Emmons@arm.com 369646SChris.Emmons@arm.com#include <cstdio> 379646SChris.Emmons@arm.com#include <iostream> 3811090Sandreas.sandberg@arm.com#include <string> 399646SChris.Emmons@arm.com 409646SChris.Emmons@arm.com 4110839Sandreas.sandberg@arm.com#include "base/misc.hh" 4210839Sandreas.sandberg@arm.com#include "config/full_system.hh" 439646SChris.Emmons@arm.com#include "mem/packet_impl.hh" 449646SChris.Emmons@arm.com#include "mem/physical.hh" 459646SChris.Emmons@arm.com#include "sim/host.hh" 4611090Sandreas.sandberg@arm.com#include "sim/builder.hh" 479646SChris.Emmons@arm.com#include "sim/eventq.hh" 489646SChris.Emmons@arm.com#include "arch/isa_traits.hh" 499646SChris.Emmons@arm.com 509646SChris.Emmons@arm.com 519646SChris.Emmons@arm.comusing namespace std; 5211090Sandreas.sandberg@arm.comusing namespace TheISA; 539646SChris.Emmons@arm.com 549646SChris.Emmons@arm.comPhysicalMemory::MemResponseEvent::MemResponseEvent(Packet &pkt, MemoryPort* _m) 559646SChris.Emmons@arm.com : Event(&mainEventQueue, CPU_Tick_Pri), pkt(pkt), memoryPort(_m) 569646SChris.Emmons@arm.com{ 579646SChris.Emmons@arm.com 589646SChris.Emmons@arm.com this->setFlags(AutoDelete); 5911090Sandreas.sandberg@arm.com} 6011090Sandreas.sandberg@arm.com 6111090Sandreas.sandberg@arm.comvoid 6211090Sandreas.sandberg@arm.comPhysicalMemory::MemResponseEvent::process() 6311090Sandreas.sandberg@arm.com{ 6411090Sandreas.sandberg@arm.com memoryPort->sendTiming(pkt); 6511090Sandreas.sandberg@arm.com} 6611090Sandreas.sandberg@arm.com 6711090Sandreas.sandberg@arm.comconst char * 6811090Sandreas.sandberg@arm.comPhysicalMemory::MemResponseEvent::description() 6911090Sandreas.sandberg@arm.com{ 7011090Sandreas.sandberg@arm.com return "Physical Memory Timing Access respnse event"; 7111090Sandreas.sandberg@arm.com} 7211090Sandreas.sandberg@arm.com 739646SChris.Emmons@arm.comPhysicalMemory::PhysicalMemory(const string &n, Tick latency) 749646SChris.Emmons@arm.com : MemObject(n),base_addr(0), pmem_addr(NULL), port(NULL), lat(latency) 7511090Sandreas.sandberg@arm.com{ 769646SChris.Emmons@arm.com // Hardcoded to 128 MB for now. 779646SChris.Emmons@arm.com pmem_size = 1 << 27; 7811090Sandreas.sandberg@arm.com 7911090Sandreas.sandberg@arm.com if (pmem_size % TheISA::PageBytes != 0) 8011090Sandreas.sandberg@arm.com panic("Memory Size not divisible by page size\n"); 8111090Sandreas.sandberg@arm.com 8211090Sandreas.sandberg@arm.com int map_flags = MAP_ANON | MAP_PRIVATE; 839646SChris.Emmons@arm.com pmem_addr = (uint8_t *)mmap(NULL, pmem_size, PROT_READ | PROT_WRITE, 8411090Sandreas.sandberg@arm.com map_flags, -1, 0); 8511090Sandreas.sandberg@arm.com 8611090Sandreas.sandberg@arm.com if (pmem_addr == (void *)MAP_FAILED) { 8711090Sandreas.sandberg@arm.com perror("mmap"); 889646SChris.Emmons@arm.com fatal("Could not mmap!\n"); 899646SChris.Emmons@arm.com } 9011090Sandreas.sandberg@arm.com 919646SChris.Emmons@arm.com page_ptr = 0; 929646SChris.Emmons@arm.com} 939646SChris.Emmons@arm.com 949646SChris.Emmons@arm.comvoid 959646SChris.Emmons@arm.comPhysicalMemory::init() 969646SChris.Emmons@arm.com{ 9711090Sandreas.sandberg@arm.com if (!port) 9811091Sandreas.sandberg@arm.com panic("PhysicalMemory not connected to anything!"); 9911091Sandreas.sandberg@arm.com port->sendStatusChange(Port::RangeChange); 10011091Sandreas.sandberg@arm.com} 10111091Sandreas.sandberg@arm.com 10211091Sandreas.sandberg@arm.comPhysicalMemory::~PhysicalMemory() 10311091Sandreas.sandberg@arm.com{ 10411091Sandreas.sandberg@arm.com if (pmem_addr) 10511091Sandreas.sandberg@arm.com munmap(pmem_addr, pmem_size); 10611091Sandreas.sandberg@arm.com //Remove memPorts? 10711091Sandreas.sandberg@arm.com} 10811091Sandreas.sandberg@arm.com 10911091Sandreas.sandberg@arm.comAddr 11011090Sandreas.sandberg@arm.comPhysicalMemory::new_page() 11111090Sandreas.sandberg@arm.com{ 11211090Sandreas.sandberg@arm.com Addr return_addr = page_ptr << LogVMPageSize; 11311090Sandreas.sandberg@arm.com return_addr += base_addr; 11411090Sandreas.sandberg@arm.com 11511090Sandreas.sandberg@arm.com ++page_ptr; 11611090Sandreas.sandberg@arm.com return return_addr; 11711090Sandreas.sandberg@arm.com} 11811090Sandreas.sandberg@arm.com 11911090Sandreas.sandberg@arm.comint 12011090Sandreas.sandberg@arm.comPhysicalMemory::deviceBlockSize() 12111090Sandreas.sandberg@arm.com{ 12211090Sandreas.sandberg@arm.com //Can accept anysize request 12311090Sandreas.sandberg@arm.com return 0; 12411090Sandreas.sandberg@arm.com} 12511090Sandreas.sandberg@arm.com 12611090Sandreas.sandberg@arm.combool 12711090Sandreas.sandberg@arm.comPhysicalMemory::doTimingAccess (Packet &pkt, MemoryPort* memoryPort) 12811090Sandreas.sandberg@arm.com{ 12911090Sandreas.sandberg@arm.com doFunctionalAccess(pkt); 13011090Sandreas.sandberg@arm.com 13111090Sandreas.sandberg@arm.com MemResponseEvent* response = new MemResponseEvent(pkt, memoryPort); 13211090Sandreas.sandberg@arm.com response->schedule(curTick + lat); 13311090Sandreas.sandberg@arm.com 13411090Sandreas.sandberg@arm.com return true; 13511090Sandreas.sandberg@arm.com} 13611090Sandreas.sandberg@arm.com 13711090Sandreas.sandberg@arm.comTick 13811090Sandreas.sandberg@arm.comPhysicalMemory::doAtomicAccess(Packet &pkt) 13911090Sandreas.sandberg@arm.com{ 14011090Sandreas.sandberg@arm.com doFunctionalAccess(pkt); 14111090Sandreas.sandberg@arm.com pkt.time = curTick + lat; 14211090Sandreas.sandberg@arm.com return curTick + lat; 14311090Sandreas.sandberg@arm.com} 14411090Sandreas.sandberg@arm.com 14511090Sandreas.sandberg@arm.comvoid 14611090Sandreas.sandberg@arm.comPhysicalMemory::doFunctionalAccess(Packet &pkt) 14711090Sandreas.sandberg@arm.com{ 14811090Sandreas.sandberg@arm.com assert(pkt.addr + pkt.size < pmem_size); 14911090Sandreas.sandberg@arm.com 15011090Sandreas.sandberg@arm.com switch (pkt.cmd) { 15111090Sandreas.sandberg@arm.com case Read: 15211090Sandreas.sandberg@arm.com memcpy(pkt.getPtr<uint8_t>(), pmem_addr + pkt.addr - base_addr, 15311090Sandreas.sandberg@arm.com pkt.size); 15411090Sandreas.sandberg@arm.com break; 15511090Sandreas.sandberg@arm.com case Write: 15611090Sandreas.sandberg@arm.com memcpy(pmem_addr + pkt.addr - base_addr, pkt.getPtr<uint8_t>(), 15711090Sandreas.sandberg@arm.com pkt.size); 15811090Sandreas.sandberg@arm.com break; 15911090Sandreas.sandberg@arm.com default: 16011090Sandreas.sandberg@arm.com panic("unimplemented"); 16111090Sandreas.sandberg@arm.com } 16211090Sandreas.sandberg@arm.com 16311090Sandreas.sandberg@arm.com pkt.result = Success; 16411090Sandreas.sandberg@arm.com} 16511090Sandreas.sandberg@arm.com 16611090Sandreas.sandberg@arm.comPort * 16711090Sandreas.sandberg@arm.comPhysicalMemory::getPort(const std::string &if_name) 16811090Sandreas.sandberg@arm.com{ 16911090Sandreas.sandberg@arm.com if (if_name == "") { 17011090Sandreas.sandberg@arm.com if (port != NULL) 17111090Sandreas.sandberg@arm.com panic("PhysicalMemory::getPort: additional port requested to memory!"); 17211090Sandreas.sandberg@arm.com port = new MemoryPort(this); 17311090Sandreas.sandberg@arm.com return port; 17411090Sandreas.sandberg@arm.com } else if (if_name == "functional") { 17511090Sandreas.sandberg@arm.com /* special port for functional writes at startup. */ 17611090Sandreas.sandberg@arm.com return new MemoryPort(this); 17711090Sandreas.sandberg@arm.com } else { 17811090Sandreas.sandberg@arm.com panic("PhysicalMemory::getPort: unknown port %s requested", if_name); 17911090Sandreas.sandberg@arm.com } 18011090Sandreas.sandberg@arm.com} 18111090Sandreas.sandberg@arm.com 18211090Sandreas.sandberg@arm.comvoid 18311090Sandreas.sandberg@arm.comPhysicalMemory::recvStatusChange(Port::Status status) 18411090Sandreas.sandberg@arm.com{ 18511090Sandreas.sandberg@arm.com} 18611090Sandreas.sandberg@arm.com 18711090Sandreas.sandberg@arm.comPhysicalMemory::MemoryPort::MemoryPort(PhysicalMemory *_memory) 18811090Sandreas.sandberg@arm.com : memory(_memory) 18911090Sandreas.sandberg@arm.com{ } 19011090Sandreas.sandberg@arm.com 19111090Sandreas.sandberg@arm.comvoid 19211090Sandreas.sandberg@arm.comPhysicalMemory::MemoryPort::recvStatusChange(Port::Status status) 19311090Sandreas.sandberg@arm.com{ 19411090Sandreas.sandberg@arm.com memory->recvStatusChange(status); 19511090Sandreas.sandberg@arm.com} 19611090Sandreas.sandberg@arm.com 19711090Sandreas.sandberg@arm.comvoid 19811090Sandreas.sandberg@arm.comPhysicalMemory::MemoryPort::getDeviceAddressRanges(AddrRangeList &resp, 19911090Sandreas.sandberg@arm.com AddrRangeList &snoop) 20011090Sandreas.sandberg@arm.com{ 20111090Sandreas.sandberg@arm.com memory->getAddressRanges(resp, snoop); 20211090Sandreas.sandberg@arm.com} 20311090Sandreas.sandberg@arm.com 20411090Sandreas.sandberg@arm.comvoid 20511090Sandreas.sandberg@arm.comPhysicalMemory::getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) 20611090Sandreas.sandberg@arm.com{ 20711090Sandreas.sandberg@arm.com snoop.clear(); 20811090Sandreas.sandberg@arm.com resp.clear(); 20911090Sandreas.sandberg@arm.com resp.push_back(RangeSize(base_addr, pmem_size)); 21011090Sandreas.sandberg@arm.com} 21111090Sandreas.sandberg@arm.com 21211090Sandreas.sandberg@arm.comint 2139646SChris.Emmons@arm.comPhysicalMemory::MemoryPort::deviceBlockSize() 2149646SChris.Emmons@arm.com{ 2159646SChris.Emmons@arm.com return memory->deviceBlockSize(); 2169646SChris.Emmons@arm.com} 21711090Sandreas.sandberg@arm.com 21811090Sandreas.sandberg@arm.combool 2199646SChris.Emmons@arm.comPhysicalMemory::MemoryPort::recvTiming(Packet &pkt) 22011090Sandreas.sandberg@arm.com{ 22111090Sandreas.sandberg@arm.com return memory->doTimingAccess(pkt, this); 22211090Sandreas.sandberg@arm.com} 22311090Sandreas.sandberg@arm.com 2249646SChris.Emmons@arm.comTick 22511090Sandreas.sandberg@arm.comPhysicalMemory::MemoryPort::recvAtomic(Packet &pkt) 22611090Sandreas.sandberg@arm.com{ 2279646SChris.Emmons@arm.com return memory->doAtomicAccess(pkt); 2289646SChris.Emmons@arm.com} 2299646SChris.Emmons@arm.com 2309646SChris.Emmons@arm.comvoid 2319646SChris.Emmons@arm.comPhysicalMemory::MemoryPort::recvFunctional(Packet &pkt) 2329646SChris.Emmons@arm.com{ 2339646SChris.Emmons@arm.com memory->doFunctionalAccess(pkt); 2349646SChris.Emmons@arm.com} 2359646SChris.Emmons@arm.com 2369646SChris.Emmons@arm.com 2379646SChris.Emmons@arm.com 23811090Sandreas.sandberg@arm.comvoid 2399646SChris.Emmons@arm.comPhysicalMemory::serialize(ostream &os) 24011090Sandreas.sandberg@arm.com{ 24111090Sandreas.sandberg@arm.com gzFile compressedMem; 24211090Sandreas.sandberg@arm.com string filename = name() + ".physmem"; 24311090Sandreas.sandberg@arm.com 24411090Sandreas.sandberg@arm.com SERIALIZE_SCALAR(pmem_size); 24511090Sandreas.sandberg@arm.com SERIALIZE_SCALAR(filename); 2469646SChris.Emmons@arm.com 24711090Sandreas.sandberg@arm.com // write memory file 2489646SChris.Emmons@arm.com string thefile = Checkpoint::dir() + "/" + filename.c_str(); 2499646SChris.Emmons@arm.com int fd = creat(thefile.c_str(), 0664); 2509646SChris.Emmons@arm.com if (fd < 0) { 2519646SChris.Emmons@arm.com perror("creat"); 2529646SChris.Emmons@arm.com fatal("Can't open physical memory checkpoint file '%s'\n", filename); 25311090Sandreas.sandberg@arm.com } 25411090Sandreas.sandberg@arm.com 2559646SChris.Emmons@arm.com compressedMem = gzdopen(fd, "wb"); 25611090Sandreas.sandberg@arm.com if (compressedMem == NULL) 25711090Sandreas.sandberg@arm.com fatal("Insufficient memory to allocate compression state for %s\n", 25810839Sandreas.sandberg@arm.com filename); 25911090Sandreas.sandberg@arm.com 26011090Sandreas.sandberg@arm.com if (gzwrite(compressedMem, pmem_addr, pmem_size) != pmem_size) { 26111090Sandreas.sandberg@arm.com fatal("Write failed on physical memory checkpoint file '%s'\n", 26211090Sandreas.sandberg@arm.com filename); 26311090Sandreas.sandberg@arm.com } 2649646SChris.Emmons@arm.com 26511090Sandreas.sandberg@arm.com if (gzclose(compressedMem)) 26611090Sandreas.sandberg@arm.com fatal("Close failed on physical memory checkpoint file '%s'\n", 26711090Sandreas.sandberg@arm.com filename); 26811090Sandreas.sandberg@arm.com} 26911090Sandreas.sandberg@arm.com 2709646SChris.Emmons@arm.comvoid 27111090Sandreas.sandberg@arm.comPhysicalMemory::unserialize(Checkpoint *cp, const string §ion) 27211090Sandreas.sandberg@arm.com{ 27311090Sandreas.sandberg@arm.com gzFile compressedMem; 27411090Sandreas.sandberg@arm.com long *tempPage; 27511090Sandreas.sandberg@arm.com long *pmem_current; 27611090Sandreas.sandberg@arm.com uint64_t curSize; 27711090Sandreas.sandberg@arm.com uint32_t bytesRead; 27811090Sandreas.sandberg@arm.com const int chunkSize = 16384; 27911090Sandreas.sandberg@arm.com 28010839Sandreas.sandberg@arm.com 28111090Sandreas.sandberg@arm.com // unmap file that was mmaped in the constructor 28211090Sandreas.sandberg@arm.com munmap(pmem_addr, pmem_size); 28311090Sandreas.sandberg@arm.com 28411090Sandreas.sandberg@arm.com string filename; 28511090Sandreas.sandberg@arm.com 28610839Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(pmem_size); 28711090Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(filename); 28811090Sandreas.sandberg@arm.com 2899646SChris.Emmons@arm.com filename = cp->cptDir + "/" + filename; 2909646SChris.Emmons@arm.com 2919646SChris.Emmons@arm.com // mmap memoryfile 2929646SChris.Emmons@arm.com int fd = open(filename.c_str(), O_RDONLY); 29311090Sandreas.sandberg@arm.com if (fd < 0) { 2949646SChris.Emmons@arm.com perror("open"); 29511090Sandreas.sandberg@arm.com fatal("Can't open physical memory checkpoint file '%s'", filename); 29611090Sandreas.sandberg@arm.com } 29711090Sandreas.sandberg@arm.com 2989646SChris.Emmons@arm.com compressedMem = gzdopen(fd, "rb"); 29911090Sandreas.sandberg@arm.com if (compressedMem == NULL) 30011090Sandreas.sandberg@arm.com fatal("Insufficient memory to allocate compression state for %s\n", 30111090Sandreas.sandberg@arm.com filename); 30211090Sandreas.sandberg@arm.com 30311090Sandreas.sandberg@arm.com 30411090Sandreas.sandberg@arm.com pmem_addr = (uint8_t *)mmap(NULL, pmem_size, PROT_READ | PROT_WRITE, 30511090Sandreas.sandberg@arm.com MAP_ANON | MAP_PRIVATE, -1, 0); 30611090Sandreas.sandberg@arm.com 30711090Sandreas.sandberg@arm.com if (pmem_addr == (void *)MAP_FAILED) { 30811090Sandreas.sandberg@arm.com perror("mmap"); 30911090Sandreas.sandberg@arm.com fatal("Could not mmap physical memory!\n"); 31011090Sandreas.sandberg@arm.com } 31111090Sandreas.sandberg@arm.com 31211090Sandreas.sandberg@arm.com curSize = 0; 31311090Sandreas.sandberg@arm.com tempPage = (long*)malloc(chunkSize); 31411090Sandreas.sandberg@arm.com if (tempPage == NULL) 31511090Sandreas.sandberg@arm.com fatal("Unable to malloc memory to read file %s\n", filename); 31611090Sandreas.sandberg@arm.com 31711090Sandreas.sandberg@arm.com /* Only copy bytes that are non-zero, so we don't give the VM system hell */ 31811090Sandreas.sandberg@arm.com while (curSize < pmem_size) { 31911090Sandreas.sandberg@arm.com bytesRead = gzread(compressedMem, tempPage, chunkSize); 32011090Sandreas.sandberg@arm.com if (bytesRead != chunkSize && bytesRead != pmem_size - curSize) 32111090Sandreas.sandberg@arm.com fatal("Read failed on physical memory checkpoint file '%s'" 32211090Sandreas.sandberg@arm.com " got %d bytes, expected %d or %d bytes\n", 32311090Sandreas.sandberg@arm.com filename, bytesRead, chunkSize, pmem_size-curSize); 32411090Sandreas.sandberg@arm.com 32511090Sandreas.sandberg@arm.com assert(bytesRead % sizeof(long) == 0); 32611090Sandreas.sandberg@arm.com 32711090Sandreas.sandberg@arm.com for (int x = 0; x < bytesRead/sizeof(long); x++) 32811090Sandreas.sandberg@arm.com { 32911090Sandreas.sandberg@arm.com if (*(tempPage+x) != 0) { 33011090Sandreas.sandberg@arm.com pmem_current = (long*)(pmem_addr + curSize + x * sizeof(long)); 33111090Sandreas.sandberg@arm.com *pmem_current = *(tempPage+x); 33211090Sandreas.sandberg@arm.com } 33311090Sandreas.sandberg@arm.com } 33411090Sandreas.sandberg@arm.com curSize += bytesRead; 33511090Sandreas.sandberg@arm.com } 33611090Sandreas.sandberg@arm.com 33711090Sandreas.sandberg@arm.com free(tempPage); 33811090Sandreas.sandberg@arm.com 33911090Sandreas.sandberg@arm.com if (gzclose(compressedMem)) 34011090Sandreas.sandberg@arm.com fatal("Close failed on physical memory checkpoint file '%s'\n", 34111090Sandreas.sandberg@arm.com filename); 34211090Sandreas.sandberg@arm.com 34311090Sandreas.sandberg@arm.com} 34411090Sandreas.sandberg@arm.com 34511090Sandreas.sandberg@arm.com 34611090Sandreas.sandberg@arm.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory) 34711090Sandreas.sandberg@arm.com 34811090Sandreas.sandberg@arm.com Param<string> file; 34911090Sandreas.sandberg@arm.com Param<Range<Addr> > range; 35011090Sandreas.sandberg@arm.com Param<Tick> latency; 35111090Sandreas.sandberg@arm.com 35211090Sandreas.sandberg@arm.comEND_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory) 35311090Sandreas.sandberg@arm.com 35411090Sandreas.sandberg@arm.comBEGIN_INIT_SIM_OBJECT_PARAMS(PhysicalMemory) 35511090Sandreas.sandberg@arm.com 35611090Sandreas.sandberg@arm.com INIT_PARAM_DFLT(file, "memory mapped file", ""), 35711090Sandreas.sandberg@arm.com INIT_PARAM(range, "Device Address Range"), 35811090Sandreas.sandberg@arm.com INIT_PARAM(latency, "Memory access latency") 35911090Sandreas.sandberg@arm.com 36011090Sandreas.sandberg@arm.comEND_INIT_SIM_OBJECT_PARAMS(PhysicalMemory) 36111090Sandreas.sandberg@arm.com 36211090Sandreas.sandberg@arm.comCREATE_SIM_OBJECT(PhysicalMemory) 36311090Sandreas.sandberg@arm.com{ 36411090Sandreas.sandberg@arm.com 36511090Sandreas.sandberg@arm.com return new PhysicalMemory(getInstanceName(), latency); 36611090Sandreas.sandberg@arm.com} 36711090Sandreas.sandberg@arm.com 36811090Sandreas.sandberg@arm.comREGISTER_SIM_OBJECT("PhysicalMemory", PhysicalMemory) 36911090Sandreas.sandberg@arm.com