Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_Io.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: SS_Io.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
// The code is actially in ss/api/sam/src/SS_SamIo.cc
#else
#include "SS_Io.h"
#include <stdio.h>
SS_Io SS_Io::io;
#ifndef MEMORY_MSYNC
SS_Io::SS_Io()/*{{{*/
:
SS_AddressMap()
{}
/* }}}*/
SS_Io::~SS_Io()/*{{{*/
{}
/*}}}*/
void SS_Io::st8( uint_t sid, uint64_t addr, uint8_t data )/*{{{*/
{
uint64_t _data = data;
cpu(sid,SS_Access::STORE,addr,1,&_data);
}
/*}}}*/
void SS_Io::st16( uint_t sid, uint64_t addr, uint16_t data )/*{{{*/
{
uint64_t _data = data;
cpu(sid,SS_Access::STORE,addr,2,&_data);
}
/*}}}*/
void SS_Io::st32( uint_t sid, uint64_t addr, uint32_t data )/*{{{*/
{
uint64_t _data = data;
cpu(sid,SS_Access::STORE,addr,4,&_data);
}
/*}}}*/
void SS_Io::st64( uint_t sid, uint64_t addr, uint64_t data )/*{{{*/
{
cpu(sid,SS_Access::STORE,addr,8,&data);
}
/*}}}*/
void SS_Io::st128( uint_t sid, uint64_t addr, uint64_t data[2] )/*{{{*/
{
cpu(sid,SS_Access::STORE,addr,16,data);
}
/*}}}*/
void SS_Io::st512( uint_t sid, uint64_t addr, uint64_t data[8] )/*{{{*/
{
cpu(sid,SS_Access::STORE,addr,64,data);
}
/*}}}*/
uint8_t SS_Io::ld8u( uint_t sid, uint64_t addr )/*{{{*/
{
uint64_t data;
cpu(sid,SS_Access::LOAD,addr,1,&data);
return data;
}
/*}}}*/
int8_t SS_Io::ld8s( uint_t sid, uint64_t addr )/*{{{*/
{
uint64_t data;
cpu(sid,SS_Access::LOAD,addr,1,&data);
return data;
}
/*}}}*/
uint16_t SS_Io::ld16u( uint_t sid, uint64_t addr )/*{{{*/
{
uint64_t data;
cpu(sid,SS_Access::LOAD,addr,2,&data);
return data;
}
/*}}}*/
int16_t SS_Io::ld16s( uint_t sid, uint64_t addr )/*{{{*/
{
uint64_t data;
cpu(sid,SS_Access::LOAD,addr,2,&data);
return data;
}
/*}}}*/
uint32_t SS_Io::ld32u( uint_t sid, uint64_t addr )/*{{{*/
{
uint64_t data;
cpu(sid,SS_Access::LOAD,addr,4,&data);
return data;
}
/*}}}*/
int32_t SS_Io::ld32s( uint_t sid, uint64_t addr )/*{{{*/
{
uint64_t data;
cpu(sid,SS_Access::LOAD,addr,4,&data);
return data;
}
/*}}}*/
uint64_t SS_Io::ld64( uint_t sid, uint64_t addr )/*{{{*/
{
uint64_t data;
cpu(sid,SS_Access::LOAD,addr,8,&data);
return data;
}
/*}}}*/
void SS_Io::ld128( uint_t sid, uint64_t addr, uint64_t data[2] )/*{{{*/
{
cpu(sid,SS_Access::LOAD,addr,16,data);
}
/*}}}*/
void SS_Io::ld256( uint_t sid, uint64_t addr, uint64_t data[4] )/*{{{*/
{
cpu(sid,SS_Access::LOAD,addr,32,data);
}
/*}}}*/
void SS_Io::ld512( uint_t sid, uint64_t addr, uint64_t data[8] )/*{{{*/
{
cpu(sid,SS_Access::LOAD,addr,64,data);
}
/*}}}*/
void SS_Io::st64partial( uint_t sid, uint64_t addr, uint64_t data, uint64_t mask )/*{{{*/
{
uint64_t _data[2];
_data[0] = data;
_data[1] = mask;
cpu(sid,SS_Access::STP,addr,8,_data);
}
/*}}}*/
void SS_Io::ld128atomic( uint_t sid, uint64_t addr, uint64_t data[2] )/*{{{*/
{
cpu(sid,SS_Access::LOAD,addr,16,data);
}
/*}}}*/
uint8_t SS_Io::ldstub( uint_t sid, uint64_t addr )/*{{{*/
{
uint64_t _data;
_data = 0xff;
cpu(sid,SS_Access::LDST,addr,1,&_data);
return _data;
}
/*}}}*/
uint32_t SS_Io::swap( uint_t sid, uint64_t addr, uint32_t rd )/*{{{*/
{
uint64_t _data;
_data = rd;
cpu(sid,SS_Access::SWAP,addr,4,&_data);
return _data;
}
/*}}}*/
uint64_t SS_Io::casx( uint_t sid, uint64_t addr, uint64_t rd, uint64_t rs2 )/*{{{*/
{
uint64_t _data[2];
_data[0] = rd;
_data[1] = rs2;
cpu(sid,SS_Access::CAS,addr,8,_data);
return _data[0];
}
/*}}}*/
uint32_t SS_Io::cas( uint_t sid, uint64_t addr, uint32_t rd, uint32_t rs2 )/*{{{*/
{
uint64_t _data[2];
_data[0] = rd;
_data[1] = rs2;
cpu(sid,SS_Access::CAS,addr,4,_data);
return _data[0];
return 0;
}
/*}}}*/
#else
#include <exception.h>
SS_Io::SS_Io()/*{{{*/
:
SS_AddressMap(),
msync_object(0),
msync_pre_access(0),
msync_post_access(0),
access_io(0),
memory(&SS_Memory::memory)
{
access_io_obj = (void*)this;
}
/*}}}*/
SS_Io::~SS_Io()/*{{{*/
{}
/*}}}*/
void SS_Io::msync_st( int sid, uint64_t addr, uint_t size, uint64_t data )/*{{{*/
{
mem_xact.setStrand(sid);
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_Io::msync_st( int sid, uint64_t addr, uint_t size, uint64_t* data )/*{{{*/
{
mem_xact.setStrand(sid);
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_Io::msync_ld( int sid, uint64_t addr, uint_t size )/*{{{*/
{
mem_xact.setStrand(sid);
mem_xact.paddr(addr);
mem_xact.size(size);
mem_xact.access(MemoryTransaction::READ);
mem_xact.referenceType(MemoryTransaction::DATA);
// access_io -- returns follow-me or not ..
uint64_t data = 0;
if(access_io && (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::READ,addr,size,&data,~0) == FOLLOWME){
mem_xact.setData(data);
mem_xact.access(mem_xact.access() | MemoryTransaction::FOLLOW_ME);
}
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_Io::msync_ld( int sid, uint64_t addr, uint_t size, uint64_t* data )/*{{{*/
{
mem_xact.setStrand(sid);
mem_xact.paddr(addr);
mem_xact.size(size);
mem_xact.access(MemoryTransaction::READ);
mem_xact.referenceType(MemoryTransaction::DATA);
// access_io -- returns follow-me or not ..
if(access_io && ((access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::READ,addr,size,data,~0)) == FOLLOWME){
for (uint_t i=0; size; i++, size -= 8)
mem_xact.setData(i,data[i]);
mem_xact.access(mem_xact.access() | MemoryTransaction::FOLLOW_ME);
}
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);
}
/*}}}*/
void SS_Io::poke8( int sid, uint64_t addr, uint8_t data )/*{{{*/
{
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::WRITE,addr,1,(uint64_t*)&data,~0) == NOT_HANDLED)
memory->poke8(addr,data);
}
/*}}}*/
void SS_Io::poke16( int sid, uint64_t addr, uint16_t data )/*{{{*/
{
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::WRITE,addr,2,(uint64_t*)&data,~0) == NOT_HANDLED)
memory->poke16(addr,data);
}
/*}}}*/
void SS_Io::poke32( int sid, uint64_t addr, uint32_t data )/*{{{*/
{
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::WRITE,addr,4,(uint64_t*)&data,~0) == NOT_HANDLED)
memory->poke32(addr,data);
}
/*}}}*/
void SS_Io::poke64( int sid, uint64_t addr, uint64_t data )/*{{{*/
{
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::WRITE,addr,8,&data,~0) == NOT_HANDLED)
memory->poke64(addr,data);
}
/*}}}*/
void SS_Io::poke128( int sid, uint64_t addr, uint64_t data[2] )/*{{{*/
{
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::WRITE,addr,16,data,~0) == NOT_HANDLED)
memory->poke128(addr,data);
}
/*}}}*/
void SS_Io::poke512( int sid, uint64_t addr, uint64_t data[8] )/*{{{*/
{
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::WRITE,addr,64,data,~0) == NOT_HANDLED)
memory->poke512(addr,data);
}
/*}}}*/
uint8_t SS_Io::peek8u( int sid, uint64_t addr )/*{{{*/
{
uint64_t data = 0x0;
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::READ,addr,1,&data,~0) == NOT_HANDLED)
return memory->peek8u(addr);
return (uint8_t)data;
}
/*}}}*/
int8_t SS_Io::peek8s( int sid, uint64_t addr )/*{{{*/
{
uint64_t data = 0x0;
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::READ,addr,1,&data,~0) == NOT_HANDLED)
return memory->peek8s(addr);
return (int8_t)data;
}
/*}}}*/
uint16_t SS_Io::peek16u( int sid, uint64_t addr )/*{{{*/
{
uint64_t data = 0x0;
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::READ,addr,2,&data,~0) == NOT_HANDLED)
return memory->peek16u(addr);
return (uint16_t)data;
}
/*}}}*/
int16_t SS_Io::peek16s( int sid, uint64_t addr )/*{{{*/
{
uint64_t data = 0x0;
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::READ,addr,2,&data,~0) == NOT_HANDLED)
return memory->peek16s(addr);
return (int16_t)data;
}
/*}}}*/
uint32_t SS_Io::peek32u( int sid, uint64_t addr )/*{{{*/
{
uint64_t data = 0x0;
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::READ,addr,4,&data,~0) == NOT_HANDLED)
return memory->peek32u(addr);
return (uint32_t)data;
}
/*}}}*/
int32_t SS_Io::peek32s( int sid, uint64_t addr )/*{{{*/
{
uint64_t data = 0x0;
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::READ,addr,4,&data,~0) == NOT_HANDLED)
return memory->peek32s(addr);
return (int32_t)data;
}
/*}}}*/
uint64_t SS_Io::peek64( int sid, uint64_t addr )/*{{{*/
{
uint64_t data = 0x0;
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::READ,addr,8,&data,~0) == NOT_HANDLED)
return memory->peek64(addr);
return data;
}
/*}}}*/
void SS_Io::peek128( int sid, uint64_t addr ,uint64_t data[2] )/*{{{*/
{
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::READ,addr,16,data,~0) == NOT_HANDLED)
memory->peek128(addr,data);
}
/*}}}*/
void SS_Io::peek256( int sid, uint64_t addr ,uint64_t data[4] )/*{{{*/
{
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::READ,addr,32,data,~0) == NOT_HANDLED)
memory->peek256(addr,data);
}
/*}}}*/
void SS_Io::peek512( int sid, uint64_t addr ,uint64_t data[8] )/*{{{*/
{
if (access_io == 0 || (access_io)(access_io_obj,sid,MemoryTransaction::INTERNAL|MemoryTransaction::READ,addr,64,data,~0) == NOT_HANDLED)
memory->peek512(addr,data);
}
/*}}}*/
uint32_t SS_Io::fetch32( uint_t sid, uint64_t addr )/*{{{*/
{
if (msync_object)
{
mem_xact.setStrand(sid);
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 peek32u(sid,addr);
}
/*}}}*/
void SS_Io::fetch256( uint_t sid, uint64_t addr, uint64_t data[4] )/*{{{*/
{
if (msync_object)
{
mem_xact.setStrand(sid);
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 ) {}
}
peek256(sid,addr,data);
}
/*}}}*/
void SS_Io::fetch512( uint_t sid, uint64_t addr, uint64_t data[8] )/*{{{*/
{
if (msync_object)
{
mem_xact.setStrand(sid);
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 ) {}
}
peek512(sid,addr,data);
}
/*}}}*/
void SS_Io::st8( uint_t sid, uint64_t addr, uint8_t data )/*{{{*/
{
if (msync_object)
msync_st(sid,addr,1,data);
else
poke8(sid,addr,data);
}
/*}}}*/
void SS_Io::st16( uint_t sid, uint64_t addr, uint16_t data )/*{{{*/
{
if (msync_object)
msync_st(sid,addr,2,data);
else
poke16(sid,addr,data);
}
/*}}}*/
void SS_Io::st32( uint_t sid, uint64_t addr, uint32_t data )/*{{{*/
{
if (msync_object)
msync_st(sid,addr,4,data);
else
poke32(sid,addr,data);
}
/*}}}*/
void SS_Io::st64( uint_t sid, uint64_t addr, uint64_t data )/*{{{*/
{
if (msync_object)
msync_st(sid,addr,8,data);
else
poke64(sid,addr,data);
}
/*}}}*/
void SS_Io::st128( uint_t sid, uint64_t addr, uint64_t data[2] )/*{{{*/
{
if (msync_object)
msync_st(sid,addr,16,data);
else
poke128(sid,addr,data);
}
/*}}}*/
void SS_Io::st512( uint_t sid, uint64_t addr, uint64_t data[8] )/*{{{*/
{
if (msync_object)
msync_st(sid,addr,64,data);
else
poke512(sid,addr,data);
}
/*}}}*/
uint8_t SS_Io::ld8u ( uint_t sid, uint64_t addr )/*{{{*/
{
if (msync_object)
return msync_ld(sid,addr,1);
else
return peek8u(sid,addr);
}
/*}}}*/
int8_t SS_Io::ld8s( uint_t sid, uint64_t addr )/*{{{*/
{
if (msync_object)
return msync_ld(sid,addr,1);
else
return peek8s(sid,addr);
}
/*}}}*/
uint16_t SS_Io::ld16u( uint_t sid, uint64_t addr )/*{{{*/
{
if (msync_object)
return msync_ld(sid,addr,2);
else
return peek16u(sid,addr);
}
/*}}}*/
int16_t SS_Io::ld16s( uint_t sid, uint64_t addr )/*{{{*/
{
if (msync_object)
return msync_ld(sid,addr,2);
else
return peek16s(sid,addr);
}
/*}}}*/
uint32_t SS_Io::ld32u( uint_t sid, uint64_t addr )/*{{{*/
{
if (msync_object)
return msync_ld(sid,addr,4);
else
return peek32u(sid,addr);
}
/*}}}*/
int32_t SS_Io::ld32s( uint_t sid, uint64_t addr )/*{{{*/
{
if (msync_object)
return msync_ld(sid,addr,4);
else
return peek32s(sid,addr);
}
/*}}}*/
uint64_t SS_Io::ld64( uint_t sid, uint64_t addr )/*{{{*/
{
if (msync_object)
return msync_ld(sid,addr,8);
else
return peek64(sid,addr);
}
/*}}}*/
void SS_Io::ld128( uint_t sid, uint64_t addr, uint64_t data[2] ) /*{{{*/
{
if (msync_object)
msync_ld(sid,addr,16,data);
else
peek128(sid,addr,data);
}
/*}}}*/
void SS_Io::ld256( uint_t sid, uint64_t addr, uint64_t data[4] )/*{{{*/
{
if (msync_object)
msync_ld(sid,addr,32,data);
else
peek256(sid,addr,data);
}
/*}}}*/
void SS_Io::ld512( uint_t sid, uint64_t addr, uint64_t data[8] )/*{{{*/
{
if (msync_object)
msync_ld(sid,addr,64,data);
else
peek512(sid,addr,data);
}
/*}}}*/
void SS_Io::st64partial( uint_t sid, uint64_t addr, uint64_t data, uint64_t mask ) /*{{{*/
{
if (msync_object)
{
uint64_t temp = peek64(sid,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(sid,addr,data);
}
else
st64(sid,addr,data);
}
/*}}}*/
void SS_Io::ld128atomic( uint_t sid, uint64_t addr, uint64_t data[2] )/*{{{*/
{
fprintf(stderr,"SS_Io::ld128atomic(%d,%llx) not expected, ignoring it\n",sid,addr);
}
/*}}}*/
uint8_t SS_Io::ldstub( uint_t sid, uint64_t addr )/*{{{*/
{
fprintf(stderr,"SS_Io::ldstub(%d,%llx) not expected, ignoring it\n",sid,addr);
return 0x0;
}
/*}}}*/
uint32_t SS_Io::swap( uint_t sid, uint64_t addr, uint32_t rd )/*{{{*/
{
fprintf(stderr,"SS_Io::swap(%d,%llx) not expected, ignoring it\n",sid,addr);
return 0x0;
}
/*}}}*/
uint64_t SS_Io::casx( uint_t sid, uint64_t addr, uint64_t rd, uint64_t rs2 )/*{{{*/
{
fprintf(stderr,"SS_Io::casx(%d,%llx) not expected, ignoring it\n",sid,addr);
return 0x0;
}
/*}}}*/
uint32_t SS_Io::cas( uint_t sid, uint64_t addr, uint32_t rd, uint32_t rs2 )/*{{{*/
{
fprintf(stderr,"SS_Io::cas(%d,%llx) not expected, ignoring it\n",sid,addr);
return 0x0;
}
/*}}}*/
#endif
#endif