/* * 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 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 */