1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*0Sstevel@tonic-gate /* All Rights Reserved */ 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate /* 31*0Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 4.3 BSD 32*0Sstevel@tonic-gate * under license from the Regents of the University of California. 33*0Sstevel@tonic-gate */ 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate /* 38*0Sstevel@tonic-gate * UNIX machine dependent virtual memory support. 39*0Sstevel@tonic-gate */ 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate #include <sys/vm.h> 42*0Sstevel@tonic-gate #include <sys/exec.h> 43*0Sstevel@tonic-gate #include <sys/cmn_err.h> 44*0Sstevel@tonic-gate #include <sys/cpu_module.h> 45*0Sstevel@tonic-gate #include <sys/cpu.h> 46*0Sstevel@tonic-gate #include <sys/elf_SPARC.h> 47*0Sstevel@tonic-gate #include <sys/archsystm.h> 48*0Sstevel@tonic-gate #include <vm/hat_sfmmu.h> 49*0Sstevel@tonic-gate #include <sys/memnode.h> 50*0Sstevel@tonic-gate #include <sys/mem_cage.h> 51*0Sstevel@tonic-gate #include <vm/vm_dep.h> 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate #if defined(__sparcv9) && defined(SF_ERRATA_57) 54*0Sstevel@tonic-gate caddr_t errata57_limit; 55*0Sstevel@tonic-gate #endif 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate uint_t page_colors = 0; 58*0Sstevel@tonic-gate uint_t page_colors_mask = 0; 59*0Sstevel@tonic-gate uint_t page_coloring_shift = 0; 60*0Sstevel@tonic-gate int consistent_coloring; 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate uint_t mmu_page_sizes = DEFAULT_MMU_PAGE_SIZES; 63*0Sstevel@tonic-gate uint_t max_mmu_page_sizes = MMU_PAGE_SIZES; 64*0Sstevel@tonic-gate uint_t mmu_hashcnt = DEFAULT_MAX_HASHCNT; 65*0Sstevel@tonic-gate uint_t max_mmu_hashcnt = MAX_HASHCNT; 66*0Sstevel@tonic-gate size_t mmu_ism_pagesize = DEFAULT_ISM_PAGESIZE; 67*0Sstevel@tonic-gate 68*0Sstevel@tonic-gate /* 69*0Sstevel@tonic-gate * The sun4u hardware mapping sizes which will always be supported are 70*0Sstevel@tonic-gate * 8K, 64K, 512K and 4M. If sun4u based machines need to support other 71*0Sstevel@tonic-gate * page sizes, platform or cpu specific routines need to modify the value. 72*0Sstevel@tonic-gate * The base pagesize (p_szc == 0) must always be supported by the hardware. 73*0Sstevel@tonic-gate */ 74*0Sstevel@tonic-gate int mmu_exported_pagesize_mask = (1 << TTE8K) | (1 << TTE64K) | 75*0Sstevel@tonic-gate (1 << TTE512K) | (1 << TTE4M); 76*0Sstevel@tonic-gate uint_t mmu_exported_page_sizes; 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate uint_t szc_2_userszc[MMU_PAGE_SIZES]; 79*0Sstevel@tonic-gate uint_t userszc_2_szc[MMU_PAGE_SIZES]; 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gate extern uint_t vac_colors_mask; 82*0Sstevel@tonic-gate extern int vac_shift; 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate hw_pagesize_t hw_page_array[] = { 85*0Sstevel@tonic-gate {MMU_PAGESIZE, MMU_PAGESHIFT, MMU_PAGESIZE >> MMU_PAGESHIFT}, 86*0Sstevel@tonic-gate {MMU_PAGESIZE64K, MMU_PAGESHIFT64K, MMU_PAGESIZE64K >> MMU_PAGESHIFT}, 87*0Sstevel@tonic-gate {MMU_PAGESIZE512K, MMU_PAGESHIFT512K, 88*0Sstevel@tonic-gate MMU_PAGESIZE512K >> MMU_PAGESHIFT}, 89*0Sstevel@tonic-gate {MMU_PAGESIZE4M, MMU_PAGESHIFT4M, MMU_PAGESIZE4M >> MMU_PAGESHIFT}, 90*0Sstevel@tonic-gate {MMU_PAGESIZE32M, MMU_PAGESHIFT32M, MMU_PAGESIZE32M >> MMU_PAGESHIFT}, 91*0Sstevel@tonic-gate {MMU_PAGESIZE256M, MMU_PAGESHIFT256M, 92*0Sstevel@tonic-gate MMU_PAGESIZE256M >> MMU_PAGESHIFT}, 93*0Sstevel@tonic-gate {0, 0, 0} 94*0Sstevel@tonic-gate }; 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate /* 97*0Sstevel@tonic-gate * use_text_pgsz64k, use_initdata_pgsz64k and use_text_pgsz4m 98*0Sstevel@tonic-gate * can be set in platform or CPU specific code but user can change the 99*0Sstevel@tonic-gate * default values via /etc/system. 100*0Sstevel@tonic-gate */ 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate int use_text_pgsz64k = 0; 103*0Sstevel@tonic-gate int use_text_pgsz4m = 0; 104*0Sstevel@tonic-gate int use_initdata_pgsz64k = 0; 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate /* 107*0Sstevel@tonic-gate * disable_text_largepages and disable_initdata_largepages bitmaks are set in 108*0Sstevel@tonic-gate * platform or CPU specific code to disable page sizes that should not be 109*0Sstevel@tonic-gate * used. These variables normally shouldn't be changed via /etc/system. A 110*0Sstevel@tonic-gate * particular page size for text or inititialized data will be used by default 111*0Sstevel@tonic-gate * if both one of use_* variables is set to 1 AND this page size is not 112*0Sstevel@tonic-gate * disabled in the corresponding disable_* bitmask variable. 113*0Sstevel@tonic-gate */ 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gate int disable_text_largepages = (1 << TTE4M) | (1 << TTE64K); 116*0Sstevel@tonic-gate int disable_initdata_largepages = (1 << TTE64K); 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate /* 119*0Sstevel@tonic-gate * Minimum segment size tunables before 64K or 4M large pages 120*0Sstevel@tonic-gate * should be used to map it. 121*0Sstevel@tonic-gate */ 122*0Sstevel@tonic-gate size_t text_pgsz64k_minsize = MMU_PAGESIZE64K; 123*0Sstevel@tonic-gate size_t text_pgsz4m_minsize = MMU_PAGESIZE4M; 124*0Sstevel@tonic-gate size_t initdata_pgsz64k_minsize = MMU_PAGESIZE64K; 125*0Sstevel@tonic-gate 126*0Sstevel@tonic-gate /* 127*0Sstevel@tonic-gate * map_addr_proc() is the routine called when the system is to 128*0Sstevel@tonic-gate * choose an address for the user. We will pick an address 129*0Sstevel@tonic-gate * range which is just below the current stack limit. The 130*0Sstevel@tonic-gate * algorithm used for cache consistency on machines with virtual 131*0Sstevel@tonic-gate * address caches is such that offset 0 in the vnode is always 132*0Sstevel@tonic-gate * on a shm_alignment'ed aligned address. Unfortunately, this 133*0Sstevel@tonic-gate * means that vnodes which are demand paged will not be mapped 134*0Sstevel@tonic-gate * cache consistently with the executable images. When the 135*0Sstevel@tonic-gate * cache alignment for a given object is inconsistent, the 136*0Sstevel@tonic-gate * lower level code must manage the translations so that this 137*0Sstevel@tonic-gate * is not seen here (at the cost of efficiency, of course). 138*0Sstevel@tonic-gate * 139*0Sstevel@tonic-gate * addrp is a value/result parameter. 140*0Sstevel@tonic-gate * On input it is a hint from the user to be used in a completely 141*0Sstevel@tonic-gate * machine dependent fashion. For MAP_ALIGN, addrp contains the 142*0Sstevel@tonic-gate * minimal alignment. 143*0Sstevel@tonic-gate * 144*0Sstevel@tonic-gate * On output it is NULL if no address can be found in the current 145*0Sstevel@tonic-gate * processes address space or else an address that is currently 146*0Sstevel@tonic-gate * not mapped for len bytes with a page of red zone on either side. 147*0Sstevel@tonic-gate * If vacalign is true, then the selected address will obey the alignment 148*0Sstevel@tonic-gate * constraints of a vac machine based on the given off value. 149*0Sstevel@tonic-gate */ 150*0Sstevel@tonic-gate /*ARGSUSED4*/ 151*0Sstevel@tonic-gate void 152*0Sstevel@tonic-gate map_addr_proc(caddr_t *addrp, size_t len, offset_t off, int vacalign, 153*0Sstevel@tonic-gate caddr_t userlimit, struct proc *p, uint_t flags) 154*0Sstevel@tonic-gate { 155*0Sstevel@tonic-gate struct as *as = p->p_as; 156*0Sstevel@tonic-gate caddr_t addr; 157*0Sstevel@tonic-gate caddr_t base; 158*0Sstevel@tonic-gate size_t slen; 159*0Sstevel@tonic-gate uintptr_t align_amount; 160*0Sstevel@tonic-gate int allow_largepage_alignment = 1; 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gate base = p->p_brkbase; 163*0Sstevel@tonic-gate if (userlimit < as->a_userlimit) { 164*0Sstevel@tonic-gate /* 165*0Sstevel@tonic-gate * This happens when a program wants to map something in 166*0Sstevel@tonic-gate * a range that's accessible to a program in a smaller 167*0Sstevel@tonic-gate * address space. For example, a 64-bit program might 168*0Sstevel@tonic-gate * be calling mmap32(2) to guarantee that the returned 169*0Sstevel@tonic-gate * address is below 4Gbytes. 170*0Sstevel@tonic-gate */ 171*0Sstevel@tonic-gate ASSERT(userlimit > base); 172*0Sstevel@tonic-gate slen = userlimit - base; 173*0Sstevel@tonic-gate } else { 174*0Sstevel@tonic-gate slen = p->p_usrstack - base - (((size_t)rctl_enforced_value( 175*0Sstevel@tonic-gate rctlproc_legacy[RLIMIT_STACK], p->p_rctls, p) + PAGEOFFSET) 176*0Sstevel@tonic-gate & PAGEMASK); 177*0Sstevel@tonic-gate } 178*0Sstevel@tonic-gate len = (len + PAGEOFFSET) & PAGEMASK; 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gate /* 181*0Sstevel@tonic-gate * Redzone for each side of the request. This is done to leave 182*0Sstevel@tonic-gate * one page unmapped between segments. This is not required, but 183*0Sstevel@tonic-gate * it's useful for the user because if their program strays across 184*0Sstevel@tonic-gate * a segment boundary, it will catch a fault immediately making 185*0Sstevel@tonic-gate * debugging a little easier. 186*0Sstevel@tonic-gate */ 187*0Sstevel@tonic-gate len += (2 * PAGESIZE); 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate /* 190*0Sstevel@tonic-gate * If the request is larger than the size of a particular 191*0Sstevel@tonic-gate * mmu level, then we use that level to map the request. 192*0Sstevel@tonic-gate * But this requires that both the virtual and the physical 193*0Sstevel@tonic-gate * addresses be aligned with respect to that level, so we 194*0Sstevel@tonic-gate * do the virtual bit of nastiness here. 195*0Sstevel@tonic-gate * 196*0Sstevel@tonic-gate * For 32-bit processes, only those which have specified 197*0Sstevel@tonic-gate * MAP_ALIGN or an addr will be aligned on a page size > 4MB. Otherwise 198*0Sstevel@tonic-gate * we can potentially waste up to 256MB of the 4G process address 199*0Sstevel@tonic-gate * space just for alignment. 200*0Sstevel@tonic-gate */ 201*0Sstevel@tonic-gate if (p->p_model == DATAMODEL_ILP32 && ((flags & MAP_ALIGN) == 0 || 202*0Sstevel@tonic-gate ((uintptr_t)*addrp) != 0)) { 203*0Sstevel@tonic-gate allow_largepage_alignment = 0; 204*0Sstevel@tonic-gate } 205*0Sstevel@tonic-gate if ((mmu_page_sizes == max_mmu_page_sizes) && 206*0Sstevel@tonic-gate allow_largepage_alignment && 207*0Sstevel@tonic-gate (len >= MMU_PAGESIZE256M)) { /* 256MB mappings */ 208*0Sstevel@tonic-gate align_amount = MMU_PAGESIZE256M; 209*0Sstevel@tonic-gate } else if ((mmu_page_sizes == max_mmu_page_sizes) && 210*0Sstevel@tonic-gate allow_largepage_alignment && 211*0Sstevel@tonic-gate (len >= MMU_PAGESIZE32M)) { /* 32MB mappings */ 212*0Sstevel@tonic-gate align_amount = MMU_PAGESIZE32M; 213*0Sstevel@tonic-gate } else if (len >= MMU_PAGESIZE4M) { /* 4MB mappings */ 214*0Sstevel@tonic-gate align_amount = MMU_PAGESIZE4M; 215*0Sstevel@tonic-gate } else if (len >= MMU_PAGESIZE512K) { /* 512KB mappings */ 216*0Sstevel@tonic-gate align_amount = MMU_PAGESIZE512K; 217*0Sstevel@tonic-gate } else if (len >= MMU_PAGESIZE64K) { /* 64KB mappings */ 218*0Sstevel@tonic-gate align_amount = MMU_PAGESIZE64K; 219*0Sstevel@tonic-gate } else { 220*0Sstevel@tonic-gate /* 221*0Sstevel@tonic-gate * Align virtual addresses on a 64K boundary to ensure 222*0Sstevel@tonic-gate * that ELF shared libraries are mapped with the appropriate 223*0Sstevel@tonic-gate * alignment constraints by the run-time linker. 224*0Sstevel@tonic-gate */ 225*0Sstevel@tonic-gate align_amount = ELF_SPARC_MAXPGSZ; 226*0Sstevel@tonic-gate if ((flags & MAP_ALIGN) && ((uintptr_t)*addrp != 0) && 227*0Sstevel@tonic-gate ((uintptr_t)*addrp < align_amount)) 228*0Sstevel@tonic-gate align_amount = (uintptr_t)*addrp; 229*0Sstevel@tonic-gate } 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate /* 232*0Sstevel@tonic-gate * 64-bit processes require 1024K alignment of ELF shared libraries. 233*0Sstevel@tonic-gate */ 234*0Sstevel@tonic-gate if (p->p_model == DATAMODEL_LP64) 235*0Sstevel@tonic-gate align_amount = MAX(align_amount, ELF_SPARCV9_MAXPGSZ); 236*0Sstevel@tonic-gate #ifdef VAC 237*0Sstevel@tonic-gate if (vac && vacalign && (align_amount < shm_alignment)) 238*0Sstevel@tonic-gate align_amount = shm_alignment; 239*0Sstevel@tonic-gate #endif 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gate if ((flags & MAP_ALIGN) && ((uintptr_t)*addrp > align_amount)) { 242*0Sstevel@tonic-gate align_amount = (uintptr_t)*addrp; 243*0Sstevel@tonic-gate } 244*0Sstevel@tonic-gate len += align_amount; 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gate /* 247*0Sstevel@tonic-gate * Look for a large enough hole starting below the stack limit. 248*0Sstevel@tonic-gate * After finding it, use the upper part. Addition of PAGESIZE is 249*0Sstevel@tonic-gate * for the redzone as described above. 250*0Sstevel@tonic-gate */ 251*0Sstevel@tonic-gate as_purge(as); 252*0Sstevel@tonic-gate if (as_gap(as, len, &base, &slen, AH_HI, NULL) == 0) { 253*0Sstevel@tonic-gate caddr_t as_addr; 254*0Sstevel@tonic-gate 255*0Sstevel@tonic-gate addr = base + slen - len + PAGESIZE; 256*0Sstevel@tonic-gate as_addr = addr; 257*0Sstevel@tonic-gate /* 258*0Sstevel@tonic-gate * Round address DOWN to the alignment amount, 259*0Sstevel@tonic-gate * add the offset, and if this address is less 260*0Sstevel@tonic-gate * than the original address, add alignment amount. 261*0Sstevel@tonic-gate */ 262*0Sstevel@tonic-gate addr = (caddr_t)((uintptr_t)addr & (~(align_amount - 1l))); 263*0Sstevel@tonic-gate addr += (long)(off & (align_amount - 1l)); 264*0Sstevel@tonic-gate if (addr < as_addr) { 265*0Sstevel@tonic-gate addr += align_amount; 266*0Sstevel@tonic-gate } 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate ASSERT(addr <= (as_addr + align_amount)); 269*0Sstevel@tonic-gate ASSERT(((uintptr_t)addr & (align_amount - 1l)) == 270*0Sstevel@tonic-gate ((uintptr_t)(off & (align_amount - 1l)))); 271*0Sstevel@tonic-gate *addrp = addr; 272*0Sstevel@tonic-gate 273*0Sstevel@tonic-gate #if defined(SF_ERRATA_57) 274*0Sstevel@tonic-gate if (AS_TYPE_64BIT(as) && addr < errata57_limit) { 275*0Sstevel@tonic-gate *addrp = NULL; 276*0Sstevel@tonic-gate } 277*0Sstevel@tonic-gate #endif 278*0Sstevel@tonic-gate } else { 279*0Sstevel@tonic-gate *addrp = NULL; /* no more virtual space */ 280*0Sstevel@tonic-gate } 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate /* 284*0Sstevel@tonic-gate * Platforms with smaller or larger TLBs may wish to change this. Most 285*0Sstevel@tonic-gate * sun4u platforms can hold 1024 8K entries by default and most processes 286*0Sstevel@tonic-gate * are observed to be < 6MB on these machines, so we decide to move up 287*0Sstevel@tonic-gate * here to give ourselves some wiggle room for other, smaller segments. 288*0Sstevel@tonic-gate */ 289*0Sstevel@tonic-gate int auto_lpg_tlb_threshold = 768; 290*0Sstevel@tonic-gate int auto_lpg_minszc = TTE4M; 291*0Sstevel@tonic-gate int auto_lpg_maxszc = TTE4M; 292*0Sstevel@tonic-gate size_t auto_lpg_heap_default = MMU_PAGESIZE; 293*0Sstevel@tonic-gate size_t auto_lpg_stack_default = MMU_PAGESIZE; 294*0Sstevel@tonic-gate size_t auto_lpg_va_default = MMU_PAGESIZE; 295*0Sstevel@tonic-gate size_t auto_lpg_remap_threshold = 0; 296*0Sstevel@tonic-gate 297*0Sstevel@tonic-gate /* 298*0Sstevel@tonic-gate * Suggest a page size to be used to map a segment of type maptype and length 299*0Sstevel@tonic-gate * len. Returns a page size (not a size code). 300*0Sstevel@tonic-gate * If remap is non-NULL, fill in a value suggesting whether or not to remap 301*0Sstevel@tonic-gate * this segment. 302*0Sstevel@tonic-gate */ 303*0Sstevel@tonic-gate size_t 304*0Sstevel@tonic-gate map_pgsz(int maptype, struct proc *p, caddr_t addr, size_t len, int *remap) 305*0Sstevel@tonic-gate { 306*0Sstevel@tonic-gate uint_t n; 307*0Sstevel@tonic-gate size_t pgsz = 0; 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gate if (remap) 310*0Sstevel@tonic-gate *remap = (len > auto_lpg_remap_threshold); 311*0Sstevel@tonic-gate 312*0Sstevel@tonic-gate switch (maptype) { 313*0Sstevel@tonic-gate case MAPPGSZ_ISM: 314*0Sstevel@tonic-gate n = hat_preferred_pgsz(p->p_as->a_hat, addr, len, maptype); 315*0Sstevel@tonic-gate pgsz = hw_page_array[n].hp_size; 316*0Sstevel@tonic-gate 317*0Sstevel@tonic-gate /* 318*0Sstevel@tonic-gate * For non-Panther systems, the following code sets the [D]ISM 319*0Sstevel@tonic-gate * pagesize to 4M if either of the DTLBs happens to be 320*0Sstevel@tonic-gate * programmed to a different large pagesize. 321*0Sstevel@tonic-gate * The Panther code might hit this case as well, 322*0Sstevel@tonic-gate * if and only if the addr is not aligned to >= 4M. 323*0Sstevel@tonic-gate */ 324*0Sstevel@tonic-gate if ((pgsz > 0) && (pgsz < MMU_PAGESIZE4M)) 325*0Sstevel@tonic-gate pgsz = MMU_PAGESIZE4M; 326*0Sstevel@tonic-gate break; 327*0Sstevel@tonic-gate 328*0Sstevel@tonic-gate case MAPPGSZ_VA: 329*0Sstevel@tonic-gate n = hat_preferred_pgsz(p->p_as->a_hat, addr, len, maptype); 330*0Sstevel@tonic-gate pgsz = hw_page_array[n].hp_size; 331*0Sstevel@tonic-gate if ((pgsz <= MMU_PAGESIZE) || 332*0Sstevel@tonic-gate !IS_P2ALIGNED(addr, pgsz) || !IS_P2ALIGNED(len, pgsz)) 333*0Sstevel@tonic-gate pgsz = map_pgszva(p, addr, len); 334*0Sstevel@tonic-gate break; 335*0Sstevel@tonic-gate 336*0Sstevel@tonic-gate case MAPPGSZ_STK: 337*0Sstevel@tonic-gate pgsz = map_pgszstk(p, addr, len); 338*0Sstevel@tonic-gate break; 339*0Sstevel@tonic-gate 340*0Sstevel@tonic-gate case MAPPGSZ_HEAP: 341*0Sstevel@tonic-gate pgsz = map_pgszheap(p, addr, len); 342*0Sstevel@tonic-gate break; 343*0Sstevel@tonic-gate } 344*0Sstevel@tonic-gate return (pgsz); 345*0Sstevel@tonic-gate } 346*0Sstevel@tonic-gate 347*0Sstevel@tonic-gate /* 348*0Sstevel@tonic-gate * Platform-dependent page scrub call. 349*0Sstevel@tonic-gate */ 350*0Sstevel@tonic-gate void 351*0Sstevel@tonic-gate pagescrub(page_t *pp, uint_t off, uint_t len) 352*0Sstevel@tonic-gate { 353*0Sstevel@tonic-gate /* 354*0Sstevel@tonic-gate * For now, we rely on the fact that pagezero() will 355*0Sstevel@tonic-gate * always clear UEs. 356*0Sstevel@tonic-gate */ 357*0Sstevel@tonic-gate pagezero(pp, off, len); 358*0Sstevel@tonic-gate } 359*0Sstevel@tonic-gate 360*0Sstevel@tonic-gate /*ARGSUSED*/ 361*0Sstevel@tonic-gate void 362*0Sstevel@tonic-gate sync_data_memory(caddr_t va, size_t len) 363*0Sstevel@tonic-gate { 364*0Sstevel@tonic-gate cpu_flush_ecache(); 365*0Sstevel@tonic-gate } 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate /* 368*0Sstevel@tonic-gate * platform specific large pages for kernel heap support 369*0Sstevel@tonic-gate */ 370*0Sstevel@tonic-gate void 371*0Sstevel@tonic-gate mmu_init_kcontext() 372*0Sstevel@tonic-gate { 373*0Sstevel@tonic-gate extern void set_kcontextreg(); 374*0Sstevel@tonic-gate 375*0Sstevel@tonic-gate if (kcontextreg) 376*0Sstevel@tonic-gate set_kcontextreg(); 377*0Sstevel@tonic-gate } 378*0Sstevel@tonic-gate 379*0Sstevel@tonic-gate void 380*0Sstevel@tonic-gate contig_mem_init(void) 381*0Sstevel@tonic-gate { 382*0Sstevel@tonic-gate /* not applicable to sun4u */ 383*0Sstevel@tonic-gate } 384