diff options
Diffstat (limited to 'mem/physical.cc')
-rw-r--r-- | mem/physical.cc | 373 |
1 files changed, 0 insertions, 373 deletions
diff --git a/mem/physical.cc b/mem/physical.cc deleted file mode 100644 index bc2500678..000000000 --- a/mem/physical.cc +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright (c) 2001-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/types.h> -#include <sys/mman.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <zlib.h> - -#include <iostream> -#include <string> - - -#include "base/misc.hh" -#include "config/full_system.hh" -#include "mem/packet_impl.hh" -#include "mem/physical.hh" -#include "sim/host.hh" -#include "sim/builder.hh" -#include "sim/eventq.hh" -#include "arch/isa_traits.hh" - - -using namespace std; -using namespace TheISA; - -PhysicalMemory::MemResponseEvent::MemResponseEvent(Packet *pkt, MemoryPort* _m) - : Event(&mainEventQueue, CPU_Tick_Pri), pkt(pkt), memoryPort(_m) -{ - - this->setFlags(AutoDelete); -} - -void -PhysicalMemory::MemResponseEvent::process() -{ - memoryPort->sendTiming(pkt); -} - -const char * -PhysicalMemory::MemResponseEvent::description() -{ - return "Physical Memory Timing Access respnse event"; -} - -PhysicalMemory::PhysicalMemory(const string &n, Tick latency) - : MemObject(n),base_addr(0), pmem_addr(NULL), port(NULL), lat(latency) -{ - // Hardcoded to 128 MB for now. - pmem_size = 1 << 27; - - if (pmem_size % TheISA::PageBytes != 0) - panic("Memory Size not divisible by page size\n"); - - int map_flags = MAP_ANON | MAP_PRIVATE; - pmem_addr = (uint8_t *)mmap(NULL, pmem_size, PROT_READ | PROT_WRITE, - map_flags, -1, 0); - - if (pmem_addr == (void *)MAP_FAILED) { - perror("mmap"); - fatal("Could not mmap!\n"); - } - - page_ptr = 0; -} - -void -PhysicalMemory::init() -{ - if (!port) - panic("PhysicalMemory not connected to anything!"); - port->sendStatusChange(Port::RangeChange); -} - -PhysicalMemory::~PhysicalMemory() -{ - if (pmem_addr) - munmap(pmem_addr, pmem_size); - //Remove memPorts? -} - -Addr -PhysicalMemory::new_page() -{ - Addr return_addr = page_ptr << LogVMPageSize; - return_addr += base_addr; - - ++page_ptr; - return return_addr; -} - -int -PhysicalMemory::deviceBlockSize() -{ - //Can accept anysize request - return 0; -} - -bool -PhysicalMemory::doTimingAccess (Packet *pkt, MemoryPort* memoryPort) -{ - doFunctionalAccess(pkt); - - pkt->dest = pkt->src; - MemResponseEvent* response = new MemResponseEvent(pkt, memoryPort); - response->schedule(curTick + lat); - - return true; -} - -Tick -PhysicalMemory::doAtomicAccess(Packet *pkt) -{ - doFunctionalAccess(pkt); - pkt->time = curTick + lat; - return curTick + lat; -} - -void -PhysicalMemory::doFunctionalAccess(Packet *pkt) -{ - assert(pkt->addr + pkt->size < pmem_size); - - switch (pkt->cmd) { - case Read: - memcpy(pkt->getPtr<uint8_t>(), pmem_addr + pkt->addr - base_addr, - pkt->size); - break; - case Write: - memcpy(pmem_addr + pkt->addr - base_addr, pkt->getPtr<uint8_t>(), - pkt->size); - // temporary hack: will need to add real LL/SC implementation - // for cacheless systems later. - if (pkt->req->getFlags() & LOCKED) { - pkt->req->setScResult(1); - } - break; - default: - panic("unimplemented"); - } - - pkt->result = Success; -} - -Port * -PhysicalMemory::getPort(const std::string &if_name) -{ - if (if_name == "") { - if (port != NULL) - panic("PhysicalMemory::getPort: additional port requested to memory!"); - port = new MemoryPort(this); - return port; - } else if (if_name == "functional") { - /* special port for functional writes at startup. */ - return new MemoryPort(this); - } else { - panic("PhysicalMemory::getPort: unknown port %s requested", if_name); - } -} - -void -PhysicalMemory::recvStatusChange(Port::Status status) -{ -} - -PhysicalMemory::MemoryPort::MemoryPort(PhysicalMemory *_memory) - : memory(_memory) -{ } - -void -PhysicalMemory::MemoryPort::recvStatusChange(Port::Status status) -{ - memory->recvStatusChange(status); -} - -void -PhysicalMemory::MemoryPort::getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) -{ - memory->getAddressRanges(resp, snoop); -} - -void -PhysicalMemory::getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) -{ - snoop.clear(); - resp.clear(); - resp.push_back(RangeSize(base_addr, pmem_size)); -} - -int -PhysicalMemory::MemoryPort::deviceBlockSize() -{ - return memory->deviceBlockSize(); -} - -bool -PhysicalMemory::MemoryPort::recvTiming(Packet *pkt) -{ - return memory->doTimingAccess(pkt, this); -} - -Tick -PhysicalMemory::MemoryPort::recvAtomic(Packet *pkt) -{ - return memory->doAtomicAccess(pkt); -} - -void -PhysicalMemory::MemoryPort::recvFunctional(Packet *pkt) -{ - memory->doFunctionalAccess(pkt); -} - - - -void -PhysicalMemory::serialize(ostream &os) -{ - gzFile compressedMem; - string filename = name() + ".physmem"; - - SERIALIZE_SCALAR(pmem_size); - SERIALIZE_SCALAR(filename); - - // write memory file - string thefile = Checkpoint::dir() + "/" + filename.c_str(); - int fd = creat(thefile.c_str(), 0664); - if (fd < 0) { - perror("creat"); - fatal("Can't open physical memory checkpoint file '%s'\n", filename); - } - - compressedMem = gzdopen(fd, "wb"); - if (compressedMem == NULL) - fatal("Insufficient memory to allocate compression state for %s\n", - filename); - - if (gzwrite(compressedMem, pmem_addr, pmem_size) != pmem_size) { - fatal("Write failed on physical memory checkpoint file '%s'\n", - filename); - } - - if (gzclose(compressedMem)) - fatal("Close failed on physical memory checkpoint file '%s'\n", - filename); -} - -void -PhysicalMemory::unserialize(Checkpoint *cp, const string §ion) -{ - gzFile compressedMem; - long *tempPage; - long *pmem_current; - uint64_t curSize; - uint32_t bytesRead; - const int chunkSize = 16384; - - - // unmap file that was mmaped in the constructor - munmap(pmem_addr, pmem_size); - - string filename; - - UNSERIALIZE_SCALAR(pmem_size); - UNSERIALIZE_SCALAR(filename); - - filename = cp->cptDir + "/" + filename; - - // mmap memoryfile - int fd = open(filename.c_str(), O_RDONLY); - if (fd < 0) { - perror("open"); - fatal("Can't open physical memory checkpoint file '%s'", filename); - } - - compressedMem = gzdopen(fd, "rb"); - if (compressedMem == NULL) - fatal("Insufficient memory to allocate compression state for %s\n", - filename); - - - pmem_addr = (uint8_t *)mmap(NULL, pmem_size, PROT_READ | PROT_WRITE, - MAP_ANON | MAP_PRIVATE, -1, 0); - - if (pmem_addr == (void *)MAP_FAILED) { - perror("mmap"); - fatal("Could not mmap physical memory!\n"); - } - - curSize = 0; - tempPage = (long*)malloc(chunkSize); - if (tempPage == NULL) - fatal("Unable to malloc memory to read file %s\n", filename); - - /* Only copy bytes that are non-zero, so we don't give the VM system hell */ - while (curSize < pmem_size) { - bytesRead = gzread(compressedMem, tempPage, chunkSize); - if (bytesRead != chunkSize && bytesRead != pmem_size - curSize) - fatal("Read failed on physical memory checkpoint file '%s'" - " got %d bytes, expected %d or %d bytes\n", - filename, bytesRead, chunkSize, pmem_size-curSize); - - assert(bytesRead % sizeof(long) == 0); - - for (int x = 0; x < bytesRead/sizeof(long); x++) - { - if (*(tempPage+x) != 0) { - pmem_current = (long*)(pmem_addr + curSize + x * sizeof(long)); - *pmem_current = *(tempPage+x); - } - } - curSize += bytesRead; - } - - free(tempPage); - - if (gzclose(compressedMem)) - fatal("Close failed on physical memory checkpoint file '%s'\n", - filename); - -} - - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory) - - Param<string> file; - Param<Range<Addr> > range; - Param<Tick> latency; - -END_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory) - -BEGIN_INIT_SIM_OBJECT_PARAMS(PhysicalMemory) - - INIT_PARAM_DFLT(file, "memory mapped file", ""), - INIT_PARAM(range, "Device Address Range"), - INIT_PARAM(latency, "Memory access latency") - -END_INIT_SIM_OBJECT_PARAMS(PhysicalMemory) - -CREATE_SIM_OBJECT(PhysicalMemory) -{ - - return new PhysicalMemory(getInstanceName(), latency); -} - -REGISTER_SIM_OBJECT("PhysicalMemory", PhysicalMemory) |