niagara2.c revision b02e9a2d4d2071d770e5aa9ae8f83f2bbe1f2ced
4496171313bed39e96f21bc2f9faf2868e267ae3girish * CDDL HEADER START
4496171313bed39e96f21bc2f9faf2868e267ae3girish * The contents of this file are subject to the terms of the
4496171313bed39e96f21bc2f9faf2868e267ae3girish * Common Development and Distribution License (the "License").
4496171313bed39e96f21bc2f9faf2868e267ae3girish * You may not use this file except in compliance with the License.
4496171313bed39e96f21bc2f9faf2868e267ae3girish * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4496171313bed39e96f21bc2f9faf2868e267ae3girish * See the License for the specific language governing permissions
4496171313bed39e96f21bc2f9faf2868e267ae3girish * and limitations under the License.
4496171313bed39e96f21bc2f9faf2868e267ae3girish * When distributing Covered Code, include this CDDL HEADER in each
4496171313bed39e96f21bc2f9faf2868e267ae3girish * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4496171313bed39e96f21bc2f9faf2868e267ae3girish * If applicable, add the following below this CDDL HEADER, with the
4496171313bed39e96f21bc2f9faf2868e267ae3girish * fields enclosed by brackets "[]" replaced with your own identifying
4496171313bed39e96f21bc2f9faf2868e267ae3girish * information: Portions Copyright [yyyy] [name of copyright owner]
4496171313bed39e96f21bc2f9faf2868e267ae3girish * CDDL HEADER END
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
4496171313bed39e96f21bc2f9faf2868e267ae3girish * Use is subject to license terms.
4496171313bed39e96f21bc2f9faf2868e267ae3girish#pragma ident "%Z%%M% %I% %E% SMI"
59ac0c1669407488b67ae9e273667a340dccc611davemq * Hypervisor services information for the NIAGARA2 and Victoria Falls
59ac0c1669407488b67ae9e273667a340dccc611davemq * CPU module
59ac0c1669407488b67ae9e273667a340dccc611davemqstatic uint64_t cpu_sup_minor; /* Supported minor number */
4496171313bed39e96f21bc2f9faf2868e267ae3girish HSVC_REV_1, NULL, HSVC_GROUP_NIAGARA2_CPU, NIAGARA2_HSVC_MAJOR,
59ac0c1669407488b67ae9e273667a340dccc611davemq HSVC_REV_1, NULL, HSVC_GROUP_VFALLS_CPU, VFALLS_HSVC_MAJOR,
4496171313bed39e96f21bc2f9faf2868e267ae3girish * Negotiate the API version for Niagara2 specific hypervisor
4496171313bed39e96f21bc2f9faf2868e267ae3girish * services.
4496171313bed39e96f21bc2f9faf2868e267ae3girish if (status != 0) {
4496171313bed39e96f21bc2f9faf2868e267ae3girish cmn_err(CE_WARN, "%s: cannot negotiate hypervisor services "
4496171313bed39e96f21bc2f9faf2868e267ae3girish "group: 0x%lx major: 0x%lx minor: 0x%lx errno: %d",
4496171313bed39e96f21bc2f9faf2868e267ae3girish * The setup common to all CPU modules is done in cpu_setup_common
4496171313bed39e96f21bc2f9faf2868e267ae3girish " does not have required sun4v page sizes"
4496171313bed39e96f21bc2f9faf2868e267ae3girish " 8K, 64K and 4M: MD mask is 0x%x",
4496171313bed39e96f21bc2f9faf2868e267ae3girish cpu_hwcap_flags = AV_SPARC_VIS | AV_SPARC_VIS2 | AV_SPARC_ASI_BLK_INIT;
4496171313bed39e96f21bc2f9faf2868e267ae3girish * Niagara2 supports a 48-bit subset of the full 64-bit virtual
4496171313bed39e96f21bc2f9faf2868e267ae3girish * address space. Virtual addresses between 0x0000800000000000
4496171313bed39e96f21bc2f9faf2868e267ae3girish * and 0xffff.7fff.ffff.ffff inclusive lie within a "VA Hole"
4496171313bed39e96f21bc2f9faf2868e267ae3girish * and must never be mapped. In addition, software must not use
4496171313bed39e96f21bc2f9faf2868e267ae3girish * pages within 4GB of the VA hole as instruction pages to
4496171313bed39e96f21bc2f9faf2868e267ae3girish * avoid problems with prefetching into the VA hole.
4496171313bed39e96f21bc2f9faf2868e267ae3girish hole_start = (caddr_t)((1ull << (va_bits - 1)) - (1ull << 32));
4496171313bed39e96f21bc2f9faf2868e267ae3girish hole_end = (caddr_t)((0ull - (1ull << (va_bits - 1))) + (1ull << 32));
4496171313bed39e96f21bc2f9faf2868e267ae3girish * Niagara2 has a performance counter overflow interrupt
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp * Enable 4M pages for OOB.
4496171313bed39e96f21bc2f9faf2868e267ae3girish * Set the magic constants of the implementation.
4496171313bed39e96f21bc2f9faf2868e267ae3girish * The Cache node is optional in MD. Therefore in case "Cache"
4496171313bed39e96f21bc2f9faf2868e267ae3girish * node does not exists in MD, set the default L2 cache associativity,
4496171313bed39e96f21bc2f9faf2868e267ae3girish * size, linesize.
4496171313bed39e96f21bc2f9faf2868e267ae3girish cpunode->ecache_associativity = L2CACHE_ASSOCIATIVITY;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * The cpu_ipipe and cpu_fpu fields are initialized based on
459190a5c46206e7885f6a649a055ceb46be49a7rsmaeda * the execution unit sharing information from the MD. They
459190a5c46206e7885f6a649a055ceb46be49a7rsmaeda * default to the CPU id in the absence of such information.
4496171313bed39e96f21bc2f9faf2868e267ae3girish cp->cpu_m.cpu_ipipe = cpunodes[cp->cpu_id].exec_unit_mapping;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Niagara 2 defines the core to be at the FPU level
59ac0c1669407488b67ae9e273667a340dccc611davemq * The cpu_chip field is initialized based on the information
59ac0c1669407488b67ae9e273667a340dccc611davemq * in the MD and assume that all cpus within a chip
59ac0c1669407488b67ae9e273667a340dccc611davemq * share the same L2 cache. If no such info is available, we
59ac0c1669407488b67ae9e273667a340dccc611davemq * set the cpu to belong to the defacto chip 0.
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp cp->cpu_m.cpu_mpipe = cpunodes[cp->cpu_id].l2_cache_mapping;
e853d8c363bb48f997502f6e034877de20256ab0jc cp->cpu_m.cpu_chip = cpunodes[cp->cpu_id].l2_cache_mapping;
459190a5c46206e7885f6a649a055ceb46be49a7rsmaeda extern void niagara_kstat_init(void);
59ac0c1669407488b67ae9e273667a340dccc611davemq if ((cpucnt++ == 0) && (cpu_hsvc_available == B_TRUE))
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*ARGSUSED*/
459190a5c46206e7885f6a649a055ceb46be49a7rsmaeda extern void niagara_kstat_fini(void);
59ac0c1669407488b67ae9e273667a340dccc611davemq if ((--cpucnt == 0) && (cpu_hsvc_available == B_TRUE))
4496171313bed39e96f21bc2f9faf2868e267ae3girish * On Niagara2, any flush will cause all preceding stores to be
4496171313bed39e96f21bc2f9faf2868e267ae3girish * synchronized wrt the i$, regardless of address or ASI. In fact,
4496171313bed39e96f21bc2f9faf2868e267ae3girish * the address is ignored, so we always flush address 0.
4496171313bed39e96f21bc2f9faf2868e267ae3girish/*ARGSUSED*/
4496171313bed39e96f21bc2f9faf2868e267ae3girish * Trapstat support for Niagara2 processor
4496171313bed39e96f21bc2f9faf2868e267ae3girish * The Niagara2 provides HWTW support for TSB lookup and with HWTW
4496171313bed39e96f21bc2f9faf2868e267ae3girish * enabled no TSB hit information will be available. Therefore setting
4496171313bed39e96f21bc2f9faf2868e267ae3girish * the time spent in TLB miss handler for TSB hits to 0.
4496171313bed39e96f21bc2f9faf2868e267ae3girish tstatp->tpgsz_kernel.tmode_itlb.ttlb_tlb.tmiss_count = 0;
4496171313bed39e96f21bc2f9faf2868e267ae3girish tstatp->tpgsz_kernel.tmode_itlb.ttlb_tlb.tmiss_time = 0;
4496171313bed39e96f21bc2f9faf2868e267ae3girish tstatp->tpgsz_user.tmode_itlb.ttlb_tlb.tmiss_count = 0;
4496171313bed39e96f21bc2f9faf2868e267ae3girish tstatp->tpgsz_user.tmode_itlb.ttlb_tlb.tmiss_time = 0;
4496171313bed39e96f21bc2f9faf2868e267ae3girish tstatp->tpgsz_kernel.tmode_dtlb.ttlb_tlb.tmiss_count = 0;
4496171313bed39e96f21bc2f9faf2868e267ae3girish tstatp->tpgsz_kernel.tmode_dtlb.ttlb_tlb.tmiss_time = 0;
4496171313bed39e96f21bc2f9faf2868e267ae3girish tstatp->tpgsz_user.tmode_dtlb.ttlb_tlb.tmiss_count = 0;
4496171313bed39e96f21bc2f9faf2868e267ae3girish tstatp->tpgsz_user.tmode_dtlb.ttlb_tlb.tmiss_time = 0;
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * Page coloring support for hashed cache index mode
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * Node id bits from machine description (MD). Node id distinguishes
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * local versus remote memory. Because of MPO, page allocation does
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * not cross node boundaries. Therefore, remove the node id bits from
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * the color, since they are fixed. Either bit 30, or 31:30 in
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * Victoria Falls processors.
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * The number of node id bits is always 0 in Niagara2.
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dptypedef struct n2color {
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * Remove node id bits from color bits 32:28.
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * This will reduce the number of colors.
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * No change if number of node bits is zero.
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dpstatic inline uint_t
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp if (m.nnbits > 0) {
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp color = ((color >> m.nnbits) & ~m.lomask) | (color & m.lomask);
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp ASSERT((color & ~(hw_page_array[szc].hp_colors - 1)) == 0);
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * Restore node id bits into page color.
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * This will increase the number of colors to match N2.
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * No change if number of node bits is zero.
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dpstatic inline uint_t
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp if (m.nnbits > 0) {
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp color = ((color & ~m.lomask) << m.nnbits) | (color & m.lomask);
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp/* NI2 L2$ index is pa[32:28]^pa[17:13].pa[19:18]^pa[12:11].pa[10:6] */
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * iterator NULL means pfn is VA, do not adjust ra_to_pa
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * iterator (-1) means pfn is RA, need to convert to PA
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * iterator non-null means pfn is RA, use ra_to_pa
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dppage_pfn_2_color_cpu(pfn_t pfn, uchar_t szc, void *cookie)
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp ASSERT(pfn >= it->mi_mblock_base && pfn <= it->mi_mblock_end);
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp /* 19:18 */
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp /* 19:18 */
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp static uint_t ni2_color_masks[5] = {0x63, 0x1e, 0x3e, 0x1f, 0x1f};
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp return (s);
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dppage_convert_color_cpu(uint_t ncolor, uchar_t szc, uchar_t nszc)
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp (((pfn) & it->mi_mnode_pfn_mask) >> it->mi_mnode_pfn_shift)
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp/*ARGSUSED*/
102033aa92edf302ad31b3bdd7c6fcd2d6910903dppage_next_pfn_for_color_cpu(pfn_t pfn, uchar_t szc, uint_t color,
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp ASSERT(pfn >= it->mi_mblock_base && pfn <= it->mi_mblock_end);
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp /* convert RA to PA for accurate color calculation */
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp /* first call after it, so cache these values */
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp /* restart here when we switch memblocks */
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp if (((page_papfn_2_color_cpu(pfn, szc) ^ color) & ceq_mask) == 0 &&
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp /* we start from the page with correct color */
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp /* page color is PA[32:28] */
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp /* page color is PA[32:28].PA[19:19] */
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp * We deal 64K or 8K page. Check if we could the
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp * satisfy the request without changing PA[32:28]
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp * for next pfn we have to change bits PA[32:28]
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp * set PA[63:28] and PA[19:18] of the next pfn
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp * set bits PA[17:13] to match the color
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp * we start from the page with incorrect color - rare case
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp /* page color is in bits PA[32:28] */
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp /* try get the right color by changing bit PA[19:19] */
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp /* page color is PA[32:28].PA[19:19] */
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * We deal 64K or 8K page of incorrect color.
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp * Try correcting color without changing PA[32:28]
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp npfn |= (((pfn >> 15) & 0x1f) ^ pfn_color) & pfn_ceq_mask;
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp /* the color is fixed - find the next page */
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp /* to fix the color need to touch PA[32:28] */
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp /* fix mnode if input pfn is in the wrong mnode. */
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp /* set bits PA[19:13] to match the color */
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp npfn |= (((npfn >> 15) & 0x1f) ^ pfn_color) & pfn_ceq_mask;
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp ASSERT(((page_papfn_2_color_cpu(npfn, szc) ^ color) & ceq_mask) == 0);
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp /* PA to RA */
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp /* check for possible memblock switch */
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp pfn = plat_mem_node_iterator_init(npfn, it->mi_mnode, it, 0);
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp ASSERT(pfn >= it->mi_mblock_base && pfn <= it->mi_mblock_end);
102033aa92edf302ad31b3bdd7c6fcd2d6910903dp * init page coloring
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * VF encodes node_id for an L-group in either bit 30 or 31:30,
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp * which effectively reduces the number of colors available per mnode.
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp static uchar_t idmask[] = {0, 0x7, 0x1f, 0x1f, 0x1f, 0x1f};
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp for (i = 0; i < mmu_page_sizes; i++) {
b02e9a2d4d2071d770e5aa9ae8f83f2bbe1f2cedsvemuri (void) memset(&m, 0, sizeof (m));
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp if (lo > 0) {
ce8eb11a8717b4a57c68fd77ab9f8aac15b16bf2dp hw_page_array[i].hp_colors = 1 << (nhbits[i] - m.nnbits);
fe70c9cf90dfc23d18485fb7b4b20a1175d53a8bdp * group colorequiv colors on N2 by low order bits of the color first
fe70c9cf90dfc23d18485fb7b4b20a1175d53a8bdp static uint_t nequiv_shades_log2[MMU_PAGE_SIZES] = {2, 5, 0, 0, 0, 0};
fe70c9cf90dfc23d18485fb7b4b20a1175d53a8bdp for (i = 0; i < MMU_PAGE_SIZES; i++) {
fe70c9cf90dfc23d18485fb7b4b20a1175d53a8bdp while ((colors >> a) == 0)
fe70c9cf90dfc23d18485fb7b4b20a1175d53a8bdp if (a <= nequiv_shades_log2[i]) {