Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / analyzers / trapcount / my_sparc.h
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: my_sparc.h
* 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 ============================================
*/
/*
* SPARC Instruction and Register stuff .....
*
*/
// ----------------------------------------------- Instruction decoding
#define get_rd(X) (((X) >> 25) & 0x1f)
#define get_op3(X) (((X) >> 19) & 0x3f)
#define get_rs1(X) (((X) >> 14) & 0x1f)
#define get_rs2(X) (((X) >> 0) & 0x1f)
#define is_imm(X) (((X) >> 13) & 0x1)
#define get_simm(X) ((((signed int)(X)) << 19) >> 19)
#define is_asi(X) ((get_op3(X) & 0x10) != 0)
#define is_imasi(X) (! is_imm(X))
#define get_imasi(X) (((X) >> 5) & 0xff)
#define get_iop(X) spix_sparc_iop(SPIX_SPARC_V9, &(X))
// --------------------------------------------------------- Registers
// ------------------------------------------------ Integer
#define REG_g0 0 /* (always) zero register */
#define REG_g1 1
#define REG_g2 2
#define REG_g3 3
#define REG_g4 4
#define REG_g5 5
#define REG_g6 6
#define REG_g7 7 /* (sometimes) thread pointer */
#define REG_o0 8
#define REG_o1 9
#define REG_o2 10
#define REG_o3 11
#define REG_o4 12
#define REG_o5 13
#define REG_o6 14 /* sp = o6 after SAVE */
#define REG_o7 15 /* ra = o7 before SAVE */
#define REG_l0 16
#define REG_l1 17
#define REG_l2 18
#define REG_l3 19
#define REG_l4 20
#define REG_l5 21
#define REG_l6 22
#define REG_l7 23
#define REG_i0 24
#define REG_i1 25
#define REG_i2 26
#define REG_i3 27
#define REG_i4 28
#define REG_i5 29
#define REG_i6 30
#define REG_i7 31 /* ra = i7 after SAVE */
#define REG_sp REG_o6 /* sp = o6 after SAVE (new, decremented, sp) */
#define REG_fp REG_i6 /* fp = i6 after SAVE (previous sp) */
const char * regnames[32] = {
"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
"%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%o6", "%o7",
"%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
"%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%i6", "%i7" };
// ------------------------------------------------ Hypervisor
# define HPSTATE_PRIV 0x4 /* Hyper-Privileged Mode */
// ------------------------------------------------ Privileged
#define PR_TPC 0x0 /* pc of the trapped process */
#define PR_TNPC 0x1 /* npc of the trapped process */
#define PR_TSTATE 0x2 /* */
#define PR_TT 0x3 /* 0..0xff HW, 0x100..0x17f SW */
#define PR_TICK 0x4 /* cpu cycle counter */
#define PR_TBA 0x5 /* trap base address */
#define PR_PSTATE 0x6
# define PSTATE_AG 0x1 /* Alternate Globals */
# define PSTATE_IE 0x2 /* Interrupts Enabled */
# define PSTATE_PRIV 0x4 /* Privileged Mode */
# define PSTATE_AM 0x8 /* Address Model (32/64 bit) */
# define PSTATE_MG 0x400 /* MMU Globals */
# define PSTATE_IG 0x800 /* Interrupt Globals */
#define PR_TL 0x7 /* trap level: 0(normal), 1,2,3,4 */
#define PR_PIL 0x8 /* interrupt level: 0(low)..15(hi) */
#define PR_CWP 0x9 /* current window pointer */
#define PR_CANSAVE 0xa
#define PR_CANRESTORE 0xb
#define PR_CLEANWIN 0xc
#define PR_OTHERWIN 0xd
#define PR_WSTATE 0xe
#define PR_FPQ 0xf
#define PR_VER 0x1f
#define MAX_TL 5
// ------------------------------------------------ Ancillary
#define ASR_Y 0x0 /* Y multipler reg (obsolete) */
#define ASR_CCR 0x02 /* condition code reg */
#define ASR_ASI 0x03 /* ASI indirect reg */
#define ASR_TICK 0x04 /* the TICK cpu clock counter */
#define ASR_PC 0x05 /* PC */
#define ASR_FPSR 0x06 /* Floating Point Status Reg */
/****Cheetah*** specific ASRs ****/
#define ASR_PCR 0x10 /* PIC control reg */
#define ASR_PIC 0x11 /* Performance Instrumentation Counter*/
#define ASR_DCR 0x12 /* Dispatch Control Reg */
#define ASR_GSR 0x13 /* Graphics Status Reg */
#define ASR_SSI 0x14 /* Set Soft Int reg */
#define ASR_CSI 0x15 /* Clear Soft Int reg */
#define ASR_SFTINT 0x16 /* the SoftInt reg */
#define ASR_TCMP 0x17 /* Tick Compare reg */
#define ASR_STICK 0x18 /* STick (system timer/counter) */
#define ASR_STCMP 0x19 /* STick Compare reg */
/* Cheetah actually defines separate bits for IG, MG, AG; we use an enumeration
like Millenium and Niagara */
#define PS_NormGlobals 0 /* PSTATE Globals specifiers */
#define PS_AltGlobals 1
#define PS_MmuGlobals 2
#define PS_IntrGlobals 3
int TT_Globals[512] = {0}; /* what globals get used for each TT */
/* ,and how to initialize it:... */
#define Init_TT_Globals { \
for (int i=0; i<512; i++) \
TT_Globals[i] = PS_AltGlobals; /* default: Window, Level, */ \
TT_Globals[0x008] = PS_MmuGlobals; /* i-fetch exception */ \
TT_Globals[0x030] = PS_MmuGlobals; /* data-access exception */ \
TT_Globals[0x060] = PS_IntrGlobals; /* mondo interrupts */ \
for (int i=0x064; i<=0x06f; i++) /* i/d tlb misses */ \
TT_Globals[i] = PS_MmuGlobals; \
}
const char * pstate_globals_str[4] = {"ng", "AG", "MG", "IG"};
/* the Cheetah real hardware... */
#define ALT_GLB_MASK 0xc01 /* pstate alt-globals bit mask, for Cheetah */
#define AG_MASK 0x001
#define MG_MASK 0x400
#define IG_MASK 0x800
// --------------------------------------------------------- Addressing
int64_t IOSpaceMask = 0x40000000000LL; /* bit#42 for sun4u platform only ??? */
#define ASI_PHYS_MEM 0x14 /* memory, no translation, E-cacheable */
#define ASI_PHYS_IO 0x15 /* io space, no trans, non-cacheable, sideeffect*/
#define ASI_PHYS_MEM_LE 0x1c
#define ASI_PHYS_IO_LE 0x1d
// --------------------------------------------------------- LITTLE-ENDIAN
#define ASI_NUCLEUS_LITTLE 0x0c
#define ASI_AS_IF_USER_PRIMARY_LITTLE 0x18
#define ASI_AS_IF_USER_SECONDARY_LITTLE 0x19
#define ASI_PRIMARY_LITTLE 0x88
#define ASI_SECONDARY_LITTLE 0x89
#define ASI_PRIMARY_NO_FAULT_LITTLE 0x8a
#define ASI_SECONDARY_NO_FAULT_LITTLE 0x8b
#define ASI_PHYS_USE_EC_LITTLE 0x1c
#define ASI_PHYS_BYPASS_EC_LITTLE 0x1d
#define ASI_QUAD_LDD_LITTLE 0x2c
#define ASI_PST8_PRIMARY_LITTLE 0xc8
#define ASI_PST8_SECONDARY_LITTLE 0xc9
#define ASI_PST16_PRIMARY_LITTLE 0xca
#define ASI_PST16_SECONDARY_LITTLE 0xcb
#define ASI_PST32_PRIMARY_LITTLE 0xcc
#define ASI_PST32_SECONDARY_LITTLE 0xcd
#define ASI_FL8_PRIMARY_LITTLE 0xd8
#define ASI_FL8_SECONDARY_LITTLE 0xd9
#define ASI_FL16_PRIMARY_LITTLE 0xda
#define ASI_FL16_SECONDARY_LITTLE 0xdb
#define ASI_BLOCK_PRIMARY_LITTLE 0xf8
#define ASI_BLOCK_SECONDARY_LITTLE 0xf9
// --------------------------------------------------------- MMU/TLB
/*
* useful ultrasparc MMU info:
*
* OS explicitly priming the TLB:
* write VA/cntx to TagAccess
* write Data to DataAccess, this second write causes the TLB entry
*
* OS tlb miss handler:
* read TagTarget, the address/cntx that caused the miss
* read 8kPointer, the mmu computed address into the TSB
* load-quad-atomic from TSB
* write DataIn, new tlb entry composed of {TagTarget, DataIn} pair
*
*
*/
/*
* The following seem(?) to have held constant throughout US-I,II,III,III+,
*/
#define MMU_PRI_CNTX_ASI 0x58 // OS tells MMU what CNTX its running
#define MMU_PRI_CNTX_OFFSET 0x08
#define MMU_SEC_CNTX_ASI 0x58
#define MMU_SEC_CNTX_OFFSET 0x10
#define MMU_ITSB_BASE_ASI 0x50 // OS tells MMU where the TSB is in memory
#define MMU_ITSB_BASE_OFFSET 0x28
#define MMU_DTSB_BASE_ASI 0x58
#define MMU_DTSB_BASE_OFFSET 0x28
#define MMU_ITSB_TAGMISS_ASI 0x50 // MMU tells OS what address missed in TLB
#define MMU_ITSB_TAGMISS_OFFSET 0x00
#define MMU_DTSB_TAGMISS_ASI 0x58
#define MMU_DTSB_TAGMISS_OFFSET 0x00
#define MMU_ITSB_8KPTR_ASI 0x51 // MMU tells OS what address in TSB to fetch
#define MMU_ITSB_8KPTR_OFFSET 0x00
#define MMU_DTSB_8KPTR_ASI 0x59
#define MMU_DTSB_8KPTR_OFFSET 0x00
#define MMU_ITLB_DATAIN_ASI 0x54 // OS feeds MMU with TSB entry to fill TLB
#define MMU_ITLB_DATAIN_OFFSET 0x00
#define MMU_DTLB_DATAIN_ASI 0x5c
#define MMU_DTLB_DATAIN_OFFSET 0x00
/* ----------------------------------------------------------------------------
*
*/
#define spix_iop(instref) spix_sparc_iop(SPIX_SPARC_V9, &(instref))
char spix_dis_buf[120];
unsigned long long spix_dis_pc = 0;
#define spix_disasm(iop,inst) (spix_sparc_dis(spix_dis_buf, 120, (iop), &(inst), spix_dis_pc), spix_dis_buf)
#define spix_is_integer_rd(iop) \
(iop != SPIX_SPARC_IOP_CALL \
&& ! spix_sparc_iop_istype (iop, SPIX_SPARC_ITYPE_BRANCH) \
&& ! spix_sparc_iop_istype (iop, SPIX_SPARC_ITYPE_FP))
/*#define spix_is_any_g7(iop) \
/* (iop != SPIX_SPARC_IOP_CALL \
/* && ! spix_sparc_iop_istype (iop, SPIX_SPARC_ITYPE_BRANCH) \
/* && ! spix_sparc_iop_istype (iop, SPIX_SPARC_ITYPE_FP) \
/* && (spixter.memarithi.rd == REG_g7 \
/* || (iop != SPIX_SPARC_IOP_SETHI \
/* && (spixter.memarithi.rs1 == REG_g7 \
/* || (! spixter.memarithi.i \
/* && spixter.memarithr.rs2 == REG_g7))))) */