17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51e2e7a75Shuah * Common Development and Distribution License (the "License"). 61e2e7a75Shuah * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*1426d65aSsm142603 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <sys/types.h> 297c478bd9Sstevel@tonic-gate #include <sys/systm.h> 307c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 317c478bd9Sstevel@tonic-gate #include <sys/archsystm.h> 327c478bd9Sstevel@tonic-gate #include <sys/vmsystm.h> 337c478bd9Sstevel@tonic-gate #include <sys/machparam.h> 347c478bd9Sstevel@tonic-gate #include <sys/machsystm.h> 357c478bd9Sstevel@tonic-gate #include <vm/vm_dep.h> 367c478bd9Sstevel@tonic-gate #include <vm/hat_sfmmu.h> 377c478bd9Sstevel@tonic-gate #include <vm/seg_kmem.h> 387c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 397c478bd9Sstevel@tonic-gate #include <sys/debug.h> 407c478bd9Sstevel@tonic-gate #include <sys/cpu_module.h> 417c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 427c478bd9Sstevel@tonic-gate #include <sys/panic.h> 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate /* 457c478bd9Sstevel@tonic-gate * pan_disable_ism_large_pages and pan_disable_large_pages are the Panther- 467c478bd9Sstevel@tonic-gate * specific versions of disable_ism_large_pages and disable_large_pages, 477c478bd9Sstevel@tonic-gate * and feed back into those two hat variables at hat initialization time, 487c478bd9Sstevel@tonic-gate * for Panther-only systems. 497c478bd9Sstevel@tonic-gate * 50ec25b48fSsusans * chpjag_disable_large_pages is the Ch/Jaguar-specific version of 51ec25b48fSsusans * disable_large_pages. Ditto for pan_disable_large_pages. 52ec25b48fSsusans * Note that the Panther and Ch/Jaguar ITLB do not support 32M/256M pages. 537c478bd9Sstevel@tonic-gate */ 547c478bd9Sstevel@tonic-gate static int panther_only = 0; 557c478bd9Sstevel@tonic-gate 56ec25b48fSsusans static uint_t pan_disable_large_pages = (1 << TTE256M); 57ec25b48fSsusans static uint_t chjag_disable_large_pages = ((1 << TTE32M) | (1 << TTE256M)); 587c478bd9Sstevel@tonic-gate 59ec25b48fSsusans static uint_t mmu_disable_ism_large_pages = ((1 << TTE64K) | 607c478bd9Sstevel@tonic-gate (1 << TTE512K) | (1 << TTE32M) | (1 << TTE256M)); 61ec25b48fSsusans static uint_t mmu_disable_auto_data_large_pages = ((1 << TTE64K) | 62ec25b48fSsusans (1 << TTE512K) | (1 << TTE32M) | (1 << TTE256M)); 63ec25b48fSsusans static uint_t mmu_disable_auto_text_large_pages = ((1 << TTE64K) | 64582cbfcbSjimand (1 << TTE512K) | (1 << TTE32M) | (1 << TTE256M)); 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate /* 67ec25b48fSsusans * The function returns the USIII+(i)-IV+ mmu-specific values for the 687c478bd9Sstevel@tonic-gate * hat's disable_large_pages and disable_ism_large_pages variables. 697c478bd9Sstevel@tonic-gate * Currently the hat's disable_large_pages and disable_ism_large_pages 707c478bd9Sstevel@tonic-gate * already contain the generic sparc 4 page size info, and the return 717c478bd9Sstevel@tonic-gate * values are or'd with those values. 727c478bd9Sstevel@tonic-gate */ 73ec25b48fSsusans uint_t 747c478bd9Sstevel@tonic-gate mmu_large_pages_disabled(uint_t flag) 757c478bd9Sstevel@tonic-gate { 76ec25b48fSsusans uint_t pages_disable = 0; 77ec25b48fSsusans extern int use_text_pgsz64K; 78ec25b48fSsusans extern int use_text_pgsz512K; 797c478bd9Sstevel@tonic-gate 80ec25b48fSsusans if (flag == HAT_LOAD) { 817c478bd9Sstevel@tonic-gate if (panther_only) { 827c478bd9Sstevel@tonic-gate pages_disable = pan_disable_large_pages; 837c478bd9Sstevel@tonic-gate } else { 847c478bd9Sstevel@tonic-gate pages_disable = chjag_disable_large_pages; 85ec25b48fSsusans } 867c478bd9Sstevel@tonic-gate } else if (flag == HAT_LOAD_SHARE) { 87ec25b48fSsusans pages_disable = mmu_disable_ism_large_pages; 88ec25b48fSsusans } else if (flag == HAT_AUTO_DATA) { 89ec25b48fSsusans pages_disable = mmu_disable_auto_data_large_pages; 90ec25b48fSsusans } else if (flag == HAT_AUTO_TEXT) { 91ec25b48fSsusans pages_disable = mmu_disable_auto_text_large_pages; 92ec25b48fSsusans if (use_text_pgsz512K) { 93ec25b48fSsusans pages_disable &= ~(1 << TTE512K); 94ec25b48fSsusans } 95ec25b48fSsusans if (use_text_pgsz64K) { 96ec25b48fSsusans pages_disable &= ~(1 << TTE64K); 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate return (pages_disable); 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate #if defined(CPU_IMP_DUAL_PAGESIZE) 1037c478bd9Sstevel@tonic-gate /* 1047c478bd9Sstevel@tonic-gate * If a platform is running with only Ch+ or Jaguar, and then someone DR's 1057c478bd9Sstevel@tonic-gate * in a Panther board, the Panther mmu will not like it if one of the already 1067c478bd9Sstevel@tonic-gate * running threads is context switched to the Panther and tries to program 1077c478bd9Sstevel@tonic-gate * a 512K or 4M page into the T512_1. So make these platforms pay the price 1087c478bd9Sstevel@tonic-gate * and follow the Panther DTLB restrictions by default. :) 1097c478bd9Sstevel@tonic-gate * The mmu_init_mmu_page_sizes code below takes care of heterogeneous 1107c478bd9Sstevel@tonic-gate * platforms that don't support DR, like daktari. 1117c478bd9Sstevel@tonic-gate * 1127c478bd9Sstevel@tonic-gate * The effect of these restrictions is to limit the allowable values in 1137c478bd9Sstevel@tonic-gate * sfmmu_pgsz[0] and sfmmu_pgsz[1], since these hat variables are used in 1141e2e7a75Shuah * mmu_set_ctx_page_sizes to set up the values in the sfmmu_cext that 1157c478bd9Sstevel@tonic-gate * are used at context switch time. The value in sfmmu_pgsz[0] is used in 1167c478bd9Sstevel@tonic-gate * P_pgsz0 and sfmmu_pgsz[1] is used in P_pgsz1, as per Figure F-1-1 1177c478bd9Sstevel@tonic-gate * IMMU and DMMU Primary Context Register in the Panther Implementation 1187c478bd9Sstevel@tonic-gate * Supplement and Table 15-21 DMMU Primary Context Register in the 1197c478bd9Sstevel@tonic-gate * Cheetah+ Delta PRM. 1207c478bd9Sstevel@tonic-gate */ 1217c478bd9Sstevel@tonic-gate #ifdef MIXEDCPU_DR_SUPPORTED 1227c478bd9Sstevel@tonic-gate int panther_dtlb_restrictions = 1; 1237c478bd9Sstevel@tonic-gate #else 1247c478bd9Sstevel@tonic-gate int panther_dtlb_restrictions = 0; 1257c478bd9Sstevel@tonic-gate #endif /* MIXEDCPU_DR_SUPPORTED */ 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate /* 1287c478bd9Sstevel@tonic-gate * init_mmu_page_sizes is set to one after the bootup time initialization 1297c478bd9Sstevel@tonic-gate * via mmu_init_mmu_page_sizes, to indicate that mmu_page_sizes has a 1307c478bd9Sstevel@tonic-gate * valid value. 1317c478bd9Sstevel@tonic-gate */ 1327c478bd9Sstevel@tonic-gate int init_mmu_page_sizes = 0; 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate /* 1357c478bd9Sstevel@tonic-gate * mmu_init_large_pages is called with the desired ism_pagesize parameter, 1367c478bd9Sstevel@tonic-gate * for Panther-only systems. It may be called from set_platform_defaults, 137*1426d65aSsm142603 * if some value other than 4M is desired, for Panther-only systems. 1387c478bd9Sstevel@tonic-gate * mmu_ism_pagesize is the tunable. If it has a bad value, then only warn, 1397c478bd9Sstevel@tonic-gate * since it would be bad form to panic due 1407c478bd9Sstevel@tonic-gate * to a user typo. 1417c478bd9Sstevel@tonic-gate * 142ec25b48fSsusans * The function re-initializes the disable_ism_large_pages and 1437c478bd9Sstevel@tonic-gate * pan_disable_large_pages variables, which are closely related. 1447c478bd9Sstevel@tonic-gate * Aka, if 32M is the desired [D]ISM page sizes, then 256M cannot be allowed 1457c478bd9Sstevel@tonic-gate * for non-ISM large page usage, or DTLB conflict will occur. Please see the 1467c478bd9Sstevel@tonic-gate * Panther PRM for additional DTLB technical info. 1477c478bd9Sstevel@tonic-gate */ 1487c478bd9Sstevel@tonic-gate void 1497c478bd9Sstevel@tonic-gate mmu_init_large_pages(size_t ism_pagesize) 1507c478bd9Sstevel@tonic-gate { 1511e2e7a75Shuah if (cpu_impl_dual_pgsz == 0) { /* disable_dual_pgsz flag */ 1527c478bd9Sstevel@tonic-gate pan_disable_large_pages = ((1 << TTE32M) | (1 << TTE256M)); 153ec25b48fSsusans mmu_disable_ism_large_pages = ((1 << TTE64K) | 154ec25b48fSsusans (1 << TTE512K) | (1 << TTE32M) | (1 << TTE256M)); 155ec25b48fSsusans mmu_disable_auto_data_large_pages = ((1 << TTE64K) | 156ec25b48fSsusans (1 << TTE512K) | (1 << TTE32M) | (1 << TTE256M)); 1577c478bd9Sstevel@tonic-gate return; 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate switch (ism_pagesize) { 1617c478bd9Sstevel@tonic-gate case MMU_PAGESIZE4M: 1627c478bd9Sstevel@tonic-gate pan_disable_large_pages = (1 << TTE256M); 163ec25b48fSsusans mmu_disable_ism_large_pages = ((1 << TTE64K) | 164582cbfcbSjimand (1 << TTE512K) | (1 << TTE32M) | (1 << TTE256M)); 165ec25b48fSsusans mmu_disable_auto_data_large_pages = ((1 << TTE64K) | 166ec25b48fSsusans (1 << TTE512K) | (1 << TTE32M) | (1 << TTE256M)); 1677c478bd9Sstevel@tonic-gate break; 1687c478bd9Sstevel@tonic-gate case MMU_PAGESIZE32M: 1697c478bd9Sstevel@tonic-gate pan_disable_large_pages = (1 << TTE256M); 170ec25b48fSsusans mmu_disable_ism_large_pages = ((1 << TTE64K) | 171ec25b48fSsusans (1 << TTE512K) | (1 << TTE256M)); 172ec25b48fSsusans mmu_disable_auto_data_large_pages = ((1 << TTE64K) | 173582cbfcbSjimand (1 << TTE512K) | (1 << TTE4M) | (1 << TTE256M)); 174ec25b48fSsusans adjust_data_maxlpsize(ism_pagesize); 1757c478bd9Sstevel@tonic-gate break; 1767c478bd9Sstevel@tonic-gate case MMU_PAGESIZE256M: 1777c478bd9Sstevel@tonic-gate pan_disable_large_pages = (1 << TTE32M); 178ec25b48fSsusans mmu_disable_ism_large_pages = ((1 << TTE64K) | 179ec25b48fSsusans (1 << TTE512K) | (1 << TTE32M)); 180ec25b48fSsusans mmu_disable_auto_data_large_pages = ((1 << TTE64K) | 181582cbfcbSjimand (1 << TTE512K) | (1 << TTE4M) | (1 << TTE32M)); 182ec25b48fSsusans adjust_data_maxlpsize(ism_pagesize); 1837c478bd9Sstevel@tonic-gate break; 1847c478bd9Sstevel@tonic-gate default: 1857c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "Unrecognized mmu_ism_pagesize value 0x%lx", 1867c478bd9Sstevel@tonic-gate ism_pagesize); 1877c478bd9Sstevel@tonic-gate break; 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate /* 1927c478bd9Sstevel@tonic-gate * Re-initialize mmu_page_sizes and friends, for Panther mmu support. 1937c478bd9Sstevel@tonic-gate * Called during very early bootup from check_cpus_set(). 1947c478bd9Sstevel@tonic-gate * Can be called to verify that mmu_page_sizes are set up correctly. 1957c478bd9Sstevel@tonic-gate * Note that ncpus is not initialized at this point in the bootup sequence. 1967c478bd9Sstevel@tonic-gate */ 1977c478bd9Sstevel@tonic-gate int 1987c478bd9Sstevel@tonic-gate mmu_init_mmu_page_sizes(int cinfo) 1997c478bd9Sstevel@tonic-gate { 2007c478bd9Sstevel@tonic-gate int npanther = cinfo; 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate if (!init_mmu_page_sizes) { 2037c478bd9Sstevel@tonic-gate if (npanther == ncpunode) { 2047c478bd9Sstevel@tonic-gate mmu_page_sizes = MMU_PAGE_SIZES; 2057c478bd9Sstevel@tonic-gate mmu_hashcnt = MAX_HASHCNT; 206e12a8a13Ssusans mmu_ism_pagesize = DEFAULT_ISM_PAGESIZE; 2077c478bd9Sstevel@tonic-gate mmu_exported_pagesize_mask = (1 << TTE8K) | 2087c478bd9Sstevel@tonic-gate (1 << TTE64K) | (1 << TTE512K) | (1 << TTE4M) | 2097c478bd9Sstevel@tonic-gate (1 << TTE32M) | (1 << TTE256M); 2107c478bd9Sstevel@tonic-gate panther_dtlb_restrictions = 1; 2117c478bd9Sstevel@tonic-gate panther_only = 1; 2127c478bd9Sstevel@tonic-gate } else if (npanther > 0) { 2137c478bd9Sstevel@tonic-gate panther_dtlb_restrictions = 1; 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate init_mmu_page_sizes = 1; 2167c478bd9Sstevel@tonic-gate return (0); 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate return (1); 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate /* Cheetah+ and later worst case DTLB parameters */ 2237c478bd9Sstevel@tonic-gate #ifndef LOCKED_DTLB_ENTRIES 2247c478bd9Sstevel@tonic-gate #define LOCKED_DTLB_ENTRIES 5 /* 2 user TSBs, 2 nucleus, + OBP */ 2257c478bd9Sstevel@tonic-gate #endif 2267c478bd9Sstevel@tonic-gate #define TOTAL_DTLB_ENTRIES 16 2277c478bd9Sstevel@tonic-gate #define AVAIL_32M_ENTRIES 0 2287c478bd9Sstevel@tonic-gate #define AVAIL_256M_ENTRIES 0 2297c478bd9Sstevel@tonic-gate #define AVAIL_DTLB_ENTRIES (TOTAL_DTLB_ENTRIES - LOCKED_DTLB_ENTRIES) 2307c478bd9Sstevel@tonic-gate static uint64_t ttecnt_threshold[MMU_PAGE_SIZES] = { 2317c478bd9Sstevel@tonic-gate AVAIL_DTLB_ENTRIES, AVAIL_DTLB_ENTRIES, 2327c478bd9Sstevel@tonic-gate AVAIL_DTLB_ENTRIES, AVAIL_DTLB_ENTRIES, 2337c478bd9Sstevel@tonic-gate AVAIL_32M_ENTRIES, AVAIL_256M_ENTRIES }; 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate /* 2367c478bd9Sstevel@tonic-gate * The purpose of this code is to indirectly reorganize the sfmmu_pgsz array 2377c478bd9Sstevel@tonic-gate * in order to handle the Panther mmu DTLB requirements. Panther only supports 2387c478bd9Sstevel@tonic-gate * the 32M/256M pages in the T512_1 and not in the T16, so the Panther cpu 2397c478bd9Sstevel@tonic-gate * can only support one of the two largest page sizes at a time (efficiently). 2407c478bd9Sstevel@tonic-gate * Panther only supports 512K and 4M pages in the T512_0, and 32M/256M pages 2417c478bd9Sstevel@tonic-gate * in the T512_1. So check the sfmmu flags and ttecnt before enabling 2427c478bd9Sstevel@tonic-gate * the T512_1 for 32M or 256M page sizes, and make sure that 512K and 4M 2437c478bd9Sstevel@tonic-gate * requests go to the T512_0. 2447c478bd9Sstevel@tonic-gate * 2457c478bd9Sstevel@tonic-gate * The tmp_pgsz array comes into this routine in sorted order, as it is 2467c478bd9Sstevel@tonic-gate * sorted from largest to smallest #pages per pagesize in use by the hat code, 2477c478bd9Sstevel@tonic-gate * and leaves with the Panther mmu DTLB requirements satisfied. Note that 2487c478bd9Sstevel@tonic-gate * when the array leaves this function it may not contain all of the page 2497c478bd9Sstevel@tonic-gate * size codes that it had coming into the function. 2507c478bd9Sstevel@tonic-gate * 2517c478bd9Sstevel@tonic-gate * Note that for DISM the flag can be set but the ttecnt can be 0, if we 2527c478bd9Sstevel@tonic-gate * didn't fault any pages in. This allows the t512_1 to be reprogrammed, 2537c478bd9Sstevel@tonic-gate * because the T16 does not support the two giant page sizes. ouch. 2547c478bd9Sstevel@tonic-gate */ 255*1426d65aSsm142603 static void 2567c478bd9Sstevel@tonic-gate mmu_fixup_large_pages(struct hat *hat, uint64_t *ttecnt, uint8_t *tmp_pgsz) 2577c478bd9Sstevel@tonic-gate { 2587c478bd9Sstevel@tonic-gate uint_t pgsz0 = tmp_pgsz[0]; 2597c478bd9Sstevel@tonic-gate uint_t pgsz1 = tmp_pgsz[1]; 2607c478bd9Sstevel@tonic-gate uint_t spgsz; 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate /* 2637c478bd9Sstevel@tonic-gate * Don't program 2nd dtlb for kernel and ism hat 2647c478bd9Sstevel@tonic-gate */ 26505d3dc4bSpaulsan ASSERT(hat->sfmmu_ismhat == 0); 2667c478bd9Sstevel@tonic-gate ASSERT(hat != ksfmmup); 2671e2e7a75Shuah ASSERT(cpu_impl_dual_pgsz == 1); 2687c478bd9Sstevel@tonic-gate 26905d3dc4bSpaulsan ASSERT(!SFMMU_TTEFLAGS_ISSET(hat, HAT_32M_FLAG) || 27005d3dc4bSpaulsan !SFMMU_TTEFLAGS_ISSET(hat, HAT_256M_FLAG)); 27105d3dc4bSpaulsan ASSERT(!SFMMU_TTEFLAGS_ISSET(hat, HAT_256M_FLAG) || 27205d3dc4bSpaulsan !SFMMU_TTEFLAGS_ISSET(hat, HAT_32M_FLAG)); 27305d3dc4bSpaulsan ASSERT(!SFMMU_FLAGS_ISSET(hat, HAT_32M_ISM) || 27405d3dc4bSpaulsan !SFMMU_FLAGS_ISSET(hat, HAT_256M_ISM)); 27505d3dc4bSpaulsan ASSERT(!SFMMU_FLAGS_ISSET(hat, HAT_256M_ISM) || 27605d3dc4bSpaulsan !SFMMU_FLAGS_ISSET(hat, HAT_32M_ISM)); 2777c478bd9Sstevel@tonic-gate 27805d3dc4bSpaulsan if (SFMMU_TTEFLAGS_ISSET(hat, HAT_32M_FLAG) || 27905d3dc4bSpaulsan (ttecnt[TTE32M] != 0) || 28005d3dc4bSpaulsan SFMMU_FLAGS_ISSET(hat, HAT_32M_ISM)) { 28105d3dc4bSpaulsan 2827c478bd9Sstevel@tonic-gate spgsz = pgsz1; 2837c478bd9Sstevel@tonic-gate pgsz1 = TTE32M; 2847c478bd9Sstevel@tonic-gate if (pgsz0 == TTE32M) 2857c478bd9Sstevel@tonic-gate pgsz0 = spgsz; 28605d3dc4bSpaulsan 28705d3dc4bSpaulsan } else if (SFMMU_TTEFLAGS_ISSET(hat, HAT_256M_FLAG) || 28805d3dc4bSpaulsan (ttecnt[TTE256M] != 0) || 28905d3dc4bSpaulsan SFMMU_FLAGS_ISSET(hat, HAT_256M_ISM)) { 29005d3dc4bSpaulsan 2917c478bd9Sstevel@tonic-gate spgsz = pgsz1; 2927c478bd9Sstevel@tonic-gate pgsz1 = TTE256M; 2937c478bd9Sstevel@tonic-gate if (pgsz0 == TTE256M) 2947c478bd9Sstevel@tonic-gate pgsz0 = spgsz; 29505d3dc4bSpaulsan 2967c478bd9Sstevel@tonic-gate } else if ((pgsz1 == TTE512K) || (pgsz1 == TTE4M)) { 2977c478bd9Sstevel@tonic-gate if ((pgsz0 != TTE512K) && (pgsz0 != TTE4M)) { 2987c478bd9Sstevel@tonic-gate spgsz = pgsz0; 2997c478bd9Sstevel@tonic-gate pgsz0 = pgsz1; 3007c478bd9Sstevel@tonic-gate pgsz1 = spgsz; 3017c478bd9Sstevel@tonic-gate } else { 3027c478bd9Sstevel@tonic-gate pgsz1 = page_szc(MMU_PAGESIZE); 3037c478bd9Sstevel@tonic-gate } 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate /* 3067c478bd9Sstevel@tonic-gate * This implements PAGESIZE programming of the T8s 3077c478bd9Sstevel@tonic-gate * if large TTE counts don't exceed the thresholds. 3087c478bd9Sstevel@tonic-gate */ 3097c478bd9Sstevel@tonic-gate if (ttecnt[pgsz0] < ttecnt_threshold[pgsz0]) 3107c478bd9Sstevel@tonic-gate pgsz0 = page_szc(MMU_PAGESIZE); 3117c478bd9Sstevel@tonic-gate if (ttecnt[pgsz1] < ttecnt_threshold[pgsz1]) 3127c478bd9Sstevel@tonic-gate pgsz1 = page_szc(MMU_PAGESIZE); 3137c478bd9Sstevel@tonic-gate tmp_pgsz[0] = pgsz0; 3147c478bd9Sstevel@tonic-gate tmp_pgsz[1] = pgsz1; 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate /* 3187c478bd9Sstevel@tonic-gate * Function to set up the page size values used to reprogram the DTLBs, 3197c478bd9Sstevel@tonic-gate * when page sizes used by a process change significantly. 3207c478bd9Sstevel@tonic-gate */ 321*1426d65aSsm142603 static void 3227c478bd9Sstevel@tonic-gate mmu_setup_page_sizes(struct hat *hat, uint64_t *ttecnt, uint8_t *tmp_pgsz) 3237c478bd9Sstevel@tonic-gate { 3247c478bd9Sstevel@tonic-gate uint_t pgsz0, pgsz1; 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate /* 3277c478bd9Sstevel@tonic-gate * Don't program 2nd dtlb for kernel and ism hat 3287c478bd9Sstevel@tonic-gate */ 3297c478bd9Sstevel@tonic-gate ASSERT(hat->sfmmu_ismhat == NULL); 3307c478bd9Sstevel@tonic-gate ASSERT(hat != ksfmmup); 3317c478bd9Sstevel@tonic-gate 3321e2e7a75Shuah if (cpu_impl_dual_pgsz == 0) /* disable_dual_pgsz flag */ 3337c478bd9Sstevel@tonic-gate return; 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate /* 3367c478bd9Sstevel@tonic-gate * hat->sfmmu_pgsz[] is an array whose elements 3377c478bd9Sstevel@tonic-gate * contain a sorted order of page sizes. Element 3387c478bd9Sstevel@tonic-gate * 0 is the most commonly used page size, followed 3397c478bd9Sstevel@tonic-gate * by element 1, and so on. 3407c478bd9Sstevel@tonic-gate * 3417c478bd9Sstevel@tonic-gate * ttecnt[] is an array of per-page-size page counts 3427c478bd9Sstevel@tonic-gate * mapped into the process. 3437c478bd9Sstevel@tonic-gate * 3447c478bd9Sstevel@tonic-gate * If the HAT's choice for page sizes is unsuitable, 3457c478bd9Sstevel@tonic-gate * we can override it here. The new values written 3467c478bd9Sstevel@tonic-gate * to the array will be handed back to us later to 3477c478bd9Sstevel@tonic-gate * do the actual programming of the TLB hardware. 3487c478bd9Sstevel@tonic-gate * 3497c478bd9Sstevel@tonic-gate * The policy we use for programming the dual T8s on 3507c478bd9Sstevel@tonic-gate * Cheetah+ and beyond is as follows: 3517c478bd9Sstevel@tonic-gate * 3527c478bd9Sstevel@tonic-gate * We have two programmable TLBs, so we look at 3537c478bd9Sstevel@tonic-gate * the two most common page sizes in the array, which 3547c478bd9Sstevel@tonic-gate * have already been computed for us by the HAT. 3557c478bd9Sstevel@tonic-gate * If the TTE count of either of a preferred page size 3567c478bd9Sstevel@tonic-gate * exceeds the number of unlocked T16 entries, 3577c478bd9Sstevel@tonic-gate * we reprogram one of the T8s to that page size 3587c478bd9Sstevel@tonic-gate * to avoid thrashing in the T16. Else we program 3597c478bd9Sstevel@tonic-gate * that T8 to the base page size. Note that we do 3607c478bd9Sstevel@tonic-gate * not force either T8 to be the base page size if a 3617c478bd9Sstevel@tonic-gate * process is using more than two page sizes. Policy 3627c478bd9Sstevel@tonic-gate * decisions about which page sizes are best to use are 3637c478bd9Sstevel@tonic-gate * left to the upper layers. 3647c478bd9Sstevel@tonic-gate * 3657c478bd9Sstevel@tonic-gate * Note that for Panther, 4M and 512K pages need to be 3667c478bd9Sstevel@tonic-gate * programmed into T512_0, and 32M and 256M into T512_1, 3677c478bd9Sstevel@tonic-gate * so we don't want to go through the MIN/MAX code. 3687c478bd9Sstevel@tonic-gate * For partial-Panther systems, we still want to make sure 3697c478bd9Sstevel@tonic-gate * that 4M and 512K page sizes NEVER get into the T512_1. 3707c478bd9Sstevel@tonic-gate * Since the DTLB flags are not set up on a per-cpu basis, 3717c478bd9Sstevel@tonic-gate * Panther rules must be applied for mixed Panther/Cheetah+/ 3727c478bd9Sstevel@tonic-gate * Jaguar configurations. 3737c478bd9Sstevel@tonic-gate */ 3747c478bd9Sstevel@tonic-gate if (panther_dtlb_restrictions) { 3757c478bd9Sstevel@tonic-gate if ((tmp_pgsz[1] == TTE512K) || (tmp_pgsz[1] == TTE4M)) { 3767c478bd9Sstevel@tonic-gate if ((tmp_pgsz[0] != TTE512K) && 3777c478bd9Sstevel@tonic-gate (tmp_pgsz[0] != TTE4M)) { 3787c478bd9Sstevel@tonic-gate pgsz1 = tmp_pgsz[0]; 3797c478bd9Sstevel@tonic-gate pgsz0 = tmp_pgsz[1]; 3807c478bd9Sstevel@tonic-gate } else { 3817c478bd9Sstevel@tonic-gate pgsz0 = tmp_pgsz[0]; 3827c478bd9Sstevel@tonic-gate pgsz1 = page_szc(MMU_PAGESIZE); 3837c478bd9Sstevel@tonic-gate } 3847c478bd9Sstevel@tonic-gate } else { 3857c478bd9Sstevel@tonic-gate pgsz0 = tmp_pgsz[0]; 3867c478bd9Sstevel@tonic-gate pgsz1 = tmp_pgsz[1]; 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate } else { 3897c478bd9Sstevel@tonic-gate pgsz0 = MIN(tmp_pgsz[0], tmp_pgsz[1]); 3907c478bd9Sstevel@tonic-gate pgsz1 = MAX(tmp_pgsz[0], tmp_pgsz[1]); 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate /* 3947c478bd9Sstevel@tonic-gate * This implements PAGESIZE programming of the T8s 3957c478bd9Sstevel@tonic-gate * if large TTE counts don't exceed the thresholds. 3967c478bd9Sstevel@tonic-gate */ 3977c478bd9Sstevel@tonic-gate if (ttecnt[pgsz0] < ttecnt_threshold[pgsz0]) 3987c478bd9Sstevel@tonic-gate pgsz0 = page_szc(MMU_PAGESIZE); 3997c478bd9Sstevel@tonic-gate if (ttecnt[pgsz1] < ttecnt_threshold[pgsz1]) 4007c478bd9Sstevel@tonic-gate pgsz1 = page_szc(MMU_PAGESIZE); 4017c478bd9Sstevel@tonic-gate tmp_pgsz[0] = pgsz0; 4027c478bd9Sstevel@tonic-gate tmp_pgsz[1] = pgsz1; 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate /* 4067c478bd9Sstevel@tonic-gate * The HAT calls this function when an MMU context is allocated so that we 4077c478bd9Sstevel@tonic-gate * can reprogram the large TLBs appropriately for the new process using 4087c478bd9Sstevel@tonic-gate * the context. 4097c478bd9Sstevel@tonic-gate * 4107c478bd9Sstevel@tonic-gate * The caller must hold the HAT lock. 4117c478bd9Sstevel@tonic-gate */ 4127c478bd9Sstevel@tonic-gate void 4137c478bd9Sstevel@tonic-gate mmu_set_ctx_page_sizes(struct hat *hat) 4147c478bd9Sstevel@tonic-gate { 4157c478bd9Sstevel@tonic-gate uint_t pgsz0, pgsz1; 4167c478bd9Sstevel@tonic-gate uint_t new_cext; 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate ASSERT(sfmmu_hat_lock_held(hat)); 4197c478bd9Sstevel@tonic-gate ASSERT(hat != ksfmmup); 4207c478bd9Sstevel@tonic-gate 4211e2e7a75Shuah if (cpu_impl_dual_pgsz == 0) /* disable_dual_pgsz flag */ 4227c478bd9Sstevel@tonic-gate return; 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate /* 4257c478bd9Sstevel@tonic-gate * If supported, reprogram the TLBs to a larger pagesize. 4267c478bd9Sstevel@tonic-gate */ 4277c478bd9Sstevel@tonic-gate pgsz0 = hat->sfmmu_pgsz[0]; 4287c478bd9Sstevel@tonic-gate pgsz1 = hat->sfmmu_pgsz[1]; 4297c478bd9Sstevel@tonic-gate ASSERT(pgsz0 < mmu_page_sizes); 4307c478bd9Sstevel@tonic-gate ASSERT(pgsz1 < mmu_page_sizes); 4317c478bd9Sstevel@tonic-gate #ifdef DEBUG 4327c478bd9Sstevel@tonic-gate if (panther_dtlb_restrictions) { 4337c478bd9Sstevel@tonic-gate ASSERT(pgsz1 != TTE512K); 4347c478bd9Sstevel@tonic-gate ASSERT(pgsz1 != TTE4M); 4357c478bd9Sstevel@tonic-gate } 4367c478bd9Sstevel@tonic-gate if (panther_only) { 4377c478bd9Sstevel@tonic-gate ASSERT(pgsz0 != TTE32M); 4387c478bd9Sstevel@tonic-gate ASSERT(pgsz0 != TTE256M); 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 4417c478bd9Sstevel@tonic-gate new_cext = TAGACCEXT_MKSZPAIR(pgsz1, pgsz0); 4427c478bd9Sstevel@tonic-gate if (hat->sfmmu_cext != new_cext) { 4431e2e7a75Shuah #ifdef DEBUG 4441e2e7a75Shuah int i; 4451e2e7a75Shuah /* 4461e2e7a75Shuah * assert cnum should be invalid, this is because pagesize 4471e2e7a75Shuah * can only be changed after a proc's ctxs are invalidated. 4481e2e7a75Shuah */ 4491e2e7a75Shuah for (i = 0; i < max_mmu_ctxdoms; i++) { 4501e2e7a75Shuah ASSERT(hat->sfmmu_ctxs[i].cnum == INVALID_CONTEXT); 4511e2e7a75Shuah } 4521e2e7a75Shuah #endif /* DEBUG */ 4537c478bd9Sstevel@tonic-gate hat->sfmmu_cext = new_cext; 4547c478bd9Sstevel@tonic-gate } 4551e2e7a75Shuah 4567c478bd9Sstevel@tonic-gate /* 4577c478bd9Sstevel@tonic-gate * sfmmu_setctx_sec() will take care of the 4581e2e7a75Shuah * rest of the chores reprogramming the hat->sfmmu_cext 4597c478bd9Sstevel@tonic-gate * page size values into the DTLBs. 4607c478bd9Sstevel@tonic-gate */ 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate /* 4647c478bd9Sstevel@tonic-gate * This function assumes that there are either four or six supported page 4657c478bd9Sstevel@tonic-gate * sizes and at most two programmable TLBs, so we need to decide which 4667c478bd9Sstevel@tonic-gate * page sizes are most important and then adjust the TLB page sizes 4677c478bd9Sstevel@tonic-gate * accordingly (if supported). 4687c478bd9Sstevel@tonic-gate * 4697c478bd9Sstevel@tonic-gate * If these assumptions change, this function will need to be 4707c478bd9Sstevel@tonic-gate * updated to support whatever the new limits are. 4717c478bd9Sstevel@tonic-gate */ 4727c478bd9Sstevel@tonic-gate void 4737c478bd9Sstevel@tonic-gate mmu_check_page_sizes(sfmmu_t *sfmmup, uint64_t *ttecnt) 4747c478bd9Sstevel@tonic-gate { 4757c478bd9Sstevel@tonic-gate uint64_t sortcnt[MMU_PAGE_SIZES]; 4767c478bd9Sstevel@tonic-gate uint8_t tmp_pgsz[MMU_PAGE_SIZES]; 4777c478bd9Sstevel@tonic-gate uint8_t i, j, max; 4787c478bd9Sstevel@tonic-gate uint16_t oldval, newval; 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate /* 4817c478bd9Sstevel@tonic-gate * We only consider reprogramming the TLBs if one or more of 4827c478bd9Sstevel@tonic-gate * the two most used page sizes changes and we're using 4837c478bd9Sstevel@tonic-gate * large pages in this process, except for Panther 32M/256M pages, 4847c478bd9Sstevel@tonic-gate * which the Panther T16 does not support. 4857c478bd9Sstevel@tonic-gate */ 48605d3dc4bSpaulsan if (SFMMU_LGPGS_INUSE(sfmmup)) { 4877c478bd9Sstevel@tonic-gate /* Sort page sizes. */ 4887c478bd9Sstevel@tonic-gate for (i = 0; i < mmu_page_sizes; i++) { 4897c478bd9Sstevel@tonic-gate sortcnt[i] = ttecnt[i]; 4907c478bd9Sstevel@tonic-gate } 4917c478bd9Sstevel@tonic-gate for (j = 0; j < mmu_page_sizes; j++) { 4927c478bd9Sstevel@tonic-gate for (i = mmu_page_sizes - 1, max = 0; i > 0; i--) { 4937c478bd9Sstevel@tonic-gate if (sortcnt[i] > sortcnt[max]) 4947c478bd9Sstevel@tonic-gate max = i; 4957c478bd9Sstevel@tonic-gate } 4967c478bd9Sstevel@tonic-gate tmp_pgsz[j] = max; 4977c478bd9Sstevel@tonic-gate sortcnt[max] = 0; 4987c478bd9Sstevel@tonic-gate } 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate /* 5017c478bd9Sstevel@tonic-gate * Handle Panther page dtlb calcs separately. The check 5027c478bd9Sstevel@tonic-gate * for actual or potential 32M/256M pages must occur 5037c478bd9Sstevel@tonic-gate * every time due to lack of T16 support for them. 5047c478bd9Sstevel@tonic-gate * The sort works fine for Ch+/Jag, but Panther has 5057c478bd9Sstevel@tonic-gate * pagesize restrictions for both DTLBs. 5067c478bd9Sstevel@tonic-gate */ 5077c478bd9Sstevel@tonic-gate oldval = sfmmup->sfmmu_pgsz[0] << 8 | sfmmup->sfmmu_pgsz[1]; 5087c478bd9Sstevel@tonic-gate 5097c478bd9Sstevel@tonic-gate if (panther_only) { 5107c478bd9Sstevel@tonic-gate mmu_fixup_large_pages(sfmmup, ttecnt, tmp_pgsz); 5117c478bd9Sstevel@tonic-gate } else { 5127c478bd9Sstevel@tonic-gate /* Check 2 largest values after the sort. */ 5137c478bd9Sstevel@tonic-gate mmu_setup_page_sizes(sfmmup, ttecnt, tmp_pgsz); 5147c478bd9Sstevel@tonic-gate } 5157c478bd9Sstevel@tonic-gate newval = tmp_pgsz[0] << 8 | tmp_pgsz[1]; 5167c478bd9Sstevel@tonic-gate if (newval != oldval) { 5171e2e7a75Shuah sfmmu_reprog_pgsz_arr(sfmmup, tmp_pgsz); 5187c478bd9Sstevel@tonic-gate } 5197c478bd9Sstevel@tonic-gate } 5207c478bd9Sstevel@tonic-gate } 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate #endif /* CPU_IMP_DUAL_PAGESIZE */ 5237c478bd9Sstevel@tonic-gate 5247c478bd9Sstevel@tonic-gate struct heap_lp_page_size { 5257c478bd9Sstevel@tonic-gate int impl; 5267c478bd9Sstevel@tonic-gate uint_t tte; 5277c478bd9Sstevel@tonic-gate int use_dt512; 5287c478bd9Sstevel@tonic-gate }; 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate struct heap_lp_page_size heap_lp_pgsz[] = { 5317c478bd9Sstevel@tonic-gate 5327c478bd9Sstevel@tonic-gate {CHEETAH_IMPL, TTE8K, 0}, /* default */ 5337c478bd9Sstevel@tonic-gate {CHEETAH_IMPL, TTE64K, 0}, 5347c478bd9Sstevel@tonic-gate {CHEETAH_IMPL, TTE4M, 0}, 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate { CHEETAH_PLUS_IMPL, TTE4M, 1 }, /* default */ 5377c478bd9Sstevel@tonic-gate { CHEETAH_PLUS_IMPL, TTE4M, 0 }, 5387c478bd9Sstevel@tonic-gate { CHEETAH_PLUS_IMPL, TTE64K, 1 }, 5397c478bd9Sstevel@tonic-gate { CHEETAH_PLUS_IMPL, TTE64K, 0 }, 5407c478bd9Sstevel@tonic-gate { CHEETAH_PLUS_IMPL, TTE8K, 0 }, 5417c478bd9Sstevel@tonic-gate 5427c478bd9Sstevel@tonic-gate { JALAPENO_IMPL, TTE4M, 1 }, /* default */ 5437c478bd9Sstevel@tonic-gate { JALAPENO_IMPL, TTE4M, 0 }, 5447c478bd9Sstevel@tonic-gate { JALAPENO_IMPL, TTE64K, 1 }, 5457c478bd9Sstevel@tonic-gate { JALAPENO_IMPL, TTE64K, 0 }, 5467c478bd9Sstevel@tonic-gate { JALAPENO_IMPL, TTE8K, 0 }, 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate { JAGUAR_IMPL, TTE4M, 1 }, /* default */ 5497c478bd9Sstevel@tonic-gate { JAGUAR_IMPL, TTE4M, 0 }, 5507c478bd9Sstevel@tonic-gate { JAGUAR_IMPL, TTE64K, 1 }, 5517c478bd9Sstevel@tonic-gate { JAGUAR_IMPL, TTE64K, 0 }, 5527c478bd9Sstevel@tonic-gate { JAGUAR_IMPL, TTE8K, 0 }, 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate { SERRANO_IMPL, TTE4M, 1 }, /* default */ 5557c478bd9Sstevel@tonic-gate { SERRANO_IMPL, TTE4M, 0 }, 5567c478bd9Sstevel@tonic-gate { SERRANO_IMPL, TTE64K, 1 }, 5577c478bd9Sstevel@tonic-gate { SERRANO_IMPL, TTE64K, 0 }, 5587c478bd9Sstevel@tonic-gate { SERRANO_IMPL, TTE8K, 0 }, 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate { PANTHER_IMPL, TTE4M, 1 }, /* default */ 5617c478bd9Sstevel@tonic-gate { PANTHER_IMPL, TTE4M, 0 }, 5627c478bd9Sstevel@tonic-gate { PANTHER_IMPL, TTE64K, 1 }, 5637c478bd9Sstevel@tonic-gate { PANTHER_IMPL, TTE64K, 0 }, 5647c478bd9Sstevel@tonic-gate { PANTHER_IMPL, TTE8K, 0 } 5657c478bd9Sstevel@tonic-gate }; 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate int heaplp_use_dt512 = -1; 5687c478bd9Sstevel@tonic-gate 5697c478bd9Sstevel@tonic-gate void 5707c478bd9Sstevel@tonic-gate mmu_init_kernel_pgsz(struct hat *hat) 5717c478bd9Sstevel@tonic-gate { 5727c478bd9Sstevel@tonic-gate uint_t tte = page_szc(segkmem_lpsize); 5737c478bd9Sstevel@tonic-gate uchar_t new_cext_primary, new_cext_nucleus; 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate if (heaplp_use_dt512 == 0 || tte > TTE4M) { 5767c478bd9Sstevel@tonic-gate /* do not reprogram dt512 tlb */ 5777c478bd9Sstevel@tonic-gate tte = TTE8K; 5787c478bd9Sstevel@tonic-gate } 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate new_cext_nucleus = TAGACCEXT_MKSZPAIR(tte, TTE8K); 5817c478bd9Sstevel@tonic-gate new_cext_primary = TAGACCEXT_MKSZPAIR(TTE8K, tte); 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate hat->sfmmu_cext = new_cext_primary; 5847c478bd9Sstevel@tonic-gate kcontextreg = ((uint64_t)new_cext_nucleus << CTXREG_NEXT_SHIFT) | 5857c478bd9Sstevel@tonic-gate ((uint64_t)new_cext_primary << CTXREG_EXT_SHIFT); 5867c478bd9Sstevel@tonic-gate } 5877c478bd9Sstevel@tonic-gate 5887c478bd9Sstevel@tonic-gate size_t 5897c478bd9Sstevel@tonic-gate mmu_get_kernel_lpsize(size_t lpsize) 5907c478bd9Sstevel@tonic-gate { 5917c478bd9Sstevel@tonic-gate struct heap_lp_page_size *p_lpgsz, *pend_lpgsz; 5927c478bd9Sstevel@tonic-gate int impl = cpunodes[getprocessorid()].implementation; 5937c478bd9Sstevel@tonic-gate uint_t tte = TTE8K; 5947c478bd9Sstevel@tonic-gate 5951e2e7a75Shuah if (cpu_impl_dual_pgsz == 0) { 5961e2e7a75Shuah heaplp_use_dt512 = 0; 5971e2e7a75Shuah return (MMU_PAGESIZE); 5981e2e7a75Shuah } 5991e2e7a75Shuah 6007c478bd9Sstevel@tonic-gate pend_lpgsz = (struct heap_lp_page_size *) 6017c478bd9Sstevel@tonic-gate ((char *)heap_lp_pgsz + sizeof (heap_lp_pgsz)); 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate /* search for a valid segkmem_lpsize */ 6047c478bd9Sstevel@tonic-gate for (p_lpgsz = heap_lp_pgsz; p_lpgsz < pend_lpgsz; p_lpgsz++) { 6057c478bd9Sstevel@tonic-gate if (impl != p_lpgsz->impl) 6067c478bd9Sstevel@tonic-gate continue; 6077c478bd9Sstevel@tonic-gate 6087c478bd9Sstevel@tonic-gate if (lpsize == 0) { 6097c478bd9Sstevel@tonic-gate /* 6107c478bd9Sstevel@tonic-gate * no setting for segkmem_lpsize in /etc/system 6117c478bd9Sstevel@tonic-gate * use default from the table 6127c478bd9Sstevel@tonic-gate */ 6137c478bd9Sstevel@tonic-gate tte = p_lpgsz->tte; 6147c478bd9Sstevel@tonic-gate heaplp_use_dt512 = p_lpgsz->use_dt512; 6157c478bd9Sstevel@tonic-gate break; 6167c478bd9Sstevel@tonic-gate } 6177c478bd9Sstevel@tonic-gate 6187c478bd9Sstevel@tonic-gate if (lpsize == TTEBYTES(p_lpgsz->tte) && 6197c478bd9Sstevel@tonic-gate (heaplp_use_dt512 == -1 || 6207c478bd9Sstevel@tonic-gate heaplp_use_dt512 == p_lpgsz->use_dt512)) { 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate tte = p_lpgsz->tte; 6237c478bd9Sstevel@tonic-gate heaplp_use_dt512 = p_lpgsz->use_dt512; 6247c478bd9Sstevel@tonic-gate 6257c478bd9Sstevel@tonic-gate /* found a match */ 6267c478bd9Sstevel@tonic-gate break; 6277c478bd9Sstevel@tonic-gate } 6287c478bd9Sstevel@tonic-gate } 6297c478bd9Sstevel@tonic-gate 6307c478bd9Sstevel@tonic-gate if (p_lpgsz == pend_lpgsz) { 6317c478bd9Sstevel@tonic-gate /* nothing found: disable large page kernel heap */ 6327c478bd9Sstevel@tonic-gate tte = TTE8K; 6337c478bd9Sstevel@tonic-gate heaplp_use_dt512 = 0; 6347c478bd9Sstevel@tonic-gate } 6357c478bd9Sstevel@tonic-gate 6367c478bd9Sstevel@tonic-gate lpsize = TTEBYTES(tte); 6377c478bd9Sstevel@tonic-gate 6387c478bd9Sstevel@tonic-gate return (lpsize); 6397c478bd9Sstevel@tonic-gate } 640