/*
 * Copyright (c) 1990,1993-2001 by Sun Microsystems, Inc.
 * All rights reserved.
 */

#ifndef	_SYS_MMU_H
#define	_SYS_MMU_H

#pragma ident	"@(#)mmu.h	1.36	01/05/18 SMI"

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * Definitions for the SOFT MMU
 */

#define	FAST_IMMU_MISS_TT	0x64
#define	FAST_DMMU_MISS_TT	0x68
#define	FAST_PROT_TT		0x6c

/*
 * Constants defining alternate spaces
 * and register layouts within them,
 * and a few other interesting assembly constants.
 */

#ifndef STINGRAY
/*
 * vaddr offsets of various registers
 */
#define	MMU_TTARGET		0x00 /* TSB tag target */
#define	MMU_PCONTEXT		0x08 /* primary context number */
#define	MMU_SCONTEXT		0x10 /* secondary context number */
#define	MMU_SFSR		0x18 /* sync fault status reg */
#define	MMU_SFAR		0x20 /* sync fault addr reg */
#define	MMU_TSB			0x28 /* tsb base and config */
#define	MMU_TAG_ACCESS		0x30 /* tlb tag access */
#define	MMU_VAW			0x38 /* virtual watchpoint */
#define	MMU_PAW			0x40 /* physical watchpoint */
#endif
#define	MMU_TSB_PX		0x48 /* i/d tsb primary extension reg */
#define	MMU_TSB_SX		0x50 /* d tsb secondary extension reg */
#define	MMU_TSB_NX		0x58 /* i/d tsb nucleus extension reg */
#define	MMU_TAG_ACCESS_EXT	0x60 /* tlb tag access extension reg */

#ifdef STINGRAY
/*
 * Stingray ASI 0x3F - ASI_MMU
 * Offsets and function.
 */
#define	IMMU_TAG_ACCESS		0x10 /* itlb tag access */
#define	DMMU_TAG_ACCESS		0x20 /* dtlb tag access */	
#define	IMMU_TSB		0x30 /* tsb base address (instruction) */
#define	DMMU_TSB		0x40 /* tsb base address (data) */

/*
 * Stingray ASI 0x40 - ASI_MMU_CONFIG
 * Offsets and function.
 */
#define	MMU_PCONTEXT		0x10 /* primary context register */
#define	MMU_SCONTEXT		0x20 /* secondary context register */
#define	MMU_NCONTEXT		0x30 /* nucleus context register */
#define	MMU_TLB_LOCK_ENTRY	0x50 /* TLB lock entry register*/
#define	MMU_TLB_FIFO_COUNTER	0x60 /* TLB FIFO counter */

/*
 * Stingray D-MMU SFSR (Synchronous Fault Status Register)
 * aka Data Fault Access Type Register
 *
 * +----------+---------+----------+-------+-----+---+---+-+-+
 * | Reserved | Context | Reserved | FType | ASI |Rsv|PRV|R|W|
 * +----------+---------+----------+-------+-----+---+---+-+-+
 *  63      60 59     48 47      16 15	 12 11  4  3   2  1 0
 *
 */
#define	DSFSR_WR		0x00000001	/* data write */
#define	DSFSR_RD		0x00000002	/* data read */
#define	DSFSR_ALS		0x00000003	/* atomic load-store */
#define	DSFSR_PR		0x00000004	/* privilege mode */

#define	DSFSR_ASI_SHIFT		4
#define	DSFSR_ASI_MASK		0x00000FF0	/* ASI used for access */
#define	FAULT_ASI(x)		(((x) & DSFSR_ASI_MASK) >> DSFSR_ASI_SHIFT)

#define	DSFSR_FTYPE_SHIFT	12
#define	DSFSR_FTYPE_MASK	0x0000F000	/* fault access type */
#define	FAULT_TYPE(x)		(((x) & DSFSR_FTYPE_MASK) >> DSFSR_FTYPE_SHIFT)
/*
 * Various fault types
 */
#define	FT_NOERR		0x0	/* no error */
#define	FT_UDTLB_HIT		0x1	/* uDTLB multiple hit */
#define	FT_MTLB_PAR		0x2	/* MTLB parity error */
#define	FT_MTLB_HIT		0x3	/* MTLB multiple hit */
#define	FT_D1_TAG_PAR		0x4	/* D1 Cache Tag parity err */
#define	FT_D1_TAG_HIT		0x5	/* D1 Cache Tag multiple hit */
#define	FT_D1_ECC_1BIT		0x6	/* D1 Cache Data ECC single bit */
#define	FT_D1_ECC_NBIT		0x7	/* D1 Cache Data ECC multiple hit */
#define	FT_UPA_BUSERR		0x8	/* UPA Bus Error */
#define	FT_UPA_TIMEOUT		0x9	/* UPA time out */
					/* 0xA - 0xB reserved */
#define	FT_SO_ACCESS		0xC	/* Strongly ordered page access */
#define	FT_NFO_ACCESS		0xD	/* Non-faulting only page access */
#define	FT_NC_ACCESS		0xE	/* Non-cacheable page access */
#define	FT_INV_ASI		0xF	/* Invalid ASI */

#define	DSFSR_CTX_SHIFT		48
#define	DSFSR_CTX_MASK		0x0FFF000000000000
#define	FAULT_CONTEXT(x)	(((x) & DSFSR_CTX_MASK) >> DSFSR_CTX_SHIFT)
	

/*
 * packed SFSR format
 *
 * +--------------+-----+-------+-----+---+---+-+-+
 * | Context      | Rev | FType | ASI |Rsv|PRV|R|W|
 * +--------------+-----+-------+-----+---+---+-+-+
 * 31           20 18 16 15   12 11  4  3   2  1 0
 */	

#define	PACKED_DSFSR_CTX_SHIFT	20
#define	PACKED_DSFSR_CTX_MASK	0xFFF00000

/*
 * Stingray I-MMU SFSR (Synchronous Fault Status Register)
 * aka Instruction Fault Type Register
 *
 * +----------------------------------------+--------+
 * |                   0                    |  type  |
 * +----------------------------------------+--------+
 *  63                                     4 3      0
 */

/*
 * Various fault types
 */
#define	FT_I_NOERR		0x0	/* no error */
#define	FT_UDTLB_HIT		0x1	/* uDTLB multiple hit */
#define	FT_I_MTLB_PAR		0x2	/* MTLB parity error */
#define	FT_I_MTLB_HIT		0x3	/* MTLB multiple hit */
#define	FT_I1_TAG_PAR		0x4	/* I1 Cache Tag parity err */
#define	FT_I1_TAG_HIT		0x5	/* I1 Cache Tag multiple hit */
#define	FT_I1_ECC_1BIT		0x6	/* I1 Cache Data ECC single bit */
#define	FT_I1_ECC_NBIT		0x7	/* I1 Cache Data ECC multiple hit */
#define	FT_I_UPA_BUSERR		0x8	/* UPA Bus Error */
#define	FT_I_UPA_TIMEOUT	0x9	/* UPA time out */
					/* 0xA - 0xD reserved */
#define	FT_I0_TAG_PAR		0xE	/* I0 Cache Tag parity err */
#define	FT_I0_DATA_PAR		0xF	/* I0 Cache Data parity err */

#else /* STINGRAY */

/*
 * Synchronous Fault Status Register Layout
 *
 * IMMU and DMMU maintain their own SFSR Register
 * ______________________________________________________________________
 * |   Reserved   |  ASI | Reserved | FT | E | Cntx | PRIV | W | OW | FV|
 * |--------------|------|----------|----|---|------|------|---|----|---|
 *  63		24 23  16 15	  14 13 7  6  5	   4	3    2	  1   0
 *
 */
#define	SFSR_FV		0x00000001	/* fault valid */
#define	SFSR_OW		0x00000002	/* overwrite */
#define	SFSR_W		0x00000004	/* data write */
#define	SFSR_PR		0x00000008	/* privilege mode */
#define	SFSR_CTX	0x00000030	/* context id */
#define	SFSR_E		0x00000040	/* side-effect */
#define	SFSR_FT		0x00003F80	/* fault type mask */
#define	SFSR_ASI	0x00FF0000	/* ASI */

/*
 * Definition of FT (Fault Type) bit field of sfsr.
 */
#define	FT_NONE		0x00
#define	FT_PRIV		0x01		/* privilege violation */
#define	FT_SPEC_LD	0x02		/* speculative ld to e page */
#define	FT_ATOMIC_NC	0x04		/* atomic to nc page */
#define	FT_ILL_ALT	0x08		/* illegal lda/sta */
#define	FT_NFO		0x10		/* normal access to nfo page */
#define	FT_RANGE	0x20		/* dmmu or immu address out of range */
#define	FT_RANGE_REG	0x40		/* jump to reg out of range */
#define	SFSR_FT_SHIFT	7	/* amt. to shift right to get flt type */
#define	X_FAULT_TYPE(x)	(((x) & SFSR_FT) >> SFSR_FT_SHIFT)

/*
 * Defines for CT (ConText id) bit field of sfsr.
 */
#define	CT_PRIMARY	0x0	/* primary */
#define	CT_SECONDARY	0x1	/* secondary */
#define	CT_NUCLEUS	0x2	/* nucleus */
#define	SFSR_CT_SHIFT	4

#define	SFSR_ASI_SHIFT	16

#endif /* STINGRAY */

/*
 * MMU TAG TARGET register Layout
 *
 * +-----+---------+------+-------------------------+
 * | 000 | context |  --  | virtual address [63:22] |
 * +-----+---------+------+-------------------------+
 *  63 61 60	 48 47	42 41			   0
 */
#define	TTARGET_CTX_SHIFT	48
#define	TTARGET_VA_SHIFT	22
#ifdef STINGRAY
#define	TTARGET_VALID_SHIFT	63	/* valid bit */
#endif

#ifdef STINGRAY
/*
 * Stingray MMU TAG ACCESS register Layout
 *
 * +-----------------+--------------------------+
 * | context [63:52] |  virtual address [51:0]  |
 * +-----------------+--------------------------+
 *  63             52 51                       0
 */
#define	SR_TAGACC_CTX_SHIFT	52
#define	SR_TAGACC_VA_SHIFT	12
#define SR_TAGACC_SHIFT		1
#define	SR_TAGACC_CTX_MASK	0xFFF0000000000000

#define	TAGACC_CTX_MASK		0x1FFF
#define TAGACC_SHIFT		13
#define	TAGACC_VADDR_MASK	(~TAGACC_CTX_MASK)
#define	TAGACC_CTX_SHIFT	19

#define CONVERT_TAG_SR_TO_US(tag, tmp)	\
	srlx	tag, SR_TAGACC_CTX_SHIFT, tmp	;\
	srln	tag,1,tag			;\
	slln	tag, (SR_TAGACC_VA_SHIFT + 1),tag	;\
	or	tag,tmp,tag

#define CONVERT_TAG_US_TO_SR(tag, tmp)	\
	sllx	tag, SR_TAGACC_CTX_SHIFT, tmp	;\
	srln	tag, (SR_TAGACC_VA_SHIFT + 1), tag	;\
	slln	tag, 1, tag			;\
	or	tag, tmp, tag


/*
 * Stingray MTLB Demap Layout
 *
 * +-----------------+--------------------------+
 * | context [63:52] |  virtual address [51:0]  |
 * +-----------------+--------------------------+
 *  63             52 51                       0
 */
#define	DEMAP_CTX_SHIFT		52
#define	DEMAP_VA_SHIFT		12	/* address to VA format */
	
/*
 * Used for indexing into TLB (ie data access)
 * format: VA[11:4] = entry #
 */
#define	TLB_ENTRY_SHIFT		4
#define	TLB_ENTRY_SIZE		(1 << TLB_ENTRY_SHIFT)

#else /* STINGRAY */

/*
 * MMU TAG ACCESS register Layout
 *
 * +-------------------------+------------------+
 * | virtual address [63:13] |  context [12:0]  |
 * +-------------------------+------------------+
 *  63			  13	12		0
 */
#define	TAGACC_CTX_MASK		0x1FFF
#define	TAGACC_SHIFT		13
#define	TAGACC_VADDR_MASK	(~TAGACC_CTX_MASK)
#define	TAGACC_CTX_SHIFT	19

#endif	/* STINGRAY */

/*
 * MMU DEMAP Register Layout
 *
 * +-------------------------+------+------+---------+-----+
 * | virtual address [63:13] | rsvd | type | context |  0  |
 * +-------------------------+------+------+---------+-----+
 *  63			   13 12   8  7   6   5	    4 3   0
 */
#define	DEMAP_PRIMARY		(CT_PRIMARY << SFSR_CT_SHIFT)
#define	DEMAP_SECOND		(CT_SECONDARY << SFSR_CT_SHIFT)
#define	DEMAP_NUCLEUS		(CT_NUCLEUS << SFSR_CT_SHIFT)
#define	DEMAP_TYPE_SHIFT	6
#define	DEMAP_PAGE_TYPE		(0 << DEMAP_TYPE_SHIFT)
#define	DEMAP_CTX_TYPE		(1 << DEMAP_TYPE_SHIFT)
#define	DEMAP_ALL_TYPE		(2 << DEMAP_TYPE_SHIFT)

/*
 * TLB DATA ACCESS Address Layout
 *
 * +-------------+---------------+---+
 * +   Not used	 |   tlb entry	 | 0 |
 * +-------------+---------------+---+
 *  63		9 8		3 2  0
 */
#define	DTACC_SHIFT	0x3
#define	DTACC_INC	0x8

/*
 * TSB Register Layout
 *
 * +----------------------+-------+-----+-------+
 * +  tsb_base va [63:13] | split |  -  |  size |
 * +----------------------+-------+-----+-------+
 *  63			13   12	    11 3 2	0
 */
#define	TSBBASE_SHIFT		13
#define	TSBSPLIT_SHIFT		12
#define	TSB_SPLIT_CONFIG	1
#define	TSB_COMMON_CONFIG	0
#define	TSB_SZ_MASK		0x7

#ifdef STINGRAY
/*
 * Stingray MMU TLB TAG READ register Layout
 *
 * +-----------------+--------------------------+
 * | context [63:52] |  virtual address [51:0]  |
 * +-----------------+--------------------------+
 *  63             52 51                       0
 */
#define	TAGREAD_CTX_SHIFT		52
#define	TAGREAD_VA_SHIFT		12

#else	/* STINGRAY */

/*
 * MMU TAG READ register Layout
 *
 * +-------------------------+------------------+
 * | virtual address [63:13] |  context [12:0]  |
 * +-------------------------+------------------+
 *  63			  13	12		0
 */
#define	TAGREAD_CTX_MASK	0x1FFF
#define	TAGREAD_SHIFT		13
#define	TAGREAD_VADDR_MASK	(~TAGREAD_CTX_MASK)

/*
 * MMU TAG ACCESS EXTENSION register Layout
 *
 * DTLB only
 * +-----+-------+-------+-----+
 * |  -  | pgsz1 | pgsz0 |  -  |
 * +-----+-------+-------+-----+
 *  63    21   19 18   16 15  0
 */
#define	TAGACCEXT_SHIFT		16
#define	TAGACCEXT_MKSZPAIR(SZ0, SZ1)	(((SZ1) << 3) | (SZ0))

/*
 * MMU PRIMARY/SECONDARY CONTEXT register
 */
#define	CTXREG_CTX_MASK		0x1FFF
#define	CTXREG_EXT_SHIFT	16

#endif	/* STINGRAY */

/*
 * The kernel always runs in KCONTEXT, and no user mappings
 * are ever valid in it (so any user access pagefaults).
 */
#define	KCONTEXT	0

/*
 * FLUSH_ADDR is used in the flush instruction to guarantee stores to mmu
 * registers complete.  It is selected so it won't miss in the tlb.
 */
#define	FLUSH_ADDR	(KERNELBASE + MMU_PAGESIZE4M)

#ifdef	__cplusplus
}
#endif

#endif /* _SYS_MMU_H */
