Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_MsyncMemory.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: SS_MsyncMemory.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 MEMORY_MSYNC
#include <sys/mman.h>
#include <errno.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "SS_MsyncMemory.h"
#include "SS_Strand.h"
#include <exception.h>
SS_MsyncMemory SS_MsyncMemory::memory;
SS_MsyncMemory::SS_MsyncMemory()/*{{{*/
:
SS_FastMemory(),
msync_object(0),
msync_pre_access(0),
msync_post_access(0)
{
}
/*}}}*/
SS_MsyncMemory::~SS_MsyncMemory()/*{{{*/
{
}
/*}}}*/
void SS_MsyncMemory::msync_st( uint64_t addr, uint_t size, uint64_t data )/*{{{*/
{
mem_xact.paddr(addr);
mem_xact.size(size);
mem_xact.access(MemoryTransaction::WRITE);
mem_xact.referenceType(MemoryTransaction::DATA);
mem_xact.setData(data);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
}
/*}}}*/
void SS_MsyncMemory::msync_st( uint64_t addr, uint_t size, uint64_t* data )/*{{{*/
{
mem_xact.paddr(addr);
mem_xact.size(size);
mem_xact.access(MemoryTransaction::WRITE);
mem_xact.referenceType(MemoryTransaction::DATA);
for (uint_t i=0; size; i++, size -= 8)
mem_xact.setData(i,data[i]);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
}
/*}}}*/
uint64_t SS_MsyncMemory::msync_ld( uint64_t addr, uint_t size )/*{{{*/
{
mem_xact.paddr(addr);
mem_xact.size(size);
mem_xact.access(MemoryTransaction::READ);
mem_xact.referenceType(MemoryTransaction::DATA);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
return mem_xact.getData();
}
/*}}}*/
void SS_MsyncMemory::msync_ld( uint64_t addr, uint_t size, uint64_t* data )/*{{{*/
{
mem_xact.paddr(addr);
mem_xact.size(size);
mem_xact.access(MemoryTransaction::READ);
mem_xact.referenceType(MemoryTransaction::DATA);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
for (uint_t i=0; size; i++, size -= 8)
data[i]= mem_xact.getData(i);
}
/*}}}*/
uint32_t SS_MsyncMemory::fetch32( uint64_t addr )/*{{{*/
{
if (msync_object)
{
mem_xact.paddr(addr);
mem_xact.size(4);
mem_xact.access(MemoryTransaction::READ);
mem_xact.referenceType(MemoryTransaction::INSTR);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
}
return SS_FastMemory::fetch32(addr);
}
/*}}}*/
void SS_MsyncMemory::fetch256( uint64_t addr, uint64_t data[4] )/*{{{*/
{
if (msync_object)
{
mem_xact.paddr(addr);
mem_xact.size(32);
mem_xact.access(MemoryTransaction::READ);
mem_xact.referenceType(MemoryTransaction::INSTR);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
}
SS_FastMemory::fetch256(addr,data);
}
/*}}}*/
void SS_MsyncMemory::fetch512( uint64_t addr, uint64_t data[8] )/*{{{*/
{
if (msync_object)
{
mem_xact.paddr(addr);
mem_xact.size(64);
mem_xact.access(MemoryTransaction::READ);
mem_xact.referenceType(MemoryTransaction::INSTR);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
}
SS_FastMemory::fetch512(addr,data);
}
/*}}}*/
void SS_MsyncMemory::st8( uint64_t addr, uint8_t data )/*{{{*/
{
if (msync_object)
msync_st(addr,1,data);
else
SS_FastMemory::st8(addr,data);
}
/*}}}*/
void SS_MsyncMemory::st16( uint64_t addr, uint16_t data )/*{{{*/
{
if (msync_object)
msync_st(addr,2,data);
else
SS_FastMemory::st16(addr,data);
}
/*}}}*/
void SS_MsyncMemory::st32( uint64_t addr, uint32_t data )/*{{{*/
{
if (msync_object)
msync_st(addr,4,data);
else
SS_FastMemory::st32(addr,data);
}
/*}}}*/
void SS_MsyncMemory::st64( uint64_t addr, uint64_t data )/*{{{*/
{
if (msync_object)
msync_st(addr,8,data);
else
SS_FastMemory::st64(addr,data);
}
/*}}}*/
void SS_MsyncMemory::st128( uint64_t addr, uint64_t data[2] )/*{{{*/
{
if (msync_object)
msync_st(addr,16,data);
else
{
SS_FastMemory::st128(addr,data);
}
}
/*}}}*/
void SS_MsyncMemory::st512( uint64_t addr, uint64_t data[8] )/*{{{*/
{
if (msync_object)
msync_st(addr,64,data);
else
{
SS_FastMemory::st512(addr,data);
}
}
/*}}}*/
uint8_t SS_MsyncMemory::ld8u ( uint64_t addr )/*{{{*/
{
if (msync_object)
return msync_ld(addr,1);
else
return SS_FastMemory::ld8u(addr);
}
/*}}}*/
int8_t SS_MsyncMemory::ld8s( uint64_t addr )/*{{{*/
{
if (msync_object)
return msync_ld(addr,1);
else
return SS_FastMemory::ld8s(addr);
}
/*}}}*/
uint16_t SS_MsyncMemory::ld16u( uint64_t addr )/*{{{*/
{
if (msync_object)
return msync_ld(addr,2);
else
return SS_FastMemory::ld16u(addr);
}
/*}}}*/
int16_t SS_MsyncMemory::ld16s( uint64_t addr )/*{{{*/
{
if (msync_object)
return msync_ld(addr,2);
else
return SS_FastMemory::ld16s(addr);
}
/*}}}*/
uint32_t SS_MsyncMemory::ld32u( uint64_t addr )/*{{{*/
{
if (msync_object)
return msync_ld(addr,4);
else
return SS_FastMemory::ld32u(addr);
}
/*}}}*/
int32_t SS_MsyncMemory::ld32s( uint64_t addr )/*{{{*/
{
if (msync_object)
return msync_ld(addr,4);
else
return SS_FastMemory::ld32s(addr);
}
/*}}}*/
uint64_t SS_MsyncMemory::ld64( uint64_t addr )/*{{{*/
{
if (msync_object)
return msync_ld(addr,8);
else
return SS_FastMemory::ld64(addr);
}
/*}}}*/
void SS_MsyncMemory::ld128( uint64_t addr, uint64_t data[2] ) /*{{{*/
{
if (msync_object)
msync_ld(addr,16,data);
else
{
SS_FastMemory::ld128(addr,data);
}
}
/*}}}*/
void SS_MsyncMemory::ld256( uint64_t addr, uint64_t data[4] )/*{{{*/
{
if (msync_object)
msync_ld(addr,32,data);
else
{
SS_FastMemory::ld256(addr,data);
}
}
/*}}}*/
void SS_MsyncMemory::ld512( uint64_t addr, uint64_t data[8] )/*{{{*/
{
if (msync_object)
msync_ld(addr,64,data);
else
{
SS_FastMemory::ld512(addr,data);
}
}
/*}}}*/
void SS_MsyncMemory::st64partial( uint64_t addr, uint64_t data, uint64_t mask ) /*{{{*/
{
if (msync_object)
{
uint64_t temp = peek64(addr);
if (mask < 0x100)
{
uint64_t data_mask = 0x0;
for(int i=0; i < 0x8; i++)
if((mask >> i) & 0x1)
data_mask |= (0xffULL << (0x8 * i));
data = (temp & ~data_mask) | (data & data_mask);
}
st64(addr,data);
}
else
SS_FastMemory::st64partial(addr,data,mask);
}
/*}}}*/
void SS_MsyncMemory::ld128atomic( uint64_t addr, uint64_t data[2] )/*{{{*/
{
if (msync_object && (msync_help == NONE))
msync_ld(addr,16,data);
else
{
SS_FastMemory::ld128atomic(addr,data);
}
}
/*}}}*/
uint8_t SS_MsyncMemory::ldstub( uint64_t addr )/*{{{*/
{
if (msync_object)
{
mem_xact.referenceType(MemoryTransaction::DATA);
mem_xact.paddr(addr);
mem_xact.size(1);
mem_xact.access(MemoryTransaction::READ|MemoryTransaction::ATOMIC);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
uint8_t data = mem_xact.getData();
mem_xact.access(MemoryTransaction::WRITE|MemoryTransaction::ATOMIC);
mem_xact.setData(0xff);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
return data;
}
else
return SS_FastMemory::ldstub( addr );
}
/*}}}*/
uint32_t SS_MsyncMemory::swap( uint64_t addr, uint32_t rd )/*{{{*/
{
if (msync_object)
{
mem_xact.referenceType(MemoryTransaction::DATA);
mem_xact.paddr(addr);
mem_xact.size(4);
mem_xact.access(MemoryTransaction::READ|MemoryTransaction::ATOMIC);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
uint32_t data = mem_xact.getData();
mem_xact.access(MemoryTransaction::WRITE|MemoryTransaction::ATOMIC);
mem_xact.setData(rd);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
return data;
}
else
return SS_FastMemory::swap( addr,rd );
}
/*}}}*/
uint64_t SS_MsyncMemory::casx( uint64_t addr, uint64_t rd, uint64_t rs2 )/*{{{*/
{
if (msync_object)
{
mem_xact.referenceType(MemoryTransaction::DATA);
mem_xact.paddr(addr);
mem_xact.size(8);
mem_xact.access(MemoryTransaction::READ|MemoryTransaction::ATOMIC);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
uint64_t data = mem_xact.getData();
if (data == rs2)
{
mem_xact.setData(rd);
mem_xact.access(MemoryTransaction::WRITE|MemoryTransaction::ATOMIC);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
}
return data;
}
else
return SS_FastMemory::casx( addr,rd ,rs2);
}
/*}}}*/
uint32_t SS_MsyncMemory::cas( uint64_t addr, uint32_t rd, uint32_t rs2 )/*{{{*/
{
if (msync_object)
{
mem_xact.referenceType(MemoryTransaction::DATA);
mem_xact.paddr(addr);
mem_xact.size(4);
mem_xact.access(MemoryTransaction::READ|MemoryTransaction::ATOMIC);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
uint32_t data = mem_xact.getData();
if (data == rs2)
{
mem_xact.setData(rd);
mem_xact.access(MemoryTransaction::WRITE|MemoryTransaction::ATOMIC);
try { msync_pre_access(msync_object,mem_xact); } catch (exception &e) {}
try { msync_post_access(msync_object,mem_xact); } catch (exception &e) {}
}
return data;
}
else
return SS_FastMemory::cas( addr,rd ,rs2);
}
/*}}}*/
#endif /* MEMORY_MSYNC */