diff options
Diffstat (limited to 'usr/src/uts/sun4v/cpu/niagara2.c')
-rw-r--r-- | usr/src/uts/sun4v/cpu/niagara2.c | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/usr/src/uts/sun4v/cpu/niagara2.c b/usr/src/uts/sun4v/cpu/niagara2.c index 4f3fd3017f..714d7f2d42 100644 --- a/usr/src/uts/sun4v/cpu/niagara2.c +++ b/usr/src/uts/sun4v/cpu/niagara2.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/systm.h> #include <sys/archsystm.h> @@ -66,6 +64,8 @@ uint_t root_phys_addr_lo_mask = 0xffffffffU; char cpu_module_name[] = "SUNW,UltraSPARC-T2"; #elif defined(VFALLS_IMPL) char cpu_module_name[] = "SUNW,UltraSPARC-T2+"; +#elif defined(KT_IMPL) +char cpu_module_name[] = "SUNW,UltraSPARC-KT"; #endif /* @@ -84,6 +84,11 @@ static hsvc_info_t cpu_hsvc = { HSVC_REV_1, NULL, HSVC_GROUP_VFALLS_CPU, VFALLS_HSVC_MAJOR, VFALLS_HSVC_MINOR, cpu_module_name }; +#elif defined(KT_IMPL) +static hsvc_info_t cpu_hsvc = { + HSVC_REV_1, NULL, HSVC_GROUP_KT_CPU, KT_HSVC_MAJOR, + KT_HSVC_MINOR, cpu_module_name +}; #endif void @@ -113,6 +118,24 @@ cpu_setup(void) */ cpu_setup_common(NULL); + /* + * Initialize the cpu_hwcap_flags for N2 and VF if it is not already + * set in cpu_setup_common() by the hwcap MD info. Note that this MD + * info may not be available for N2/VF. + */ + if (cpu_hwcap_flags == 0) { +#ifdef KT_IMPL + /* + * This should not happen since hwcap MD info is always + * available for KT platforms. + */ + ASSERT(cpu_hwcap_flags != 0); /* panic in DEBUG mode */ + cpu_hwcap_flags |= AV_SPARC_VIS3 | AV_SPARC_HPC | AV_SPARC_FMAF; +#endif /* KT_IMPL */ + cpu_hwcap_flags |= AV_SPARC_VIS | AV_SPARC_VIS2 | + AV_SPARC_ASI_BLK_INIT | AV_SPARC_POPC; + } + cache |= (CACHE_PTAG | CACHE_IOCOHERENT); if ((mmu_exported_pagesize_mask & @@ -123,9 +146,6 @@ cpu_setup(void) " 8K, 64K and 4M: MD mask is 0x%x", mmu_exported_pagesize_mask); - cpu_hwcap_flags = AV_SPARC_VIS | AV_SPARC_VIS2 | - AV_SPARC_ASI_BLK_INIT | AV_SPARC_POPC; - /* * Niagara2 supports a 48-bit subset of the full 64-bit virtual * address space. Virtual addresses between 0x0000800000000000 @@ -494,13 +514,11 @@ page_next_pfn_for_color_cpu(pfn_t pfn, uchar_t szc, uint_t color, /* restart here when we switch memblocks */ next_mem_block: - if (szc <= TTE64K) { - pfnmn = PAPFN_2_MNODE(pfn); - } - if (((page_papfn_2_color_cpu(pfn, szc) ^ color) & ceq_mask) == 0 && - (szc > TTE64K || pfnmn == it->mi_mnode)) { + pfnmn = PAPFN_2_MNODE(pfn); + if ((((page_papfn_2_color_cpu(pfn, szc) ^ color) & ceq_mask) == 0) && + (pfnmn == it->mi_mnode)) { - /* we start from the page with correct color */ + /* we start from the page with correct color and mnode */ if (szc >= TTE512K) { if (szc >= TTE4M) { /* page color is PA[32:28] */ @@ -510,6 +528,11 @@ next_mem_block: pfn_ceq_mask = ((ceq_mask & 1) << 6) | ((ceq_mask >> 1) << 15); } + /* + * Preserve mnode bits in case they are not part of the + * color mask (eg., 8GB interleave, mnode bits 34:33). + */ + pfn_ceq_mask |= it->mi_mnode_pfn_mask; npfn = ADD_MASKED(pfn, pstep, pfn_ceq_mask, mask); goto done; } else { @@ -554,8 +577,9 @@ next_mem_block: } else { /* try get the right color by changing bit PA[19:19] */ npfn = pfn + pstep; - if (((page_papfn_2_color_cpu(npfn, szc) ^ color) & - ceq_mask) == 0) + pfnmn = PAPFN_2_MNODE(npfn); + if ((((page_papfn_2_color_cpu(npfn, szc) ^ color) & + ceq_mask) == 0) && (pfnmn == it->mi_mnode)) goto done; /* page color is PA[32:28].PA[19:19] */ @@ -565,6 +589,16 @@ next_mem_block: npfn = ((pfn >> 20) << 20) | pfn_color; } + /* Fix mnode if necessary */ + if ((pfnmn = PAPFN_2_MNODE(npfn)) != it->mi_mnode) + npfn += ((it->mi_mnode - pfnmn) & it->mi_mnode_mask) << + it->mi_mnode_pfn_shift; + + /* + * Preserve mnode bits in case they are not part of the color + * mask eg 8GB interleave, mnode bits 34:33). + */ + pfn_ceq_mask |= it->mi_mnode_pfn_mask; while (npfn <= pfn) { npfn = ADD_MASKED(npfn, pstep, pfn_ceq_mask, mask); } |