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 &section)
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