/*
    cpu.h, Copyright  (c) by ,
    Swiss Federal Institute of Technology,
    Computer Engineering and Networks Laboratory.
 
    TOPSY -- A Teachable Operating System.
             Implementation of a tiny and simple
             micro kernel for teaching purposes.
 
    For further information, please visit http://www.tik.ee.ethz.ch/~topsy
 
    This software is provided under the terms of the GNU General Public Licence.
 
    A full copy of the GNU GPL is provided in the file COPYING found in the 
    development root of Topsy.
*/
/*
	
	File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/Topsy/mips/cpu.h,v $
 	Author(s):             
 	Affiliation:           ETH Zuerich, TIK
 	Version:               $Revision: 2922 $
 	Creation Date:         
 	Last Date of Change:   $Date: 2007-03-19 17:48:52 +0100 (Mon, 19 Mär 2007) $      by: $Author: baderma $
	
*/

#define PHYS_BASE					0
#define	KUSEG_BASE				0
#define	KUSEG_SIZE				0x80000000
#define	K0SEG_BASE				0x80000000
#define	K0SEG_SIZE				0x20000000
#define	K1SEG_BASE				0xa0000000
#define	K1SEG_SIZE				0x20000000
#define	K2SEG_BASE				0xc0000000
#define	K2SEG_SIZE				0x40000000

#define	ISA_KUSEG(x)			((unsigned)(x)  <  K0SEG_BASE)
#define	ISA_K0SEG(x)			(((unsigned)(x) >= K0SEG_BASE) && \
								((unsigned)(x) <  K1SEG_BASE))
#define	ISA_K1SEG(x)			(((unsigned)(x) >= K1SEG_BASE) && \
				 				((unsigned)(x) <  K2SEG_BASE))
#define	ISA_K2SEG(x)			((unsigned)(x)  >= K2SEG_BASE)

#define ISA_DIRECTMAPPED(x) (((unsigned)(x) >= K0SEG_BASE) && \
				 				((unsigned)(x) <  K2SEG_BASE))

#define	K0SEG_TO_PHYS(x)		((unsigned)(x) & 0x1fffffff)
#define	PHYS_TO_K0SEG(x)		((unsigned)(x) | K0SEG_BASE)

#define	K1SEG_TO_PHYS(x)		((unsigned)(x) & 0x1fffffff)
#define	PHYS_TO_K1SEG(x)		((unsigned)(x) | K1SEG_BASE)

#define	K0SEG_TO_K1SEG(x)		((unsigned)(x) | K1SEG_BASE)
#define	K1SEG_TO_K0SEG(x)		((unsigned)(x) & 0x9fffffff)

#define	VEC_TLB_UMISS			K0SEG_BASE
#define	VEC_RESET				(K1SEG_BASE+0x1fc00000)

#define	VEC_EXCEPTION_R3k		(K0SEG_BASE+0x80)
#define VEC_EXCEPTION_R4k		(K0SEG_BASE+0x180)

#define	TLB_BASE				0
#define	TLB_SIZE_R3k			64
#define	TLB_SIZE_R4k			48
#define TLB_SAFE_BASE			0
#define	TLB_SAFE_SIZE_R3k		8
#define	TLB_SAFE_SIZE_R4k		32
#define	TLB_USER_BASE			8
#define	TLB_USER_SIZE_R3k		56
#define	TLB_USER_SIZE_R4k		32


#define	c0_tlbhi				$10			/* EntryHi Register */
#define	TLB_HI_VPN_MASK_R3k		0xfffff000	/* 20 high bits */
#define	TLB_HI_VPN_MASK_R4k		0xffffe000	/* 19 high bits */
#define	TLB_HI_VPN_SHIFT_R3k	12
#define	TLB_HI_VPN_SHIFT_R4k	13
#define	TLB_HI_PID_MASK_R3k		0xfc0		/* 6 bits */
#define	TLB_HI_PID_MASK_R4k		0x000000ff	/* 8 bits */
#define	TLB_HI_PID_SHIFT_R3k	6
#define	TLB_HI_PID_SHIFT_R4k	0
#define	TLB_HI_NPID_R3k			64			/* tlb context ids */
#define	TLB_HI_NPID_R4k			64			/* tlb context ids */

#define	C0_TLBLO				$2			/* Entry Lo Register */
#define	C0_TLBLO0				$2			/* Entry Lo Register */
#define	C0_TLBLO1				$3			/* Entry Lo1 Register */
#define	TLB_LO_PFN_MASK_R3k		0xfffff000	/* 20 high bits */
#define	TLB_LO_PFN_MASK_R4k		0x3fffffc0
#define	TLB_LO_PFN_SHIFT_R3k	12
#define	TLB_LO_PFN_SHIFT_R4k	6
#define TLB_LO_CAT_MASK_R4k		0x00000038
#define TLB_LO_CAT_SHIFT_R4k	3
#define	TLB_NOCACHE_R3k			0x0800		/* No cache */
#define	TLB_CACHED_R4k			0x28		/* Cacheable coherent exclusive on write (shared) */
#define	TLB_DIRTY_R3k			0x0400		/* Dirty */
#define	TLB_DIRTY_R4k			0x4			/* Dirty */
#define	TLB_VALID_R3k			0x0200		/* Valid */
#define	TLB_VALID_R4k			0x2			/* Valid */
#define	TLB_GLOBAL_R3k			0x0100		/* Global */
#define	TLB_GLOBAL_R4k			0x1			/* Global */

#define C0_TLBPM				$5			/* Page Mask Register */
#define TLB_PM_MASK				0x1ffe000	/* Mask */
#define TLB_PM_SHIFT			13

#define C0_TLBWRD				$6			/* Wired Register */
#define TLB_WRD_MASK			0x000000ef	/* Mask */

#define	C0_TLBIND				$0			/* Index Register */
#define	TLB_IND_P				0x80000000	/* Probe */
#define	TLB_IND_INX_MASK_R3k	0x00003f00	/* Index */
#define	TLB_IND_INX_MASK_R4k	0x0000003f	/* Index */
#define	TLB_IND_INX_SHIFT_R3k	8
#define	TLB_IND_INX_SHIFT_R4k	0

#define C0_TLBRND				$1			/* Random Register */
#define	TLB_RND_MASK_R3k		0x00003f00	/* Index */
#define	TLB_RND_MASK_R4k		0x0000003f  /* Index */
#define	TLB_RND_SHIFT_R3k		8
#define	TLB_RND_SHIFT_R4k		0

#define C0_TLBCXT				$4			/* Context Register */
#define	TLB_CXT_PTE_MASK		0xffe00000	/* PTE base */
#define	TLB_CXT_PTE_SHIFT		21
#define	TLB_CXT_VPN_MASK		0x001ffffc	/* Failed VPN */
#define	TLB_CXT_VPN_SHIFT		2

#define	C0_BADVM				$8			/* BadVAddr Register */

#define	C0_STATUS				$12			/* Status Register */
#define	SR_CU_MASK				0xf0000000	/* Coproc Usable */
#define	SR_CU3					0x80000000	/* Coprocessor 3 usable */
#define	SR_CU2					0x40000000	/* Coprocessor 2 usable */
#define	SR_CU1					0x20000000	/* Coprocessor 1 usable */
#define	SR_CU0					0x10000000	/* Coprocessor 0 usable */
#define	SR_BEV					0x00400000	/* Boot Exception Vectors */
#define	SR_TS					0x00200000	/* TLB shutdown */
#define	SR_PE					0x00100000	/* Parity Error (cache) */
#define	SR_CM					0x00080000	/* Cache Miss */
#define	SR_PZ					0x00040000	/* Parity Zero (cache) */
#define	SR_S_W_C				0x00020000	/* Swap Caches */
#define	SR_I_S_C				0x00010000	/* Isolate (data) Cache */
#define	SR_INT_MASK				0x0000ff00	/* Interrupt Mask (1=enable)*/
#define	INT_LEV8				0x00000000	/* Interrupt level 8 */
#define	INT_LEV7				0x00008000	/* Interrupt level 7 */
#define	INT_LEV6				0x0000c000	/* Interrupt level 6 */
#define	INT_LEV5				0x0000e000	/* Interrupt level 5 */
#define	INT_LEV4				0x0000f000	/* Interrupt level 4 */
#define	INT_LEV3				0x0000f800	/* Interrupt level 3 */
#define	INT_LEV2				0x0000fc00	/* Interrupt level 2 */
#define	INT_LEV1				0x0000fe00	/* Interrupt level 1 */
#define	INT_LEV0				0x0000ff00	/* Interrupt level 0 */
#define INTMASK_SHIFT       	8

/* R3k mode defines */
#define	SR_KU_O					0x00000020	/* old  mode (1 => user) */
#define	SR_KU_P					0x00000008	/* previous mode */
#define SR_KU_O_SHIFT			5
#define SR_KU_P_SHIFT			3
#define	SR_KU_C					0x00000002	/* currrent mode */
#define	SR_IE_O					0x00000010	/* old IntEn (1 => enable) */
#define	SR_IE_P					0x00000004	/* previous IntEn */
#define	SR_IE_C					0x00000001	/* Current IntEn */

/* R4k mode defines */
#define SR_KSU_MASK				0x00000018	/* Mode */
#define SR_KSU_KERNEL			(0 << 3)
#define SR_KSU_SUPERVISOR		(1 << 3)
#define SR_KSU_USER	        	(2 << 3)
#define SR_ERL					0x00000004
#define SR_EXL					0x00000002
#define SR_IE					0x00000001


#define	C0_CAUSE				$13			/* Cause Register */
#define	CAUSE_BD				0x80000000	/* Branch Delay */
#define	CAUSE_CE_MASK			0x30000000	/* Coprocessor Error */
#define	CAUSE_CE_SHIFT			28
#define	CAUSE_IP_MASK			0x0000ff00	/* Interrupts Pending */
#define	CAUSE_IP_SHIFT			8
#define	IP_NLEV					8			/* No. of Interrupt Levels */
#define	IP_LEV7					0x00008000	/* Hardware level 7 pending */
#define	IP_LEV6					0x00004000	/* Hardware level 6 pending */
#define	IP_LEV5					0x00002000	/* Hardware level 5 pending */
#define	IP_LEV4					0x00001000	/* Hardware level 4 pending */
#define	IP_LEV3					0x00000800	/* Hardware level 3 pending */
#define	IP_LEV2					0x00000400	/* Hardware level 2 pending */
#define	IP_LEV1					0x00000200	/* Software level 1 pending */
#define	IP_LEV0					0x00000100	/* Software level 0 pending */
#define	CAUSE_EXC_MASK			0x0000003c	/* Exc Code */
#define	CAUSE_EXC_SHIFT			2
#define	EXC_INT					0x00000000	/* Interrupt */
#define	EXC_MOD					0x00000004	/* TLB mod */
#define	EXC_TLBL				0x00000008	/* TLB Miss (Load) */
#define	EXC_TLBS				0x0000000c	/* TLB Miss (Store) */
#define	EXC_ADEL				0x00000010	/* Address Error (Load) */
#define	EXC_ADES				0x00000014	/* Address Error (Store) */
#define	EXC_IBE					0x00000018	/* Bus Error (Instruction) */
#define	EXC_DBE					0x0000001c	/* Bus Error (Data) */
#define	EXC_SYS					0x00000020	/* Syscall */
#define	EXC_BP					0x00000024	/* Breakpoint */
#define	EXC_RI					0x00000028	/* Reserved Instruction */
#define	EXC_CU					0x0000002c	/* Coprocessor Unusable */
#define	EXC_OVF					0x00000030	/* Arithmetic Overflow */

#define	C0_EPC					$14			/* ExceptionPC Register */

#define	C0_PRID					$15			/* Processor Id Register */
#define PRID_REV_MASK			0x000000ff	/* Revision number */
#define PRID_REV_SHIFT			0
#define PRID_IMP_MASK			0x0000ff00	/* Implementation number */
#define PRID_IMP_SHIFT			8
#define PRID_R4K				0x00000440
#define PRID_R3K				0x00000230
/* XXX this is not perfect: R4k is when getPRID()&0x0000ff00 == 0x0000400 */
