addr_layout.h 5.96 KB
/*
 * Copyright (C) 1996-1998 by the Board of Trustees
 *    of Leland Stanford Junior University.
 * 
 * This file is part of the SimOS distribution. 
 * See LICENSE file for terms of the license. 
 *
 */

/**************************************************************************
 * addr_layout.h
 *
 * We currently support several configurations...
 *   OLD SIMOS:     kernel was linked at 0x60000000
 *   EXTENDED_PMEM: used in hive studies 
 *   SIMOS_VERSION_3: kernel is where it should be
 *   R4K: only under SIMOS_VERSION_3
 *
 * $Author: blythe $
 * $Date: 2002/05/29 01:09:10 $
 **************************************************************************/
#if !defined(SIM_MIPS32) && !defined(SIM_MIPS64)
#error <should not be here>
#endif

#ifndef ADDR_LAYOUT_H
#define ADDR_LAYOUT_H

/*
 * Define _SEXT(), a macro that sign-extends to the proper length 
 * this is needed for 64bit mode to work correctly.
 */

#if defined(SIM_MIPS32)
#define _SEXT(_x) (_x)
#else
#define _SEXT(_x) ((Reg64)(Reg32_s)(_x))
#endif

#define KUBASE	_SEXT(0)
#define KUSIZE	_SEXT(0x80000000)
#define K0BASE	_SEXT(0x80000000)
#define K0SIZE	_SEXT(0x20000000)
#define K1BASE	_SEXT(0xA0000000)
#define K1SIZE	_SEXT(0x20000000)
#define K2BASE	_SEXT(0xC0000000)
#define K2SIZE _SEXT(0x20000000)
#define KSBASE _SEXT(0xC0000000)
#define K3BASE _SEXT(0xE0000000)
#define XKPHYS_BASE 0xa800000000000000LL
#define XKPHYS_END  0xa800010000000000LL
#if defined(SIM_MIPS32)
#define K0_TO_K1(x)	((x)|_SEXT(0xA0000000))	/* kseg0 to kseg1 */
#define K1_TO_K0(x)	((x)&_SEXT(0x9FFFFFFF))	/* kseg1 to kseg0 */
#define K0_TO_PHYS(x)	((x)&0x1FFFFFFF)	/* kseg0 to physical */
#define K1_TO_PHYS(x)	((x)&0x1FFFFFFF)	/* kseg1 to physical */
#define KDM_TO_PHYS(x)	((x)&0x1FFFFFFF)	/* DirectMapped to physical */
#define PHYS_TO_K0(x)	((x)|_SEXT(0x80000000))	/* physical to kseg0 */
#elif defined(SIM_MIPS64)
/* the other macros under mips32 are not used */
#define K0_TO_PHYS(x)	(IS_CKSEG0(x) ? 	\
                         ((x)&0x1FFFFFFF) :	\
                         ((x)-XKPHYS_BASE))	/* kseg0 to physical */

#define PHYS_TO_K0(x)	(PHYS_TO_XKPHYS(x))
#define PHYS_TO_XKPHYS(x)	((x)+XKPHYS_BASE)	/* physical to xkphys */
#define XKPHYS_TO_PHYS(x)	((x)-XKPHYS_BASE)	/* xkphys to physical */
#endif

#undef UT_VEC
#undef R_VEC
#undef IS_KSEG0
#undef IS_KSEG1
#undef IS_KSEGDM
#undef IS_KSEG2
#undef IS_KPTESEG
#undef IS_KUSEG

/* Exception vectors */
#define	UT_VEC		K0BASE			/* utlbmiss(refill) vector */
#define	R_VEC		(K1BASE+0x1fc00000)	/* reset vector */
#define	XUT_VEC	 	(K0BASE+0x80)		/* extended address tlbmiss */
#define	E_VEC		(K0BASE+0x180)		/* Gen. exception vector */
#define	XUT_VEC_OFFSET	(0x80)
#define	E_VEC_OFFSET	(0x180)
#define	EXC_VEC_BASE_0    _SEXT((0x80000000))	/* vec base BEV = 0 normal*/
#define	EXC_VEC_BASE_1    _SEXT((0xBFC00200))	/* vec base BEV = 1 bootstrap*/
#define	CACHE_ERR_VEC_BEV0	(K1BASE+0x100)	/* cache error when BEV==0 */
#define	CACHE_ERR_VEC_BEV1	_SEXT(0xBFC00300)	/* cache error when BEV==1 */


/*
 * Address predicates
 */
#define	IS_XKPHYS(x)	(((Reg)(x) >= XKPHYS_BASE) && ((Reg)(x) < XKPHYS_END))
#define	IS_CKSEG0(x)	((Reg)(x) >= K0BASE && (Reg)(x) < (K0BASE+K0SIZE))
#if defined(SIM_MIPS64)
#define	IS_KSEG0(x)	(IS_XKPHYS(x) || IS_CKSEG0(x))
#else
#define	IS_KSEG0(x)	(IS_CKSEG0(x))
#endif
#define	IS_KSEG1(x)	((Reg)(x) >= K1BASE && (Reg)(x) < ((Reg)K1BASE+(Reg)K1SIZE))
#define	IS_KSEGDM(x)	((Reg)(x) >= K0BASE && (Reg)(x) < K2BASE)
#define IS_KSEG2(x)     ((Reg)(x) >= K2BASE && (Reg)(x) < (Reg64)K2BASE+K2SIZE)
#define	IS_KPTESEG(x)	((Reg)(x) >= KPTE_SHDUBASE)
#define	IS_KUSEG(x)	((Reg)(x) < K0BASE)

#define IS_SUPERV_SEG(vaddr) (((Reg)(vaddr) >= KSBASE && (Reg)(vaddr) < K3BASE) || (GET_REGION(vaddr)==1))

/*
 * 64bit MIPS layout */

#define CKSEG0_START_ADDR   K0BASE
#define CKSEG1_START_ADDR   K1BASE
#define CKSSEG_START_ADDR   KSBASE
#define XKSEG_START_ADDR    0xc000000000000000LL
#define XKSEG_END_ADDR      0xc0000fff00000000LL
#define XKUSEG_START_ADDR   0x0000000000000000LL
#define XKUSEG_END_ADDR     0x0000010000000000LL
#ifdef oldR4000
#define XKSEG_END_ADDR      0xc00000ff80000000LL  /* Old R4000 value */
#endif

#define IS_XKSEG(x)        (((Reg)(x) >= XKSEG_START_ADDR) && \
                            ((Reg)(x) < XKSEG_END_ADDR))

#define IS_XKUSEG(x)        (((Reg)(x) < XKUSEG_END_ADDR))


  /*
 * Macro's for breaking about the MIPS R10000 XKPHYS region, see the
 * R1000 manual for details.
 */
#define XKPHYS_CACHE_ALGORITHM(_va) (((_va)>>59)&0x7)
#define XKPHYS_ONE_PAGE_OFFSET(_va) ((_va) & 0x07ffffffffffffffLL)
#define XKPHYS_FOUR_PAGE_OFFSET(_va) ((_va) & 0x01ffffffffffffffLL)
#define XKPHYS_UNCACHED_FLAVOR(_va)  (((_va) >> 57) & 0x3)
#define XKPHYS_INVALID_OFFSET(_offset) ((_offset) & ~((1LL << PA_VALID_BITS)-1))

#define XKPHYS_TO_CKSEG0(_va) (CKSEG0_START_ADDR + XKPHYS_FOUR_PAGE_OFFSET(_va))
#define CKSEG0_TO_XKPHYS(_va) (XKPHYS_BASE + ((_va) - CKSEG0_START_ADDR))

#define _HI_MASK  (TLBHI_REGIONMASK|TLBHI_VPN2MASK)
#define CKSEG0_TLBHI_ADDR   (CKSEG0_START_ADDR&_HI_MASK)
#define CKSSEG_TLBHI_ADDR   (CKSSEG_START_ADDR&_HI_MASK)

/*
 * IS_UNMAPPED_TLBHI() - Is the specified TLBHI reg an unmapped address? 
 *   for 32bit mode this means Kseg0 or Kseg1 for 64bit bit mode it is 
 *   more complicated since we must both handle XKPHYS as well as the
 *   hole in the VA address space.
 */
#if defined(SIM_MIPS32)
#define IS_UNMAPPED_TLBHI(_hi) (IS_KSEG0(_hi) || IS_KSEG1(_hi))
#define IS_UNMAPPED_ADDR(_addr) (IS_KSEG0(_addr) || IS_KSEG1(_addr))
#else
#define IS_UNMAPPED_TLBHI(_hi) ((GET_REGION(_hi) == 2) ||  \
                                ((GET_REGION(_hi) == 3) && \
                                 ((((_hi)&_HI_MASK) >= CKSEG0_TLBHI_ADDR) && \
                                (((_hi)&_HI_MASK) <  CKSSEG_TLBHI_ADDR))))
#define IS_UNMAPPED_ADDR(_addr) ((GET_REGION(_addr) == 2) ||  \
                                ((GET_REGION(_addr) == 3) && \
                                 (((_addr) >= CKSEG0_START_ADDR) && \
                                ((_addr) <  CKSSEG_START_ADDR))))
#endif
#endif /* ADDR_LAYOUT_H */