* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: ss_common.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 ============================================
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
#pragma ident "@(#)ss_common.h 1.54 07/03/07 SMI"
#include "tsparcv9internal.h"
#include "execinstns.h" /* autogenerated core defined instructions */
#include "sparcv9decode.h"
#include "sparcv9instns.h" /* autogenerated sparcv9 instruction definitions */
#define RW_lock_t volatile int64_t
#define RW_rdlock(_l) ss_rdlock(_l)
#define RW_wrlock(_l) ss_wrlock(_l)
#define RW_unlock(_l) ss_unlock(_l)
#define RW_lock_init(_l, _a) do { *(_l) = 0; } while (0)
extern void ss_rdlock(RW_lock_t
*);
extern void ss_wrlock(RW_lock_t
*);
extern void ss_unlock(RW_lock_t
*);
#elif HAS_POSIX_RW_LOCK /* } { */
#define RW_lock_t pthread_rwlock_t
#define RW_rdlock(_l) pthread_rwlock_rdlock(_l)
#define RW_wrlock(_l) pthread_rwlock_wrlock(_l)
#define RW_unlock(_l) pthread_rwlock_unlock(_l)
#define RW_lock_init(_l, _a) pthread_rwlock_init(_l, _a)
#define RW_lock_t pthread_mutex_t
#define RW_rdlock(_l) pthread_mutex_lock(_l)
#define RW_wrlock(_l) pthread_mutex_lock(_l)
#define RW_unlock(_l) pthread_mutex_unlock(_l)
#define RW_lock_init(_l, _a) pthread_mutex_init(_l, _a)
* SunSPARC / this file specific definitions
#define DBG_CMP 0x100000000000LL
#define DBGCMP(_s) do { if (debug_bits & DBG_CMP) { _s; } } while (0)
#define DBG_TM 0x80000000000LL
#define DBGTM(_s) do { if (debug_bits & DBG_TM) { _s; } } while (0)
#define DBG_SCRATCH 0x10000000000LL
#define DBGSCRATCH(_s) do { if (debug_bits & DBG_SCRATCH) { _s; } } while (0)
#define DBG_DAE 0x8000000000LL
#define DBGDAE(_s) do { if (debug_bits & DBG_DAE) { _s; } } while (0)
#define DBG_LE 0x2000000LL
#define DBGLE(_s) do { if (debug_bits & DBG_LE) { _s } } while (0) /* debug little endian */
#define DBG_ALIGN 0x4000000LL
#define DBGALIGN(_s) do { if (debug_bits & DBG_ALIGN) { _s } } while (0)
#define DBGEPM(_s) do { if (debug_bits & DBG_EPM) { _s } } while (0)
#define DBG_HCALL 0x8000LL
#define DBGHC(s) do { if (debug_bits & DBG_HCALL) { s } } while (0) /* debug hcalls */
#define DBG_PIC 0x10000LL
#define DBGPIC(s) do { if (debug_bits & DBG_PIC) { s } } while (0) /* debug Perf Cntrs */
#define DBG_SOFTINT 0x10000000LL
#define DBGSOFTINT(s) do { if (debug_bits & DBG_SOFTINT) { s } } while (0)
#define DBG_TICK 0x20000000LL
#define DBGTICK(s) do { if (debug_bits & DBG_TICK) { s } } while (0)
#define DBG_TICK_READ 0x4000000000LL
#define DBGTICKREAD(s) do { if (debug_bits & DBG_TICK_READ) { s } } while (0)
#define DBG_EXCEPT 0x20000LL
#define DBGE(s) do { if (debug_bits & DBG_EXCEPT) { s } } while (0) /* debug exceptions */
#define DBG_HPSTATE 0x40000LL
#define DBGHPS(s) do { if (debug_bits & DBG_HPSTATE) { s } } while (0) /* debug hpstate changes */
#define DBG_MMU 0x80000LL
#define DBGMMU(s) do { if (debug_bits & DBG_MMU) { s } } while (0) /* debug mmu */
#define DBG_MISS 0x100000LL
#define DBGMISS(s) do { if (debug_bits & DBG_MISS) { s } } while (0) /* debug mmu miss */
#define DBG_MC 0x200000LL
#define DBGMC(s) do { if (debug_bits & DBG_MC) { s } } while (0) /* debug dram controllers */
#define DBG_TS 0x400000LL
#define DBGTSTACK(s) do { if (debug_bits & DBG_TS) { s } } while (0) /* debug TSTATE etc. */
#define DBG_ERR 0x800000LL
#define DBGERR(s) do { if (debug_bits & DBG_ERR) { s } } while (0) /* debug error injection */
#define DBG_SSI 0x1000000LL
#define DBGSSI(s) do { if (debug_bits & DBG_SSI) { s } } while (0) /* debug SSI interrupts */
#define DBG_MONDO 0x8000000LL
#define DBGMONDO(s) do { if (debug_bits & DBG_MONDO) { s } } while (0) /* debug mondo interrupts */
#define DBG_ERR_TRAP 0x200000000LL
#define DBGERRTRAP(s) do { if (debug_bits & DBG_ERR_TRAP) { s } } while (0) /* debug error trap generation */
#define DBG_MUL_NODE 0x4000LL
#define DBGMULNODE(s) do { if (debug_bits & DBG_MUL_NODE) { s } } while (0) /* debug multinode, only VF for now */
* debug_bits values already reserved:
* 0x2000 < not reserved >
* 0x100000000 DBG_EXEC_LOOP
* 0x200000000 DBG_ERR_TRAP
* 0x4000000000 DBG_TICK_READ
* 0x10000000000 DBG_SCRATCH
* 0x20000000000 DBG_XCACHE
#define DBGCMP(_s) do { } while (0)
#define DBGTM(_s) do { } while (0)
#define DBGSCRATCH(_s) do { } while (0)
#define DBGDAE(_s) do { } while (0)
#define DBGLE(_s) do { } while (0) /* debug little endian */
#define DBGPIC(s) do { } while (0) /* debug Perf Cntrs */
#define DBGSOFTINT(s) do { } while (0)
#define DBGTICK(s) do { } while (0)
#define DBGTICKREAD(s) do { } while (0)
#define DBGEPM(_s) do { } while (0)
#define DBGALIGN(_s) do { } while (0)
#define DBGHC(s) do { } while (0) /* debug exceptions */
#define DBGE(s) do { } while (0) /* debug exceptions */
#define DBGHPS(s) do { } while (0) /* debug exceptions */
#define DBGMMU(s) do { } while (0) /* debug exceptions */
#define DBGMISS(s) do { } while (0) /* debug exceptions */
#define DBGMC(s) do { } while (0) /* debug dram controllers */
#define DBGERR(s) do { } while (0) /* debug error injection */
#define DBGTSTACK(s) do { } while (0) /* debug TSTATE etc. */
#define DBGSSI(s) do { } while (0) /* debug SSI interrupts */
#define DBGMONDO(s) do { } while (0) /* debug mondo interrupts */
#define DBGERRTRAP(s) do { } while (0) /* debug error trap generation */
#define DBGMULNODE(s) do { } while (0) /* debug multinode, only VF for now */
TFlag_Not_Poss
, TFlag_Priv
, TFlag_HypPriv
#define T( _name ) SS_trap_##_name, #_name /* SunSPARC standard trap naming convention */
#define TN1( _name ) N1_trap_##_name, #_name /* Niagara1 specific trap naming convention */
#define TN2( _name ) N2_trap_##_name, #_name /* Niagara2 standard trap naming convention */
#define TRK( _name ) RK_trap_##_name, #_name /* Rock standard trap naming convention */
#define X TFlag_Not_Poss /* Cant be generated by HW - SW emulated only */
#define SW TFlag_Not_Poss /* Cant be generated by HW - SW emulated only */
#define UH TFlag_HypPriv /* legal, but unexpected by hypervisor (supervisor error) */
#define Pri(_maj, _min) (((_maj)<<16)|(_min))
#define E( _name ) _name, #_name /* Error naming convention */
#define B( _name, _i ) #_name, ((uint64_t)1 << _i) /* Error field name, bit position in CERER */
* macros used for determing the fields of sun4v TTE format
#define SUN4V_TTED_V_BIT 63
#define SUN4V_TTED_V(n) (uint_t)((uint64_t)n >> SUN4V_TTED_V_BIT)
#define SUN4V_TTED_NFO(n) (uint_t)(((uint64_t)n >> 62) & 0x1)
#define SUN4V_TTED_IE(n) (uint_t)(((uint64_t)n >> 12) & 0x1)
#define SUN4V_TTED_E(n) (uint_t)(((uint64_t)n >> 11) & 0x1)
#define SUN4V_TTED_CP(n) (uint_t)(((uint64_t)n >> 10) & 0x1)
#define SUN4V_TTED_CV(n) (uint_t)(((uint64_t)n >> 9) & 0x1)
#define SUN4V_TTED_P(n) (uint_t)(((uint64_t)n >> 8) & 0x1)
#define SUN4V_TTED_EP(n) (uint_t)(((uint64_t)n >> 7) & 0x1)
#define SUN4V_TTED_X(n) SUN4V_TTED_EP(n)
#define SUN4V_TTED_W(n) (uint_t)(((uint64_t)n >> 6) & 0x1)
#define SUN4V_TTED_PS(n) (uint_t)((uint64_t)n & MASK64(3, 0))
#define SUN4V_TTET_VA(n) ((uint64_t)n & MASK64(41, 0))
#define SUN4V_TTE_ENTRY_SIZE 16
/* Use global array for this calculation */
extern uint8_t ss_page_size_shift
[];
#define SUN4V_PAGE_SIZE_SHIFT(ps) ((uint_t)(ss_page_size_shift[(ps)]))
* SunSPARC CPU core structures and typedefs
* Common set of strand core identification fields for use in SS_STRAND
* vthread: thread number within the core
* vcore_id: the thread number within the chip
#define SS_CORE_NUM_FIELDS \
/* SSR => Strand Specific Registers */
SSR_ScratchPad4
, /* hypervisor only (Niagara) */
SSR_ScratchPad5
, /* hypervisor only (Niagara) */
/* Hypervisor Scratchpad Registers (0x00 to 0x18) */
typedef struct SS_TLB ss_tlb_t
;
typedef struct NA_QUEUE
{
typedef struct SS_MMU ss_mmu_t
;
typedef struct SS_ERROR ss_error_t
;
/* Numbers for the SunSPARC strand interrupt queues */
typedef struct SS_L1_CACHE
{
uint64_t bist_ctl
; /* asi 0x42 va 0x00 ASI_SPARC_BIST_CTL_REG */
uint64_t inst_mask
; /* asi 0x42 va 0x08 ASI_INST_MASK_REG */
bool_t assocdis
; /* asi 0x42 va 0x10 ASI_LSU_DIAG_REG */
#define BIT(i) ((uint64_t)1<<i)
#define BIT_TEST(_val, _bit) (((_val)>>(_bit)) & 0x1)
* Context Type Encoding defined by SunSPARC
* N.B. These values are used as defined in the Rock DFSR
* so they cannot be changed to arbitrary values other than
#if defined(NIAGARA1) || defined(NIAGARA2) /* { */
/* Sparc Error Address Register Fields */
#define I_SYND(val) ((val & 0xff) << 16)
#define I_REG_WIN(val) ((val & 0x3) << 9)
#define I_REG_NUM(val) ((val & 0x1f) << 4)
#define F_REG_NUM(val) ((val & 0x3f) << 4)
#define EVEN_SYND(val) ((val & 0x7f) << 24)
#define ODD_SYND(val) ((val & 0x7f) << 16)
#define TLB_INDEX(val) ((val & 0x3f) << 4)
#define MMU_PC(val) (val & 0xfffffffffff0) /* PC:47-4 Rsvd:3-0 */
#define MMU_VA(val) (val & 0xfffffffffff0) /* VA:47-4 Rsvd:3-0 */
#define L1_PA(val) (val & 0xfffffffff0) /* PA:39-4 Rsvd:3-0 */
/* ECC Codes section in Appendix A of PRM 1.2 */
#define IREG_FAKE_SYND_SINGLE 0x83 /* single bit error on data bit 0 */
#define IREG_FAKE_SYND_DOUBLE 0x73 /* uncorrectable double bit error */
#define FREG_FAKE_SYND_SINGLE 0x43 /* single bit error on bit 0 */
#define FREG_FAKE_SYND_DOUBLE 0x33 /* uncorrectible double bit error */
* Bitfield definitions for the LSU_CONTROL register
#if defined(NIAGARA1) /* { */
#define LSU_CTRL_WATCH_VM MASK64(32,25)
#define LSU_CTRL_WATCH_VR MASK64(22,22)
#define LSU_CTRL_WATCH_VW MASK64(21,21)
#if defined(NIAGARA2) /* { */
#define LSU_CTRL_WATCH_MODE MASK64(34,33)
#define LSU_CTRL_WATCH_BM MASK64(32,25)
#define LSU_CTRL_WATCH_RE MASK64(24,24)
#define LSU_CTRL_WATCH_WE MASK64(23,23)
#define LSU_CTRL_SPEC_EN MASK64(4,4)
#define LSU_CTRL_DMMU_EN MASK64(3,3)
#define LSU_CTRL_IMMU_EN MASK64(2,2)
#define LSU_CTRL_DC_EN MASK64(1,1)
#define LSU_CTRL_IC_EN MASK64(0,0)
#if defined(NIAGARA1) /* { */
#define LSU_CTRL_REG_MASK (LSU_CTRL_WATCH_VM | LSU_CTRL_WATCH_VR | \
LSU_CTRL_WATCH_VW | LSU_CTRL_DMMU_EN | \
LSU_CTRL_IMMU_EN | LSU_CTRL_DC_EN | \
#if defined(NIAGARA2) /* { */
#define LSU_CTRL_REG_MASK (LSU_CTRL_WATCH_MODE | LSU_CTRL_WATCH_BM | \
LSU_CTRL_WATCH_RE | LSU_CTRL_WATCH_WE | \
LSU_CTRL_SPEC_EN | LSU_CTRL_DMMU_EN | \
LSU_CTRL_IMMU_EN | LSU_CTRL_DC_EN | \
#define LSU_CTRL_INITVAL (0LL)
* Functions and definitions for TLB and MMU code
* This macro is a place holder for the correct register setup
* that is required in order to be able to deliver a particular
* fault resulting from a memory reference.
#define MEMORY_ACCESS_TRAP() do { } while (0)
* SunSPARC CPU TLB structures
* Each hash table is divided into buckets, based on pfn, context and partid
* The chains attached to a bucket are designed to have multiple readers and
* only a single writer/modifier at any one time.
* FIXME: However, operations like entry probling and invalidate all etc. don't
* ... I'm going to assume that TLB contention between strands is sufficiently
* low that we can get away with a single rw lock for the entire TLB.
* This should be enough to get something working - we'll fix the performance
* later when we get a chance to profile the running code ....
* Naturally, if we don't share TLBs between strand threads then there is no
* Otherwise we have to implement a fair multiple-reader, single writer locking
* scheme, that is hopefully fast - ish.
* FIXME: we use Solaris' reader/writer locks to get this working, but I suspect
* they are tediously slow - quick measurement indicates they take around 400 instructions
* to take and release an uncontested lock !! Need to profile this code and see if this is
* a performance bottleneck. But for now this is sufficient to get this working.
* NOTE: if this is very low contention, we should probably simply move to a mutex
* per bucket, since the performance of Solaris' mutexes is about twice that of the rwlock.
* Increasing the number of buckets and better hashing alg would also reduce contention.
typedef uint32_t matchcontext_t
;
typedef uint16_t matchcontext_t
;
#define SS_TLB_REAL_CONTEXT ((matchcontext_t)-1)
#define SS_TLB_INVALID_CONTEXT ((matchcontext_t)-2)
#define SS_TLB_INVALID_PARTID ((uint16_t)-1)
#define SS_NUCLEUS_CONTEXT 0
typedef struct TLB_ENTRY tlb_entry_t
;
SS_TLB_FLAG_READ
= 0x001, /* niagara doesn't have read bit */
SS_TLB_FLAG_WRITE
= 0x002, /* writeable */
SS_TLB_FLAG_EXEC
= 0x004, /* executable */
SS_TLB_FLAG_PRIV
= 0x008, /* privileged */
SS_TLB_FLAG_CP
= 0x010, /* cachable in physically-indexed cache */
SS_TLB_FLAG_E
= 0x020, /* side-effect */
SS_TLB_FLAG_NFO
= 0x040, /* no-fault-only */
SS_TLB_FLAG_IE
= 0x080, /* Invert Endian */
SS_TLB_FLAG_V
= 0x100, /* valid */
SS_TLB_FLAG_LOCKED
= 0x200 /* locked */
uint64_t pa_offset
; /* (i.e. pa-va) */
uint64_t data
; /* as returned by the data register read */
bool_t is_real
; /* true for RA to PA, false for VA to PA translation */
uint16_t tag_context
; /* context value in TLB entry tag field */
matchcontext_t match_context
; /* context used when matching entries; 0..12 bits */
/* -1 if this is a real translation not a virtual one */
/* -2 if this is not a valid translation */
sint16_t hashidx
; /* used to help find the entry in the hash for unhooking */
/* == -1 if the entry is on the free list */
* Niagara max page size is 256MB .. this value is used for
* the TLB hashing index value
#define SS_MAX_PAGE_SIZE_BITS 28
#if defined(NIAGARA1) || defined(NIAGARA2) /* { */
#define SS_VA_HOLE_LB 0x0000800000000000
#define SS_VA_HOLE_UB 0xffff7fffffffffff
/* Extend 48 bit VA to 64 bits */
#define VA48(_va) (((int64_t)(_va) << 16) >> 16)
#define VA48_WARNING(_sp, _va) do {\
EXEC_WARNING(("@pc=0x%llx not a 48-bit VA 0x%llx",\
#define VA48_ASSERT(_va) ASSERT((_va) == VA48(_va))
* TLB organisation is independent of the
* search hash - and is merely determined by the
* behaviour of the insert / demap functions.
#if defined(NIAGARA1) || defined(NIAGARA2) /* { */
#define SS_TLB_HASH_ENTRIES 32 /* modest number */
#define SS_TLB_HASH_ENTRIES 256 /* less modest number */
#define SS_TLB_HASH_MASK (SS_TLB_HASH_ENTRIES-1)
/* define replacement policy when all entries are valid: */
#define SS_TLB_REPLACE_RROBIN 1
/* #define SS_TLB_REPLACE_RANDOM 1 */
tlb_hash_bucket_t hash
[SS_TLB_HASH_ENTRIES
];
tlb_entry_t
* tlb_entryp
;
#if SS_TLB_REPLACE_RROBIN /* { */
typedef struct SS_TLB_SPEC
{
typedef struct ERROR_PROC
{
* SunSPARC CPU specific info about how a debugger instance is
* attached ... handled as a hidden data type from the debugger,
* but provides this module info on which strand etc. the debugger
* is actually attached to.
config_proc_t
* config_procp
;
typedef enum SS_DEMAP ss_demap_t
;
NA_mem_read
, NA_mem_write
, NA_mem_clear
* All memory ASIs bit3=1 if the ASI is Little Endian
#define SS_ASI_LE_MASK (1 << 3)
MF_Normal
= 0x01, /* if normal access, else alternate address space being used */
MF_MMU_Bypass
= 0x02, /* if this ld/st should bypass MMU translation */
MF_Has_Priv
= 0x04, /* if access is from priv or hpriv mode */
MF_No_Fault
= 0x08, /* No faulting load specified */
MF_IO_Access
= 0x10, /* Not a cacheable access - e.g. REAL_IO */
MF_Blk_Init
= 0x20, /* Block Initialize effect */
MF_Atomic_Access
= 0x40, /* Atomic instruction access (including 128-bit atomic load) */
MF_TLB_Real_Ctx
= 0x80, /* Search TLB RA->PA mapping (due to ASI_*_real_* access) */
typedef uint64_t error_type_t
;
#define ss_set_errcheck(npp) do { \
npp->error_check = npp->errorp->ldac_addr | \
npp->errorp->ldau_addr | npp->errorp->dac_addr | \
#endif /* ERROR_INJECTION */
/* The processor specific structure. */
typedef struct SS_PROC ss_proc_t
;
* functions defined outside the CPU loadable modules
extern void host_atomic_get128be(uint64_t *, uint64_t *, uint64_t *);
* extern definitions used by more than one libsunsparc source file
extern void ss_parse(domain_t
*, config_proc_t
*);
extern void ss_parse_tlb(ss_tlb_spec_t
*);
extern void ss_init(domain_t
*, config_proc_t
*);
extern void ss_dump(domain_t
*, config_proc_t
*);
extern bool_t
ss_dbgr_regread(void*, uint_t
, uint64_t*);
extern bool_t
ss_dbgr_regwrite(void*, uint_t
, uint64_t);
extern void ss_exec_setup(simcpu_t
*);
extern void ss_exec_cleanup(simcpu_t
*);
extern bool_t
ss_save_state(simcpu_t
*);
extern void ss_check_async_event(simcpu_t
*);
extern void ss_take_exception(simcpu_t
*);
extern void ss_dump_tlbs(config_proc_t
*, bool_t
);
extern void ss_dump_tlbs_nolock(config_proc_t
*, bool_t
);
extern void ss_dump_instruction_counts(config_proc_t
*);
extern uint64_t ss_ext_signal(config_proc_t
*, ext_sig_t
, void*);
extern bool_t
ss_dev_mem_access(config_proc_t
*config_procp
, tpaddr_t addr
,
uint8_t *datap
, uint64_t size
, dev_access_t type
);
extern void * ss_dbgr_attach(domain_t
*, config_proc_t
*, char*);
extern void ss_dbgr_detach(void*);
extern uint64_t ss_dbgr_mem_read(void*, tvaddr_t
, bool_t
, uint8_t*, uint64_t);
extern uint64_t ss_dbgr_mem_write(void*, tvaddr_t
, bool_t
, uint8_t*, uint64_t);
extern uint64_t ss_dbgr_mem_clear(void*, tvaddr_t
, bool_t
, uint64_t);
extern void ss_dbgr_set_break(void*, tvaddr_t
);
extern void ss_dbgr_clear_break(void*, tvaddr_t
);
extern void ss_tlb_unhash(ss_tlb_t
*, tlb_entry_t
*);
extern void ss_tlb_unfree(ss_tlb_t
*, tlb_entry_t
*);
extern void ss_free_tlb_entry(ss_tlb_t
*, tlb_entry_t
*);
extern void ss_tlb_scrub(simcpu_t
*, ss_tlb_t
*, bool_t
);
extern void ss_xic_miss(simcpu_t
*, xicache_line_t
*, tvaddr_t
);
extern bool_t
ss_tm_chkpt(simcpu_t
*, tvaddr_t
);
extern void ss_tm_commit(simcpu_t
*);
extern void ss_tm_fail(simcpu_t
*, uint64_t);
extern uint64_t ss_read_pstate(sparcv9_cpu_t
*);
extern error_conf_t
* new_errconf(error_op_t
, error_type_t
);
extern error_conf_t
* find_errconf(simcpu_t
*, error_op_t
, error_type_t
);
extern bool_t
remove_errconf(simcpu_t
* sp
, error_conf_t
* rmep
);
extern void dump_errconf(error_conf_t
*);
extern void extract_error_type(error_conf_t
* errorconfp
);
extern void update_errflags(simcpu_t
* sp
);
extern void clear_errflags(simcpu_t
* sp
);
extern void ss_error_condition(simcpu_t
*, error_conf_t
*);
extern void tlb_entry_error_match(simcpu_t
*, ss_mmu_t
*, tlb_entry_t
*);
#endif /* ERROR_INJECTION */
#if !defined(NDEBUG) /* { */
extern void ss_tlb_contents(FILE*, ss_tlb_t
*, bool_t
);
extern uint64_t ss_cpu_mem(domain_t
*, void*, sparcv9_cpu_t
*, dbgr_mem_op_t
, tvaddr_t
, bool_t
, uint8_t*, uint_t
);
extern void ss_asi_access( simcpu_t
*, maccess_t
, uint_t
, uint_t
, uint64_t, uint64_t, asi_flag_t
);
extern bool_t
ss_demap(simcpu_t
*, ss_demap_t
, ss_mmu_t
*, ss_tlb_t
*, uint_t
, bool_t
, uint_t
, tvaddr_t
);
extern void ss_tlb_flush_shares(simcpu_t
*, ss_tlb_t
*, bool_t
);
extern uint64_t ss_read_tick(simcpu_t
*);
extern void ss_write_tick(simcpu_t
*, uint64_t);
extern uint64_t ss_read_stick(simcpu_t
*);
extern void ss_write_stick(simcpu_t
*, uint64_t);
extern void ss_recomp_tick_target(simcpu_t
*);
extern uint64_t ss_tick_cmpr_read(simcpu_t
*, tick_compare_t
*);
extern void ss_tick_cmpr_write(simcpu_t
*, tick_compare_t
*, uint64_t);
extern void ss_recomp_cycle_target(simcpu_t
*);
extern void ss_memory_asi_access(simcpu_t
*, maccess_t
, uint64_t*, mem_flags_t
, uint_t
, uint_t
, uint_t
, tvaddr_t
, tvaddr_t
);
extern void ss_check_interrupts(simcpu_t
*);
extern uint8_t host_ldstub(uint8_t *, uint8_t, uint8_t);
extern uint32_t host_cas32(uint32_t *, uint32_t, uint32_t);
extern uint64_t host_cas64(uint64_t *, uint64_t, uint64_t);
extern uint32_t host_swap(uint32_t *, uint32_t);
extern void v9_set_fsr_lower(simcpu_t
*, uint64_t);
extern void v9_set_fsr(simcpu_t
*, uint64_t);
extern void v9_set_fsr_fp_op(simcpu_t
*, uint64_t);
extern uint64_t v9_get_fsr(simcpu_t
*);
extern void ss_change_exec_state(ss_proc_t
*npp
, uint64_t running_status
);
extern uint64_t xor_bits(uint64_t);
uint_t
ss_get_cpuid(simcpu_t
*sp
);
void ss_trash_regs(sparcv9_cpu_t
* v9p
, uint64_t val
);
#define SS_VER_MANUF_OFFSET 48 /* bits 63:48 */
#define SS_VER_IMPL_OFFSET 32 /* bits 47:32 */
#define SS_VER_MASK_OFFSET 24 /* bits 31:24 */
#define SS_VER_MAXGL_OFFSET 16 /* bits 18:16 */
#define SS_VER_MAXTL_OFFSET 8 /* bits 15:8:0 */
#define SS_VER_NWINS_OFFSET 0 /* bits 4:0 */
#define SS_MAKE_VER_UPPER40(manuf, impl, mask) \
((manuf<<SS_VER_MANUF_OFFSET)| \
(impl<<SS_VER_IMPL_OFFSET)| \
(mask<<SS_VER_MASK_OFFSET))
#define SS_MAKE_VER_LOWER24(ngl, maxtl, nwins) \
(((ngl-1)<<SS_VER_MAXGL_OFFSET)| \
(maxtl<<SS_VER_MAXTL_OFFSET)| \
((nwins-1)<<SS_VER_NWINS_OFFSET))
#define RSVD_MASK(_sp, mask, val, asi, addr) \
EXEC_WARNING(("pc=0x%llx : stxa 0x%llx, [0x%x]0x%x: " \
"Attempted store to rsvd fields being masked out", \
(_sp)->pc, (val), (addr), (asi))); \
* Identical to above RSVD_MASK macro, but safe for use when _sp pointer may be NULL.
* Should be kept in sync with the above macro for any changes.
#define ROCK_RSVD_MASK(_sp, mask, val, asi, addr) \
EXEC_WARNING(("pc=0x%llx : stxa 0x%llx, [0x%x]0x%x: " \
"Attempted store to rsvd fields being masked out", \
(_sp)->pc, (val), (addr), (asi))); \
EXEC_WARNING(("System controller access : stxa 0x%llx, [0x%x]0x%x: " \
"Attempted store to rsvd fields being masked out", \
(val), (addr), (asi))); \
#endif /* _SS_COMMON_H */