mmu.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SUN4_MMU_H
#define _SUN4_MMU_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Sun-4 memory management unit.
* All sun-4 implementations use 32 bits of address.
* A particular implementation may implement a smaller MMU.
* If so, the missing addresses are in the "middle" of the
* 32 bit address space. All accesses in this range behave
* as if there was an invalid page map entry correspronding
* to the address.
*
* There are two types of MMUs a 2 level MMU and a 3 level MMU.
* Three level MMUs do not have holes.
*/
/*
* Hardware context and segment information
* Mnemonic decoding:
* PMENT - Page Map ENTry
* PMGRP - Group of PMENTs (aka "segment")
* SMENT - Segment Map ENTry - 3 level MMU only
* SMGRP - Group of SMENTs (aka "region") - 3 level MMU only
*/
/* fixed SUN4 constants */
#define NPMENTPERPMGRP 32
#define NPMENTPERPMGRPSHIFT 5 /* log2(NPMENTPERPMGRP) */
#define PMGRPSIZE (NPMENTPERPMGRP * PAGESIZE)
#define PMGRPOFFSET (PMGRPSIZE - 1)
#define PMGRPSHIFT (PAGESHIFT + NPMENTPERPMGRPSHIFT)
#define PMGRPMASK (~PMGRPOFFSET)
#define NSMENTPERSMGRP 64
#define NSMENTPERSMGRPSHIFT 6 /* log2(NSMENTPERSMGRP) */
#define SMGRPSIZE (NSMENTPERSMGRP * PMGRPSIZE)
#define SMGRPOFFSET (SMGRPSIZE - 1)
#define SMGRPSHIFT (PMGRPSHIFT + NSMENTPERSMGRPSHIFT)
#define SMGRPMASK (~SMGRPOFFSET)
#define NSMGRPPERCTX 256
/*
* Useful defines for hat constants,
* Every implementation seems to have its own set
* they are set at boot time by setcputype()
*/
#define NCTXS nctxs
#define NPMGRPS npmgrps
#define NSMGRPS nsmgrps
/*
* Variables set at boot time to reflect cpu type.
*/
#ifndef LOCORE
#include <sys/types.h>
extern uint_t nctxs; /* number of implemented contexts */
extern uint_t npmgrps; /* number of pmgrps in page map */
#ifdef MMU_3LEVEL
extern uint_t nsmgrps; /* number of smgrps in segment map (3 level) */
#endif /* MMU_3LEVEL */
extern uint_t segmask; /* mask for segment number */
extern addr_t hole_start; /* addr of start of MMU "hole" */
extern addr_t hole_end; /* addr of end of MMU "hole" */
extern uint_t shm_alignment; /* VAC address consistency modulus */
#ifdef MMU_3LEVEL
extern int mmu_3level; /* indicates 3 level MMU can exist */
#endif /* MMU_3LEVEL */
#define PMGRP_INVALID (NPMGRPS - 1)
#define SMGRP_INVALID (NSMGRPS - 1)
/*
* Macro to determine whether an address is within the range of the MMU.
*/
#ifdef MMU_3LEVEL
#define good_addr(a) \
(mmu_3level || (addr_t)(a) < hole_start || (addr_t)(a) >= hole_end)
#else
#define good_addr(a) \
((addr_t)(a) < hole_start || (addr_t)(a) >= hole_end)
#endif /* MMU_3LEVEL */
#endif /* !LOCORE */
/*
* Address space identifiers.
*/
#define ASI_CTL 0x2 /* control space */
#define ASI_SM 0x3 /* segment map */
#define ASI_PM 0x4 /* page map */
#define ASI_BC 0x5 /* block copy */
#define ASI_RM 0x6 /* region map */
#define ASI_FCR 0x7 /* flush cache region */
#define ASI_UP 0x8 /* user program */
#define ASI_SP 0x9 /* supervisor program */
#define ASI_UD 0xA /* user data */
#define ASI_SD 0xB /* supervisor data */
#define ASI_FCS 0xC /* flush cache segment */
#define ASI_FCP 0xD /* flush cache page */
#define ASI_FCC 0xE /* flush cache context */
#define ASI_FCU 0xF /* flush cache user, sunray */
#define ASI_CD 0xF /* cache data, sunrise */
/*
* ASI_CTL addresses
*/
#define ID_PROM 0x00000000
#define CONTEXT_REG 0x30000000
#define SYSTEM_ENABLE 0x40000000
#define BUS_ERROR_REG 0x60000000
#define DIAGNOSTIC_REG 0x70000000
#define CACHE_TAGS 0x80000000
#define CACHE_DATA 0x90000000 /* cache data, sunray */
#define VME_INT_VEC 0xE0000000
#define UART_BYPASS 0xF0000000
#define IDPROMSIZE 0x20 /* size of id prom in bytes */
/*
* Constants for cache operations.
* XXX - should be deleted but the standalones (boot) use them.
*/
#define VAC_SIZE 0x20000 /* 128K */
#define VAC_LINESIZE_SUNRISE 16 /* 16 bytes per line */
#define VAC_LINESIZE_SUNRAY 32 /* 32 bytes per line */
#define NPMGRPPERCTX_110 4096
#define NPMGRPPERCTX_260 4096
#define NPMGRPPERCTX_330 4096
#define NPMGRPS_110 256
#define NPMGRPS_260 512
#define NPMGRPS_330 256
#define NPMGRPS_470 1024
/*
* Various I/O space related constants
*/
#define VME16_BASE 0xFFFF0000
#define VME16_SIZE (1<<16)
#define VME16_MASK (VME16_SIZE-1)
#define VME24_BASE 0xFF000000
#define VME24_SIZE (1<<24)
#define VME24_MASK (VME24_SIZE-1)
/*
* Virtual address where dvma starts.
*/
#define DVMABASE (0-(1024*1024))
/*
* Context for kernel. On a Sun-4 the kernel is in every address space,
* but KCONTEXT is magic in that there is never any user context there.
*/
#define KCONTEXT 0
/*
* MDEVBASE is a virtual segment reserved for mapping misc. obio devices.
* The base address and the number of devices mapped should not cause the
* device mappings to cross a segment boundary. We use the segment
* immediately before SYSBASE
*/
#define MDEVBASE (SYSBASE - PMGRPSIZE)
/*
* SEGTEMP & SEGTEMP2 are virtual segments reserved for temporary operations.
* We use the segments immediately before the start of debugger area.
*/
#define SEGTEMP ((addr_t)(DEBUGSTART - (2 * PMGRPSIZE)))
#define SEGTEMP2 ((addr_t)(DEBUGSTART - PMGRPSIZE))
/*
* REGTEMP is only during intialization, we use the
* REGION immediately before KERNELBASE, it is invalidated
* after use
*/
#define REGTEMP ((KERNELBASE-SMGRPSIZE)&SMGRPMASK)
#if defined(KERNEL) && !defined(LOCORE)
#ifdef VAC
void vac_dontcache();
/*
* cache related constants set at boot time
*/
extern int vac_size; /* size of cache in bytes */
extern int vac_linesize; /* cache linesize */
extern int vac_nlines; /* number of lines in cache */
extern int vac_pglines; /* number of cache lines in a page */
#endif /* VAC */
/*
* Low level mmu-specific functions
*/
struct ctx *mmu_getctx();
void mmu_setctx(/* ctx */);
void mmu_setpmg(/* base, pmg */);
void mmu_settpmg(/* base, pmg */);
struct pmgrp *mmu_getpmg(/* base */);
void mmu_setpte(/* base, pte */);
void mmu_getpte(/* base, ppte */);
void mmu_getkpte(/* base, ppte */);
void mmu_pmginval(/* pmg */);
#ifdef MMU_3LEVEL
struct smgrp *mmu_getsmg(/* base */);
void mmu_setsmg(/* base, smg */);
void mmu_settsmg(/* base, smg */);
void mmu_smginval(/* smg */);
#endif /* MMU_3LEVEL */
/*
* Cache specific routines - ifdef'ed out if there is no chance
* of running on a machine with a virtual address cache.
*/
#ifdef VAC
void vac_init();
void vac_tagsinit();
void vac_flushall();
void vac_ctxflush();
#ifdef MMU_3LEVEL
void vac_usrflush();
void vac_rgnflush(/* base */);
#endif /* MMU_3LEVEL */
void vac_segflush(/* base */);
void vac_pageflush(/* base */);
void vac_flush(/* base, len */);
int bp_alloc(/* map, bp, size */);
#else /* VAC */
#define vac_init()
#define vac_tagsinit()
#define vac_flushall()
#define vac_usrflush()
#define vac_ctxflush()
#define vac_rgnflush(base)
#define vac_segflush(base)
#define vac_pageflush(base)
#define vac_flush(base, len)
#define bp_alloc(map, bp, size) (int)rmalloc((map), (long)(size))
#endif /* VAC */
int valid_va_range(/* basep, lenp, minlen, dir */);
#endif /* defined(KERNEL) && !defined(LOCORE) */
#ifdef __cplusplus
}
#endif
#endif /* !_SUN4_MMU_H */