1/* 2 * Copyright (c) 2001-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 17 unchanged lines hidden (view full) --- 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Ron Dreslinski 29 * Ali Saidi 30 */ 31 32#include <sys/types.h> 33#include <sys/mman.h> |
34#include <sys/user.h> |
35#include <errno.h> 36#include <fcntl.h> 37#include <unistd.h> 38#include <zlib.h> 39 40#include <cstdio> 41#include <iostream> 42#include <string> 43 44#include "arch/registers.hh" |
45#include "base/intmath.hh" |
46#include "base/misc.hh" 47#include "base/random.hh" 48#include "base/types.hh" 49#include "config/full_system.hh" 50#include "config/the_isa.hh" 51#include "mem/packet_access.hh" 52#include "mem/physical.hh" 53#include "sim/eventq.hh" 54 55using namespace std; 56using namespace TheISA; 57 58PhysicalMemory::PhysicalMemory(const Params *p) 59 : MemObject(p), pmemAddr(NULL), pagePtr(0), 60 lat(p->latency), lat_var(p->latency_var), |
61 _size(params()->range.size()), _start(params()->range.start) |
62{ |
63 if (size() % TheISA::PageBytes != 0) |
64 panic("Memory Size not divisible by page size\n"); 65 66 if (params()->null) 67 return; 68 |
69 |
70 if (params()->file == "") { 71 int map_flags = MAP_ANON | MAP_PRIVATE; 72 pmemAddr = (uint8_t *)mmap(NULL, size(), 73 PROT_READ | PROT_WRITE, map_flags, -1, 0); 74 } else { 75 int map_flags = MAP_PRIVATE; 76 int fd = open(params()->file.c_str(), O_RDONLY); 77 _size = lseek(fd, 0, SEEK_END); 78 lseek(fd, 0, SEEK_SET); 79 pmemAddr = (uint8_t *)mmap(NULL, roundUp(size(), PAGE_SIZE), 80 PROT_READ | PROT_WRITE, map_flags, fd, 0); 81 } 82 |
83 if (pmemAddr == (void *)MAP_FAILED) { 84 perror("mmap"); |
85 if (params()->file == "") 86 fatal("Could not mmap!\n"); 87 else 88 fatal("Could not find file: %s\n", params()->file); |
89 } 90 91 //If requested, initialize all the memory to 0 92 if (p->zero) |
93 memset(pmemAddr, 0, size()); |
94} 95 96void 97PhysicalMemory::init() 98{ 99 if (ports.size() == 0) { 100 fatal("PhysicalMemory object %s is unconnected!", name()); 101 } 102 103 for (PortIterator pi = ports.begin(); pi != ports.end(); ++pi) { 104 if (*pi) 105 (*pi)->sendStatusChange(Port::RangeChange); 106 } 107} 108 109PhysicalMemory::~PhysicalMemory() 110{ 111 if (pmemAddr) |
112 munmap((char*)pmemAddr, size()); |
113} 114 115Addr 116PhysicalMemory::new_page() 117{ 118 Addr return_addr = pagePtr << LogVMPageSize; 119 return_addr += start(); 120 --- 296 unchanged lines hidden (view full) --- 417 memory->getAddressRanges(resp, snoop); 418} 419 420void 421PhysicalMemory::getAddressRanges(AddrRangeList &resp, bool &snoop) 422{ 423 snoop = false; 424 resp.clear(); |
425 resp.push_back(RangeSize(start(), size())); |
426} 427 428unsigned 429PhysicalMemory::MemoryPort::deviceBlockSize() const 430{ 431 return memory->deviceBlockSize(); 432} 433 --- 38 unchanged lines hidden (view full) --- 472{ 473 if (!pmemAddr) 474 return; 475 476 gzFile compressedMem; 477 string filename = name() + ".physmem"; 478 479 SERIALIZE_SCALAR(filename); |
480 SERIALIZE_SCALAR(_size); |
481 482 // write memory file 483 string thefile = Checkpoint::dir() + "/" + filename.c_str(); 484 int fd = creat(thefile.c_str(), 0664); 485 if (fd < 0) { 486 perror("creat"); 487 fatal("Can't open physical memory checkpoint file '%s'\n", filename); 488 } 489 490 compressedMem = gzdopen(fd, "wb"); 491 if (compressedMem == NULL) 492 fatal("Insufficient memory to allocate compression state for %s\n", 493 filename); 494 |
495 if (gzwrite(compressedMem, pmemAddr, size()) != (int)size()) { |
496 fatal("Write failed on physical memory checkpoint file '%s'\n", 497 filename); 498 } 499 500 if (gzclose(compressedMem)) 501 fatal("Close failed on physical memory checkpoint file '%s'\n", 502 filename); 503} --- 27 unchanged lines hidden (view full) --- 531 compressedMem = gzdopen(fd, "rb"); 532 if (compressedMem == NULL) 533 fatal("Insufficient memory to allocate compression state for %s\n", 534 filename); 535 536 // unmap file that was mmaped in the constructor 537 // This is done here to make sure that gzip and open don't muck with our 538 // nice large space of memory before we reallocate it |
539 munmap((char*)pmemAddr, size()); |
540 |
541 UNSERIALIZE_SCALAR(_size); 542 if (size() > params()->range.size()) 543 fatal("Memory size has changed!\n"); 544 545 pmemAddr = (uint8_t *)mmap(NULL, size(), |
546 PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); 547 548 if (pmemAddr == (void *)MAP_FAILED) { 549 perror("mmap"); 550 fatal("Could not mmap physical memory!\n"); 551 } 552 553 curSize = 0; 554 tempPage = (long*)malloc(chunkSize); 555 if (tempPage == NULL) 556 fatal("Unable to malloc memory to read file %s\n", filename); 557 558 /* Only copy bytes that are non-zero, so we don't give the VM system hell */ |
559 while (curSize < size()) { |
560 bytesRead = gzread(compressedMem, tempPage, chunkSize); 561 if (bytesRead == 0) 562 break; 563 564 assert(bytesRead % sizeof(long) == 0); 565 566 for (uint32_t x = 0; x < bytesRead / sizeof(long); x++) 567 { --- 21 unchanged lines hidden --- |