* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: SS_Python.i
* 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 ============================================
#include "SS_Registers.h"
#include "SS_PythonTracer.h"
#include "SS_PythonAsiReg.h"
#include "SS_AddressMap.h"
/* val2ptr() converts an integer value back to proper pointer *\
\* that within the swig framework will get the right type. */
Ptr* val2ptr( int64_t val )
#elif (defined(ARCH_V9) || defined(ARCH_X64))
#error "Define ARCH=v9 or ARCH=v8plus or ARCH=amd64"
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned int uint32_t;
typedef unsigned int uint_t;
typedef signed int int32_t;
#if (defined(ARCH_V9) || defined(ARCH_X64))
typedef unsigned long uint64_t;
typedef signed long int64_t;
typedef unsigned long long uint64_t;
typedef signed long long int64_t;
#error "Define ARCH=v9 or ARCH=v8plus or ARCH=amd64"
typedef int64_t SS_Vaddr;
typedef uint64_t SS_Paddr;
%typemap(python,in) PyObject *func
if (!PyCallable_Check($input))
PyErr_SetString(PyExc_TypeError, "Need a callable object!");
/*============================================================================*\
\*============================================================================*/
/* ha144505: we need to stay away from having the uint32_t; it confuses SWIG */
char* dis( int64_t opc, uint64_t pc )
uint32_t _opc = uint32_t(opc);
size_t n = spix_sparc_dis(buffer,256,spix_sparc_iop(SPIX_SPARC_V9,&_opc),&_opc,pc);
/*============================================================================*\
\*============================================================================*/
const char* get_node_name();
/*============================================================================*\
\*============================================================================*/
static const char* get_name( Index );
/*============================================================================*\
\*============================================================================*/
/*============================================================================*\
\*============================================================================*/
SS_TrapInfo* get_trap_info( uint_t tt ) { return &SS_Trap::table[tt]; }
/*============================================================================*\
\*============================================================================*/
SS_AsiSpace* get( uint8_t asi ) { return &(self->operator[](asi)); }
/*============================================================================*\
\*============================================================================*/
SS_AsiCtrReg( const char* __name, uint64_t __mask_ro, uint64_t __mask_r1c, uint64_t __mask_rw, uint64_t __mask_w1c, uint64_t __init );
void set_unmasked( uint64_t v );
static SS_AsiSpace::Error ld64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t* data );
static SS_AsiSpace::Error st64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t data );
static SS_AsiSpace::Error rd64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t* data );
static SS_AsiSpace::Error wr64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t data );
class SS_SharedAsiCtrReg : public SS_AsiCtrReg
SS_SharedAsiCtrReg( const char* __name, uint64_t __mask_ro, uint64_t __mask_r1c, uint64_t __mask_rw, uint64_t __mask_w1c, uint64_t __init );
static SS_AsiSpace::Error ld64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t* data );
static SS_AsiSpace::Error st64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t data );
static SS_AsiSpace::Error rd64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t* data );
static SS_AsiSpace::Error wr64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t data );
class SS_PythonAsiReg : public SS_AsiCtrReg
void set_ld64( PyObject* func );
void set_st64( PyObject* func );
void set_rd64( PyObject* func );
void set_wr64( PyObject* func );
/*============================================================================*\
\*============================================================================*/
typedef Error (*Read) ( SS_Node* obj, void* reg, SS_Strand* s, SS_Vaddr, uint64_t* data );
typedef Error (*Write)( SS_Node* obj, void* reg, SS_Strand* s, SS_Vaddr, uint64_t data );
void add( uint64_t lo, uint64_t hi, SS_Node* obj, void* reg, Read ld, Write st, Read rd, Write wr )
self->add((SS_Vaddr)lo,(SS_Vaddr)hi,obj,reg,ld,st,rd,wr);
void add_state( SS_PythonAsiReg* reg, uint64_t va )
self->add((SS_Vaddr)va,(SS_Vaddr)va,(SS_Node*)0,reg,
&SS_PythonAsiReg::ld64,&SS_PythonAsiReg::st64,
&SS_PythonAsiReg::rd64,&SS_PythonAsiReg::st64);
void add_space( SS_PythonAsiReg* reg, uint64_t lo, uint64_t hi )
self->add((SS_Vaddr)lo,(SS_Vaddr)hi,(SS_Node*)0,reg,
&SS_PythonAsiReg::ld64,&SS_PythonAsiReg::st64,
&SS_PythonAsiReg::rd64,&SS_PythonAsiReg::st64);
/*============================================================================*\
\*============================================================================*/
/*============================================================================*\
\*============================================================================*/
/*============================================================================*\
\*============================================================================*/
class SS_PythonTracer : public SS_Tracer
void set_exe_instr( PyObject* func );
void set_reg_value( PyObject* func );
void set_trap( PyObject* func );
void set_mem_access( PyObject* func );
void set_tlb_update( PyObject* func );
void set_end_instr( PyObject* func );
/*============================================================================*\
\*============================================================================*/
/* ss_instr() is used when get an uint64_t value but need a proper
SS_Tte python object pointer type */
SS_Instr* ss_instr( int64_t p )
return val2ptr<SS_Instr>(p);
uint32_t get_opc() { return self->opc.get(); }
/*============================================================================*\
\*============================================================================*/
const char* get_node_name();
char* icache_info(uint64_t pa);
char* icache_set(uint_t set);
char* dcache_set(uint_t set);
char* l2cache_set(uint_t set);
char* l2cache_set(uint_t bank, uint_t set);
SS_Registers::Error reg_error;
SS_AsiSpace::Error asi_error;
const char* get_state_name( SS_Registers::Index index )
return (self->get_state_name)(self,index);
uint64_t get_reg( SS_Registers::Index index )
self->reg_error = (self->get_state)(self,index,&value);
void set_reg( SS_Registers::Index index, uint64_t value )
self->reg_error = (self->set_state)(self,index,value);
uint64_t get_reg_tl( uint64_t tl, SS_Registers::Index index )
(self->get_state)(self,SS_Registers::PR_TL,&save_tl);
(self->set_state)(self,SS_Registers::PR_TL,tl);
self->reg_error = (self->get_state)(self,index,&value);
(self->set_state)(self,SS_Registers::PR_TL,save_tl);
void set_reg_tl( uint64_t tl, SS_Registers::Index index, uint64_t value )
(self->get_state)(self,SS_Registers::PR_TL,&save_tl);
(self->set_state)(self,SS_Registers::PR_TL,tl);
self->reg_error = (self->set_state)(self,index,value);
(self->set_state)(self,SS_Registers::PR_TL,save_tl);
uint64_t get_reg_gl( uint64_t gl, SS_Registers::Index index )
(self->get_state)(self,SS_Registers::PR_GL,&save_gl);
(self->set_state)(self,SS_Registers::PR_GL,gl);
self->reg_error = (self->get_state)(self,index,&value);
(self->set_state)(self,SS_Registers::PR_GL,save_gl);
void set_reg_gl( uint64_t gl, SS_Registers::Index index, uint64_t value )
(self->get_state)(self,SS_Registers::PR_GL,&save_gl);
(self->set_state)(self,SS_Registers::PR_GL,gl);
self->reg_error = (self->set_state)(self,index,value);
(self->set_state)(self,SS_Registers::PR_GL,save_gl);
uint64_t get_reg_wp( uint64_t wp, SS_Registers::Index index )
(self->get_state)(self,SS_Registers::PR_CWP,&save_wp);
(self->set_state)(self,SS_Registers::PR_CWP,wp);
self->reg_error = (self->get_state)(self,index,&value);
(self->set_state)(self,SS_Registers::PR_CWP,save_wp);
void set_reg_wp( uint64_t wp, SS_Registers::Index index, uint64_t value )
(self->get_state)(self,SS_Registers::PR_CWP,&save_wp);
(self->set_state)(self,SS_Registers::PR_CWP,wp);
self->reg_error = (self->set_state)(self,index,value);
(self->set_state)(self,SS_Registers::PR_CWP,save_wp);
uint64_t get_asi( uint8_t asi, uint64_t addr )
self->asi_error = self->asi_map.rd64(self,asi,SS_Vaddr(addr),&data);
void set_asi( uint8_t asi, uint64_t addr, uint64_t data )
self->asi_error = self->asi_map.wr64(self,asi,SS_Vaddr(addr),data);
uint64_t run_step( uint64_t n );
uint64_t trc_step( uint64_t n );
void add_tracer( SS_Tracer* );
void del_tracer( SS_Tracer* );
SS_BreakPoint* break_points;
SS_BreakPoint* break_hit;
SS_BreakPoint::Ident break_on_trap( uint_t tt );
SS_BreakPoint::Ident break_on_red_mode();
SS_BreakPoint::Error break_enable( SS_BreakPoint::Ident id );
SS_BreakPoint::Error break_disable( SS_BreakPoint::Ident id );
SS_BreakPoint::Error break_delete( SS_BreakPoint::Ident id );
// Wrap to avoid swig issues with int64_t
SS_BreakPoint::Ident break_on_inst_va( uint64_t va )
return self->break_on_inst_va(SS_Vaddr(va));
SS_Paddr va2pa( uint64_t va )
return self->va2pa(SS_Vaddr(va));
SS_Paddr va2pa( uint64_t va, uint_t ctx )
return self->va2pa(SS_Vaddr(va),ctx);
SS_Paddr va2pa( uint64_t va, uint_t ctx, uint_t pid )
return self->va2pa(SS_Vaddr(va),ctx,pid);
SS_Paddr ra2pa( uint64_t ra )
return self->ra2pa(SS_Vaddr(ra));
SS_Paddr ra2pa( uint64_t ra, uint_t pid )
return self->ra2pa(SS_Vaddr(ra),pid);
/*============================================================================*\
\*============================================================================*/
/* ss_tte() is used when get an uint64_t value but need a proper
SS_Tte python object pointer type */
SS_Tte* ss_tte( int64_t p )
return val2ptr<SS_Tte>(p);
void tag_parity_error( int f );
void data_parity_error( int f );
void context( uint16_t c );
void page_size( uint8_t p );
void taddr( SS_Paddr t );
// Wrap to avoid swig issues with int64_t
SS_Paddr trans( uint64_t va )
return self->trans(SS_Vaddr(va));
bool match_real( uint64_t ra, uint_t pid )
return self->match_real(SS_Vaddr(ra),pid);
bool match_virt( uint64_t va, uint64_t ctxt, uint_t pid )
return self->match_virt(SS_Vaddr(va),ctxt,pid);
bool match_virt( uint64_t va, uint64_t ctxt0, uint64_t ctxt1, uint_t pid )
return self->match_virt(SS_Vaddr(va),ctxt0,ctxt1,pid);
void insert_tsb_tte( uint16_t pid, uint64_t tag, uint64_t data, uint64_t addr )
self->insert_tsb_tte(pid,tag,data,SS_Vaddr(addr));
/*============================================================================*\
\*============================================================================*/
/* ss_tlb() is used when get an uint64_t value but need a proper
SS_Tlb python object pointer type */
SS_Tlb* ss_tlb( uint64_t p )
return val2ptr<SS_Tlb>(p);
SS_Tte* get( uint_t index );
void set( uint_t index, SS_Tte* tte );
void flush( SS_Tte* tte );
int next_valid_index( int );
/*============================================================================*\
\*============================================================================*/
SS_SnapShot( FILE* f, bool _load );
/*============================================================================*\
\*============================================================================*/
SS_Io* get_io() { return &SS_Io::io; }
class SS_Io : public SS_AddressMap
void poke8( uint_t sid,uint64_t addr, uint8_t data );
void poke16( uint_t sid,uint64_t addr, uint16_t data );
%extend { /* python 2.4 became pedantic about int values with signbit set, this avoids the nagging */
void poke32( uint_t sid, int64_t addr, uint64_t data )
self->poke32(sid,addr,uint32_t(data));
void poke64( uint_t sid, uint64_t addr, uint64_t data );
uint8_t peek8u ( uint_t sid, uint64_t addr );
int8_t peek8s ( uint_t sid, uint64_t addr );
uint16_t peek16u( uint_t sid, uint64_t addr );
int16_t peek16s( uint_t sid, uint64_t addr );
uint32_t peek32u( uint_t sid, uint64_t addr );
int32_t peek32s( uint_t sid, uint64_t addr );
uint64_t peek64 ( uint_t sid, uint64_t addr );
void flush( SS_Paddr pa );
void snapshot( SS_SnapShot& ss );
void ras_enable( char* cmd );