Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_FastMemory.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: SS_FastMemory.cc
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
//
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
//
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// ========== Copyright Header End ============================================
#ifdef COMPILE_FOR_SAM
#else // Vonk's own memory
#include <sys/mman.h>
#include <errno.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include "SS_FastMemory.h"
SS_FastMemory SS_FastMemory::memory;
SS_FastMemory::SS_FastMemory()/*{{{*/
{
page_size = sysconf(_SC_PAGESIZE);
page_mask = page_size-1;
// Note mmap with MAP_ANON zero's memory for us. Doing mmap here
// in stead of calloc safes us a bundle of page faults. Besides
// the initial memory footprint now very small.
l1 = (uint8_t**)mmap((char*)0,(1ull << L1BITS) * sizeof(uint8_t*),PROT_READ|PROT_WRITE,
MAP_NORESERVE|MAP_PRIVATE|MAP_ANON|MAP_ALIGN,-1,0);
}
/*}}}*/
SS_FastMemory::~SS_FastMemory()/*{{{*/
{
// We should in to be nice and do unmap of all the mmap's
// here, but what is the point of that .... we're gonna
// exit anyways. Worse, if we do this then we incur
// quite a few page misses at the end of the program,
// which means exit seems slow.
}
/*}}}*/
void SS_FastMemory::allocate( uint64_t _ram_size, uint64_t _rom_size, uint_t pa_bits )/*{{{*/
{
ram_size = _ram_size;
rom_size = _rom_size;
}
/*}}}*/
#include <zlib.h>
enum { BUFFER_SIZE = 512 };
static char buffer[BUFFER_SIZE];
void SS_FastMemory::load( const char* filename )/*{{{*/
{
const char* separ = " \n";
gzFile image;
uint64_t addr = 0;
bool gunzip = false;
uint_t len = strlen(filename);
image = gzopen(filename,"r");
if (!image)
throw "No such ascii memory image file found.";
while (gzgets(image,buffer,BUFFER_SIZE))
{
if (buffer[0] == '@')
{
addr = strtoull(buffer+1,0,16);
}
else if (isxdigit(buffer[0]))
{
char* token = strtok(buffer,separ);
uint_t length = strlen(token);
if (length == 16)
{
do
{
uint64_t data = strtoull(token,0,16);
poke64(addr,data);
addr += 8;
}
while ((token = strtok(0,separ)));
}
else if (length == 8)
{
do
{
uint32_t data = strtoul(token,0,16);
poke32(addr,data);
addr += 4;
}
while ((token = strtok(0,separ)));
}
else
throw "A memory entry must be either 4 or 8 bytes.";
}
}
gzclose(image);
}
/*}}}*/
void SS_FastMemory::load( const char* filename, uint64_t addr )/*{{{*/
{
FILE* image = fopen(filename,"r");
if (!image)
throw "No such binary memory image file found.";
if ((addr & page_mask) != 0)
{
fread(get_ptr(addr),1,page_size - (addr & page_mask),image);
addr = (addr + page_size) &~ page_mask;
}
while (!feof(image))
{
fread(get_ptr(addr),1,page_size,image);
addr += page_size;
}
fclose(image);
}
/*}}}*/
void SS_FastMemory::save( const char* filename, uint64_t addr, uint64_t size )/*{{{*/
{
FILE* image = fopen(filename,"w");
if (!image)
throw "No such binary memory image file found.";
if ((addr & page_mask) != 0)
{
uint64_t n = page_size - (addr & page_mask);
if (size < n)
n = size;
fwrite(get_ptr(addr),1,n,image);
addr += n;
size -= n;
}
while (size >= page_size)
{
fwrite(get_ptr(addr),1,page_size,image);
addr += page_size;
size -= page_size;
}
if (size)
fwrite(get_ptr(addr),1,size,image);
fclose(image);
}
/*}}}*/
#endif /* COMPILE_FOR_SAM */