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*bd963cb9SEthindra Ramamurthy * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate * 257c478bd9Sstevel@tonic-gate * Assembly code support for Cheetah/Cheetah+ modules 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate#if !defined(lint) 297c478bd9Sstevel@tonic-gate#include "assym.h" 307c478bd9Sstevel@tonic-gate#endif /* !lint */ 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 337c478bd9Sstevel@tonic-gate#include <sys/mmu.h> 347c478bd9Sstevel@tonic-gate#include <vm/hat_sfmmu.h> 357c478bd9Sstevel@tonic-gate#include <sys/machparam.h> 367c478bd9Sstevel@tonic-gate#include <sys/machcpuvar.h> 377c478bd9Sstevel@tonic-gate#include <sys/machthread.h> 387c478bd9Sstevel@tonic-gate#include <sys/machtrap.h> 397c478bd9Sstevel@tonic-gate#include <sys/privregs.h> 407c478bd9Sstevel@tonic-gate#include <sys/trap.h> 417c478bd9Sstevel@tonic-gate#include <sys/cheetahregs.h> 427c478bd9Sstevel@tonic-gate#include <sys/us3_module.h> 437c478bd9Sstevel@tonic-gate#include <sys/xc_impl.h> 447c478bd9Sstevel@tonic-gate#include <sys/intreg.h> 457c478bd9Sstevel@tonic-gate#include <sys/async.h> 467c478bd9Sstevel@tonic-gate#include <sys/clock.h> 477c478bd9Sstevel@tonic-gate#include <sys/cheetahasm.h> 487c478bd9Sstevel@tonic-gate#include <sys/cmpregs.h> 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 517c478bd9Sstevel@tonic-gate#include <sys/traptrace.h> 527c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */ 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate#if !defined(lint) 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate/* BEGIN CSTYLED */ 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate#define DCACHE_FLUSHPAGE(arg1, arg2, tmp1, tmp2, tmp3) \ 597c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_DCU, tmp1 ;\ 607c478bd9Sstevel@tonic-gate btst DCU_DC, tmp1 /* is dcache enabled? */ ;\ 617c478bd9Sstevel@tonic-gate bz,pn %icc, 1f ;\ 627c478bd9Sstevel@tonic-gate ASM_LD(tmp1, dcache_linesize) ;\ 637c478bd9Sstevel@tonic-gate ASM_LD(tmp2, dflush_type) ;\ 647c478bd9Sstevel@tonic-gate cmp tmp2, FLUSHPAGE_TYPE ;\ 657c478bd9Sstevel@tonic-gate be,pt %icc, 2f ;\ 667c478bd9Sstevel@tonic-gate nop ;\ 677c478bd9Sstevel@tonic-gate sllx arg1, CHEETAH_DC_VBIT_SHIFT, arg1/* tag to compare */ ;\ 687c478bd9Sstevel@tonic-gate ASM_LD(tmp3, dcache_size) ;\ 697c478bd9Sstevel@tonic-gate cmp tmp2, FLUSHMATCH_TYPE ;\ 707c478bd9Sstevel@tonic-gate be,pt %icc, 3f ;\ 717c478bd9Sstevel@tonic-gate nop ;\ 727c478bd9Sstevel@tonic-gate /* \ 737c478bd9Sstevel@tonic-gate * flushtype = FLUSHALL_TYPE, flush the whole thing \ 747c478bd9Sstevel@tonic-gate * tmp3 = cache size \ 757c478bd9Sstevel@tonic-gate * tmp1 = cache line size \ 767c478bd9Sstevel@tonic-gate */ \ 777c478bd9Sstevel@tonic-gate sub tmp3, tmp1, tmp2 ;\ 787c478bd9Sstevel@tonic-gate4: \ 797c478bd9Sstevel@tonic-gate stxa %g0, [tmp2]ASI_DC_TAG ;\ 807c478bd9Sstevel@tonic-gate membar #Sync ;\ 817c478bd9Sstevel@tonic-gate cmp %g0, tmp2 ;\ 827c478bd9Sstevel@tonic-gate bne,pt %icc, 4b ;\ 837c478bd9Sstevel@tonic-gate sub tmp2, tmp1, tmp2 ;\ 847c478bd9Sstevel@tonic-gate ba,pt %icc, 1f ;\ 857c478bd9Sstevel@tonic-gate nop ;\ 867c478bd9Sstevel@tonic-gate /* \ 877c478bd9Sstevel@tonic-gate * flushtype = FLUSHPAGE_TYPE \ 887c478bd9Sstevel@tonic-gate * arg1 = pfn \ 897c478bd9Sstevel@tonic-gate * arg2 = virtual color \ 907c478bd9Sstevel@tonic-gate * tmp1 = cache line size \ 917c478bd9Sstevel@tonic-gate * tmp2 = tag from cache \ 927c478bd9Sstevel@tonic-gate * tmp3 = counter \ 937c478bd9Sstevel@tonic-gate */ \ 947c478bd9Sstevel@tonic-gate2: \ 957c478bd9Sstevel@tonic-gate set MMU_PAGESIZE, tmp3 ;\ 967c478bd9Sstevel@tonic-gate sllx arg1, MMU_PAGESHIFT, arg1 /* pfn to 43 bit PA */ ;\ 977c478bd9Sstevel@tonic-gate sub tmp3, tmp1, tmp3 ;\ 987c478bd9Sstevel@tonic-gate4: \ 997c478bd9Sstevel@tonic-gate stxa %g0, [arg1 + tmp3]ASI_DC_INVAL ;\ 1007c478bd9Sstevel@tonic-gate membar #Sync ;\ 1017c478bd9Sstevel@tonic-gate5: \ 1027c478bd9Sstevel@tonic-gate cmp %g0, tmp3 ;\ 1037c478bd9Sstevel@tonic-gate bnz,pt %icc, 4b /* branch if not done */ ;\ 1047c478bd9Sstevel@tonic-gate sub tmp3, tmp1, tmp3 ;\ 1057c478bd9Sstevel@tonic-gate ba,pt %icc, 1f ;\ 1067c478bd9Sstevel@tonic-gate nop ;\ 1077c478bd9Sstevel@tonic-gate /* \ 1087c478bd9Sstevel@tonic-gate * flushtype = FLUSHMATCH_TYPE \ 1097c478bd9Sstevel@tonic-gate * arg1 = tag to compare against \ 1107c478bd9Sstevel@tonic-gate * tmp1 = cache line size \ 1117c478bd9Sstevel@tonic-gate * tmp3 = cache size \ 1127c478bd9Sstevel@tonic-gate * arg2 = counter \ 1137c478bd9Sstevel@tonic-gate * tmp2 = cache tag \ 1147c478bd9Sstevel@tonic-gate */ \ 1157c478bd9Sstevel@tonic-gate3: \ 1167c478bd9Sstevel@tonic-gate sub tmp3, tmp1, arg2 ;\ 1177c478bd9Sstevel@tonic-gate4: \ 1187c478bd9Sstevel@tonic-gate ldxa [arg2]ASI_DC_TAG, tmp2 /* read tag */ ;\ 1197c478bd9Sstevel@tonic-gate btst CHEETAH_DC_VBIT_MASK, tmp2 ;\ 1207c478bd9Sstevel@tonic-gate bz,pn %icc, 5f /* br if no valid sub-blocks */ ;\ 1217c478bd9Sstevel@tonic-gate andn tmp2, CHEETAH_DC_VBIT_MASK, tmp2 /* clear out v bits */ ;\ 1227c478bd9Sstevel@tonic-gate cmp tmp2, arg1 ;\ 1237c478bd9Sstevel@tonic-gate bne,pn %icc, 5f /* branch if tag miss */ ;\ 1247c478bd9Sstevel@tonic-gate nop ;\ 1257c478bd9Sstevel@tonic-gate stxa %g0, [arg2]ASI_DC_TAG ;\ 1267c478bd9Sstevel@tonic-gate membar #Sync ;\ 1277c478bd9Sstevel@tonic-gate5: \ 1287c478bd9Sstevel@tonic-gate cmp %g0, arg2 ;\ 1297c478bd9Sstevel@tonic-gate bne,pt %icc, 4b /* branch if not done */ ;\ 1307c478bd9Sstevel@tonic-gate sub arg2, tmp1, arg2 ;\ 1317c478bd9Sstevel@tonic-gate1: 1327c478bd9Sstevel@tonic-gate 133444ce08eSDonghai Qiao/* 134444ce08eSDonghai Qiao * macro that flushes the entire dcache color 135444ce08eSDonghai Qiao * dcache size = 64K, one way 16K 136*bd963cb9SEthindra Ramamurthy * 137*bd963cb9SEthindra Ramamurthy * In: 138*bd963cb9SEthindra Ramamurthy * arg = virtual color register (not clobbered) 139*bd963cb9SEthindra Ramamurthy * way = way#, can either be a constant or a register (not clobbered) 140*bd963cb9SEthindra Ramamurthy * tmp1, tmp2, tmp3 = scratch registers 141*bd963cb9SEthindra Ramamurthy * 142444ce08eSDonghai Qiao */ 143444ce08eSDonghai Qiao#define DCACHE_FLUSHCOLOR(arg, way, tmp1, tmp2, tmp3) \ 144444ce08eSDonghai Qiao ldxa [%g0]ASI_DCU, tmp1; \ 145444ce08eSDonghai Qiao btst DCU_DC, tmp1; /* is dcache enabled? */ \ 146444ce08eSDonghai Qiao bz,pn %icc, 1f; \ 147444ce08eSDonghai Qiao ASM_LD(tmp1, dcache_linesize) \ 148444ce08eSDonghai Qiao /* \ 149444ce08eSDonghai Qiao * arg = virtual color \ 150444ce08eSDonghai Qiao * tmp1 = cache line size \ 151444ce08eSDonghai Qiao */ \ 152*bd963cb9SEthindra Ramamurthy sllx arg, MMU_PAGESHIFT, tmp2; /* color to dcache page */ \ 153444ce08eSDonghai Qiao mov way, tmp3; \ 154444ce08eSDonghai Qiao sllx tmp3, 14, tmp3; /* One way 16K */ \ 155*bd963cb9SEthindra Ramamurthy or tmp2, tmp3, tmp3; \ 156*bd963cb9SEthindra Ramamurthy set MMU_PAGESIZE, tmp2; \ 157*bd963cb9SEthindra Ramamurthy /* \ 158*bd963cb9SEthindra Ramamurthy * tmp2 = page size \ 159*bd963cb9SEthindra Ramamurthy * tmp3 = cached page in dcache \ 160*bd963cb9SEthindra Ramamurthy */ \ 161444ce08eSDonghai Qiao sub tmp2, tmp1, tmp2; \ 162444ce08eSDonghai Qiao2: \ 163*bd963cb9SEthindra Ramamurthy stxa %g0, [tmp3 + tmp2]ASI_DC_TAG; \ 164444ce08eSDonghai Qiao membar #Sync; \ 165444ce08eSDonghai Qiao cmp %g0, tmp2; \ 166444ce08eSDonghai Qiao bne,pt %icc, 2b; \ 167444ce08eSDonghai Qiao sub tmp2, tmp1, tmp2; \ 168444ce08eSDonghai Qiao1: 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate/* END CSTYLED */ 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate#endif /* !lint */ 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate/* 1757c478bd9Sstevel@tonic-gate * Cheetah MMU and Cache operations. 1767c478bd9Sstevel@tonic-gate */ 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate#if defined(lint) 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate/* ARGSUSED */ 1817c478bd9Sstevel@tonic-gatevoid 1821e2e7a75Shuahvtag_flushpage(caddr_t vaddr, uint64_t sfmmup) 1837c478bd9Sstevel@tonic-gate{} 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate#else /* lint */ 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate ENTRY_NP(vtag_flushpage) 1887c478bd9Sstevel@tonic-gate /* 1897c478bd9Sstevel@tonic-gate * flush page from the tlb 1907c478bd9Sstevel@tonic-gate * 1917c478bd9Sstevel@tonic-gate * %o0 = vaddr 1921e2e7a75Shuah * %o1 = sfmmup 1937c478bd9Sstevel@tonic-gate */ 1947c478bd9Sstevel@tonic-gate rdpr %pstate, %o5 1957c478bd9Sstevel@tonic-gate#ifdef DEBUG 1961e2e7a75Shuah PANIC_IF_INTR_DISABLED_PSTR(%o5, u3_di_label0, %g1) 1977c478bd9Sstevel@tonic-gate#endif /* DEBUG */ 1987c478bd9Sstevel@tonic-gate /* 1997c478bd9Sstevel@tonic-gate * disable ints 2007c478bd9Sstevel@tonic-gate */ 2017c478bd9Sstevel@tonic-gate andn %o5, PSTATE_IE, %o4 2027c478bd9Sstevel@tonic-gate wrpr %o4, 0, %pstate 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate /* 2057c478bd9Sstevel@tonic-gate * Then, blow out the tlb 2067c478bd9Sstevel@tonic-gate * Interrupts are disabled to prevent the primary ctx register 2077c478bd9Sstevel@tonic-gate * from changing underneath us. 2087c478bd9Sstevel@tonic-gate */ 2091e2e7a75Shuah sethi %hi(ksfmmup), %o3 2101e2e7a75Shuah ldx [%o3 + %lo(ksfmmup)], %o3 2111e2e7a75Shuah cmp %o3, %o1 2121e2e7a75Shuah bne,pt %xcc, 1f ! if not kernel as, go to 1 2137c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %o3 2147c478bd9Sstevel@tonic-gate /* 2151e2e7a75Shuah * For Kernel demaps use primary. type = page implicitly 2167c478bd9Sstevel@tonic-gate */ 2177c478bd9Sstevel@tonic-gate stxa %g0, [%o0]ASI_DTLB_DEMAP /* dmmu flush for KCONTEXT */ 2187c478bd9Sstevel@tonic-gate stxa %g0, [%o0]ASI_ITLB_DEMAP /* immu flush for KCONTEXT */ 2197c478bd9Sstevel@tonic-gate flush %o3 2201e2e7a75Shuah retl 2211e2e7a75Shuah wrpr %g0, %o5, %pstate /* enable interrupts */ 2227c478bd9Sstevel@tonic-gate1: 2237c478bd9Sstevel@tonic-gate /* 2247c478bd9Sstevel@tonic-gate * User demap. We need to set the primary context properly. 2257c478bd9Sstevel@tonic-gate * Secondary context cannot be used for Cheetah IMMU. 2267c478bd9Sstevel@tonic-gate * %o0 = vaddr 2271e2e7a75Shuah * %o1 = sfmmup 2287c478bd9Sstevel@tonic-gate * %o3 = FLUSH_ADDR 2297c478bd9Sstevel@tonic-gate */ 2301e2e7a75Shuah SFMMU_CPU_CNUM(%o1, %g1, %g2) ! %g1 = sfmmu cnum on this CPU 2311e2e7a75Shuah 2321e2e7a75Shuah ldub [%o1 + SFMMU_CEXT], %o4 ! %o4 = sfmmup->sfmmu_cext 2337c478bd9Sstevel@tonic-gate sll %o4, CTXREG_EXT_SHIFT, %o4 234febcc4a5Sjimand or %g1, %o4, %g1 ! %g1 = primary pgsz | cnum 2351e2e7a75Shuah 2367c478bd9Sstevel@tonic-gate wrpr %g0, 1, %tl 2377c478bd9Sstevel@tonic-gate set MMU_PCONTEXT, %o4 2387c478bd9Sstevel@tonic-gate or DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %o0, %o0 2391e2e7a75Shuah ldxa [%o4]ASI_DMMU, %o2 ! %o2 = save old ctxnum 240febcc4a5Sjimand srlx %o2, CTXREG_NEXT_SHIFT, %o1 ! need to preserve nucleus pgsz 241febcc4a5Sjimand sllx %o1, CTXREG_NEXT_SHIFT, %o1 ! %o1 = nucleus pgsz 242febcc4a5Sjimand or %g1, %o1, %g1 ! %g1 = nucleus pgsz | primary pgsz | cnum 2431e2e7a75Shuah stxa %g1, [%o4]ASI_DMMU ! wr new ctxum 2441e2e7a75Shuah 2457c478bd9Sstevel@tonic-gate stxa %g0, [%o0]ASI_DTLB_DEMAP 2467c478bd9Sstevel@tonic-gate stxa %g0, [%o0]ASI_ITLB_DEMAP 2477c478bd9Sstevel@tonic-gate stxa %o2, [%o4]ASI_DMMU /* restore old ctxnum */ 2487c478bd9Sstevel@tonic-gate flush %o3 2497c478bd9Sstevel@tonic-gate wrpr %g0, 0, %tl 2501e2e7a75Shuah 2517c478bd9Sstevel@tonic-gate retl 2527c478bd9Sstevel@tonic-gate wrpr %g0, %o5, %pstate /* enable interrupts */ 2537c478bd9Sstevel@tonic-gate SET_SIZE(vtag_flushpage) 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate#endif /* lint */ 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate#if defined(lint) 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gatevoid 2607c478bd9Sstevel@tonic-gatevtag_flushall(void) 2617c478bd9Sstevel@tonic-gate{} 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate#else /* lint */ 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate ENTRY_NP2(vtag_flushall, demap_all) 2667c478bd9Sstevel@tonic-gate /* 2677c478bd9Sstevel@tonic-gate * flush the tlb 2687c478bd9Sstevel@tonic-gate */ 2697c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %o3 2707c478bd9Sstevel@tonic-gate set DEMAP_ALL_TYPE, %g1 2717c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_DTLB_DEMAP 2727c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_ITLB_DEMAP 2737c478bd9Sstevel@tonic-gate flush %o3 2747c478bd9Sstevel@tonic-gate retl 2757c478bd9Sstevel@tonic-gate nop 2767c478bd9Sstevel@tonic-gate SET_SIZE(demap_all) 2777c478bd9Sstevel@tonic-gate SET_SIZE(vtag_flushall) 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate#endif /* lint */ 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate#if defined(lint) 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate/* ARGSUSED */ 2857c478bd9Sstevel@tonic-gatevoid 2861e2e7a75Shuahvtag_flushpage_tl1(uint64_t vaddr, uint64_t sfmmup) 2877c478bd9Sstevel@tonic-gate{} 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate#else /* lint */ 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate ENTRY_NP(vtag_flushpage_tl1) 2927c478bd9Sstevel@tonic-gate /* 2937c478bd9Sstevel@tonic-gate * x-trap to flush page from tlb and tsb 2947c478bd9Sstevel@tonic-gate * 2957c478bd9Sstevel@tonic-gate * %g1 = vaddr, zero-extended on 32-bit kernel 2961e2e7a75Shuah * %g2 = sfmmup 2977c478bd9Sstevel@tonic-gate * 2987c478bd9Sstevel@tonic-gate * assumes TSBE_TAG = 0 2997c478bd9Sstevel@tonic-gate */ 3007c478bd9Sstevel@tonic-gate srln %g1, MMU_PAGESHIFT, %g1 3011e2e7a75Shuah 3021e2e7a75Shuah sethi %hi(ksfmmup), %g3 3031e2e7a75Shuah ldx [%g3 + %lo(ksfmmup)], %g3 3041e2e7a75Shuah cmp %g3, %g2 3051e2e7a75Shuah bne,pt %xcc, 1f ! if not kernel as, go to 1 3067c478bd9Sstevel@tonic-gate slln %g1, MMU_PAGESHIFT, %g1 /* g1 = vaddr */ 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate /* We need to demap in the kernel context */ 3097c478bd9Sstevel@tonic-gate or DEMAP_NUCLEUS | DEMAP_PAGE_TYPE, %g1, %g1 3107c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_DTLB_DEMAP 3117c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_ITLB_DEMAP 3127c478bd9Sstevel@tonic-gate retry 3137c478bd9Sstevel@tonic-gate1: 3147c478bd9Sstevel@tonic-gate /* We need to demap in a user context */ 3157c478bd9Sstevel@tonic-gate or DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %g1, %g1 3161e2e7a75Shuah 3171e2e7a75Shuah SFMMU_CPU_CNUM(%g2, %g6, %g3) ! %g6 = sfmmu cnum on this CPU 3181e2e7a75Shuah 3191e2e7a75Shuah ldub [%g2 + SFMMU_CEXT], %g4 ! %g4 = sfmmup->cext 3207c478bd9Sstevel@tonic-gate sll %g4, CTXREG_EXT_SHIFT, %g4 3211e2e7a75Shuah or %g6, %g4, %g6 ! %g6 = pgsz | cnum 3221e2e7a75Shuah 3237c478bd9Sstevel@tonic-gate set MMU_PCONTEXT, %g4 3247c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_DMMU, %g5 /* rd old ctxnum */ 325febcc4a5Sjimand srlx %g5, CTXREG_NEXT_SHIFT, %g2 /* %g2 = nucleus pgsz */ 326febcc4a5Sjimand sllx %g2, CTXREG_NEXT_SHIFT, %g2 /* preserve nucleus pgsz */ 327febcc4a5Sjimand or %g6, %g2, %g6 /* %g6 = nucleus pgsz | primary pgsz | cnum */ 3281e2e7a75Shuah stxa %g6, [%g4]ASI_DMMU /* wr new ctxum */ 3297c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_DTLB_DEMAP 3307c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_ITLB_DEMAP 3317c478bd9Sstevel@tonic-gate stxa %g5, [%g4]ASI_DMMU /* restore old ctxnum */ 3327c478bd9Sstevel@tonic-gate retry 3337c478bd9Sstevel@tonic-gate SET_SIZE(vtag_flushpage_tl1) 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate#endif /* lint */ 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate#if defined(lint) 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate/* ARGSUSED */ 3417c478bd9Sstevel@tonic-gatevoid 3421e2e7a75Shuahvtag_flush_pgcnt_tl1(uint64_t vaddr, uint64_t sfmmup_pgcnt) 3437c478bd9Sstevel@tonic-gate{} 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate#else /* lint */ 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate ENTRY_NP(vtag_flush_pgcnt_tl1) 3487c478bd9Sstevel@tonic-gate /* 3497c478bd9Sstevel@tonic-gate * x-trap to flush pgcnt MMU_PAGESIZE pages from tlb 3507c478bd9Sstevel@tonic-gate * 3517c478bd9Sstevel@tonic-gate * %g1 = vaddr, zero-extended on 32-bit kernel 3521e2e7a75Shuah * %g2 = <sfmmup58|pgcnt6>, (pgcnt - 1) is pass'ed in via pgcnt6 bits. 3537c478bd9Sstevel@tonic-gate * 3547c478bd9Sstevel@tonic-gate * NOTE: this handler relies on the fact that no 3557c478bd9Sstevel@tonic-gate * interrupts or traps can occur during the loop 3567c478bd9Sstevel@tonic-gate * issuing the TLB_DEMAP operations. It is assumed 3577c478bd9Sstevel@tonic-gate * that interrupts are disabled and this code is 3587c478bd9Sstevel@tonic-gate * fetching from the kernel locked text address. 3597c478bd9Sstevel@tonic-gate * 3607c478bd9Sstevel@tonic-gate * assumes TSBE_TAG = 0 3617c478bd9Sstevel@tonic-gate */ 3621e2e7a75Shuah set SFMMU_PGCNT_MASK, %g4 3631e2e7a75Shuah and %g4, %g2, %g3 /* g3 = pgcnt - 1 */ 3641e2e7a75Shuah add %g3, 1, %g3 /* g3 = pgcnt */ 3651e2e7a75Shuah 3661e2e7a75Shuah andn %g2, SFMMU_PGCNT_MASK, %g2 /* g2 = sfmmup */ 3677c478bd9Sstevel@tonic-gate srln %g1, MMU_PAGESHIFT, %g1 3681e2e7a75Shuah 3691e2e7a75Shuah sethi %hi(ksfmmup), %g4 3701e2e7a75Shuah ldx [%g4 + %lo(ksfmmup)], %g4 3711e2e7a75Shuah cmp %g4, %g2 3721e2e7a75Shuah bne,pn %xcc, 1f /* if not kernel as, go to 1 */ 3737c478bd9Sstevel@tonic-gate slln %g1, MMU_PAGESHIFT, %g1 /* g1 = vaddr */ 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate /* We need to demap in the kernel context */ 3767c478bd9Sstevel@tonic-gate or DEMAP_NUCLEUS | DEMAP_PAGE_TYPE, %g1, %g1 3777c478bd9Sstevel@tonic-gate set MMU_PAGESIZE, %g2 /* g2 = pgsize */ 3781e2e7a75Shuah sethi %hi(FLUSH_ADDR), %g5 3797c478bd9Sstevel@tonic-gate4: 3807c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_DTLB_DEMAP 3817c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_ITLB_DEMAP 3821e2e7a75Shuah flush %g5 ! flush required by immu 3831e2e7a75Shuah 3847c478bd9Sstevel@tonic-gate deccc %g3 /* decr pgcnt */ 3857c478bd9Sstevel@tonic-gate bnz,pt %icc,4b 3867c478bd9Sstevel@tonic-gate add %g1, %g2, %g1 /* next page */ 3877c478bd9Sstevel@tonic-gate retry 3887c478bd9Sstevel@tonic-gate1: 3891e2e7a75Shuah /* 3901e2e7a75Shuah * We need to demap in a user context 3911e2e7a75Shuah * 3921e2e7a75Shuah * g2 = sfmmup 3931e2e7a75Shuah * g3 = pgcnt 3941e2e7a75Shuah */ 3951e2e7a75Shuah SFMMU_CPU_CNUM(%g2, %g5, %g6) ! %g5 = sfmmu cnum on this CPU 3961e2e7a75Shuah 3977c478bd9Sstevel@tonic-gate or DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %g1, %g1 3981e2e7a75Shuah 3991e2e7a75Shuah ldub [%g2 + SFMMU_CEXT], %g4 ! %g4 = sfmmup->cext 4007c478bd9Sstevel@tonic-gate sll %g4, CTXREG_EXT_SHIFT, %g4 4011e2e7a75Shuah or %g5, %g4, %g5 4021e2e7a75Shuah 4037c478bd9Sstevel@tonic-gate set MMU_PCONTEXT, %g4 4041e2e7a75Shuah ldxa [%g4]ASI_DMMU, %g6 /* rd old ctxnum */ 405febcc4a5Sjimand srlx %g6, CTXREG_NEXT_SHIFT, %g2 /* %g2 = nucleus pgsz */ 406febcc4a5Sjimand sllx %g2, CTXREG_NEXT_SHIFT, %g2 /* preserve nucleus pgsz */ 407febcc4a5Sjimand or %g5, %g2, %g5 /* %g5 = nucleus pgsz | primary pgsz | cnum */ 4081e2e7a75Shuah stxa %g5, [%g4]ASI_DMMU /* wr new ctxum */ 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate set MMU_PAGESIZE, %g2 /* g2 = pgsize */ 4111e2e7a75Shuah sethi %hi(FLUSH_ADDR), %g5 4127c478bd9Sstevel@tonic-gate3: 4137c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_DTLB_DEMAP 4147c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_ITLB_DEMAP 4151e2e7a75Shuah flush %g5 ! flush required by immu 4161e2e7a75Shuah 4177c478bd9Sstevel@tonic-gate deccc %g3 /* decr pgcnt */ 4187c478bd9Sstevel@tonic-gate bnz,pt %icc,3b 4197c478bd9Sstevel@tonic-gate add %g1, %g2, %g1 /* next page */ 4207c478bd9Sstevel@tonic-gate 4211e2e7a75Shuah stxa %g6, [%g4]ASI_DMMU /* restore old ctxnum */ 4227c478bd9Sstevel@tonic-gate retry 4237c478bd9Sstevel@tonic-gate SET_SIZE(vtag_flush_pgcnt_tl1) 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate#endif /* lint */ 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate#if defined(lint) 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 4307c478bd9Sstevel@tonic-gatevoid 4317c478bd9Sstevel@tonic-gatevtag_flushall_tl1(uint64_t dummy1, uint64_t dummy2) 4327c478bd9Sstevel@tonic-gate{} 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate#else /* lint */ 4357c478bd9Sstevel@tonic-gate 4367c478bd9Sstevel@tonic-gate ENTRY_NP(vtag_flushall_tl1) 4377c478bd9Sstevel@tonic-gate /* 4387c478bd9Sstevel@tonic-gate * x-trap to flush tlb 4397c478bd9Sstevel@tonic-gate */ 4407c478bd9Sstevel@tonic-gate set DEMAP_ALL_TYPE, %g4 4417c478bd9Sstevel@tonic-gate stxa %g0, [%g4]ASI_DTLB_DEMAP 4427c478bd9Sstevel@tonic-gate stxa %g0, [%g4]ASI_ITLB_DEMAP 4437c478bd9Sstevel@tonic-gate retry 4447c478bd9Sstevel@tonic-gate SET_SIZE(vtag_flushall_tl1) 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate#endif /* lint */ 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate#if defined(lint) 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate/* ARGSUSED */ 4527c478bd9Sstevel@tonic-gatevoid 4537c478bd9Sstevel@tonic-gatevac_flushpage(pfn_t pfnum, int vcolor) 4547c478bd9Sstevel@tonic-gate{} 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate#else /* lint */ 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate/* 4597c478bd9Sstevel@tonic-gate * vac_flushpage(pfnum, color) 4607c478bd9Sstevel@tonic-gate * Flush 1 8k page of the D-$ with physical page = pfnum 4617c478bd9Sstevel@tonic-gate * Algorithm: 4627c478bd9Sstevel@tonic-gate * The cheetah dcache is a 64k psuedo 4 way accaociative cache. 4637c478bd9Sstevel@tonic-gate * It is virtual indexed, physically tagged cache. 4647c478bd9Sstevel@tonic-gate */ 4657c478bd9Sstevel@tonic-gate .seg ".data" 4667c478bd9Sstevel@tonic-gate .align 8 4677c478bd9Sstevel@tonic-gate .global dflush_type 4687c478bd9Sstevel@tonic-gatedflush_type: 4697c478bd9Sstevel@tonic-gate .word FLUSHPAGE_TYPE 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate ENTRY(vac_flushpage) 4727c478bd9Sstevel@tonic-gate /* 4737c478bd9Sstevel@tonic-gate * flush page from the d$ 4747c478bd9Sstevel@tonic-gate * 4757c478bd9Sstevel@tonic-gate * %o0 = pfnum, %o1 = color 4767c478bd9Sstevel@tonic-gate */ 4777c478bd9Sstevel@tonic-gate DCACHE_FLUSHPAGE(%o0, %o1, %o2, %o3, %o4) 4787c478bd9Sstevel@tonic-gate retl 4797c478bd9Sstevel@tonic-gate nop 4807c478bd9Sstevel@tonic-gate SET_SIZE(vac_flushpage) 4817c478bd9Sstevel@tonic-gate 4827c478bd9Sstevel@tonic-gate#endif /* lint */ 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate 4857c478bd9Sstevel@tonic-gate#if defined(lint) 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate/* ARGSUSED */ 4887c478bd9Sstevel@tonic-gatevoid 4897c478bd9Sstevel@tonic-gatevac_flushpage_tl1(uint64_t pfnum, uint64_t vcolor) 4907c478bd9Sstevel@tonic-gate{} 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate#else /* lint */ 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate ENTRY_NP(vac_flushpage_tl1) 4957c478bd9Sstevel@tonic-gate /* 4967c478bd9Sstevel@tonic-gate * x-trap to flush page from the d$ 4977c478bd9Sstevel@tonic-gate * 4987c478bd9Sstevel@tonic-gate * %g1 = pfnum, %g2 = color 4997c478bd9Sstevel@tonic-gate */ 5007c478bd9Sstevel@tonic-gate DCACHE_FLUSHPAGE(%g1, %g2, %g3, %g4, %g5) 5017c478bd9Sstevel@tonic-gate retry 5027c478bd9Sstevel@tonic-gate SET_SIZE(vac_flushpage_tl1) 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate#endif /* lint */ 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate#if defined(lint) 5087c478bd9Sstevel@tonic-gate 5097c478bd9Sstevel@tonic-gate/* ARGSUSED */ 5107c478bd9Sstevel@tonic-gatevoid 5117c478bd9Sstevel@tonic-gatevac_flushcolor(int vcolor, pfn_t pfnum) 5127c478bd9Sstevel@tonic-gate{} 5137c478bd9Sstevel@tonic-gate 5147c478bd9Sstevel@tonic-gate#else /* lint */ 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate ENTRY(vac_flushcolor) 5177c478bd9Sstevel@tonic-gate /* 518444ce08eSDonghai Qiao * %o0 = vcolor 5197c478bd9Sstevel@tonic-gate */ 520444ce08eSDonghai Qiao DCACHE_FLUSHCOLOR(%o0, 0, %o1, %o2, %o3) 521444ce08eSDonghai Qiao DCACHE_FLUSHCOLOR(%o0, 1, %o1, %o2, %o3) 522444ce08eSDonghai Qiao DCACHE_FLUSHCOLOR(%o0, 2, %o1, %o2, %o3) 523444ce08eSDonghai Qiao DCACHE_FLUSHCOLOR(%o0, 3, %o1, %o2, %o3) 5247c478bd9Sstevel@tonic-gate retl 5257c478bd9Sstevel@tonic-gate nop 5267c478bd9Sstevel@tonic-gate SET_SIZE(vac_flushcolor) 5277c478bd9Sstevel@tonic-gate 5287c478bd9Sstevel@tonic-gate#endif /* lint */ 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate#if defined(lint) 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate/* ARGSUSED */ 5347c478bd9Sstevel@tonic-gatevoid 5357c478bd9Sstevel@tonic-gatevac_flushcolor_tl1(uint64_t vcolor, uint64_t pfnum) 5367c478bd9Sstevel@tonic-gate{} 5377c478bd9Sstevel@tonic-gate 5387c478bd9Sstevel@tonic-gate#else /* lint */ 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate ENTRY(vac_flushcolor_tl1) 5417c478bd9Sstevel@tonic-gate /* 5427c478bd9Sstevel@tonic-gate * %g1 = vcolor 5437c478bd9Sstevel@tonic-gate */ 544444ce08eSDonghai Qiao DCACHE_FLUSHCOLOR(%g1, 0, %g2, %g3, %g4) 545444ce08eSDonghai Qiao DCACHE_FLUSHCOLOR(%g1, 1, %g2, %g3, %g4) 546444ce08eSDonghai Qiao DCACHE_FLUSHCOLOR(%g1, 2, %g2, %g3, %g4) 547444ce08eSDonghai Qiao DCACHE_FLUSHCOLOR(%g1, 3, %g2, %g3, %g4) 5487c478bd9Sstevel@tonic-gate retry 5497c478bd9Sstevel@tonic-gate SET_SIZE(vac_flushcolor_tl1) 5507c478bd9Sstevel@tonic-gate 5517c478bd9Sstevel@tonic-gate#endif /* lint */ 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate#if defined(lint) 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gateint 5567c478bd9Sstevel@tonic-gateidsr_busy(void) 5577c478bd9Sstevel@tonic-gate{ 5587c478bd9Sstevel@tonic-gate return (0); 5597c478bd9Sstevel@tonic-gate} 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate#else /* lint */ 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate/* 5647c478bd9Sstevel@tonic-gate * Determine whether or not the IDSR is busy. 5657c478bd9Sstevel@tonic-gate * Entry: no arguments 5667c478bd9Sstevel@tonic-gate * Returns: 1 if busy, 0 otherwise 5677c478bd9Sstevel@tonic-gate */ 5687c478bd9Sstevel@tonic-gate ENTRY(idsr_busy) 5697c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_INTR_DISPATCH_STATUS, %g1 5707c478bd9Sstevel@tonic-gate clr %o0 5717c478bd9Sstevel@tonic-gate btst IDSR_BUSY, %g1 5727c478bd9Sstevel@tonic-gate bz,a,pt %xcc, 1f 5737c478bd9Sstevel@tonic-gate mov 1, %o0 5747c478bd9Sstevel@tonic-gate1: 5757c478bd9Sstevel@tonic-gate retl 5767c478bd9Sstevel@tonic-gate nop 5777c478bd9Sstevel@tonic-gate SET_SIZE(idsr_busy) 5787c478bd9Sstevel@tonic-gate 5797c478bd9Sstevel@tonic-gate#endif /* lint */ 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate#if defined(lint) 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate/* ARGSUSED */ 5847c478bd9Sstevel@tonic-gatevoid 5857c478bd9Sstevel@tonic-gateinit_mondo(xcfunc_t *func, uint64_t arg1, uint64_t arg2) 5867c478bd9Sstevel@tonic-gate{} 5877c478bd9Sstevel@tonic-gate 5887c478bd9Sstevel@tonic-gate/* ARGSUSED */ 5897c478bd9Sstevel@tonic-gatevoid 5907c478bd9Sstevel@tonic-gateinit_mondo_nocheck(xcfunc_t *func, uint64_t arg1, uint64_t arg2) 5917c478bd9Sstevel@tonic-gate{} 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate#else /* lint */ 5947c478bd9Sstevel@tonic-gate 5957c478bd9Sstevel@tonic-gate .global _dispatch_status_busy 5967c478bd9Sstevel@tonic-gate_dispatch_status_busy: 5977c478bd9Sstevel@tonic-gate .asciz "ASI_INTR_DISPATCH_STATUS error: busy" 5987c478bd9Sstevel@tonic-gate .align 4 5997c478bd9Sstevel@tonic-gate 6007c478bd9Sstevel@tonic-gate/* 6017c478bd9Sstevel@tonic-gate * Setup interrupt dispatch data registers 6027c478bd9Sstevel@tonic-gate * Entry: 6037c478bd9Sstevel@tonic-gate * %o0 - function or inumber to call 6047c478bd9Sstevel@tonic-gate * %o1, %o2 - arguments (2 uint64_t's) 6057c478bd9Sstevel@tonic-gate */ 6067c478bd9Sstevel@tonic-gate .seg "text" 6077c478bd9Sstevel@tonic-gate 6087c478bd9Sstevel@tonic-gate ENTRY(init_mondo) 6097c478bd9Sstevel@tonic-gate#ifdef DEBUG 6107c478bd9Sstevel@tonic-gate ! 6117c478bd9Sstevel@tonic-gate ! IDSR should not be busy at the moment 6127c478bd9Sstevel@tonic-gate ! 6137c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_INTR_DISPATCH_STATUS, %g1 6147c478bd9Sstevel@tonic-gate btst IDSR_BUSY, %g1 6157c478bd9Sstevel@tonic-gate bz,pt %xcc, 1f 6167c478bd9Sstevel@tonic-gate nop 6177c478bd9Sstevel@tonic-gate sethi %hi(_dispatch_status_busy), %o0 6187c478bd9Sstevel@tonic-gate call panic 6197c478bd9Sstevel@tonic-gate or %o0, %lo(_dispatch_status_busy), %o0 6207c478bd9Sstevel@tonic-gate#endif /* DEBUG */ 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate ALTENTRY(init_mondo_nocheck) 6237c478bd9Sstevel@tonic-gate ! 6247c478bd9Sstevel@tonic-gate ! interrupt vector dispatch data reg 0 6257c478bd9Sstevel@tonic-gate ! 6267c478bd9Sstevel@tonic-gate1: 6277c478bd9Sstevel@tonic-gate mov IDDR_0, %g1 6287c478bd9Sstevel@tonic-gate mov IDDR_1, %g2 6297c478bd9Sstevel@tonic-gate mov IDDR_2, %g3 6307c478bd9Sstevel@tonic-gate stxa %o0, [%g1]ASI_INTR_DISPATCH 6317c478bd9Sstevel@tonic-gate 6327c478bd9Sstevel@tonic-gate ! 6337c478bd9Sstevel@tonic-gate ! interrupt vector dispatch data reg 1 6347c478bd9Sstevel@tonic-gate ! 6357c478bd9Sstevel@tonic-gate stxa %o1, [%g2]ASI_INTR_DISPATCH 6367c478bd9Sstevel@tonic-gate 6377c478bd9Sstevel@tonic-gate ! 6387c478bd9Sstevel@tonic-gate ! interrupt vector dispatch data reg 2 6397c478bd9Sstevel@tonic-gate ! 6407c478bd9Sstevel@tonic-gate stxa %o2, [%g3]ASI_INTR_DISPATCH 6417c478bd9Sstevel@tonic-gate 6427c478bd9Sstevel@tonic-gate membar #Sync 6437c478bd9Sstevel@tonic-gate retl 6447c478bd9Sstevel@tonic-gate nop 6457c478bd9Sstevel@tonic-gate SET_SIZE(init_mondo_nocheck) 6467c478bd9Sstevel@tonic-gate SET_SIZE(init_mondo) 6477c478bd9Sstevel@tonic-gate 6487c478bd9Sstevel@tonic-gate#endif /* lint */ 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate#if !(defined(JALAPENO) || defined(SERRANO)) 6527c478bd9Sstevel@tonic-gate 6537c478bd9Sstevel@tonic-gate#if defined(lint) 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate/* ARGSUSED */ 6567c478bd9Sstevel@tonic-gatevoid 6577c478bd9Sstevel@tonic-gateshipit(int upaid, int bn) 6587c478bd9Sstevel@tonic-gate{ return; } 6597c478bd9Sstevel@tonic-gate 6607c478bd9Sstevel@tonic-gate#else /* lint */ 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate/* 6637c478bd9Sstevel@tonic-gate * Ship mondo to aid using busy/nack pair bn 6647c478bd9Sstevel@tonic-gate */ 6657c478bd9Sstevel@tonic-gate ENTRY_NP(shipit) 6667c478bd9Sstevel@tonic-gate sll %o0, IDCR_PID_SHIFT, %g1 ! IDCR<18:14> = agent id 6677c478bd9Sstevel@tonic-gate sll %o1, IDCR_BN_SHIFT, %g2 ! IDCR<28:24> = b/n pair 6687c478bd9Sstevel@tonic-gate or %g1, IDCR_OFFSET, %g1 ! IDCR<13:0> = 0x70 6697c478bd9Sstevel@tonic-gate or %g1, %g2, %g1 6707c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_INTR_DISPATCH ! interrupt vector dispatch 6717c478bd9Sstevel@tonic-gate membar #Sync 6727c478bd9Sstevel@tonic-gate retl 6737c478bd9Sstevel@tonic-gate nop 6747c478bd9Sstevel@tonic-gate SET_SIZE(shipit) 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate#endif /* lint */ 6777c478bd9Sstevel@tonic-gate 6787c478bd9Sstevel@tonic-gate#endif /* !(JALAPENO || SERRANO) */ 6797c478bd9Sstevel@tonic-gate 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate#if defined(lint) 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate/* ARGSUSED */ 6847c478bd9Sstevel@tonic-gatevoid 6857c478bd9Sstevel@tonic-gateflush_instr_mem(caddr_t vaddr, size_t len) 6867c478bd9Sstevel@tonic-gate{} 6877c478bd9Sstevel@tonic-gate 6887c478bd9Sstevel@tonic-gate#else /* lint */ 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate/* 6917c478bd9Sstevel@tonic-gate * flush_instr_mem: 6927c478bd9Sstevel@tonic-gate * Flush 1 page of the I-$ starting at vaddr 6937c478bd9Sstevel@tonic-gate * %o0 vaddr 6947c478bd9Sstevel@tonic-gate * %o1 bytes to be flushed 6957c478bd9Sstevel@tonic-gate * UltraSPARC-III maintains consistency of the on-chip Instruction Cache with 6967c478bd9Sstevel@tonic-gate * the stores from all processors so that a FLUSH instruction is only needed 6977c478bd9Sstevel@tonic-gate * to ensure pipeline is consistent. This means a single flush is sufficient at 6987c478bd9Sstevel@tonic-gate * the end of a sequence of stores that updates the instruction stream to 6997c478bd9Sstevel@tonic-gate * ensure correct operation. 7007c478bd9Sstevel@tonic-gate */ 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate ENTRY(flush_instr_mem) 70363360950Smp204432 flush %o0 ! address irrelevant 7047c478bd9Sstevel@tonic-gate retl 7057c478bd9Sstevel@tonic-gate nop 7067c478bd9Sstevel@tonic-gate SET_SIZE(flush_instr_mem) 7077c478bd9Sstevel@tonic-gate 7087c478bd9Sstevel@tonic-gate#endif /* lint */ 7097c478bd9Sstevel@tonic-gate 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate#if defined(CPU_IMP_ECACHE_ASSOC) 7127c478bd9Sstevel@tonic-gate 7137c478bd9Sstevel@tonic-gate#if defined(lint) 7147c478bd9Sstevel@tonic-gate 7157c478bd9Sstevel@tonic-gate/* ARGSUSED */ 7167c478bd9Sstevel@tonic-gateuint64_t 7177c478bd9Sstevel@tonic-gateget_ecache_ctrl(void) 7187c478bd9Sstevel@tonic-gate{ return (0); } 7197c478bd9Sstevel@tonic-gate 7207c478bd9Sstevel@tonic-gate#else /* lint */ 7217c478bd9Sstevel@tonic-gate 7227c478bd9Sstevel@tonic-gate ENTRY(get_ecache_ctrl) 7237c478bd9Sstevel@tonic-gate GET_CPU_IMPL(%o0) 7247c478bd9Sstevel@tonic-gate cmp %o0, JAGUAR_IMPL 7257c478bd9Sstevel@tonic-gate ! 7267c478bd9Sstevel@tonic-gate ! Putting an ASI access in the delay slot may 7277c478bd9Sstevel@tonic-gate ! cause it to be accessed, even when annulled. 7287c478bd9Sstevel@tonic-gate ! 7297c478bd9Sstevel@tonic-gate bne 1f 7307c478bd9Sstevel@tonic-gate nop 7317c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_EC_CFG_TIMING, %o0 ! read Jaguar shared E$ ctrl reg 7327c478bd9Sstevel@tonic-gate b 2f 7337c478bd9Sstevel@tonic-gate nop 7347c478bd9Sstevel@tonic-gate1: 7357c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_EC_CTRL, %o0 ! read Ch/Ch+ E$ control reg 7367c478bd9Sstevel@tonic-gate2: 7377c478bd9Sstevel@tonic-gate retl 7387c478bd9Sstevel@tonic-gate nop 7397c478bd9Sstevel@tonic-gate SET_SIZE(get_ecache_ctrl) 7407c478bd9Sstevel@tonic-gate 7417c478bd9Sstevel@tonic-gate#endif /* lint */ 7427c478bd9Sstevel@tonic-gate 7437c478bd9Sstevel@tonic-gate#endif /* CPU_IMP_ECACHE_ASSOC */ 7447c478bd9Sstevel@tonic-gate 7457c478bd9Sstevel@tonic-gate 7467c478bd9Sstevel@tonic-gate#if !(defined(JALAPENO) || defined(SERRANO)) 7477c478bd9Sstevel@tonic-gate 7487c478bd9Sstevel@tonic-gate/* 7497c478bd9Sstevel@tonic-gate * flush_ecache: 7507c478bd9Sstevel@tonic-gate * %o0 - 64 bit physical address 7517c478bd9Sstevel@tonic-gate * %o1 - ecache size 7527c478bd9Sstevel@tonic-gate * %o2 - ecache linesize 7537c478bd9Sstevel@tonic-gate */ 7547c478bd9Sstevel@tonic-gate#if defined(lint) 7557c478bd9Sstevel@tonic-gate 7567c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 7577c478bd9Sstevel@tonic-gatevoid 7587c478bd9Sstevel@tonic-gateflush_ecache(uint64_t physaddr, size_t ecache_size, size_t ecache_linesize) 7597c478bd9Sstevel@tonic-gate{} 7607c478bd9Sstevel@tonic-gate 7617c478bd9Sstevel@tonic-gate#else /* !lint */ 7627c478bd9Sstevel@tonic-gate 7637c478bd9Sstevel@tonic-gate ENTRY(flush_ecache) 7647c478bd9Sstevel@tonic-gate 7657c478bd9Sstevel@tonic-gate /* 7667c478bd9Sstevel@tonic-gate * For certain CPU implementations, we have to flush the L2 cache 7677c478bd9Sstevel@tonic-gate * before flushing the ecache. 7687c478bd9Sstevel@tonic-gate */ 7697c478bd9Sstevel@tonic-gate PN_L2_FLUSHALL(%g3, %g4, %g5) 7707c478bd9Sstevel@tonic-gate 7717c478bd9Sstevel@tonic-gate /* 7727c478bd9Sstevel@tonic-gate * Flush the entire Ecache using displacement flush. 7737c478bd9Sstevel@tonic-gate */ 7747c478bd9Sstevel@tonic-gate ECACHE_FLUSHALL(%o1, %o2, %o0, %o4) 7757c478bd9Sstevel@tonic-gate 7767c478bd9Sstevel@tonic-gate retl 7777c478bd9Sstevel@tonic-gate nop 7787c478bd9Sstevel@tonic-gate SET_SIZE(flush_ecache) 7797c478bd9Sstevel@tonic-gate 7807c478bd9Sstevel@tonic-gate#endif /* lint */ 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate#endif /* !(JALAPENO || SERRANO) */ 7837c478bd9Sstevel@tonic-gate 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate#if defined(lint) 7867c478bd9Sstevel@tonic-gate 7877c478bd9Sstevel@tonic-gatevoid 7887c478bd9Sstevel@tonic-gateflush_dcache(void) 7897c478bd9Sstevel@tonic-gate{} 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate#else /* lint */ 7927c478bd9Sstevel@tonic-gate 7937c478bd9Sstevel@tonic-gate ENTRY(flush_dcache) 7947c478bd9Sstevel@tonic-gate ASM_LD(%o0, dcache_size) 7957c478bd9Sstevel@tonic-gate ASM_LD(%o1, dcache_linesize) 7967c478bd9Sstevel@tonic-gate CH_DCACHE_FLUSHALL(%o0, %o1, %o2) 7977c478bd9Sstevel@tonic-gate retl 7987c478bd9Sstevel@tonic-gate nop 7997c478bd9Sstevel@tonic-gate SET_SIZE(flush_dcache) 8007c478bd9Sstevel@tonic-gate 8017c478bd9Sstevel@tonic-gate#endif /* lint */ 8027c478bd9Sstevel@tonic-gate 8037c478bd9Sstevel@tonic-gate 8047c478bd9Sstevel@tonic-gate#if defined(lint) 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gatevoid 8077c478bd9Sstevel@tonic-gateflush_icache(void) 8087c478bd9Sstevel@tonic-gate{} 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate#else /* lint */ 8117c478bd9Sstevel@tonic-gate 8127c478bd9Sstevel@tonic-gate ENTRY(flush_icache) 8137c478bd9Sstevel@tonic-gate GET_CPU_PRIVATE_PTR(%g0, %o0, %o2, flush_icache_1); 8147c478bd9Sstevel@tonic-gate ld [%o0 + CHPR_ICACHE_LINESIZE], %o1 8157c478bd9Sstevel@tonic-gate ba,pt %icc, 2f 8167c478bd9Sstevel@tonic-gate ld [%o0 + CHPR_ICACHE_SIZE], %o0 8177c478bd9Sstevel@tonic-gateflush_icache_1: 8187c478bd9Sstevel@tonic-gate ASM_LD(%o0, icache_size) 8197c478bd9Sstevel@tonic-gate ASM_LD(%o1, icache_linesize) 8207c478bd9Sstevel@tonic-gate2: 8217c478bd9Sstevel@tonic-gate CH_ICACHE_FLUSHALL(%o0, %o1, %o2, %o4) 8227c478bd9Sstevel@tonic-gate retl 8237c478bd9Sstevel@tonic-gate nop 8247c478bd9Sstevel@tonic-gate SET_SIZE(flush_icache) 8257c478bd9Sstevel@tonic-gate 8267c478bd9Sstevel@tonic-gate#endif /* lint */ 8277c478bd9Sstevel@tonic-gate 8287c478bd9Sstevel@tonic-gate#if defined(lint) 8297c478bd9Sstevel@tonic-gate 8307c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 8317c478bd9Sstevel@tonic-gatevoid 8327c478bd9Sstevel@tonic-gatekdi_flush_idcache(int dcache_size, int dcache_lsize, int icache_size, 8337c478bd9Sstevel@tonic-gate int icache_lsize) 8347c478bd9Sstevel@tonic-gate{ 8357c478bd9Sstevel@tonic-gate} 8367c478bd9Sstevel@tonic-gate 8377c478bd9Sstevel@tonic-gate#else /* lint */ 8387c478bd9Sstevel@tonic-gate 8397c478bd9Sstevel@tonic-gate ENTRY(kdi_flush_idcache) 8407c478bd9Sstevel@tonic-gate CH_DCACHE_FLUSHALL(%o0, %o1, %g1) 8417c478bd9Sstevel@tonic-gate CH_ICACHE_FLUSHALL(%o2, %o3, %g1, %g2) 8427c478bd9Sstevel@tonic-gate membar #Sync 8437c478bd9Sstevel@tonic-gate retl 8447c478bd9Sstevel@tonic-gate nop 8457c478bd9Sstevel@tonic-gate SET_SIZE(kdi_flush_idcache) 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate#endif /* lint */ 8487c478bd9Sstevel@tonic-gate 8497c478bd9Sstevel@tonic-gate#if defined(lint) 8507c478bd9Sstevel@tonic-gate 8517c478bd9Sstevel@tonic-gatevoid 8527c478bd9Sstevel@tonic-gateflush_pcache(void) 8537c478bd9Sstevel@tonic-gate{} 8547c478bd9Sstevel@tonic-gate 8557c478bd9Sstevel@tonic-gate#else /* lint */ 8567c478bd9Sstevel@tonic-gate 8577c478bd9Sstevel@tonic-gate ENTRY(flush_pcache) 8587c478bd9Sstevel@tonic-gate PCACHE_FLUSHALL(%o0, %o1, %o2) 8597c478bd9Sstevel@tonic-gate retl 8607c478bd9Sstevel@tonic-gate nop 8617c478bd9Sstevel@tonic-gate SET_SIZE(flush_pcache) 8627c478bd9Sstevel@tonic-gate 8637c478bd9Sstevel@tonic-gate#endif /* lint */ 8647c478bd9Sstevel@tonic-gate 8657c478bd9Sstevel@tonic-gate 8667c478bd9Sstevel@tonic-gate#if defined(CPU_IMP_L1_CACHE_PARITY) 8677c478bd9Sstevel@tonic-gate 8687c478bd9Sstevel@tonic-gate#if defined(lint) 8697c478bd9Sstevel@tonic-gate 8707c478bd9Sstevel@tonic-gate/* ARGSUSED */ 8717c478bd9Sstevel@tonic-gatevoid 8727c478bd9Sstevel@tonic-gateget_dcache_dtag(uint32_t dcache_idx, uint64_t *data) 8737c478bd9Sstevel@tonic-gate{} 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate#else /* lint */ 8767c478bd9Sstevel@tonic-gate 8777c478bd9Sstevel@tonic-gate/* 8787c478bd9Sstevel@tonic-gate * Get dcache data and tag. The Dcache data is a pointer to a ch_dc_data_t 8797c478bd9Sstevel@tonic-gate * structure (see cheetahregs.h): 8807c478bd9Sstevel@tonic-gate * The Dcache *should* be turned off when this code is executed. 8817c478bd9Sstevel@tonic-gate */ 8827c478bd9Sstevel@tonic-gate .align 128 8837c478bd9Sstevel@tonic-gate ENTRY(get_dcache_dtag) 8847c478bd9Sstevel@tonic-gate rdpr %pstate, %o5 8857c478bd9Sstevel@tonic-gate andn %o5, PSTATE_IE | PSTATE_AM, %o3 8867c478bd9Sstevel@tonic-gate wrpr %g0, %o3, %pstate 8877c478bd9Sstevel@tonic-gate b 1f 8887c478bd9Sstevel@tonic-gate stx %o0, [%o1 + CH_DC_IDX] 8897c478bd9Sstevel@tonic-gate 8907c478bd9Sstevel@tonic-gate .align 128 8917c478bd9Sstevel@tonic-gate1: 8927c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_DC_TAG, %o2 8937c478bd9Sstevel@tonic-gate stx %o2, [%o1 + CH_DC_TAG] 8947c478bd9Sstevel@tonic-gate membar #Sync 8957c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_DC_UTAG, %o2 8967c478bd9Sstevel@tonic-gate membar #Sync 8977c478bd9Sstevel@tonic-gate stx %o2, [%o1 + CH_DC_UTAG] 8987c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_DC_SNP_TAG, %o2 8997c478bd9Sstevel@tonic-gate stx %o2, [%o1 + CH_DC_SNTAG] 9007c478bd9Sstevel@tonic-gate add %o1, CH_DC_DATA, %o1 9017c478bd9Sstevel@tonic-gate clr %o3 9027c478bd9Sstevel@tonic-gate2: 9037c478bd9Sstevel@tonic-gate membar #Sync ! required before ASI_DC_DATA 9047c478bd9Sstevel@tonic-gate ldxa [%o0 + %o3]ASI_DC_DATA, %o2 9057c478bd9Sstevel@tonic-gate membar #Sync ! required after ASI_DC_DATA 9067c478bd9Sstevel@tonic-gate stx %o2, [%o1 + %o3] 9077c478bd9Sstevel@tonic-gate cmp %o3, CH_DC_DATA_REG_SIZE - 8 9087c478bd9Sstevel@tonic-gate blt 2b 9097c478bd9Sstevel@tonic-gate add %o3, 8, %o3 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate /* 9127c478bd9Sstevel@tonic-gate * Unlike other CPUs in the family, D$ data parity bits for Panther 9137c478bd9Sstevel@tonic-gate * do not reside in the microtag. Instead, we have to read them 9147c478bd9Sstevel@tonic-gate * using the DC_data_parity bit of ASI_DCACHE_DATA. Also, instead 9157c478bd9Sstevel@tonic-gate * of just having 8 parity bits to protect all 32 bytes of data 9167c478bd9Sstevel@tonic-gate * per line, we now have 32 bits of parity. 9177c478bd9Sstevel@tonic-gate */ 9187c478bd9Sstevel@tonic-gate GET_CPU_IMPL(%o3) 9197c478bd9Sstevel@tonic-gate cmp %o3, PANTHER_IMPL 9207c478bd9Sstevel@tonic-gate bne 4f 9217c478bd9Sstevel@tonic-gate clr %o3 9227c478bd9Sstevel@tonic-gate 9237c478bd9Sstevel@tonic-gate /* 9247c478bd9Sstevel@tonic-gate * move our pointer to the next field where we store parity bits 9257c478bd9Sstevel@tonic-gate * and add the offset of the last parity byte since we will be 9267c478bd9Sstevel@tonic-gate * storing all 4 parity bytes within one 64 bit field like this: 9277c478bd9Sstevel@tonic-gate * 9287c478bd9Sstevel@tonic-gate * +------+------------+------------+------------+------------+ 9297c478bd9Sstevel@tonic-gate * | - | DC_parity | DC_parity | DC_parity | DC_parity | 9307c478bd9Sstevel@tonic-gate * | - | for word 3 | for word 2 | for word 1 | for word 0 | 9317c478bd9Sstevel@tonic-gate * +------+------------+------------+------------+------------+ 9327c478bd9Sstevel@tonic-gate * 63:32 31:24 23:16 15:8 7:0 9337c478bd9Sstevel@tonic-gate */ 9347c478bd9Sstevel@tonic-gate add %o1, CH_DC_PN_DATA_PARITY - CH_DC_DATA + 7, %o1 9357c478bd9Sstevel@tonic-gate 9367c478bd9Sstevel@tonic-gate /* add the DC_data_parity bit into our working index */ 9377c478bd9Sstevel@tonic-gate mov 1, %o2 9387c478bd9Sstevel@tonic-gate sll %o2, PN_DC_DATA_PARITY_BIT_SHIFT, %o2 9397c478bd9Sstevel@tonic-gate or %o0, %o2, %o0 9407c478bd9Sstevel@tonic-gate3: 9417c478bd9Sstevel@tonic-gate membar #Sync ! required before ASI_DC_DATA 9427c478bd9Sstevel@tonic-gate ldxa [%o0 + %o3]ASI_DC_DATA, %o2 9437c478bd9Sstevel@tonic-gate membar #Sync ! required after ASI_DC_DATA 9447c478bd9Sstevel@tonic-gate stb %o2, [%o1] 9457c478bd9Sstevel@tonic-gate dec %o1 9467c478bd9Sstevel@tonic-gate cmp %o3, CH_DC_DATA_REG_SIZE - 8 9477c478bd9Sstevel@tonic-gate blt 3b 9487c478bd9Sstevel@tonic-gate add %o3, 8, %o3 9497c478bd9Sstevel@tonic-gate4: 9507c478bd9Sstevel@tonic-gate retl 9517c478bd9Sstevel@tonic-gate wrpr %g0, %o5, %pstate 9527c478bd9Sstevel@tonic-gate SET_SIZE(get_dcache_dtag) 9537c478bd9Sstevel@tonic-gate 9547c478bd9Sstevel@tonic-gate#endif /* lint */ 9557c478bd9Sstevel@tonic-gate 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate#if defined(lint) 9587c478bd9Sstevel@tonic-gate 9597c478bd9Sstevel@tonic-gate/* ARGSUSED */ 9607c478bd9Sstevel@tonic-gatevoid 9617c478bd9Sstevel@tonic-gateget_icache_dtag(uint32_t ecache_idx, uint64_t *data) 9627c478bd9Sstevel@tonic-gate{} 9637c478bd9Sstevel@tonic-gate 9647c478bd9Sstevel@tonic-gate#else /* lint */ 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate/* 9677c478bd9Sstevel@tonic-gate * Get icache data and tag. The data argument is a pointer to a ch_ic_data_t 9687c478bd9Sstevel@tonic-gate * structure (see cheetahregs.h): 9697c478bd9Sstevel@tonic-gate * The Icache *Must* be turned off when this function is called. 9707c478bd9Sstevel@tonic-gate * This is because diagnostic accesses to the Icache interfere with cache 9717c478bd9Sstevel@tonic-gate * consistency. 9727c478bd9Sstevel@tonic-gate */ 9737c478bd9Sstevel@tonic-gate .align 128 9747c478bd9Sstevel@tonic-gate ENTRY(get_icache_dtag) 9757c478bd9Sstevel@tonic-gate rdpr %pstate, %o5 9767c478bd9Sstevel@tonic-gate andn %o5, PSTATE_IE | PSTATE_AM, %o3 9777c478bd9Sstevel@tonic-gate wrpr %g0, %o3, %pstate 9787c478bd9Sstevel@tonic-gate 9797c478bd9Sstevel@tonic-gate stx %o0, [%o1 + CH_IC_IDX] 9807c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_IC_TAG, %o2 9817c478bd9Sstevel@tonic-gate stx %o2, [%o1 + CH_IC_PATAG] 9827c478bd9Sstevel@tonic-gate add %o0, CH_ICTAG_UTAG, %o0 9837c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_IC_TAG, %o2 9847c478bd9Sstevel@tonic-gate add %o0, (CH_ICTAG_UPPER - CH_ICTAG_UTAG), %o0 9857c478bd9Sstevel@tonic-gate stx %o2, [%o1 + CH_IC_UTAG] 9867c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_IC_TAG, %o2 9877c478bd9Sstevel@tonic-gate add %o0, (CH_ICTAG_LOWER - CH_ICTAG_UPPER), %o0 9887c478bd9Sstevel@tonic-gate stx %o2, [%o1 + CH_IC_UPPER] 9897c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_IC_TAG, %o2 9907c478bd9Sstevel@tonic-gate andn %o0, CH_ICTAG_TMASK, %o0 9917c478bd9Sstevel@tonic-gate stx %o2, [%o1 + CH_IC_LOWER] 9927c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_IC_SNP_TAG, %o2 9937c478bd9Sstevel@tonic-gate stx %o2, [%o1 + CH_IC_SNTAG] 9947c478bd9Sstevel@tonic-gate add %o1, CH_IC_DATA, %o1 9957c478bd9Sstevel@tonic-gate clr %o3 9967c478bd9Sstevel@tonic-gate2: 9977c478bd9Sstevel@tonic-gate ldxa [%o0 + %o3]ASI_IC_DATA, %o2 9987c478bd9Sstevel@tonic-gate stx %o2, [%o1 + %o3] 9997c478bd9Sstevel@tonic-gate cmp %o3, PN_IC_DATA_REG_SIZE - 8 10007c478bd9Sstevel@tonic-gate blt 2b 10017c478bd9Sstevel@tonic-gate add %o3, 8, %o3 10027c478bd9Sstevel@tonic-gate 10037c478bd9Sstevel@tonic-gate retl 10047c478bd9Sstevel@tonic-gate wrpr %g0, %o5, %pstate 10057c478bd9Sstevel@tonic-gate SET_SIZE(get_icache_dtag) 10067c478bd9Sstevel@tonic-gate 10077c478bd9Sstevel@tonic-gate#endif /* lint */ 10087c478bd9Sstevel@tonic-gate 10097c478bd9Sstevel@tonic-gate#if defined(lint) 10107c478bd9Sstevel@tonic-gate 10117c478bd9Sstevel@tonic-gate/* ARGSUSED */ 10127c478bd9Sstevel@tonic-gatevoid 10137c478bd9Sstevel@tonic-gateget_pcache_dtag(uint32_t pcache_idx, uint64_t *data) 10147c478bd9Sstevel@tonic-gate{} 10157c478bd9Sstevel@tonic-gate 10167c478bd9Sstevel@tonic-gate#else /* lint */ 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate/* 10197c478bd9Sstevel@tonic-gate * Get pcache data and tags. 10207c478bd9Sstevel@tonic-gate * inputs: 10217c478bd9Sstevel@tonic-gate * pcache_idx - fully constructed VA for for accessing P$ diagnostic 10227c478bd9Sstevel@tonic-gate * registers. Contains PC_way and PC_addr shifted into 10237c478bd9Sstevel@tonic-gate * the correct bit positions. See the PRM for more details. 10247c478bd9Sstevel@tonic-gate * data - pointer to a ch_pc_data_t 10257c478bd9Sstevel@tonic-gate * structure (see cheetahregs.h): 10267c478bd9Sstevel@tonic-gate */ 10277c478bd9Sstevel@tonic-gate .align 128 10287c478bd9Sstevel@tonic-gate ENTRY(get_pcache_dtag) 10297c478bd9Sstevel@tonic-gate rdpr %pstate, %o5 10307c478bd9Sstevel@tonic-gate andn %o5, PSTATE_IE | PSTATE_AM, %o3 10317c478bd9Sstevel@tonic-gate wrpr %g0, %o3, %pstate 10327c478bd9Sstevel@tonic-gate 10337c478bd9Sstevel@tonic-gate stx %o0, [%o1 + CH_PC_IDX] 10347c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_PC_STATUS_DATA, %o2 10357c478bd9Sstevel@tonic-gate stx %o2, [%o1 + CH_PC_STATUS] 10367c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_PC_TAG, %o2 10377c478bd9Sstevel@tonic-gate stx %o2, [%o1 + CH_PC_TAG] 10387c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_PC_SNP_TAG, %o2 10397c478bd9Sstevel@tonic-gate stx %o2, [%o1 + CH_PC_SNTAG] 10407c478bd9Sstevel@tonic-gate add %o1, CH_PC_DATA, %o1 10417c478bd9Sstevel@tonic-gate clr %o3 10427c478bd9Sstevel@tonic-gate2: 10437c478bd9Sstevel@tonic-gate ldxa [%o0 + %o3]ASI_PC_DATA, %o2 10447c478bd9Sstevel@tonic-gate stx %o2, [%o1 + %o3] 10457c478bd9Sstevel@tonic-gate cmp %o3, CH_PC_DATA_REG_SIZE - 8 10467c478bd9Sstevel@tonic-gate blt 2b 10477c478bd9Sstevel@tonic-gate add %o3, 8, %o3 10487c478bd9Sstevel@tonic-gate 10497c478bd9Sstevel@tonic-gate retl 10507c478bd9Sstevel@tonic-gate wrpr %g0, %o5, %pstate 10517c478bd9Sstevel@tonic-gate SET_SIZE(get_pcache_dtag) 10527c478bd9Sstevel@tonic-gate 10537c478bd9Sstevel@tonic-gate#endif /* lint */ 10547c478bd9Sstevel@tonic-gate 10557c478bd9Sstevel@tonic-gate#endif /* CPU_IMP_L1_CACHE_PARITY */ 10567c478bd9Sstevel@tonic-gate 10577c478bd9Sstevel@tonic-gate#if defined(lint) 10587c478bd9Sstevel@tonic-gate 10597c478bd9Sstevel@tonic-gate/* ARGSUSED */ 10607c478bd9Sstevel@tonic-gatevoid 10617c478bd9Sstevel@tonic-gateset_dcu(uint64_t dcu) 10627c478bd9Sstevel@tonic-gate{} 10637c478bd9Sstevel@tonic-gate 10647c478bd9Sstevel@tonic-gate#else /* lint */ 10657c478bd9Sstevel@tonic-gate 10667c478bd9Sstevel@tonic-gate/* 10677c478bd9Sstevel@tonic-gate * re-enable the i$, d$, w$, and p$ according to bootup cache state. 10687c478bd9Sstevel@tonic-gate * Turn on WE, HPE, SPE, PE, IC, and DC bits defined as DCU_CACHE. 10697c478bd9Sstevel@tonic-gate * %o0 - 64 bit constant 10707c478bd9Sstevel@tonic-gate */ 10717c478bd9Sstevel@tonic-gate ENTRY(set_dcu) 10727c478bd9Sstevel@tonic-gate stxa %o0, [%g0]ASI_DCU ! Store to DCU 10737c478bd9Sstevel@tonic-gate flush %g0 /* flush required after changing the IC bit */ 10747c478bd9Sstevel@tonic-gate retl 10757c478bd9Sstevel@tonic-gate nop 10767c478bd9Sstevel@tonic-gate SET_SIZE(set_dcu) 10777c478bd9Sstevel@tonic-gate 10787c478bd9Sstevel@tonic-gate#endif /* lint */ 10797c478bd9Sstevel@tonic-gate 10807c478bd9Sstevel@tonic-gate 10817c478bd9Sstevel@tonic-gate#if defined(lint) 10827c478bd9Sstevel@tonic-gate 10837c478bd9Sstevel@tonic-gateuint64_t 10847c478bd9Sstevel@tonic-gateget_dcu(void) 10857c478bd9Sstevel@tonic-gate{ 10867c478bd9Sstevel@tonic-gate return ((uint64_t)0); 10877c478bd9Sstevel@tonic-gate} 10887c478bd9Sstevel@tonic-gate 10897c478bd9Sstevel@tonic-gate#else /* lint */ 10907c478bd9Sstevel@tonic-gate 10917c478bd9Sstevel@tonic-gate/* 10927c478bd9Sstevel@tonic-gate * Return DCU register. 10937c478bd9Sstevel@tonic-gate */ 10947c478bd9Sstevel@tonic-gate ENTRY(get_dcu) 10957c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_DCU, %o0 /* DCU control register */ 10967c478bd9Sstevel@tonic-gate retl 10977c478bd9Sstevel@tonic-gate nop 10987c478bd9Sstevel@tonic-gate SET_SIZE(get_dcu) 10997c478bd9Sstevel@tonic-gate 11007c478bd9Sstevel@tonic-gate#endif /* lint */ 11017c478bd9Sstevel@tonic-gate 11027c478bd9Sstevel@tonic-gate/* 11037c478bd9Sstevel@tonic-gate * Cheetah/Cheetah+ level 15 interrupt handler trap table entry. 11047c478bd9Sstevel@tonic-gate * 11057c478bd9Sstevel@tonic-gate * This handler is used to check for softints generated by error trap 11067c478bd9Sstevel@tonic-gate * handlers to report errors. On Cheetah, this mechanism is used by the 11077c478bd9Sstevel@tonic-gate * Fast ECC at TL>0 error trap handler and, on Cheetah+, by both the Fast 11087c478bd9Sstevel@tonic-gate * ECC at TL>0 error and the I$/D$ parity error at TL>0 trap handlers. 11097c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must 11107c478bd9Sstevel@tonic-gate * be relocatable. 11117c478bd9Sstevel@tonic-gate */ 11127c478bd9Sstevel@tonic-gate#if defined(lint) 11137c478bd9Sstevel@tonic-gate 11147c478bd9Sstevel@tonic-gatevoid 11157c478bd9Sstevel@tonic-gatech_pil15_interrupt_instr(void) 11167c478bd9Sstevel@tonic-gate{} 11177c478bd9Sstevel@tonic-gate 11187c478bd9Sstevel@tonic-gate#else /* lint */ 11197c478bd9Sstevel@tonic-gate 11207c478bd9Sstevel@tonic-gate ENTRY_NP(ch_pil15_interrupt_instr) 11217c478bd9Sstevel@tonic-gate ASM_JMP(%g1, ch_pil15_interrupt) 11227c478bd9Sstevel@tonic-gate SET_SIZE(ch_pil15_interrupt_instr) 11237c478bd9Sstevel@tonic-gate 11247c478bd9Sstevel@tonic-gate#endif 11257c478bd9Sstevel@tonic-gate 11267c478bd9Sstevel@tonic-gate 11277c478bd9Sstevel@tonic-gate#if defined(lint) 11287c478bd9Sstevel@tonic-gate 11297c478bd9Sstevel@tonic-gatevoid 11307c478bd9Sstevel@tonic-gatech_pil15_interrupt(void) 11317c478bd9Sstevel@tonic-gate{} 11327c478bd9Sstevel@tonic-gate 11337c478bd9Sstevel@tonic-gate#else /* lint */ 11347c478bd9Sstevel@tonic-gate 11357c478bd9Sstevel@tonic-gate ENTRY_NP(ch_pil15_interrupt) 11367c478bd9Sstevel@tonic-gate 11377c478bd9Sstevel@tonic-gate /* 11387c478bd9Sstevel@tonic-gate * Since pil_interrupt is hacked to assume that every level 15 11397c478bd9Sstevel@tonic-gate * interrupt is generated by the CPU to indicate a performance 11407c478bd9Sstevel@tonic-gate * counter overflow this gets ugly. Before calling pil_interrupt 11417c478bd9Sstevel@tonic-gate * the Error at TL>0 pending status is inspected. If it is 11427c478bd9Sstevel@tonic-gate * non-zero, then an error has occurred and it is handled. 11437c478bd9Sstevel@tonic-gate * Otherwise control is transfered to pil_interrupt. Note that if 11447c478bd9Sstevel@tonic-gate * an error is detected pil_interrupt will not be called and 11457c478bd9Sstevel@tonic-gate * overflow interrupts may be lost causing erroneous performance 11467c478bd9Sstevel@tonic-gate * measurements. However, error-recovery will have a detrimental 11477c478bd9Sstevel@tonic-gate * effect on performance anyway. 11487c478bd9Sstevel@tonic-gate */ 11497c478bd9Sstevel@tonic-gate CPU_INDEX(%g1, %g4) 11507c478bd9Sstevel@tonic-gate set ch_err_tl1_pending, %g4 11517c478bd9Sstevel@tonic-gate ldub [%g1 + %g4], %g2 11527c478bd9Sstevel@tonic-gate brz %g2, 1f 11537c478bd9Sstevel@tonic-gate nop 11547c478bd9Sstevel@tonic-gate 11557c478bd9Sstevel@tonic-gate /* 11567c478bd9Sstevel@tonic-gate * We have a pending TL>0 error, clear the TL>0 pending status. 11577c478bd9Sstevel@tonic-gate */ 11587c478bd9Sstevel@tonic-gate stb %g0, [%g1 + %g4] 11597c478bd9Sstevel@tonic-gate 11607c478bd9Sstevel@tonic-gate /* 11617c478bd9Sstevel@tonic-gate * Clear the softint. 11627c478bd9Sstevel@tonic-gate */ 11637c478bd9Sstevel@tonic-gate mov 1, %g5 11647c478bd9Sstevel@tonic-gate sll %g5, PIL_15, %g5 11657c478bd9Sstevel@tonic-gate wr %g5, CLEAR_SOFTINT 11667c478bd9Sstevel@tonic-gate 11677c478bd9Sstevel@tonic-gate /* 11687c478bd9Sstevel@tonic-gate * For Cheetah*, call cpu_tl1_error via systrap at PIL 15 11697c478bd9Sstevel@tonic-gate * to process the Fast ECC/Cache Parity at TL>0 error. Clear 11707c478bd9Sstevel@tonic-gate * panic flag (%g2). 11717c478bd9Sstevel@tonic-gate */ 11727c478bd9Sstevel@tonic-gate set cpu_tl1_error, %g1 11737c478bd9Sstevel@tonic-gate clr %g2 11747c478bd9Sstevel@tonic-gate ba sys_trap 11757c478bd9Sstevel@tonic-gate mov PIL_15, %g4 11767c478bd9Sstevel@tonic-gate 11777c478bd9Sstevel@tonic-gate1: 11787c478bd9Sstevel@tonic-gate /* 11797c478bd9Sstevel@tonic-gate * The logout is invalid. 11807c478bd9Sstevel@tonic-gate * 11817c478bd9Sstevel@tonic-gate * Call the default interrupt handler. 11827c478bd9Sstevel@tonic-gate */ 11837c478bd9Sstevel@tonic-gate sethi %hi(pil_interrupt), %g1 11847c478bd9Sstevel@tonic-gate jmp %g1 + %lo(pil_interrupt) 11857c478bd9Sstevel@tonic-gate mov PIL_15, %g4 11867c478bd9Sstevel@tonic-gate 11877c478bd9Sstevel@tonic-gate SET_SIZE(ch_pil15_interrupt) 11887c478bd9Sstevel@tonic-gate#endif 11897c478bd9Sstevel@tonic-gate 11907c478bd9Sstevel@tonic-gate 11917c478bd9Sstevel@tonic-gate/* 11927c478bd9Sstevel@tonic-gate * Error Handling 11937c478bd9Sstevel@tonic-gate * 11947c478bd9Sstevel@tonic-gate * Cheetah provides error checking for all memory access paths between 11957c478bd9Sstevel@tonic-gate * the CPU, External Cache, Cheetah Data Switch and system bus. Error 11967c478bd9Sstevel@tonic-gate * information is logged in the AFSR, (also AFSR_EXT for Panther) and 11977c478bd9Sstevel@tonic-gate * AFAR and one of the following traps is generated (provided that it 11987c478bd9Sstevel@tonic-gate * is enabled in External Cache Error Enable Register) to handle that 11997c478bd9Sstevel@tonic-gate * error: 12007c478bd9Sstevel@tonic-gate * 1. trap 0x70: Precise trap 12017c478bd9Sstevel@tonic-gate * tt0_fecc for errors at trap level(TL)>=0 12027c478bd9Sstevel@tonic-gate * 2. trap 0x0A and 0x32: Deferred trap 12037c478bd9Sstevel@tonic-gate * async_err for errors at TL>=0 12047c478bd9Sstevel@tonic-gate * 3. trap 0x63: Disrupting trap 12057c478bd9Sstevel@tonic-gate * ce_err for errors at TL=0 12067c478bd9Sstevel@tonic-gate * (Note that trap 0x63 cannot happen at trap level > 0) 12077c478bd9Sstevel@tonic-gate * 12087c478bd9Sstevel@tonic-gate * Trap level one handlers panic the system except for the fast ecc 12097c478bd9Sstevel@tonic-gate * error handler which tries to recover from certain errors. 12107c478bd9Sstevel@tonic-gate */ 12117c478bd9Sstevel@tonic-gate 12127c478bd9Sstevel@tonic-gate/* 12137c478bd9Sstevel@tonic-gate * FAST ECC TRAP STRATEGY: 12147c478bd9Sstevel@tonic-gate * 12157c478bd9Sstevel@tonic-gate * Software must handle single and multi bit errors which occur due to data 12167c478bd9Sstevel@tonic-gate * or instruction cache reads from the external cache. A single or multi bit 12177c478bd9Sstevel@tonic-gate * error occuring in one of these situations results in a precise trap. 12187c478bd9Sstevel@tonic-gate * 12197c478bd9Sstevel@tonic-gate * The basic flow of this trap handler is as follows: 12207c478bd9Sstevel@tonic-gate * 12217c478bd9Sstevel@tonic-gate * 1) Record the state and then turn off the Dcache and Icache. The Dcache 12227c478bd9Sstevel@tonic-gate * is disabled because bad data could have been installed. The Icache is 12237c478bd9Sstevel@tonic-gate * turned off because we want to capture the Icache line related to the 12247c478bd9Sstevel@tonic-gate * AFAR. 12257c478bd9Sstevel@tonic-gate * 2) Disable trapping on CEEN/NCCEN errors during TL=0 processing. 12267c478bd9Sstevel@tonic-gate * 3) Park sibling core if caches are shared (to avoid race condition while 12277c478bd9Sstevel@tonic-gate * accessing shared resources such as L3 data staging register during 12287c478bd9Sstevel@tonic-gate * CPU logout. 12297c478bd9Sstevel@tonic-gate * 4) Read the AFAR and AFSR. 12307c478bd9Sstevel@tonic-gate * 5) If CPU logout structure is not being used, then: 12317c478bd9Sstevel@tonic-gate * 6) Clear all errors from the AFSR. 12327c478bd9Sstevel@tonic-gate * 7) Capture Ecache, Dcache and Icache lines in "CPU log out" structure. 12337c478bd9Sstevel@tonic-gate * 8) Flush Ecache then Flush Dcache and Icache and restore to previous 12347c478bd9Sstevel@tonic-gate * state. 12357c478bd9Sstevel@tonic-gate * 9) Unpark sibling core if we parked it earlier. 12367c478bd9Sstevel@tonic-gate * 10) call cpu_fast_ecc_error via systrap at PIL 14 unless we're already 12377c478bd9Sstevel@tonic-gate * running at PIL 15. 12387c478bd9Sstevel@tonic-gate * 6) Otherwise, if CPU logout structure is being used: 12397c478bd9Sstevel@tonic-gate * 7) Incriment the "logout busy count". 12407c478bd9Sstevel@tonic-gate * 8) Flush Ecache then Flush Dcache and Icache and restore to previous 12417c478bd9Sstevel@tonic-gate * state. 12427c478bd9Sstevel@tonic-gate * 9) Unpark sibling core if we parked it earlier. 12437c478bd9Sstevel@tonic-gate * 10) Issue a retry since the other CPU error logging code will end up 12447c478bd9Sstevel@tonic-gate * finding this error bit and logging information about it later. 12457c478bd9Sstevel@tonic-gate * 7) Alternatively (to 5 and 6 above), if the cpu_private struct is not 12467c478bd9Sstevel@tonic-gate * yet initialized such that we can't even check the logout struct, then 12477c478bd9Sstevel@tonic-gate * we place the clo_flags data into %g2 (sys_trap->have_win arg #1) and 12487c478bd9Sstevel@tonic-gate * call cpu_fast_ecc_error via systrap. The clo_flags parameter is used 12494fd7ecabSdilpreet * to determine information such as TL, TT, CEEN and NCEEN settings, etc 12504fd7ecabSdilpreet * in the high level trap handler since we don't have access to detailed 12514fd7ecabSdilpreet * logout information in cases where the cpu_private struct is not yet 12527c478bd9Sstevel@tonic-gate * initialized. 12537c478bd9Sstevel@tonic-gate * 12547c478bd9Sstevel@tonic-gate * We flush the E$ and D$ here on TL=1 code to prevent getting nested 12557c478bd9Sstevel@tonic-gate * Fast ECC traps in the TL=0 code. If we get a Fast ECC event here in 12567c478bd9Sstevel@tonic-gate * the TL=1 code, we will go to the Fast ECC at TL>0 handler which, 12577c478bd9Sstevel@tonic-gate * since it is uses different code/data from this handler, has a better 12587c478bd9Sstevel@tonic-gate * chance of fixing things up than simply recursing through this code 12597c478bd9Sstevel@tonic-gate * again (this would probably cause an eventual kernel stack overflow). 12607c478bd9Sstevel@tonic-gate * If the Fast ECC at TL>0 handler encounters a Fast ECC error before it 12617c478bd9Sstevel@tonic-gate * can flush the E$ (or the error is a stuck-at bit), we will recurse in 12627c478bd9Sstevel@tonic-gate * the Fast ECC at TL>0 handler and eventually Red Mode. 12637c478bd9Sstevel@tonic-gate * 12647c478bd9Sstevel@tonic-gate * Note that for Cheetah (and only Cheetah), we use alias addresses for 12657c478bd9Sstevel@tonic-gate * flushing rather than ASI accesses (which don't exist on Cheetah). 12667c478bd9Sstevel@tonic-gate * Should we encounter a Fast ECC error within this handler on Cheetah, 12677c478bd9Sstevel@tonic-gate * there's a good chance it's within the ecache_flushaddr buffer (since 12687c478bd9Sstevel@tonic-gate * it's the largest piece of memory we touch in the handler and it is 12697c478bd9Sstevel@tonic-gate * usually kernel text/data). For that reason the Fast ECC at TL>0 12707c478bd9Sstevel@tonic-gate * handler for Cheetah uses an alternate buffer: ecache_tl1_flushaddr. 12717c478bd9Sstevel@tonic-gate */ 12727c478bd9Sstevel@tonic-gate 12737c478bd9Sstevel@tonic-gate/* 12747c478bd9Sstevel@tonic-gate * Cheetah ecc-protected E$ trap (Trap 70) at TL=0 12757c478bd9Sstevel@tonic-gate * tt0_fecc is replaced by fecc_err_instr in cpu_init_trap of the various 12767c478bd9Sstevel@tonic-gate * architecture-specific files. 12777c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must 12787c478bd9Sstevel@tonic-gate * be relocatable. 12797c478bd9Sstevel@tonic-gate */ 12807c478bd9Sstevel@tonic-gate 12817c478bd9Sstevel@tonic-gate#if defined(lint) 12827c478bd9Sstevel@tonic-gate 12837c478bd9Sstevel@tonic-gatevoid 12847c478bd9Sstevel@tonic-gatefecc_err_instr(void) 12857c478bd9Sstevel@tonic-gate{} 12867c478bd9Sstevel@tonic-gate 12877c478bd9Sstevel@tonic-gate#else /* lint */ 12887c478bd9Sstevel@tonic-gate 12897c478bd9Sstevel@tonic-gate ENTRY_NP(fecc_err_instr) 12907c478bd9Sstevel@tonic-gate membar #Sync ! Cheetah requires membar #Sync 12917c478bd9Sstevel@tonic-gate 12927c478bd9Sstevel@tonic-gate /* 12937c478bd9Sstevel@tonic-gate * Save current DCU state. Turn off the Dcache and Icache. 12947c478bd9Sstevel@tonic-gate */ 12957c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1 12967c478bd9Sstevel@tonic-gate andn %g1, DCU_DC + DCU_IC, %g4 12977c478bd9Sstevel@tonic-gate stxa %g4, [%g0]ASI_DCU 12987c478bd9Sstevel@tonic-gate flush %g0 /* flush required after changing the IC bit */ 12997c478bd9Sstevel@tonic-gate 13007c478bd9Sstevel@tonic-gate ASM_JMP(%g4, fast_ecc_err) 13017c478bd9Sstevel@tonic-gate SET_SIZE(fecc_err_instr) 13027c478bd9Sstevel@tonic-gate 13037c478bd9Sstevel@tonic-gate#endif /* lint */ 13047c478bd9Sstevel@tonic-gate 13057c478bd9Sstevel@tonic-gate 13067c478bd9Sstevel@tonic-gate#if !(defined(JALAPENO) || defined(SERRANO)) 13077c478bd9Sstevel@tonic-gate 13087c478bd9Sstevel@tonic-gate#if defined(lint) 13097c478bd9Sstevel@tonic-gate 13107c478bd9Sstevel@tonic-gatevoid 13117c478bd9Sstevel@tonic-gatefast_ecc_err(void) 13127c478bd9Sstevel@tonic-gate{} 13137c478bd9Sstevel@tonic-gate 13147c478bd9Sstevel@tonic-gate#else /* lint */ 13157c478bd9Sstevel@tonic-gate 13167c478bd9Sstevel@tonic-gate .section ".text" 13177c478bd9Sstevel@tonic-gate .align 64 13187c478bd9Sstevel@tonic-gate ENTRY_NP(fast_ecc_err) 13197c478bd9Sstevel@tonic-gate 13207c478bd9Sstevel@tonic-gate /* 13217c478bd9Sstevel@tonic-gate * Turn off CEEN and NCEEN. 13227c478bd9Sstevel@tonic-gate */ 13237c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_ESTATE_ERR, %g3 13247c478bd9Sstevel@tonic-gate andn %g3, EN_REG_NCEEN + EN_REG_CEEN, %g4 13257c478bd9Sstevel@tonic-gate stxa %g4, [%g0]ASI_ESTATE_ERR 13267c478bd9Sstevel@tonic-gate membar #Sync ! membar sync required 13277c478bd9Sstevel@tonic-gate 13287c478bd9Sstevel@tonic-gate /* 13297c478bd9Sstevel@tonic-gate * Check to see whether we need to park our sibling core 13307c478bd9Sstevel@tonic-gate * before recording diagnostic information from caches 13317c478bd9Sstevel@tonic-gate * which may be shared by both cores. 13327c478bd9Sstevel@tonic-gate * We use %g1 to store information about whether or not 13337c478bd9Sstevel@tonic-gate * we had to park the core (%g1 holds our DCUCR value and 13347c478bd9Sstevel@tonic-gate * we only use bits from that register which are "reserved" 13357c478bd9Sstevel@tonic-gate * to keep track of core parking) so that we know whether 13367c478bd9Sstevel@tonic-gate * or not to unpark later. %g5 and %g4 are scratch registers. 13377c478bd9Sstevel@tonic-gate */ 13387c478bd9Sstevel@tonic-gate PARK_SIBLING_CORE(%g1, %g5, %g4) 13397c478bd9Sstevel@tonic-gate 13407c478bd9Sstevel@tonic-gate /* 13417c478bd9Sstevel@tonic-gate * Do the CPU log out capture. 13427c478bd9Sstevel@tonic-gate * %g3 = "failed?" return value. 13437c478bd9Sstevel@tonic-gate * %g2 = Input = AFAR. Output the clo_flags info which is passed 13447c478bd9Sstevel@tonic-gate * into this macro via %g4. Output only valid if cpu_private 13457c478bd9Sstevel@tonic-gate * struct has not been initialized. 13467c478bd9Sstevel@tonic-gate * CHPR_FECCTL0_LOGOUT = cpu logout structure offset input 13477c478bd9Sstevel@tonic-gate * %g4 = Trap information stored in the cpu logout flags field 13487c478bd9Sstevel@tonic-gate * %g5 = scr1 13497c478bd9Sstevel@tonic-gate * %g6 = scr2 13507c478bd9Sstevel@tonic-gate * %g3 = scr3 13517c478bd9Sstevel@tonic-gate * %g4 = scr4 13527c478bd9Sstevel@tonic-gate */ 13534fd7ecabSdilpreet /* store the CEEN and NCEEN values, TL=0 */ 13544fd7ecabSdilpreet and %g3, EN_REG_CEEN + EN_REG_NCEEN, %g4 13557c478bd9Sstevel@tonic-gate set CHPR_FECCTL0_LOGOUT, %g6 13567c478bd9Sstevel@tonic-gate DO_CPU_LOGOUT(%g3, %g2, %g6, %g4, %g5, %g6, %g3, %g4) 13577c478bd9Sstevel@tonic-gate 13587c478bd9Sstevel@tonic-gate /* 13597c478bd9Sstevel@tonic-gate * Flush the Ecache (and L2 cache for Panther) to get the error out 13607c478bd9Sstevel@tonic-gate * of the Ecache. If the UCC or UCU is on a dirty line, then the 13617c478bd9Sstevel@tonic-gate * following flush will turn that into a WDC or WDU, respectively. 13627c478bd9Sstevel@tonic-gate */ 13637c478bd9Sstevel@tonic-gate PN_L2_FLUSHALL(%g4, %g5, %g6) 13647c478bd9Sstevel@tonic-gate 13657c478bd9Sstevel@tonic-gate CPU_INDEX(%g4, %g5) 13667c478bd9Sstevel@tonic-gate mulx %g4, CPU_NODE_SIZE, %g4 13677c478bd9Sstevel@tonic-gate set cpunodes, %g5 13687c478bd9Sstevel@tonic-gate add %g4, %g5, %g4 13697c478bd9Sstevel@tonic-gate ld [%g4 + ECACHE_LINESIZE], %g5 13707c478bd9Sstevel@tonic-gate ld [%g4 + ECACHE_SIZE], %g4 13717c478bd9Sstevel@tonic-gate 13727c478bd9Sstevel@tonic-gate ASM_LDX(%g6, ecache_flushaddr) 13737c478bd9Sstevel@tonic-gate ECACHE_FLUSHALL(%g4, %g5, %g6, %g7) 13747c478bd9Sstevel@tonic-gate 13757c478bd9Sstevel@tonic-gate /* 13767c478bd9Sstevel@tonic-gate * Flush the Dcache. Since bad data could have been installed in 13777c478bd9Sstevel@tonic-gate * the Dcache we must flush it before re-enabling it. 13787c478bd9Sstevel@tonic-gate */ 13797c478bd9Sstevel@tonic-gate ASM_LD(%g5, dcache_size) 13807c478bd9Sstevel@tonic-gate ASM_LD(%g6, dcache_linesize) 13817c478bd9Sstevel@tonic-gate CH_DCACHE_FLUSHALL(%g5, %g6, %g7) 13827c478bd9Sstevel@tonic-gate 13837c478bd9Sstevel@tonic-gate /* 13847c478bd9Sstevel@tonic-gate * Flush the Icache. Since we turned off the Icache to capture the 13857c478bd9Sstevel@tonic-gate * Icache line it is now stale or corrupted and we must flush it 13867c478bd9Sstevel@tonic-gate * before re-enabling it. 13877c478bd9Sstevel@tonic-gate */ 13887c478bd9Sstevel@tonic-gate GET_CPU_PRIVATE_PTR(%g0, %g5, %g7, fast_ecc_err_5); 13897c478bd9Sstevel@tonic-gate ld [%g5 + CHPR_ICACHE_LINESIZE], %g6 13907c478bd9Sstevel@tonic-gate ba,pt %icc, 6f 13917c478bd9Sstevel@tonic-gate ld [%g5 + CHPR_ICACHE_SIZE], %g5 13927c478bd9Sstevel@tonic-gatefast_ecc_err_5: 13937c478bd9Sstevel@tonic-gate ASM_LD(%g5, icache_size) 13947c478bd9Sstevel@tonic-gate ASM_LD(%g6, icache_linesize) 13957c478bd9Sstevel@tonic-gate6: 13967c478bd9Sstevel@tonic-gate CH_ICACHE_FLUSHALL(%g5, %g6, %g7, %g4) 13977c478bd9Sstevel@tonic-gate 13987c478bd9Sstevel@tonic-gate /* 13997c478bd9Sstevel@tonic-gate * check to see whether we parked our sibling core at the start 14007c478bd9Sstevel@tonic-gate * of this handler. If so, we need to unpark it here. 14017c478bd9Sstevel@tonic-gate * We use DCUCR reserved bits (stored in %g1) to keep track of 14027c478bd9Sstevel@tonic-gate * whether or not we need to unpark. %g5 and %g4 are scratch registers. 14037c478bd9Sstevel@tonic-gate */ 14047c478bd9Sstevel@tonic-gate UNPARK_SIBLING_CORE(%g1, %g5, %g4) 14057c478bd9Sstevel@tonic-gate 14067c478bd9Sstevel@tonic-gate /* 14077c478bd9Sstevel@tonic-gate * Restore the Dcache and Icache to the previous state. 14087c478bd9Sstevel@tonic-gate */ 14097c478bd9Sstevel@tonic-gate stxa %g1, [%g0]ASI_DCU 14107c478bd9Sstevel@tonic-gate flush %g0 /* flush required after changing the IC bit */ 14117c478bd9Sstevel@tonic-gate 14127c478bd9Sstevel@tonic-gate /* 14137c478bd9Sstevel@tonic-gate * Make sure our CPU logout operation was successful. 14147c478bd9Sstevel@tonic-gate */ 14157c478bd9Sstevel@tonic-gate cmp %g3, %g0 14167c478bd9Sstevel@tonic-gate be 8f 14177c478bd9Sstevel@tonic-gate nop 14187c478bd9Sstevel@tonic-gate 14197c478bd9Sstevel@tonic-gate /* 14207c478bd9Sstevel@tonic-gate * If the logout structure had been busy, how many times have 14217c478bd9Sstevel@tonic-gate * we tried to use it and failed (nesting count)? If we have 14227c478bd9Sstevel@tonic-gate * already recursed a substantial number of times, then we can 14237c478bd9Sstevel@tonic-gate * assume things are not going to get better by themselves and 14247c478bd9Sstevel@tonic-gate * so it would be best to panic. 14257c478bd9Sstevel@tonic-gate */ 14267c478bd9Sstevel@tonic-gate cmp %g3, CLO_NESTING_MAX 14277c478bd9Sstevel@tonic-gate blt 7f 14287c478bd9Sstevel@tonic-gate nop 14297c478bd9Sstevel@tonic-gate 14307c478bd9Sstevel@tonic-gate call ptl1_panic 14317c478bd9Sstevel@tonic-gate mov PTL1_BAD_ECC, %g1 14327c478bd9Sstevel@tonic-gate 14337c478bd9Sstevel@tonic-gate7: 14347c478bd9Sstevel@tonic-gate /* 14357c478bd9Sstevel@tonic-gate * Otherwise, if the logout structure was busy but we have not 14367c478bd9Sstevel@tonic-gate * nested more times than our maximum value, then we simply 14377c478bd9Sstevel@tonic-gate * issue a retry. Our TL=0 trap handler code will check and 14387c478bd9Sstevel@tonic-gate * clear the AFSR after it is done logging what is currently 14397c478bd9Sstevel@tonic-gate * in the logout struct and handle this event at that time. 14407c478bd9Sstevel@tonic-gate */ 14417c478bd9Sstevel@tonic-gate retry 14427c478bd9Sstevel@tonic-gate8: 14437c478bd9Sstevel@tonic-gate /* 14447c478bd9Sstevel@tonic-gate * Call cpu_fast_ecc_error via systrap at PIL 14 unless we're 14457c478bd9Sstevel@tonic-gate * already at PIL 15. 14467c478bd9Sstevel@tonic-gate */ 14477c478bd9Sstevel@tonic-gate set cpu_fast_ecc_error, %g1 14487c478bd9Sstevel@tonic-gate rdpr %pil, %g4 14497c478bd9Sstevel@tonic-gate cmp %g4, PIL_14 14507c478bd9Sstevel@tonic-gate ba sys_trap 14517c478bd9Sstevel@tonic-gate movl %icc, PIL_14, %g4 14527c478bd9Sstevel@tonic-gate 14537c478bd9Sstevel@tonic-gate SET_SIZE(fast_ecc_err) 14547c478bd9Sstevel@tonic-gate 14557c478bd9Sstevel@tonic-gate#endif /* lint */ 14567c478bd9Sstevel@tonic-gate 14577c478bd9Sstevel@tonic-gate#endif /* !(JALAPENO || SERRANO) */ 14587c478bd9Sstevel@tonic-gate 14597c478bd9Sstevel@tonic-gate 14607c478bd9Sstevel@tonic-gate/* 14617c478bd9Sstevel@tonic-gate * Cheetah/Cheetah+ Fast ECC at TL>0 trap strategy: 14627c478bd9Sstevel@tonic-gate * 14637c478bd9Sstevel@tonic-gate * The basic flow of this trap handler is as follows: 14647c478bd9Sstevel@tonic-gate * 14657c478bd9Sstevel@tonic-gate * 1) In the "trap 70" trap table code (fecc_err_tl1_instr), generate a 14667c478bd9Sstevel@tonic-gate * software trap 0 ("ta 0") to buy an extra set of %tpc, etc. which we 14677c478bd9Sstevel@tonic-gate * will use to save %g1 and %g2. 14687c478bd9Sstevel@tonic-gate * 2) At the software trap 0 at TL>0 trap table code (fecc_err_tl1_cont_instr), 14697c478bd9Sstevel@tonic-gate * we save %g1+%g2 using %tpc, %tnpc + %tstate and jump to the fast ecc 14707c478bd9Sstevel@tonic-gate * handler (using the just saved %g1). 14717c478bd9Sstevel@tonic-gate * 3) Turn off the Dcache if it was on and save the state of the Dcache 14727c478bd9Sstevel@tonic-gate * (whether on or off) in Bit2 (CH_ERR_TSTATE_DC_ON) of %tstate. 14737c478bd9Sstevel@tonic-gate * NB: we don't turn off the Icache because bad data is not installed nor 14747c478bd9Sstevel@tonic-gate * will we be doing any diagnostic accesses. 14757c478bd9Sstevel@tonic-gate * 4) compute physical address of the per-cpu/per-tl save area using %g1+%g2 14767c478bd9Sstevel@tonic-gate * 5) Save %g1-%g7 into the per-cpu/per-tl save area (%g1 + %g2 from the 14777c478bd9Sstevel@tonic-gate * %tpc, %tnpc, %tstate values previously saved). 14787c478bd9Sstevel@tonic-gate * 6) set %tl to %tl - 1. 14797c478bd9Sstevel@tonic-gate * 7) Save the appropriate flags and TPC in the ch_err_tl1_data structure. 14807c478bd9Sstevel@tonic-gate * 8) Save the value of CH_ERR_TSTATE_DC_ON in the ch_err_tl1_tmp field. 14817c478bd9Sstevel@tonic-gate * 9) For Cheetah and Jalapeno, read the AFAR and AFSR and clear. For 14827c478bd9Sstevel@tonic-gate * Cheetah+ (and later), read the shadow AFAR and AFSR but don't clear. 14837c478bd9Sstevel@tonic-gate * Save the values in ch_err_tl1_data. For Panther, read the shadow 14847c478bd9Sstevel@tonic-gate * AFSR_EXT and save the value in ch_err_tl1_data. 14857c478bd9Sstevel@tonic-gate * 10) Disable CEEN/NCEEN to prevent any disrupting/deferred errors from 14867c478bd9Sstevel@tonic-gate * being queued. We'll report them via the AFSR/AFAR capture in step 13. 14877c478bd9Sstevel@tonic-gate * 11) Flush the Ecache. 14887c478bd9Sstevel@tonic-gate * NB: the Ecache is flushed assuming the largest possible size with 14897c478bd9Sstevel@tonic-gate * the smallest possible line size since access to the cpu_nodes may 14907c478bd9Sstevel@tonic-gate * cause an unrecoverable DTLB miss. 14917c478bd9Sstevel@tonic-gate * 12) Reenable CEEN/NCEEN with the value saved from step 10. 14927c478bd9Sstevel@tonic-gate * 13) For Cheetah and Jalapeno, read the AFAR and AFSR and clear again. 14937c478bd9Sstevel@tonic-gate * For Cheetah+ (and later), read the primary AFAR and AFSR and now clear. 14947c478bd9Sstevel@tonic-gate * Save the read AFSR/AFAR values in ch_err_tl1_data. For Panther, 14957c478bd9Sstevel@tonic-gate * read and clear the primary AFSR_EXT and save it in ch_err_tl1_data. 14967c478bd9Sstevel@tonic-gate * 14) Flush and re-enable the Dcache if it was on at step 3. 14977c478bd9Sstevel@tonic-gate * 15) Do TRAPTRACE if enabled. 14987c478bd9Sstevel@tonic-gate * 16) Check if a UCU->WDU (or L3_UCU->WDU for Panther) happened, panic if so. 14997c478bd9Sstevel@tonic-gate * 17) Set the event pending flag in ch_err_tl1_pending[CPU] 15007c478bd9Sstevel@tonic-gate * 18) Cause a softint 15. The pil15_interrupt handler will inspect the 15017c478bd9Sstevel@tonic-gate * event pending flag and call cpu_tl1_error via systrap if set. 15027c478bd9Sstevel@tonic-gate * 19) Restore the registers from step 5 and issue retry. 15037c478bd9Sstevel@tonic-gate */ 15047c478bd9Sstevel@tonic-gate 15057c478bd9Sstevel@tonic-gate/* 15067c478bd9Sstevel@tonic-gate * Cheetah ecc-protected E$ trap (Trap 70) at TL>0 15077c478bd9Sstevel@tonic-gate * tt1_fecc is replaced by fecc_err_tl1_instr in cpu_init_trap of the various 15087c478bd9Sstevel@tonic-gate * architecture-specific files. This generates a "Software Trap 0" at TL>0, 15097c478bd9Sstevel@tonic-gate * which goes to fecc_err_tl1_cont_instr, and we continue the handling there. 15107c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must 15117c478bd9Sstevel@tonic-gate * be relocatable. 15127c478bd9Sstevel@tonic-gate */ 15137c478bd9Sstevel@tonic-gate 15147c478bd9Sstevel@tonic-gate#if defined(lint) 15157c478bd9Sstevel@tonic-gate 15167c478bd9Sstevel@tonic-gatevoid 15177c478bd9Sstevel@tonic-gatefecc_err_tl1_instr(void) 15187c478bd9Sstevel@tonic-gate{} 15197c478bd9Sstevel@tonic-gate 15207c478bd9Sstevel@tonic-gate#else /* lint */ 15217c478bd9Sstevel@tonic-gate 15227c478bd9Sstevel@tonic-gate ENTRY_NP(fecc_err_tl1_instr) 15237c478bd9Sstevel@tonic-gate CH_ERR_TL1_TRAPENTRY(SWTRAP_0); 15247c478bd9Sstevel@tonic-gate SET_SIZE(fecc_err_tl1_instr) 15257c478bd9Sstevel@tonic-gate 15267c478bd9Sstevel@tonic-gate#endif /* lint */ 15277c478bd9Sstevel@tonic-gate 15287c478bd9Sstevel@tonic-gate/* 15297c478bd9Sstevel@tonic-gate * Software trap 0 at TL>0. 15307c478bd9Sstevel@tonic-gate * tt1_swtrap0 is replaced by fecc_err_tl1_cont_instr in cpu_init_trap of 15317c478bd9Sstevel@tonic-gate * the various architecture-specific files. This is used as a continuation 15327c478bd9Sstevel@tonic-gate * of the fast ecc handling where we've bought an extra TL level, so we can 15337c478bd9Sstevel@tonic-gate * use %tpc, %tnpc, %tstate to temporarily save the value of registers %g1 15347c478bd9Sstevel@tonic-gate * and %g2. Note that %tstate has bits 0-2 and then bits 8-19 as r/w, 15357c478bd9Sstevel@tonic-gate * there's a reserved hole from 3-7. We only use bits 0-1 and 8-9 (the low 15367c478bd9Sstevel@tonic-gate * order two bits from %g1 and %g2 respectively). 15377c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must 15387c478bd9Sstevel@tonic-gate * be relocatable. 15397c478bd9Sstevel@tonic-gate */ 15407c478bd9Sstevel@tonic-gate#if defined(lint) 15417c478bd9Sstevel@tonic-gate 15427c478bd9Sstevel@tonic-gatevoid 15437c478bd9Sstevel@tonic-gatefecc_err_tl1_cont_instr(void) 15447c478bd9Sstevel@tonic-gate{} 15457c478bd9Sstevel@tonic-gate 15467c478bd9Sstevel@tonic-gate#else /* lint */ 15477c478bd9Sstevel@tonic-gate 15487c478bd9Sstevel@tonic-gate ENTRY_NP(fecc_err_tl1_cont_instr) 15497c478bd9Sstevel@tonic-gate CH_ERR_TL1_SWTRAPENTRY(fast_ecc_tl1_err) 15507c478bd9Sstevel@tonic-gate SET_SIZE(fecc_err_tl1_cont_instr) 15517c478bd9Sstevel@tonic-gate 15527c478bd9Sstevel@tonic-gate#endif /* lint */ 15537c478bd9Sstevel@tonic-gate 15547c478bd9Sstevel@tonic-gate 15557c478bd9Sstevel@tonic-gate#if defined(lint) 15567c478bd9Sstevel@tonic-gate 15577c478bd9Sstevel@tonic-gatevoid 15587c478bd9Sstevel@tonic-gatece_err(void) 15597c478bd9Sstevel@tonic-gate{} 15607c478bd9Sstevel@tonic-gate 15617c478bd9Sstevel@tonic-gate#else /* lint */ 15627c478bd9Sstevel@tonic-gate 15637c478bd9Sstevel@tonic-gate/* 15647c478bd9Sstevel@tonic-gate * The ce_err function handles disrupting trap type 0x63 at TL=0. 15657c478bd9Sstevel@tonic-gate * 15667c478bd9Sstevel@tonic-gate * AFSR errors bits which cause this trap are: 15677c478bd9Sstevel@tonic-gate * CE, EMC, EDU:ST, EDC, WDU, WDC, CPU, CPC, IVU, IVC 15687c478bd9Sstevel@tonic-gate * 15697c478bd9Sstevel@tonic-gate * NCEEN Bit of Cheetah External Cache Error Enable Register enables 15707c478bd9Sstevel@tonic-gate * the following AFSR disrupting traps: EDU:ST, WDU, CPU, IVU 15717c478bd9Sstevel@tonic-gate * 15727c478bd9Sstevel@tonic-gate * CEEN Bit of Cheetah External Cache Error Enable Register enables 15737c478bd9Sstevel@tonic-gate * the following AFSR disrupting traps: CE, EMC, EDC, WDC, CPC, IVC 15747c478bd9Sstevel@tonic-gate * 15757c478bd9Sstevel@tonic-gate * Cheetah+ also handles (No additional processing required): 15767c478bd9Sstevel@tonic-gate * DUE, DTO, DBERR (NCEEN controlled) 15777c478bd9Sstevel@tonic-gate * THCE (CEEN and ET_ECC_en controlled) 15787c478bd9Sstevel@tonic-gate * TUE (ET_ECC_en controlled) 15797c478bd9Sstevel@tonic-gate * 15807c478bd9Sstevel@tonic-gate * Panther further adds: 15817c478bd9Sstevel@tonic-gate * IMU, L3_EDU, L3_WDU, L3_CPU (NCEEN controlled) 15827c478bd9Sstevel@tonic-gate * IMC, L3_EDC, L3_WDC, L3_CPC, L3_THCE (CEEN controlled) 15837c478bd9Sstevel@tonic-gate * TUE_SH, TUE (NCEEN and L2_tag_ECC_en controlled) 15847c478bd9Sstevel@tonic-gate * L3_TUE, L3_TUE_SH (NCEEN and ET_ECC_en controlled) 15857c478bd9Sstevel@tonic-gate * THCE (CEEN and L2_tag_ECC_en controlled) 15867c478bd9Sstevel@tonic-gate * L3_THCE (CEEN and ET_ECC_en controlled) 15877c478bd9Sstevel@tonic-gate * 15887c478bd9Sstevel@tonic-gate * Steps: 15897c478bd9Sstevel@tonic-gate * 1. Disable hardware corrected disrupting errors only (CEEN) 15907c478bd9Sstevel@tonic-gate * 2. Park sibling core if caches are shared (to avoid race 15917c478bd9Sstevel@tonic-gate * condition while accessing shared resources such as L3 15927c478bd9Sstevel@tonic-gate * data staging register during CPU logout. 15937c478bd9Sstevel@tonic-gate * 3. If the CPU logout structure is not currently being used: 15947c478bd9Sstevel@tonic-gate * 4. Clear AFSR error bits 15957c478bd9Sstevel@tonic-gate * 5. Capture Ecache, Dcache and Icache lines associated 15967c478bd9Sstevel@tonic-gate * with AFAR. 15977c478bd9Sstevel@tonic-gate * 6. Unpark sibling core if we parked it earlier. 15987c478bd9Sstevel@tonic-gate * 7. call cpu_disrupting_error via sys_trap at PIL 14 15997c478bd9Sstevel@tonic-gate * unless we're already running at PIL 15. 16007c478bd9Sstevel@tonic-gate * 4. Otherwise, if the CPU logout structure is busy: 16017c478bd9Sstevel@tonic-gate * 5. Incriment "logout busy count" and place into %g3 16027c478bd9Sstevel@tonic-gate * 6. Unpark sibling core if we parked it earlier. 16037c478bd9Sstevel@tonic-gate * 7. Issue a retry since the other CPU error logging 16047c478bd9Sstevel@tonic-gate * code will end up finding this error bit and logging 16057c478bd9Sstevel@tonic-gate * information about it later. 16067c478bd9Sstevel@tonic-gate * 5. Alternatively (to 3 and 4 above), if the cpu_private struct is 16077c478bd9Sstevel@tonic-gate * not yet initialized such that we can't even check the logout 16087c478bd9Sstevel@tonic-gate * struct, then we place the clo_flags data into %g2 16097c478bd9Sstevel@tonic-gate * (sys_trap->have_win arg #1) and call cpu_disrupting_error via 16107c478bd9Sstevel@tonic-gate * systrap. The clo_flags parameter is used to determine information 16117c478bd9Sstevel@tonic-gate * such as TL, TT, CEEN settings, etc in the high level trap 16127c478bd9Sstevel@tonic-gate * handler since we don't have access to detailed logout information 16137c478bd9Sstevel@tonic-gate * in cases where the cpu_private struct is not yet initialized. 16147c478bd9Sstevel@tonic-gate * 16157c478bd9Sstevel@tonic-gate * %g3: [ logout busy count ] - arg #2 16167c478bd9Sstevel@tonic-gate * %g2: [ clo_flags if cpu_private unavailable ] - sys_trap->have_win: arg #1 16177c478bd9Sstevel@tonic-gate */ 16187c478bd9Sstevel@tonic-gate 16197c478bd9Sstevel@tonic-gate .align 128 16207c478bd9Sstevel@tonic-gate ENTRY_NP(ce_err) 16217c478bd9Sstevel@tonic-gate membar #Sync ! Cheetah requires membar #Sync 16227c478bd9Sstevel@tonic-gate 16237c478bd9Sstevel@tonic-gate /* 16247c478bd9Sstevel@tonic-gate * Disable trap on hardware corrected errors (CEEN) while at TL=0 16257c478bd9Sstevel@tonic-gate * to prevent recursion. 16267c478bd9Sstevel@tonic-gate */ 16277c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_ESTATE_ERR, %g1 16287c478bd9Sstevel@tonic-gate bclr EN_REG_CEEN, %g1 16297c478bd9Sstevel@tonic-gate stxa %g1, [%g0]ASI_ESTATE_ERR 16307c478bd9Sstevel@tonic-gate membar #Sync ! membar sync required 16317c478bd9Sstevel@tonic-gate 16327c478bd9Sstevel@tonic-gate /* 16337c478bd9Sstevel@tonic-gate * Save current DCU state. Turn off Icache to allow capture of 16347c478bd9Sstevel@tonic-gate * Icache data by DO_CPU_LOGOUT. 16357c478bd9Sstevel@tonic-gate */ 16367c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1 16377c478bd9Sstevel@tonic-gate andn %g1, DCU_IC, %g4 16387c478bd9Sstevel@tonic-gate stxa %g4, [%g0]ASI_DCU 16397c478bd9Sstevel@tonic-gate flush %g0 /* flush required after changing the IC bit */ 16407c478bd9Sstevel@tonic-gate 16417c478bd9Sstevel@tonic-gate /* 16427c478bd9Sstevel@tonic-gate * Check to see whether we need to park our sibling core 16437c478bd9Sstevel@tonic-gate * before recording diagnostic information from caches 16447c478bd9Sstevel@tonic-gate * which may be shared by both cores. 16457c478bd9Sstevel@tonic-gate * We use %g1 to store information about whether or not 16467c478bd9Sstevel@tonic-gate * we had to park the core (%g1 holds our DCUCR value and 16477c478bd9Sstevel@tonic-gate * we only use bits from that register which are "reserved" 16487c478bd9Sstevel@tonic-gate * to keep track of core parking) so that we know whether 16497c478bd9Sstevel@tonic-gate * or not to unpark later. %g5 and %g4 are scratch registers. 16507c478bd9Sstevel@tonic-gate */ 16517c478bd9Sstevel@tonic-gate PARK_SIBLING_CORE(%g1, %g5, %g4) 16527c478bd9Sstevel@tonic-gate 16537c478bd9Sstevel@tonic-gate /* 16547c478bd9Sstevel@tonic-gate * Do the CPU log out capture. 16557c478bd9Sstevel@tonic-gate * %g3 = "failed?" return value. 16567c478bd9Sstevel@tonic-gate * %g2 = Input = AFAR. Output the clo_flags info which is passed 16577c478bd9Sstevel@tonic-gate * into this macro via %g4. Output only valid if cpu_private 16587c478bd9Sstevel@tonic-gate * struct has not been initialized. 16597c478bd9Sstevel@tonic-gate * CHPR_CECC_LOGOUT = cpu logout structure offset input 16607c478bd9Sstevel@tonic-gate * %g4 = Trap information stored in the cpu logout flags field 16617c478bd9Sstevel@tonic-gate * %g5 = scr1 16627c478bd9Sstevel@tonic-gate * %g6 = scr2 16637c478bd9Sstevel@tonic-gate * %g3 = scr3 16647c478bd9Sstevel@tonic-gate * %g4 = scr4 16657c478bd9Sstevel@tonic-gate */ 16667c478bd9Sstevel@tonic-gate clr %g4 ! TL=0 bit in afsr 16677c478bd9Sstevel@tonic-gate set CHPR_CECC_LOGOUT, %g6 16687c478bd9Sstevel@tonic-gate DO_CPU_LOGOUT(%g3, %g2, %g6, %g4, %g5, %g6, %g3, %g4) 16697c478bd9Sstevel@tonic-gate 16707c478bd9Sstevel@tonic-gate /* 16717c478bd9Sstevel@tonic-gate * Flush the Icache. Since we turned off the Icache to capture the 16727c478bd9Sstevel@tonic-gate * Icache line it is now stale or corrupted and we must flush it 16737c478bd9Sstevel@tonic-gate * before re-enabling it. 16747c478bd9Sstevel@tonic-gate */ 16757c478bd9Sstevel@tonic-gate GET_CPU_PRIVATE_PTR(%g0, %g5, %g7, ce_err_1); 16767c478bd9Sstevel@tonic-gate ld [%g5 + CHPR_ICACHE_LINESIZE], %g6 16777c478bd9Sstevel@tonic-gate ba,pt %icc, 2f 16787c478bd9Sstevel@tonic-gate ld [%g5 + CHPR_ICACHE_SIZE], %g5 16797c478bd9Sstevel@tonic-gatece_err_1: 16807c478bd9Sstevel@tonic-gate ASM_LD(%g5, icache_size) 16817c478bd9Sstevel@tonic-gate ASM_LD(%g6, icache_linesize) 16827c478bd9Sstevel@tonic-gate2: 16837c478bd9Sstevel@tonic-gate CH_ICACHE_FLUSHALL(%g5, %g6, %g7, %g4) 16847c478bd9Sstevel@tonic-gate 16857c478bd9Sstevel@tonic-gate /* 16867c478bd9Sstevel@tonic-gate * check to see whether we parked our sibling core at the start 16877c478bd9Sstevel@tonic-gate * of this handler. If so, we need to unpark it here. 16887c478bd9Sstevel@tonic-gate * We use DCUCR reserved bits (stored in %g1) to keep track of 16897c478bd9Sstevel@tonic-gate * whether or not we need to unpark. %g5 and %g4 are scratch registers. 16907c478bd9Sstevel@tonic-gate */ 16917c478bd9Sstevel@tonic-gate UNPARK_SIBLING_CORE(%g1, %g5, %g4) 16927c478bd9Sstevel@tonic-gate 16937c478bd9Sstevel@tonic-gate /* 16947c478bd9Sstevel@tonic-gate * Restore Icache to previous state. 16957c478bd9Sstevel@tonic-gate */ 16967c478bd9Sstevel@tonic-gate stxa %g1, [%g0]ASI_DCU 16977c478bd9Sstevel@tonic-gate flush %g0 /* flush required after changing the IC bit */ 16987c478bd9Sstevel@tonic-gate 16997c478bd9Sstevel@tonic-gate /* 17007c478bd9Sstevel@tonic-gate * Make sure our CPU logout operation was successful. 17017c478bd9Sstevel@tonic-gate */ 17027c478bd9Sstevel@tonic-gate cmp %g3, %g0 17037c478bd9Sstevel@tonic-gate be 4f 17047c478bd9Sstevel@tonic-gate nop 17057c478bd9Sstevel@tonic-gate 17067c478bd9Sstevel@tonic-gate /* 17077c478bd9Sstevel@tonic-gate * If the logout structure had been busy, how many times have 17087c478bd9Sstevel@tonic-gate * we tried to use it and failed (nesting count)? If we have 17097c478bd9Sstevel@tonic-gate * already recursed a substantial number of times, then we can 17107c478bd9Sstevel@tonic-gate * assume things are not going to get better by themselves and 17117c478bd9Sstevel@tonic-gate * so it would be best to panic. 17127c478bd9Sstevel@tonic-gate */ 17137c478bd9Sstevel@tonic-gate cmp %g3, CLO_NESTING_MAX 17147c478bd9Sstevel@tonic-gate blt 3f 17157c478bd9Sstevel@tonic-gate nop 17167c478bd9Sstevel@tonic-gate 17177c478bd9Sstevel@tonic-gate call ptl1_panic 17187c478bd9Sstevel@tonic-gate mov PTL1_BAD_ECC, %g1 17197c478bd9Sstevel@tonic-gate 17207c478bd9Sstevel@tonic-gate3: 17217c478bd9Sstevel@tonic-gate /* 17227c478bd9Sstevel@tonic-gate * Otherwise, if the logout structure was busy but we have not 17237c478bd9Sstevel@tonic-gate * nested more times than our maximum value, then we simply 17247c478bd9Sstevel@tonic-gate * issue a retry. Our TL=0 trap handler code will check and 17257c478bd9Sstevel@tonic-gate * clear the AFSR after it is done logging what is currently 17267c478bd9Sstevel@tonic-gate * in the logout struct and handle this event at that time. 17277c478bd9Sstevel@tonic-gate */ 17287c478bd9Sstevel@tonic-gate retry 17297c478bd9Sstevel@tonic-gate4: 17307c478bd9Sstevel@tonic-gate /* 17317c478bd9Sstevel@tonic-gate * Call cpu_disrupting_error via systrap at PIL 14 unless we're 17327c478bd9Sstevel@tonic-gate * already at PIL 15. 17337c478bd9Sstevel@tonic-gate */ 17347c478bd9Sstevel@tonic-gate set cpu_disrupting_error, %g1 17357c478bd9Sstevel@tonic-gate rdpr %pil, %g4 17367c478bd9Sstevel@tonic-gate cmp %g4, PIL_14 17377c478bd9Sstevel@tonic-gate ba sys_trap 17387c478bd9Sstevel@tonic-gate movl %icc, PIL_14, %g4 17397c478bd9Sstevel@tonic-gate SET_SIZE(ce_err) 17407c478bd9Sstevel@tonic-gate 17417c478bd9Sstevel@tonic-gate#endif /* lint */ 17427c478bd9Sstevel@tonic-gate 17437c478bd9Sstevel@tonic-gate 17447c478bd9Sstevel@tonic-gate#if defined(lint) 17457c478bd9Sstevel@tonic-gate 17467c478bd9Sstevel@tonic-gate/* 17477c478bd9Sstevel@tonic-gate * This trap cannot happen at TL>0 which means this routine will never 17487c478bd9Sstevel@tonic-gate * actually be called and so we treat this like a BAD TRAP panic. 17497c478bd9Sstevel@tonic-gate */ 17507c478bd9Sstevel@tonic-gatevoid 17517c478bd9Sstevel@tonic-gatece_err_tl1(void) 17527c478bd9Sstevel@tonic-gate{} 17537c478bd9Sstevel@tonic-gate 17547c478bd9Sstevel@tonic-gate#else /* lint */ 17557c478bd9Sstevel@tonic-gate 17567c478bd9Sstevel@tonic-gate .align 64 17577c478bd9Sstevel@tonic-gate ENTRY_NP(ce_err_tl1) 17587c478bd9Sstevel@tonic-gate 17597c478bd9Sstevel@tonic-gate call ptl1_panic 17607c478bd9Sstevel@tonic-gate mov PTL1_BAD_TRAP, %g1 17617c478bd9Sstevel@tonic-gate 17627c478bd9Sstevel@tonic-gate SET_SIZE(ce_err_tl1) 17637c478bd9Sstevel@tonic-gate 17647c478bd9Sstevel@tonic-gate#endif /* lint */ 17657c478bd9Sstevel@tonic-gate 17667c478bd9Sstevel@tonic-gate 17677c478bd9Sstevel@tonic-gate#if defined(lint) 17687c478bd9Sstevel@tonic-gate 17697c478bd9Sstevel@tonic-gatevoid 17707c478bd9Sstevel@tonic-gateasync_err(void) 17717c478bd9Sstevel@tonic-gate{} 17727c478bd9Sstevel@tonic-gate 17737c478bd9Sstevel@tonic-gate#else /* lint */ 17747c478bd9Sstevel@tonic-gate 17757c478bd9Sstevel@tonic-gate/* 17767c478bd9Sstevel@tonic-gate * The async_err function handles deferred trap types 0xA 17777c478bd9Sstevel@tonic-gate * (instruction_access_error) and 0x32 (data_access_error) at TL>=0. 17787c478bd9Sstevel@tonic-gate * 17797c478bd9Sstevel@tonic-gate * AFSR errors bits which cause this trap are: 17807c478bd9Sstevel@tonic-gate * UE, EMU, EDU:BLD, L3_EDU:BLD, TO, BERR 17817c478bd9Sstevel@tonic-gate * On some platforms, EMU may causes cheetah to pull the error pin 17827c478bd9Sstevel@tonic-gate * never giving Solaris a chance to take a trap. 17837c478bd9Sstevel@tonic-gate * 17847c478bd9Sstevel@tonic-gate * NCEEN Bit of Cheetah External Cache Error Enable Register enables 17857c478bd9Sstevel@tonic-gate * the following AFSR deferred traps: UE, EMU, EDU:BLD, TO, BERR 17867c478bd9Sstevel@tonic-gate * 17877c478bd9Sstevel@tonic-gate * Steps: 17887c478bd9Sstevel@tonic-gate * 1. Disable CEEN and NCEEN errors to prevent recursive errors. 17897c478bd9Sstevel@tonic-gate * 2. Turn D$ off per Cheetah PRM P.5 Note 6, turn I$ off to capture 17907c478bd9Sstevel@tonic-gate * I$ line in DO_CPU_LOGOUT. 17917c478bd9Sstevel@tonic-gate * 3. Park sibling core if caches are shared (to avoid race 17927c478bd9Sstevel@tonic-gate * condition while accessing shared resources such as L3 17937c478bd9Sstevel@tonic-gate * data staging register during CPU logout. 17947c478bd9Sstevel@tonic-gate * 4. If the CPU logout structure is not currently being used: 17957c478bd9Sstevel@tonic-gate * 5. Clear AFSR error bits 17967c478bd9Sstevel@tonic-gate * 6. Capture Ecache, Dcache and Icache lines associated 17977c478bd9Sstevel@tonic-gate * with AFAR. 17987c478bd9Sstevel@tonic-gate * 7. Unpark sibling core if we parked it earlier. 17997c478bd9Sstevel@tonic-gate * 8. call cpu_deferred_error via sys_trap. 18007c478bd9Sstevel@tonic-gate * 5. Otherwise, if the CPU logout structure is busy: 18017c478bd9Sstevel@tonic-gate * 6. Incriment "logout busy count" 18027c478bd9Sstevel@tonic-gate * 7. Unpark sibling core if we parked it earlier. 18037c478bd9Sstevel@tonic-gate * 8) Issue a retry since the other CPU error logging 18047c478bd9Sstevel@tonic-gate * code will end up finding this error bit and logging 18057c478bd9Sstevel@tonic-gate * information about it later. 18067c478bd9Sstevel@tonic-gate * 6. Alternatively (to 4 and 5 above), if the cpu_private struct is 18077c478bd9Sstevel@tonic-gate * not yet initialized such that we can't even check the logout 18087c478bd9Sstevel@tonic-gate * struct, then we place the clo_flags data into %g2 18097c478bd9Sstevel@tonic-gate * (sys_trap->have_win arg #1) and call cpu_deferred_error via 18107c478bd9Sstevel@tonic-gate * systrap. The clo_flags parameter is used to determine information 18117c478bd9Sstevel@tonic-gate * such as TL, TT, CEEN settings, etc in the high level trap handler 18127c478bd9Sstevel@tonic-gate * since we don't have access to detailed logout information in cases 18137c478bd9Sstevel@tonic-gate * where the cpu_private struct is not yet initialized. 18147c478bd9Sstevel@tonic-gate * 18157c478bd9Sstevel@tonic-gate * %g2: [ clo_flags if cpu_private unavailable ] - sys_trap->have_win: arg #1 18167c478bd9Sstevel@tonic-gate * %g3: [ logout busy count ] - arg #2 18177c478bd9Sstevel@tonic-gate */ 18187c478bd9Sstevel@tonic-gate 18197c478bd9Sstevel@tonic-gate ENTRY_NP(async_err) 18207c478bd9Sstevel@tonic-gate membar #Sync ! Cheetah requires membar #Sync 18217c478bd9Sstevel@tonic-gate 18227c478bd9Sstevel@tonic-gate /* 18237c478bd9Sstevel@tonic-gate * Disable CEEN and NCEEN. 18247c478bd9Sstevel@tonic-gate */ 18257c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_ESTATE_ERR, %g3 18267c478bd9Sstevel@tonic-gate andn %g3, EN_REG_NCEEN + EN_REG_CEEN, %g4 18277c478bd9Sstevel@tonic-gate stxa %g4, [%g0]ASI_ESTATE_ERR 18287c478bd9Sstevel@tonic-gate membar #Sync ! membar sync required 18297c478bd9Sstevel@tonic-gate 18307c478bd9Sstevel@tonic-gate /* 18317c478bd9Sstevel@tonic-gate * Save current DCU state. 18327c478bd9Sstevel@tonic-gate * Disable Icache to allow capture of Icache data by DO_CPU_LOGOUT. 18337c478bd9Sstevel@tonic-gate * Do this regardless of whether this is a Data Access Error or 18347c478bd9Sstevel@tonic-gate * Instruction Access Error Trap. 18357c478bd9Sstevel@tonic-gate * Disable Dcache for both Data Access Error and Instruction Access 18367c478bd9Sstevel@tonic-gate * Error per Cheetah PRM P.5 Note 6. 18377c478bd9Sstevel@tonic-gate */ 18387c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_DCU, %g1 ! save DCU in %g1 18397c478bd9Sstevel@tonic-gate andn %g1, DCU_IC + DCU_DC, %g4 18407c478bd9Sstevel@tonic-gate stxa %g4, [%g0]ASI_DCU 18417c478bd9Sstevel@tonic-gate flush %g0 /* flush required after changing the IC bit */ 18427c478bd9Sstevel@tonic-gate 18437c478bd9Sstevel@tonic-gate /* 18447c478bd9Sstevel@tonic-gate * Check to see whether we need to park our sibling core 18457c478bd9Sstevel@tonic-gate * before recording diagnostic information from caches 18467c478bd9Sstevel@tonic-gate * which may be shared by both cores. 18477c478bd9Sstevel@tonic-gate * We use %g1 to store information about whether or not 18487c478bd9Sstevel@tonic-gate * we had to park the core (%g1 holds our DCUCR value and 18497c478bd9Sstevel@tonic-gate * we only use bits from that register which are "reserved" 18507c478bd9Sstevel@tonic-gate * to keep track of core parking) so that we know whether 18517c478bd9Sstevel@tonic-gate * or not to unpark later. %g6 and %g4 are scratch registers. 18527c478bd9Sstevel@tonic-gate */ 18537c478bd9Sstevel@tonic-gate PARK_SIBLING_CORE(%g1, %g6, %g4) 18547c478bd9Sstevel@tonic-gate 18557c478bd9Sstevel@tonic-gate /* 18567c478bd9Sstevel@tonic-gate * Do the CPU logout capture. 18577c478bd9Sstevel@tonic-gate * 18587c478bd9Sstevel@tonic-gate * %g3 = "failed?" return value. 18597c478bd9Sstevel@tonic-gate * %g2 = Input = AFAR. Output the clo_flags info which is passed 18607c478bd9Sstevel@tonic-gate * into this macro via %g4. Output only valid if cpu_private 18617c478bd9Sstevel@tonic-gate * struct has not been initialized. 18627c478bd9Sstevel@tonic-gate * CHPR_ASYNC_LOGOUT = cpu logout structure offset input 18637c478bd9Sstevel@tonic-gate * %g4 = Trap information stored in the cpu logout flags field 18647c478bd9Sstevel@tonic-gate * %g5 = scr1 18657c478bd9Sstevel@tonic-gate * %g6 = scr2 18667c478bd9Sstevel@tonic-gate * %g3 = scr3 18677c478bd9Sstevel@tonic-gate * %g4 = scr4 18687c478bd9Sstevel@tonic-gate */ 18697c478bd9Sstevel@tonic-gate andcc %g5, T_TL1, %g0 18707c478bd9Sstevel@tonic-gate clr %g6 18717c478bd9Sstevel@tonic-gate movnz %xcc, 1, %g6 ! set %g6 if T_TL1 set 18727c478bd9Sstevel@tonic-gate sllx %g6, CLO_FLAGS_TL_SHIFT, %g6 18737c478bd9Sstevel@tonic-gate sllx %g5, CLO_FLAGS_TT_SHIFT, %g4 18747c478bd9Sstevel@tonic-gate set CLO_FLAGS_TT_MASK, %g2 18757c478bd9Sstevel@tonic-gate and %g4, %g2, %g4 ! ttype 18767c478bd9Sstevel@tonic-gate or %g6, %g4, %g4 ! TT and TL 18777c478bd9Sstevel@tonic-gate and %g3, EN_REG_CEEN, %g3 ! CEEN value 18787c478bd9Sstevel@tonic-gate or %g3, %g4, %g4 ! TT and TL and CEEN 18797c478bd9Sstevel@tonic-gate set CHPR_ASYNC_LOGOUT, %g6 18807c478bd9Sstevel@tonic-gate DO_CPU_LOGOUT(%g3, %g2, %g6, %g4, %g5, %g6, %g3, %g4) 18817c478bd9Sstevel@tonic-gate 18827c478bd9Sstevel@tonic-gate /* 18837c478bd9Sstevel@tonic-gate * If the logout struct was busy, we may need to pass the 18847c478bd9Sstevel@tonic-gate * TT, TL, and CEEN information to the TL=0 handler via 18857c478bd9Sstevel@tonic-gate * systrap parameter so save it off here. 18867c478bd9Sstevel@tonic-gate */ 18877c478bd9Sstevel@tonic-gate cmp %g3, %g0 18887c478bd9Sstevel@tonic-gate be 1f 18897c478bd9Sstevel@tonic-gate nop 18907c478bd9Sstevel@tonic-gate sllx %g4, 32, %g4 18917c478bd9Sstevel@tonic-gate or %g4, %g3, %g3 18927c478bd9Sstevel@tonic-gate1: 18937c478bd9Sstevel@tonic-gate /* 18947c478bd9Sstevel@tonic-gate * Flush the Icache. Since we turned off the Icache to capture the 18957c478bd9Sstevel@tonic-gate * Icache line it is now stale or corrupted and we must flush it 18967c478bd9Sstevel@tonic-gate * before re-enabling it. 18977c478bd9Sstevel@tonic-gate */ 18987c478bd9Sstevel@tonic-gate GET_CPU_PRIVATE_PTR(%g0, %g5, %g7, async_err_1); 18997c478bd9Sstevel@tonic-gate ld [%g5 + CHPR_ICACHE_LINESIZE], %g6 19007c478bd9Sstevel@tonic-gate ba,pt %icc, 2f 19017c478bd9Sstevel@tonic-gate ld [%g5 + CHPR_ICACHE_SIZE], %g5 19027c478bd9Sstevel@tonic-gateasync_err_1: 19037c478bd9Sstevel@tonic-gate ASM_LD(%g5, icache_size) 19047c478bd9Sstevel@tonic-gate ASM_LD(%g6, icache_linesize) 19057c478bd9Sstevel@tonic-gate2: 19067c478bd9Sstevel@tonic-gate CH_ICACHE_FLUSHALL(%g5, %g6, %g7, %g4) 19077c478bd9Sstevel@tonic-gate 19087c478bd9Sstevel@tonic-gate /* 19097c478bd9Sstevel@tonic-gate * XXX - Don't we need to flush the Dcache before turning it back 19107c478bd9Sstevel@tonic-gate * on to avoid stale or corrupt data? Was this broken? 19117c478bd9Sstevel@tonic-gate */ 19127c478bd9Sstevel@tonic-gate /* 19137c478bd9Sstevel@tonic-gate * Flush the Dcache before turning it back on since it may now 19147c478bd9Sstevel@tonic-gate * contain stale or corrupt data. 19157c478bd9Sstevel@tonic-gate */ 19167c478bd9Sstevel@tonic-gate ASM_LD(%g5, dcache_size) 19177c478bd9Sstevel@tonic-gate ASM_LD(%g6, dcache_linesize) 19187c478bd9Sstevel@tonic-gate CH_DCACHE_FLUSHALL(%g5, %g6, %g7) 19197c478bd9Sstevel@tonic-gate 19207c478bd9Sstevel@tonic-gate /* 19217c478bd9Sstevel@tonic-gate * check to see whether we parked our sibling core at the start 19227c478bd9Sstevel@tonic-gate * of this handler. If so, we need to unpark it here. 19237c478bd9Sstevel@tonic-gate * We use DCUCR reserved bits (stored in %g1) to keep track of 19247c478bd9Sstevel@tonic-gate * whether or not we need to unpark. %g5 and %g7 are scratch registers. 19257c478bd9Sstevel@tonic-gate */ 19267c478bd9Sstevel@tonic-gate UNPARK_SIBLING_CORE(%g1, %g5, %g7) 19277c478bd9Sstevel@tonic-gate 19287c478bd9Sstevel@tonic-gate /* 19297c478bd9Sstevel@tonic-gate * Restore Icache and Dcache to previous state. 19307c478bd9Sstevel@tonic-gate */ 19317c478bd9Sstevel@tonic-gate stxa %g1, [%g0]ASI_DCU 19327c478bd9Sstevel@tonic-gate flush %g0 /* flush required after changing the IC bit */ 19337c478bd9Sstevel@tonic-gate 19347c478bd9Sstevel@tonic-gate /* 19357c478bd9Sstevel@tonic-gate * Make sure our CPU logout operation was successful. 19367c478bd9Sstevel@tonic-gate */ 19377c478bd9Sstevel@tonic-gate cmp %g3, %g0 19387c478bd9Sstevel@tonic-gate be 4f 19397c478bd9Sstevel@tonic-gate nop 19407c478bd9Sstevel@tonic-gate 19417c478bd9Sstevel@tonic-gate /* 19427c478bd9Sstevel@tonic-gate * If the logout structure had been busy, how many times have 19437c478bd9Sstevel@tonic-gate * we tried to use it and failed (nesting count)? If we have 19447c478bd9Sstevel@tonic-gate * already recursed a substantial number of times, then we can 19457c478bd9Sstevel@tonic-gate * assume things are not going to get better by themselves and 19467c478bd9Sstevel@tonic-gate * so it would be best to panic. 19477c478bd9Sstevel@tonic-gate */ 19487c478bd9Sstevel@tonic-gate cmp %g3, CLO_NESTING_MAX 19497c478bd9Sstevel@tonic-gate blt 3f 19507c478bd9Sstevel@tonic-gate nop 19517c478bd9Sstevel@tonic-gate 19527c478bd9Sstevel@tonic-gate call ptl1_panic 19537c478bd9Sstevel@tonic-gate mov PTL1_BAD_ECC, %g1 19547c478bd9Sstevel@tonic-gate 19557c478bd9Sstevel@tonic-gate3: 19567c478bd9Sstevel@tonic-gate /* 19577c478bd9Sstevel@tonic-gate * Otherwise, if the logout structure was busy but we have not 19587c478bd9Sstevel@tonic-gate * nested more times than our maximum value, then we simply 19597c478bd9Sstevel@tonic-gate * issue a retry. Our TL=0 trap handler code will check and 19607c478bd9Sstevel@tonic-gate * clear the AFSR after it is done logging what is currently 19617c478bd9Sstevel@tonic-gate * in the logout struct and handle this event at that time. 19627c478bd9Sstevel@tonic-gate */ 19637c478bd9Sstevel@tonic-gate retry 19647c478bd9Sstevel@tonic-gate4: 19652dd3029aSjimand RESET_USER_RTT_REGS(%g4, %g5, async_err_resetskip) 19662dd3029aSjimandasync_err_resetskip: 19677c478bd9Sstevel@tonic-gate set cpu_deferred_error, %g1 19687c478bd9Sstevel@tonic-gate ba sys_trap 19697c478bd9Sstevel@tonic-gate mov PIL_15, %g4 ! run at pil 15 19707c478bd9Sstevel@tonic-gate SET_SIZE(async_err) 19717c478bd9Sstevel@tonic-gate 19727c478bd9Sstevel@tonic-gate#endif /* lint */ 19737c478bd9Sstevel@tonic-gate 19747c478bd9Sstevel@tonic-gate#if defined(CPU_IMP_L1_CACHE_PARITY) 19757c478bd9Sstevel@tonic-gate 19767c478bd9Sstevel@tonic-gate/* 19777c478bd9Sstevel@tonic-gate * D$ parity error trap (trap 71) at TL=0. 19787c478bd9Sstevel@tonic-gate * tt0_dperr is replaced by dcache_parity_instr in cpu_init_trap of 19797c478bd9Sstevel@tonic-gate * the various architecture-specific files. This merely sets up the 19807c478bd9Sstevel@tonic-gate * arguments for cpu_parity_error and calls it via sys_trap. 19817c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must 19827c478bd9Sstevel@tonic-gate * be relocatable. 19837c478bd9Sstevel@tonic-gate */ 19847c478bd9Sstevel@tonic-gate#if defined(lint) 19857c478bd9Sstevel@tonic-gate 19867c478bd9Sstevel@tonic-gatevoid 19877c478bd9Sstevel@tonic-gatedcache_parity_instr(void) 19887c478bd9Sstevel@tonic-gate{} 19897c478bd9Sstevel@tonic-gate 19907c478bd9Sstevel@tonic-gate#else /* lint */ 19917c478bd9Sstevel@tonic-gate ENTRY_NP(dcache_parity_instr) 19927c478bd9Sstevel@tonic-gate membar #Sync ! Cheetah+ requires membar #Sync 19937c478bd9Sstevel@tonic-gate set cpu_parity_error, %g1 19947c478bd9Sstevel@tonic-gate or %g0, CH_ERR_DPE, %g2 19957c478bd9Sstevel@tonic-gate rdpr %tpc, %g3 19967c478bd9Sstevel@tonic-gate sethi %hi(sys_trap), %g7 19977c478bd9Sstevel@tonic-gate jmp %g7 + %lo(sys_trap) 19987c478bd9Sstevel@tonic-gate mov PIL_15, %g4 ! run at pil 15 19997c478bd9Sstevel@tonic-gate SET_SIZE(dcache_parity_instr) 20007c478bd9Sstevel@tonic-gate 20017c478bd9Sstevel@tonic-gate#endif /* lint */ 20027c478bd9Sstevel@tonic-gate 20037c478bd9Sstevel@tonic-gate 20047c478bd9Sstevel@tonic-gate/* 20057c478bd9Sstevel@tonic-gate * D$ parity error trap (trap 71) at TL>0. 20067c478bd9Sstevel@tonic-gate * tt1_dperr is replaced by dcache_parity_tl1_instr in cpu_init_trap of 20077c478bd9Sstevel@tonic-gate * the various architecture-specific files. This generates a "Software 20087c478bd9Sstevel@tonic-gate * Trap 1" at TL>0, which goes to dcache_parity_tl1_cont_instr, and we 20097c478bd9Sstevel@tonic-gate * continue the handling there. 20107c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must 20117c478bd9Sstevel@tonic-gate * be relocatable. 20127c478bd9Sstevel@tonic-gate */ 20137c478bd9Sstevel@tonic-gate#if defined(lint) 20147c478bd9Sstevel@tonic-gate 20157c478bd9Sstevel@tonic-gatevoid 20167c478bd9Sstevel@tonic-gatedcache_parity_tl1_instr(void) 20177c478bd9Sstevel@tonic-gate{} 20187c478bd9Sstevel@tonic-gate 20197c478bd9Sstevel@tonic-gate#else /* lint */ 20207c478bd9Sstevel@tonic-gate ENTRY_NP(dcache_parity_tl1_instr) 20217c478bd9Sstevel@tonic-gate CH_ERR_TL1_TRAPENTRY(SWTRAP_1); 20227c478bd9Sstevel@tonic-gate SET_SIZE(dcache_parity_tl1_instr) 20237c478bd9Sstevel@tonic-gate 20247c478bd9Sstevel@tonic-gate#endif /* lint */ 20257c478bd9Sstevel@tonic-gate 20267c478bd9Sstevel@tonic-gate 20277c478bd9Sstevel@tonic-gate/* 20287c478bd9Sstevel@tonic-gate * Software trap 1 at TL>0. 20297c478bd9Sstevel@tonic-gate * tt1_swtrap1 is replaced by dcache_parity_tl1_cont_instr in cpu_init_trap 20307c478bd9Sstevel@tonic-gate * of the various architecture-specific files. This is used as a continuation 20317c478bd9Sstevel@tonic-gate * of the dcache parity handling where we've bought an extra TL level, so we 20327c478bd9Sstevel@tonic-gate * can use %tpc, %tnpc, %tstate to temporarily save the value of registers %g1 20337c478bd9Sstevel@tonic-gate * and %g2. Note that %tstate has bits 0-2 and then bits 8-19 as r/w, 20347c478bd9Sstevel@tonic-gate * there's a reserved hole from 3-7. We only use bits 0-1 and 8-9 (the low 20357c478bd9Sstevel@tonic-gate * order two bits from %g1 and %g2 respectively). 20367c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must 20377c478bd9Sstevel@tonic-gate * be relocatable. 20387c478bd9Sstevel@tonic-gate */ 20397c478bd9Sstevel@tonic-gate#if defined(lint) 20407c478bd9Sstevel@tonic-gate 20417c478bd9Sstevel@tonic-gatevoid 20427c478bd9Sstevel@tonic-gatedcache_parity_tl1_cont_instr(void) 20437c478bd9Sstevel@tonic-gate{} 20447c478bd9Sstevel@tonic-gate 20457c478bd9Sstevel@tonic-gate#else /* lint */ 20467c478bd9Sstevel@tonic-gate ENTRY_NP(dcache_parity_tl1_cont_instr) 20477c478bd9Sstevel@tonic-gate CH_ERR_TL1_SWTRAPENTRY(dcache_parity_tl1_err); 20487c478bd9Sstevel@tonic-gate SET_SIZE(dcache_parity_tl1_cont_instr) 20497c478bd9Sstevel@tonic-gate 20507c478bd9Sstevel@tonic-gate#endif /* lint */ 20517c478bd9Sstevel@tonic-gate 20527c478bd9Sstevel@tonic-gate/* 20537c478bd9Sstevel@tonic-gate * D$ parity error at TL>0 handler 20547c478bd9Sstevel@tonic-gate * We get here via trap 71 at TL>0->Software trap 1 at TL>0. We enter 20557c478bd9Sstevel@tonic-gate * this routine with %g1 and %g2 already saved in %tpc, %tnpc and %tstate. 20567c478bd9Sstevel@tonic-gate */ 20577c478bd9Sstevel@tonic-gate#if defined(lint) 20587c478bd9Sstevel@tonic-gate 20597c478bd9Sstevel@tonic-gatevoid 20607c478bd9Sstevel@tonic-gatedcache_parity_tl1_err(void) 20617c478bd9Sstevel@tonic-gate{} 20627c478bd9Sstevel@tonic-gate 20637c478bd9Sstevel@tonic-gate#else /* lint */ 20647c478bd9Sstevel@tonic-gate 20657c478bd9Sstevel@tonic-gate ENTRY_NP(dcache_parity_tl1_err) 20667c478bd9Sstevel@tonic-gate 20677c478bd9Sstevel@tonic-gate /* 20687c478bd9Sstevel@tonic-gate * This macro saves all the %g registers in the ch_err_tl1_data 20697c478bd9Sstevel@tonic-gate * structure, updates the ch_err_tl1_flags and saves the %tpc in 20707c478bd9Sstevel@tonic-gate * ch_err_tl1_tpc. At the end of this macro, %g1 will point to 20717c478bd9Sstevel@tonic-gate * the ch_err_tl1_data structure and %g2 will have the original 20727c478bd9Sstevel@tonic-gate * flags in the ch_err_tl1_data structure. All %g registers 20737c478bd9Sstevel@tonic-gate * except for %g1 and %g2 will be available. 20747c478bd9Sstevel@tonic-gate */ 20757c478bd9Sstevel@tonic-gate CH_ERR_TL1_ENTER(CH_ERR_DPE); 20767c478bd9Sstevel@tonic-gate 20777c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 20787c478bd9Sstevel@tonic-gate /* 20797c478bd9Sstevel@tonic-gate * Get current trap trace entry physical pointer. 20807c478bd9Sstevel@tonic-gate */ 20817c478bd9Sstevel@tonic-gate CPU_INDEX(%g6, %g5) 20827c478bd9Sstevel@tonic-gate sll %g6, TRAPTR_SIZE_SHIFT, %g6 20837c478bd9Sstevel@tonic-gate set trap_trace_ctl, %g5 20847c478bd9Sstevel@tonic-gate add %g6, %g5, %g6 20857c478bd9Sstevel@tonic-gate ld [%g6 + TRAPTR_LIMIT], %g5 20867c478bd9Sstevel@tonic-gate tst %g5 20877c478bd9Sstevel@tonic-gate be %icc, dpe_tl1_skip_tt 20887c478bd9Sstevel@tonic-gate nop 20897c478bd9Sstevel@tonic-gate ldx [%g6 + TRAPTR_PBASE], %g5 20907c478bd9Sstevel@tonic-gate ld [%g6 + TRAPTR_OFFSET], %g4 20917c478bd9Sstevel@tonic-gate add %g5, %g4, %g5 20927c478bd9Sstevel@tonic-gate 20937c478bd9Sstevel@tonic-gate /* 20947c478bd9Sstevel@tonic-gate * Create trap trace entry. 20957c478bd9Sstevel@tonic-gate */ 20967c478bd9Sstevel@tonic-gate rd %asi, %g7 20977c478bd9Sstevel@tonic-gate wr %g0, TRAPTR_ASI, %asi 20987c478bd9Sstevel@tonic-gate rd STICK, %g4 20997c478bd9Sstevel@tonic-gate stxa %g4, [%g5 + TRAP_ENT_TICK]%asi 21007c478bd9Sstevel@tonic-gate rdpr %tl, %g4 21017c478bd9Sstevel@tonic-gate stha %g4, [%g5 + TRAP_ENT_TL]%asi 21027c478bd9Sstevel@tonic-gate rdpr %tt, %g4 21037c478bd9Sstevel@tonic-gate stha %g4, [%g5 + TRAP_ENT_TT]%asi 21047c478bd9Sstevel@tonic-gate rdpr %tpc, %g4 21057c478bd9Sstevel@tonic-gate stna %g4, [%g5 + TRAP_ENT_TPC]%asi 21067c478bd9Sstevel@tonic-gate rdpr %tstate, %g4 21077c478bd9Sstevel@tonic-gate stxa %g4, [%g5 + TRAP_ENT_TSTATE]%asi 21087c478bd9Sstevel@tonic-gate stna %sp, [%g5 + TRAP_ENT_SP]%asi 21097c478bd9Sstevel@tonic-gate stna %g0, [%g5 + TRAP_ENT_TR]%asi 21107c478bd9Sstevel@tonic-gate stna %g0, [%g5 + TRAP_ENT_F1]%asi 21117c478bd9Sstevel@tonic-gate stna %g0, [%g5 + TRAP_ENT_F2]%asi 21127c478bd9Sstevel@tonic-gate stna %g0, [%g5 + TRAP_ENT_F3]%asi 21137c478bd9Sstevel@tonic-gate stna %g0, [%g5 + TRAP_ENT_F4]%asi 21147c478bd9Sstevel@tonic-gate wr %g0, %g7, %asi 21157c478bd9Sstevel@tonic-gate 21167c478bd9Sstevel@tonic-gate /* 21177c478bd9Sstevel@tonic-gate * Advance trap trace pointer. 21187c478bd9Sstevel@tonic-gate */ 21197c478bd9Sstevel@tonic-gate ld [%g6 + TRAPTR_OFFSET], %g5 21207c478bd9Sstevel@tonic-gate ld [%g6 + TRAPTR_LIMIT], %g4 21217c478bd9Sstevel@tonic-gate st %g5, [%g6 + TRAPTR_LAST_OFFSET] 21227c478bd9Sstevel@tonic-gate add %g5, TRAP_ENT_SIZE, %g5 21237c478bd9Sstevel@tonic-gate sub %g4, TRAP_ENT_SIZE, %g4 21247c478bd9Sstevel@tonic-gate cmp %g5, %g4 21257c478bd9Sstevel@tonic-gate movge %icc, 0, %g5 21267c478bd9Sstevel@tonic-gate st %g5, [%g6 + TRAPTR_OFFSET] 21277c478bd9Sstevel@tonic-gatedpe_tl1_skip_tt: 21287c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */ 21297c478bd9Sstevel@tonic-gate 21307c478bd9Sstevel@tonic-gate /* 21317c478bd9Sstevel@tonic-gate * I$ and D$ are automatically turned off by HW when the CPU hits 21327c478bd9Sstevel@tonic-gate * a dcache or icache parity error so we will just leave those two 21337c478bd9Sstevel@tonic-gate * off for now to avoid repeating this trap. 21347c478bd9Sstevel@tonic-gate * For Panther, however, since we trap on P$ data parity errors 21357c478bd9Sstevel@tonic-gate * and HW does not automatically disable P$, we need to disable it 21367c478bd9Sstevel@tonic-gate * here so that we don't encounter any recursive traps when we 21377c478bd9Sstevel@tonic-gate * issue the retry. 21387c478bd9Sstevel@tonic-gate */ 21397c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_DCU, %g3 21407c478bd9Sstevel@tonic-gate mov 1, %g4 21417c478bd9Sstevel@tonic-gate sllx %g4, DCU_PE_SHIFT, %g4 21427c478bd9Sstevel@tonic-gate andn %g3, %g4, %g3 21437c478bd9Sstevel@tonic-gate stxa %g3, [%g0]ASI_DCU 21447c478bd9Sstevel@tonic-gate membar #Sync 21457c478bd9Sstevel@tonic-gate 21467c478bd9Sstevel@tonic-gate /* 21477c478bd9Sstevel@tonic-gate * We fall into this macro if we've successfully logged the error in 21487c478bd9Sstevel@tonic-gate * the ch_err_tl1_data structure and want the PIL15 softint to pick 21497c478bd9Sstevel@tonic-gate * it up and log it. %g1 must point to the ch_err_tl1_data structure. 21507c478bd9Sstevel@tonic-gate * Restores the %g registers and issues retry. 21517c478bd9Sstevel@tonic-gate */ 21527c478bd9Sstevel@tonic-gate CH_ERR_TL1_EXIT; 21537c478bd9Sstevel@tonic-gate SET_SIZE(dcache_parity_tl1_err) 21547c478bd9Sstevel@tonic-gate 21557c478bd9Sstevel@tonic-gate#endif /* lint */ 21567c478bd9Sstevel@tonic-gate 21577c478bd9Sstevel@tonic-gate/* 21587c478bd9Sstevel@tonic-gate * I$ parity error trap (trap 72) at TL=0. 21597c478bd9Sstevel@tonic-gate * tt0_iperr is replaced by icache_parity_instr in cpu_init_trap of 21607c478bd9Sstevel@tonic-gate * the various architecture-specific files. This merely sets up the 21617c478bd9Sstevel@tonic-gate * arguments for cpu_parity_error and calls it via sys_trap. 21627c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must 21637c478bd9Sstevel@tonic-gate * be relocatable. 21647c478bd9Sstevel@tonic-gate */ 21657c478bd9Sstevel@tonic-gate#if defined(lint) 21667c478bd9Sstevel@tonic-gate 21677c478bd9Sstevel@tonic-gatevoid 21687c478bd9Sstevel@tonic-gateicache_parity_instr(void) 21697c478bd9Sstevel@tonic-gate{} 21707c478bd9Sstevel@tonic-gate 21717c478bd9Sstevel@tonic-gate#else /* lint */ 21727c478bd9Sstevel@tonic-gate 21737c478bd9Sstevel@tonic-gate ENTRY_NP(icache_parity_instr) 21747c478bd9Sstevel@tonic-gate membar #Sync ! Cheetah+ requires membar #Sync 21757c478bd9Sstevel@tonic-gate set cpu_parity_error, %g1 21767c478bd9Sstevel@tonic-gate or %g0, CH_ERR_IPE, %g2 21777c478bd9Sstevel@tonic-gate rdpr %tpc, %g3 21787c478bd9Sstevel@tonic-gate sethi %hi(sys_trap), %g7 21797c478bd9Sstevel@tonic-gate jmp %g7 + %lo(sys_trap) 21807c478bd9Sstevel@tonic-gate mov PIL_15, %g4 ! run at pil 15 21817c478bd9Sstevel@tonic-gate SET_SIZE(icache_parity_instr) 21827c478bd9Sstevel@tonic-gate 21837c478bd9Sstevel@tonic-gate#endif /* lint */ 21847c478bd9Sstevel@tonic-gate 21857c478bd9Sstevel@tonic-gate/* 21867c478bd9Sstevel@tonic-gate * I$ parity error trap (trap 72) at TL>0. 21877c478bd9Sstevel@tonic-gate * tt1_iperr is replaced by icache_parity_tl1_instr in cpu_init_trap of 21887c478bd9Sstevel@tonic-gate * the various architecture-specific files. This generates a "Software 21897c478bd9Sstevel@tonic-gate * Trap 2" at TL>0, which goes to icache_parity_tl1_cont_instr, and we 21907c478bd9Sstevel@tonic-gate * continue the handling there. 21917c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must 21927c478bd9Sstevel@tonic-gate * be relocatable. 21937c478bd9Sstevel@tonic-gate */ 21947c478bd9Sstevel@tonic-gate#if defined(lint) 21957c478bd9Sstevel@tonic-gate 21967c478bd9Sstevel@tonic-gatevoid 21977c478bd9Sstevel@tonic-gateicache_parity_tl1_instr(void) 21987c478bd9Sstevel@tonic-gate{} 21997c478bd9Sstevel@tonic-gate 22007c478bd9Sstevel@tonic-gate#else /* lint */ 22017c478bd9Sstevel@tonic-gate ENTRY_NP(icache_parity_tl1_instr) 22027c478bd9Sstevel@tonic-gate CH_ERR_TL1_TRAPENTRY(SWTRAP_2); 22037c478bd9Sstevel@tonic-gate SET_SIZE(icache_parity_tl1_instr) 22047c478bd9Sstevel@tonic-gate 22057c478bd9Sstevel@tonic-gate#endif /* lint */ 22067c478bd9Sstevel@tonic-gate 22077c478bd9Sstevel@tonic-gate/* 22087c478bd9Sstevel@tonic-gate * Software trap 2 at TL>0. 22097c478bd9Sstevel@tonic-gate * tt1_swtrap2 is replaced by icache_parity_tl1_cont_instr in cpu_init_trap 22107c478bd9Sstevel@tonic-gate * of the various architecture-specific files. This is used as a continuation 22117c478bd9Sstevel@tonic-gate * of the icache parity handling where we've bought an extra TL level, so we 22127c478bd9Sstevel@tonic-gate * can use %tpc, %tnpc, %tstate to temporarily save the value of registers %g1 22137c478bd9Sstevel@tonic-gate * and %g2. Note that %tstate has bits 0-2 and then bits 8-19 as r/w, 22147c478bd9Sstevel@tonic-gate * there's a reserved hole from 3-7. We only use bits 0-1 and 8-9 (the low 22157c478bd9Sstevel@tonic-gate * order two bits from %g1 and %g2 respectively). 22167c478bd9Sstevel@tonic-gate * NB: Must be 8 instructions or less to fit in trap table and code must 22177c478bd9Sstevel@tonic-gate * be relocatable. 22187c478bd9Sstevel@tonic-gate */ 22197c478bd9Sstevel@tonic-gate#if defined(lint) 22207c478bd9Sstevel@tonic-gate 22217c478bd9Sstevel@tonic-gatevoid 22227c478bd9Sstevel@tonic-gateicache_parity_tl1_cont_instr(void) 22237c478bd9Sstevel@tonic-gate{} 22247c478bd9Sstevel@tonic-gate 22257c478bd9Sstevel@tonic-gate#else /* lint */ 22267c478bd9Sstevel@tonic-gate ENTRY_NP(icache_parity_tl1_cont_instr) 22277c478bd9Sstevel@tonic-gate CH_ERR_TL1_SWTRAPENTRY(icache_parity_tl1_err); 22287c478bd9Sstevel@tonic-gate SET_SIZE(icache_parity_tl1_cont_instr) 22297c478bd9Sstevel@tonic-gate 22307c478bd9Sstevel@tonic-gate#endif /* lint */ 22317c478bd9Sstevel@tonic-gate 22327c478bd9Sstevel@tonic-gate 22337c478bd9Sstevel@tonic-gate/* 22347c478bd9Sstevel@tonic-gate * I$ parity error at TL>0 handler 22357c478bd9Sstevel@tonic-gate * We get here via trap 72 at TL>0->Software trap 2 at TL>0. We enter 22367c478bd9Sstevel@tonic-gate * this routine with %g1 and %g2 already saved in %tpc, %tnpc and %tstate. 22377c478bd9Sstevel@tonic-gate */ 22387c478bd9Sstevel@tonic-gate#if defined(lint) 22397c478bd9Sstevel@tonic-gate 22407c478bd9Sstevel@tonic-gatevoid 22417c478bd9Sstevel@tonic-gateicache_parity_tl1_err(void) 22427c478bd9Sstevel@tonic-gate{} 22437c478bd9Sstevel@tonic-gate 22447c478bd9Sstevel@tonic-gate#else /* lint */ 22457c478bd9Sstevel@tonic-gate 22467c478bd9Sstevel@tonic-gate ENTRY_NP(icache_parity_tl1_err) 22477c478bd9Sstevel@tonic-gate 22487c478bd9Sstevel@tonic-gate /* 22497c478bd9Sstevel@tonic-gate * This macro saves all the %g registers in the ch_err_tl1_data 22507c478bd9Sstevel@tonic-gate * structure, updates the ch_err_tl1_flags and saves the %tpc in 22517c478bd9Sstevel@tonic-gate * ch_err_tl1_tpc. At the end of this macro, %g1 will point to 22527c478bd9Sstevel@tonic-gate * the ch_err_tl1_data structure and %g2 will have the original 22537c478bd9Sstevel@tonic-gate * flags in the ch_err_tl1_data structure. All %g registers 22547c478bd9Sstevel@tonic-gate * except for %g1 and %g2 will be available. 22557c478bd9Sstevel@tonic-gate */ 22567c478bd9Sstevel@tonic-gate CH_ERR_TL1_ENTER(CH_ERR_IPE); 22577c478bd9Sstevel@tonic-gate 22587c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 22597c478bd9Sstevel@tonic-gate /* 22607c478bd9Sstevel@tonic-gate * Get current trap trace entry physical pointer. 22617c478bd9Sstevel@tonic-gate */ 22627c478bd9Sstevel@tonic-gate CPU_INDEX(%g6, %g5) 22637c478bd9Sstevel@tonic-gate sll %g6, TRAPTR_SIZE_SHIFT, %g6 22647c478bd9Sstevel@tonic-gate set trap_trace_ctl, %g5 22657c478bd9Sstevel@tonic-gate add %g6, %g5, %g6 22667c478bd9Sstevel@tonic-gate ld [%g6 + TRAPTR_LIMIT], %g5 22677c478bd9Sstevel@tonic-gate tst %g5 22687c478bd9Sstevel@tonic-gate be %icc, ipe_tl1_skip_tt 22697c478bd9Sstevel@tonic-gate nop 22707c478bd9Sstevel@tonic-gate ldx [%g6 + TRAPTR_PBASE], %g5 22717c478bd9Sstevel@tonic-gate ld [%g6 + TRAPTR_OFFSET], %g4 22727c478bd9Sstevel@tonic-gate add %g5, %g4, %g5 22737c478bd9Sstevel@tonic-gate 22747c478bd9Sstevel@tonic-gate /* 22757c478bd9Sstevel@tonic-gate * Create trap trace entry. 22767c478bd9Sstevel@tonic-gate */ 22777c478bd9Sstevel@tonic-gate rd %asi, %g7 22787c478bd9Sstevel@tonic-gate wr %g0, TRAPTR_ASI, %asi 22797c478bd9Sstevel@tonic-gate rd STICK, %g4 22807c478bd9Sstevel@tonic-gate stxa %g4, [%g5 + TRAP_ENT_TICK]%asi 22817c478bd9Sstevel@tonic-gate rdpr %tl, %g4 22827c478bd9Sstevel@tonic-gate stha %g4, [%g5 + TRAP_ENT_TL]%asi 22837c478bd9Sstevel@tonic-gate rdpr %tt, %g4 22847c478bd9Sstevel@tonic-gate stha %g4, [%g5 + TRAP_ENT_TT]%asi 22857c478bd9Sstevel@tonic-gate rdpr %tpc, %g4 22867c478bd9Sstevel@tonic-gate stna %g4, [%g5 + TRAP_ENT_TPC]%asi 22877c478bd9Sstevel@tonic-gate rdpr %tstate, %g4 22887c478bd9Sstevel@tonic-gate stxa %g4, [%g5 + TRAP_ENT_TSTATE]%asi 22897c478bd9Sstevel@tonic-gate stna %sp, [%g5 + TRAP_ENT_SP]%asi 22907c478bd9Sstevel@tonic-gate stna %g0, [%g5 + TRAP_ENT_TR]%asi 22917c478bd9Sstevel@tonic-gate stna %g0, [%g5 + TRAP_ENT_F1]%asi 22927c478bd9Sstevel@tonic-gate stna %g0, [%g5 + TRAP_ENT_F2]%asi 22937c478bd9Sstevel@tonic-gate stna %g0, [%g5 + TRAP_ENT_F3]%asi 22947c478bd9Sstevel@tonic-gate stna %g0, [%g5 + TRAP_ENT_F4]%asi 22957c478bd9Sstevel@tonic-gate wr %g0, %g7, %asi 22967c478bd9Sstevel@tonic-gate 22977c478bd9Sstevel@tonic-gate /* 22987c478bd9Sstevel@tonic-gate * Advance trap trace pointer. 22997c478bd9Sstevel@tonic-gate */ 23007c478bd9Sstevel@tonic-gate ld [%g6 + TRAPTR_OFFSET], %g5 23017c478bd9Sstevel@tonic-gate ld [%g6 + TRAPTR_LIMIT], %g4 23027c478bd9Sstevel@tonic-gate st %g5, [%g6 + TRAPTR_LAST_OFFSET] 23037c478bd9Sstevel@tonic-gate add %g5, TRAP_ENT_SIZE, %g5 23047c478bd9Sstevel@tonic-gate sub %g4, TRAP_ENT_SIZE, %g4 23057c478bd9Sstevel@tonic-gate cmp %g5, %g4 23067c478bd9Sstevel@tonic-gate movge %icc, 0, %g5 23077c478bd9Sstevel@tonic-gate st %g5, [%g6 + TRAPTR_OFFSET] 23087c478bd9Sstevel@tonic-gateipe_tl1_skip_tt: 23097c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */ 23107c478bd9Sstevel@tonic-gate 23117c478bd9Sstevel@tonic-gate /* 23127c478bd9Sstevel@tonic-gate * We fall into this macro if we've successfully logged the error in 23137c478bd9Sstevel@tonic-gate * the ch_err_tl1_data structure and want the PIL15 softint to pick 23147c478bd9Sstevel@tonic-gate * it up and log it. %g1 must point to the ch_err_tl1_data structure. 23157c478bd9Sstevel@tonic-gate * Restores the %g registers and issues retry. 23167c478bd9Sstevel@tonic-gate */ 23177c478bd9Sstevel@tonic-gate CH_ERR_TL1_EXIT; 23187c478bd9Sstevel@tonic-gate 23197c478bd9Sstevel@tonic-gate SET_SIZE(icache_parity_tl1_err) 23207c478bd9Sstevel@tonic-gate 23217c478bd9Sstevel@tonic-gate#endif /* lint */ 23227c478bd9Sstevel@tonic-gate 23237c478bd9Sstevel@tonic-gate#endif /* CPU_IMP_L1_CACHE_PARITY */ 23247c478bd9Sstevel@tonic-gate 23257c478bd9Sstevel@tonic-gate 23267c478bd9Sstevel@tonic-gate/* 23277c478bd9Sstevel@tonic-gate * The itlb_rd_entry and dtlb_rd_entry functions return the tag portion of the 23287c478bd9Sstevel@tonic-gate * tte, the virtual address, and the ctxnum of the specified tlb entry. They 23297c478bd9Sstevel@tonic-gate * should only be used in places where you have no choice but to look at the 23307c478bd9Sstevel@tonic-gate * tlb itself. 23317c478bd9Sstevel@tonic-gate * 23327c478bd9Sstevel@tonic-gate * Note: These two routines are required by the Estar "cpr" loadable module. 23337c478bd9Sstevel@tonic-gate */ 23347c478bd9Sstevel@tonic-gate 23357c478bd9Sstevel@tonic-gate#if defined(lint) 23367c478bd9Sstevel@tonic-gate 23377c478bd9Sstevel@tonic-gate/* ARGSUSED */ 23387c478bd9Sstevel@tonic-gatevoid 23397c478bd9Sstevel@tonic-gateitlb_rd_entry(uint_t entry, tte_t *tte, uint64_t *va_tag) 23407c478bd9Sstevel@tonic-gate{} 23417c478bd9Sstevel@tonic-gate 23427c478bd9Sstevel@tonic-gate#else /* lint */ 23437c478bd9Sstevel@tonic-gate 23447c478bd9Sstevel@tonic-gate ENTRY_NP(itlb_rd_entry) 23457c478bd9Sstevel@tonic-gate sllx %o0, 3, %o0 23467c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_ITLB_ACCESS, %g1 23477c478bd9Sstevel@tonic-gate stx %g1, [%o1] 23487c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_ITLB_TAGREAD, %g2 23497c478bd9Sstevel@tonic-gate set TAGREAD_CTX_MASK, %o4 23507c478bd9Sstevel@tonic-gate andn %g2, %o4, %o5 23517c478bd9Sstevel@tonic-gate retl 23527c478bd9Sstevel@tonic-gate stx %o5, [%o2] 23537c478bd9Sstevel@tonic-gate SET_SIZE(itlb_rd_entry) 23547c478bd9Sstevel@tonic-gate 23557c478bd9Sstevel@tonic-gate#endif /* lint */ 23567c478bd9Sstevel@tonic-gate 23577c478bd9Sstevel@tonic-gate 23587c478bd9Sstevel@tonic-gate#if defined(lint) 23597c478bd9Sstevel@tonic-gate 23607c478bd9Sstevel@tonic-gate/* ARGSUSED */ 23617c478bd9Sstevel@tonic-gatevoid 23627c478bd9Sstevel@tonic-gatedtlb_rd_entry(uint_t entry, tte_t *tte, uint64_t *va_tag) 23637c478bd9Sstevel@tonic-gate{} 23647c478bd9Sstevel@tonic-gate 23657c478bd9Sstevel@tonic-gate#else /* lint */ 23667c478bd9Sstevel@tonic-gate 23677c478bd9Sstevel@tonic-gate ENTRY_NP(dtlb_rd_entry) 23687c478bd9Sstevel@tonic-gate sllx %o0, 3, %o0 23697c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_DTLB_ACCESS, %g1 23707c478bd9Sstevel@tonic-gate stx %g1, [%o1] 23717c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_DTLB_TAGREAD, %g2 23727c478bd9Sstevel@tonic-gate set TAGREAD_CTX_MASK, %o4 23737c478bd9Sstevel@tonic-gate andn %g2, %o4, %o5 23747c478bd9Sstevel@tonic-gate retl 23757c478bd9Sstevel@tonic-gate stx %o5, [%o2] 23767c478bd9Sstevel@tonic-gate SET_SIZE(dtlb_rd_entry) 23777c478bd9Sstevel@tonic-gate#endif /* lint */ 23787c478bd9Sstevel@tonic-gate 23797c478bd9Sstevel@tonic-gate 23807c478bd9Sstevel@tonic-gate#if !(defined(JALAPENO) || defined(SERRANO)) 23817c478bd9Sstevel@tonic-gate 23827c478bd9Sstevel@tonic-gate#if defined(lint) 23837c478bd9Sstevel@tonic-gate 23847c478bd9Sstevel@tonic-gateuint64_t 23857c478bd9Sstevel@tonic-gateget_safari_config(void) 23867c478bd9Sstevel@tonic-gate{ return (0); } 23877c478bd9Sstevel@tonic-gate 23887c478bd9Sstevel@tonic-gate#else /* lint */ 23897c478bd9Sstevel@tonic-gate 23907c478bd9Sstevel@tonic-gate ENTRY(get_safari_config) 23917c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_SAFARI_CONFIG, %o0 23927c478bd9Sstevel@tonic-gate retl 23937c478bd9Sstevel@tonic-gate nop 23947c478bd9Sstevel@tonic-gate SET_SIZE(get_safari_config) 23957c478bd9Sstevel@tonic-gate 23967c478bd9Sstevel@tonic-gate#endif /* lint */ 23977c478bd9Sstevel@tonic-gate 23987c478bd9Sstevel@tonic-gate 23997c478bd9Sstevel@tonic-gate#if defined(lint) 24007c478bd9Sstevel@tonic-gate 24017c478bd9Sstevel@tonic-gate/* ARGSUSED */ 24027c478bd9Sstevel@tonic-gatevoid 24037c478bd9Sstevel@tonic-gateset_safari_config(uint64_t safari_config) 24047c478bd9Sstevel@tonic-gate{} 24057c478bd9Sstevel@tonic-gate 24067c478bd9Sstevel@tonic-gate#else /* lint */ 24077c478bd9Sstevel@tonic-gate 24087c478bd9Sstevel@tonic-gate ENTRY(set_safari_config) 24097c478bd9Sstevel@tonic-gate stxa %o0, [%g0]ASI_SAFARI_CONFIG 24107c478bd9Sstevel@tonic-gate membar #Sync 24117c478bd9Sstevel@tonic-gate retl 24127c478bd9Sstevel@tonic-gate nop 24137c478bd9Sstevel@tonic-gate SET_SIZE(set_safari_config) 24147c478bd9Sstevel@tonic-gate 24157c478bd9Sstevel@tonic-gate#endif /* lint */ 24167c478bd9Sstevel@tonic-gate 24177c478bd9Sstevel@tonic-gate#endif /* !(JALAPENO || SERRANO) */ 24187c478bd9Sstevel@tonic-gate 24197c478bd9Sstevel@tonic-gate 24207c478bd9Sstevel@tonic-gate#if defined(lint) 24217c478bd9Sstevel@tonic-gate 24227c478bd9Sstevel@tonic-gatevoid 24237c478bd9Sstevel@tonic-gatecpu_cleartickpnt(void) 24247c478bd9Sstevel@tonic-gate{} 24257c478bd9Sstevel@tonic-gate 24267c478bd9Sstevel@tonic-gate#else /* lint */ 24277c478bd9Sstevel@tonic-gate /* 24287c478bd9Sstevel@tonic-gate * Clear the NPT (non-privileged trap) bit in the %tick/%stick 24297c478bd9Sstevel@tonic-gate * registers. In an effort to make the change in the 24307c478bd9Sstevel@tonic-gate * tick/stick counter as consistent as possible, we disable 24317c478bd9Sstevel@tonic-gate * all interrupts while we're changing the registers. We also 24327c478bd9Sstevel@tonic-gate * ensure that the read and write instructions are in the same 24337c478bd9Sstevel@tonic-gate * line in the instruction cache. 24347c478bd9Sstevel@tonic-gate */ 24357c478bd9Sstevel@tonic-gate ENTRY_NP(cpu_clearticknpt) 24367c478bd9Sstevel@tonic-gate rdpr %pstate, %g1 /* save processor state */ 24377c478bd9Sstevel@tonic-gate andn %g1, PSTATE_IE, %g3 /* turn off */ 24387c478bd9Sstevel@tonic-gate wrpr %g0, %g3, %pstate /* interrupts */ 24397c478bd9Sstevel@tonic-gate rdpr %tick, %g2 /* get tick register */ 24407c478bd9Sstevel@tonic-gate brgez,pn %g2, 1f /* if NPT bit off, we're done */ 24417c478bd9Sstevel@tonic-gate mov 1, %g3 /* create mask */ 24427c478bd9Sstevel@tonic-gate sllx %g3, 63, %g3 /* for NPT bit */ 24437c478bd9Sstevel@tonic-gate ba,a,pt %xcc, 2f 24447c478bd9Sstevel@tonic-gate .align 8 /* Ensure rd/wr in same i$ line */ 24457c478bd9Sstevel@tonic-gate2: 24467c478bd9Sstevel@tonic-gate rdpr %tick, %g2 /* get tick register */ 24477c478bd9Sstevel@tonic-gate wrpr %g3, %g2, %tick /* write tick register, */ 24487c478bd9Sstevel@tonic-gate /* clearing NPT bit */ 24497c478bd9Sstevel@tonic-gate1: 24507c478bd9Sstevel@tonic-gate rd STICK, %g2 /* get stick register */ 24517c478bd9Sstevel@tonic-gate brgez,pn %g2, 3f /* if NPT bit off, we're done */ 24527c478bd9Sstevel@tonic-gate mov 1, %g3 /* create mask */ 24537c478bd9Sstevel@tonic-gate sllx %g3, 63, %g3 /* for NPT bit */ 24547c478bd9Sstevel@tonic-gate ba,a,pt %xcc, 4f 24557c478bd9Sstevel@tonic-gate .align 8 /* Ensure rd/wr in same i$ line */ 24567c478bd9Sstevel@tonic-gate4: 24577c478bd9Sstevel@tonic-gate rd STICK, %g2 /* get stick register */ 24587c478bd9Sstevel@tonic-gate wr %g3, %g2, STICK /* write stick register, */ 24597c478bd9Sstevel@tonic-gate /* clearing NPT bit */ 24607c478bd9Sstevel@tonic-gate3: 24617c478bd9Sstevel@tonic-gate jmp %g4 + 4 24627c478bd9Sstevel@tonic-gate wrpr %g0, %g1, %pstate /* restore processor state */ 24637c478bd9Sstevel@tonic-gate 24647c478bd9Sstevel@tonic-gate SET_SIZE(cpu_clearticknpt) 24657c478bd9Sstevel@tonic-gate 24667c478bd9Sstevel@tonic-gate#endif /* lint */ 24677c478bd9Sstevel@tonic-gate 24687c478bd9Sstevel@tonic-gate 24697c478bd9Sstevel@tonic-gate#if defined(CPU_IMP_L1_CACHE_PARITY) 24707c478bd9Sstevel@tonic-gate 24717c478bd9Sstevel@tonic-gate#if defined(lint) 24727c478bd9Sstevel@tonic-gate/* 24737c478bd9Sstevel@tonic-gate * correct_dcache_parity(size_t size, size_t linesize) 24747c478bd9Sstevel@tonic-gate * 24757c478bd9Sstevel@tonic-gate * Correct D$ data parity by zeroing the data and initializing microtag 24767c478bd9Sstevel@tonic-gate * for all indexes and all ways of the D$. 24777c478bd9Sstevel@tonic-gate * 24787c478bd9Sstevel@tonic-gate */ 24797c478bd9Sstevel@tonic-gate/* ARGSUSED */ 24807c478bd9Sstevel@tonic-gatevoid 24817c478bd9Sstevel@tonic-gatecorrect_dcache_parity(size_t size, size_t linesize) 24827c478bd9Sstevel@tonic-gate{} 24837c478bd9Sstevel@tonic-gate 24847c478bd9Sstevel@tonic-gate#else /* lint */ 24857c478bd9Sstevel@tonic-gate 24867c478bd9Sstevel@tonic-gate ENTRY(correct_dcache_parity) 24877c478bd9Sstevel@tonic-gate /* 24887c478bd9Sstevel@tonic-gate * Register Usage: 24897c478bd9Sstevel@tonic-gate * 24907c478bd9Sstevel@tonic-gate * %o0 = input D$ size 24917c478bd9Sstevel@tonic-gate * %o1 = input D$ line size 24927c478bd9Sstevel@tonic-gate * %o2 = scratch 24937c478bd9Sstevel@tonic-gate * %o3 = scratch 24947c478bd9Sstevel@tonic-gate * %o4 = scratch 24957c478bd9Sstevel@tonic-gate */ 24967c478bd9Sstevel@tonic-gate 24977c478bd9Sstevel@tonic-gate sub %o0, %o1, %o0 ! init cache line address 24987c478bd9Sstevel@tonic-gate 24997c478bd9Sstevel@tonic-gate /* 25007c478bd9Sstevel@tonic-gate * For Panther CPUs, we also need to clear the data parity bits 25017c478bd9Sstevel@tonic-gate * using DC_data_parity bit of the ASI_DCACHE_DATA register. 25027c478bd9Sstevel@tonic-gate */ 25037c478bd9Sstevel@tonic-gate GET_CPU_IMPL(%o3) 25047c478bd9Sstevel@tonic-gate cmp %o3, PANTHER_IMPL 25057c478bd9Sstevel@tonic-gate bne 1f 25067c478bd9Sstevel@tonic-gate clr %o3 ! zero for non-Panther 25077c478bd9Sstevel@tonic-gate mov 1, %o3 25087c478bd9Sstevel@tonic-gate sll %o3, PN_DC_DATA_PARITY_BIT_SHIFT, %o3 25097c478bd9Sstevel@tonic-gate 25107c478bd9Sstevel@tonic-gate1: 25117c478bd9Sstevel@tonic-gate /* 25127c478bd9Sstevel@tonic-gate * Set utag = way since it must be unique within an index. 25137c478bd9Sstevel@tonic-gate */ 25147c478bd9Sstevel@tonic-gate srl %o0, 14, %o2 ! get cache way (DC_way) 25157c478bd9Sstevel@tonic-gate membar #Sync ! required before ASI_DC_UTAG 25167c478bd9Sstevel@tonic-gate stxa %o2, [%o0]ASI_DC_UTAG ! set D$ utag = cache way 25177c478bd9Sstevel@tonic-gate membar #Sync ! required after ASI_DC_UTAG 25187c478bd9Sstevel@tonic-gate 25197c478bd9Sstevel@tonic-gate /* 25207c478bd9Sstevel@tonic-gate * Zero line of D$ data (and data parity bits for Panther) 25217c478bd9Sstevel@tonic-gate */ 25227c478bd9Sstevel@tonic-gate sub %o1, 8, %o2 25237c478bd9Sstevel@tonic-gate or %o0, %o3, %o4 ! same address + DC_data_parity 25247c478bd9Sstevel@tonic-gate2: 25257c478bd9Sstevel@tonic-gate membar #Sync ! required before ASI_DC_DATA 25267c478bd9Sstevel@tonic-gate stxa %g0, [%o0 + %o2]ASI_DC_DATA ! zero 8 bytes of D$ data 25277c478bd9Sstevel@tonic-gate membar #Sync ! required after ASI_DC_DATA 25287c478bd9Sstevel@tonic-gate /* 25297c478bd9Sstevel@tonic-gate * We also clear the parity bits if this is a panther. For non-Panther 25307c478bd9Sstevel@tonic-gate * CPUs, we simply end up clearing the $data register twice. 25317c478bd9Sstevel@tonic-gate */ 25327c478bd9Sstevel@tonic-gate stxa %g0, [%o4 + %o2]ASI_DC_DATA 25337c478bd9Sstevel@tonic-gate membar #Sync 25347c478bd9Sstevel@tonic-gate 25357c478bd9Sstevel@tonic-gate subcc %o2, 8, %o2 25367c478bd9Sstevel@tonic-gate bge 2b 25377c478bd9Sstevel@tonic-gate nop 25387c478bd9Sstevel@tonic-gate 25397c478bd9Sstevel@tonic-gate subcc %o0, %o1, %o0 25407c478bd9Sstevel@tonic-gate bge 1b 25417c478bd9Sstevel@tonic-gate nop 25427c478bd9Sstevel@tonic-gate 25437c478bd9Sstevel@tonic-gate retl 25447c478bd9Sstevel@tonic-gate nop 25457c478bd9Sstevel@tonic-gate SET_SIZE(correct_dcache_parity) 25467c478bd9Sstevel@tonic-gate 25477c478bd9Sstevel@tonic-gate#endif /* lint */ 25487c478bd9Sstevel@tonic-gate 25497c478bd9Sstevel@tonic-gate#endif /* CPU_IMP_L1_CACHE_PARITY */ 25507c478bd9Sstevel@tonic-gate 25517c478bd9Sstevel@tonic-gate 25527c478bd9Sstevel@tonic-gate#if defined(lint) 25537c478bd9Sstevel@tonic-gate/* 25547c478bd9Sstevel@tonic-gate * Get timestamp (stick). 25557c478bd9Sstevel@tonic-gate */ 25567c478bd9Sstevel@tonic-gate/* ARGSUSED */ 25577c478bd9Sstevel@tonic-gatevoid 25587c478bd9Sstevel@tonic-gatestick_timestamp(int64_t *ts) 25597c478bd9Sstevel@tonic-gate{ 25607c478bd9Sstevel@tonic-gate} 25617c478bd9Sstevel@tonic-gate 25627c478bd9Sstevel@tonic-gate#else /* lint */ 25637c478bd9Sstevel@tonic-gate 25647c478bd9Sstevel@tonic-gate ENTRY_NP(stick_timestamp) 25657c478bd9Sstevel@tonic-gate rd STICK, %g1 ! read stick reg 25667c478bd9Sstevel@tonic-gate sllx %g1, 1, %g1 25677c478bd9Sstevel@tonic-gate srlx %g1, 1, %g1 ! clear npt bit 25687c478bd9Sstevel@tonic-gate 25697c478bd9Sstevel@tonic-gate retl 25707c478bd9Sstevel@tonic-gate stx %g1, [%o0] ! store the timestamp 25717c478bd9Sstevel@tonic-gate SET_SIZE(stick_timestamp) 25727c478bd9Sstevel@tonic-gate 25737c478bd9Sstevel@tonic-gate#endif /* lint */ 25747c478bd9Sstevel@tonic-gate 25757c478bd9Sstevel@tonic-gate 25767c478bd9Sstevel@tonic-gate#if defined(lint) 25777c478bd9Sstevel@tonic-gate/* 25787c478bd9Sstevel@tonic-gate * Set STICK adjusted by skew. 25797c478bd9Sstevel@tonic-gate */ 25807c478bd9Sstevel@tonic-gate/* ARGSUSED */ 25817c478bd9Sstevel@tonic-gatevoid 25827c478bd9Sstevel@tonic-gatestick_adj(int64_t skew) 25837c478bd9Sstevel@tonic-gate{ 25847c478bd9Sstevel@tonic-gate} 25857c478bd9Sstevel@tonic-gate 25867c478bd9Sstevel@tonic-gate#else /* lint */ 25877c478bd9Sstevel@tonic-gate 25887c478bd9Sstevel@tonic-gate ENTRY_NP(stick_adj) 25897c478bd9Sstevel@tonic-gate rdpr %pstate, %g1 ! save processor state 25907c478bd9Sstevel@tonic-gate andn %g1, PSTATE_IE, %g3 25917c478bd9Sstevel@tonic-gate ba 1f ! cache align stick adj 25927c478bd9Sstevel@tonic-gate wrpr %g0, %g3, %pstate ! turn off interrupts 25937c478bd9Sstevel@tonic-gate 25947c478bd9Sstevel@tonic-gate .align 16 25957c478bd9Sstevel@tonic-gate1: nop 25967c478bd9Sstevel@tonic-gate 25977c478bd9Sstevel@tonic-gate rd STICK, %g4 ! read stick reg 25987c478bd9Sstevel@tonic-gate add %g4, %o0, %o1 ! adjust stick with skew 25997c478bd9Sstevel@tonic-gate wr %o1, %g0, STICK ! write stick reg 26007c478bd9Sstevel@tonic-gate 26017c478bd9Sstevel@tonic-gate retl 26027c478bd9Sstevel@tonic-gate wrpr %g1, %pstate ! restore processor state 26037c478bd9Sstevel@tonic-gate SET_SIZE(stick_adj) 26047c478bd9Sstevel@tonic-gate 26057c478bd9Sstevel@tonic-gate#endif /* lint */ 26067c478bd9Sstevel@tonic-gate 26077c478bd9Sstevel@tonic-gate#if defined(lint) 26087c478bd9Sstevel@tonic-gate/* 26097c478bd9Sstevel@tonic-gate * Debugger-specific stick retrieval 26107c478bd9Sstevel@tonic-gate */ 26117c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 26127c478bd9Sstevel@tonic-gateint 26137c478bd9Sstevel@tonic-gatekdi_get_stick(uint64_t *stickp) 26147c478bd9Sstevel@tonic-gate{ 26157c478bd9Sstevel@tonic-gate return (0); 26167c478bd9Sstevel@tonic-gate} 26177c478bd9Sstevel@tonic-gate 26187c478bd9Sstevel@tonic-gate#else /* lint */ 26197c478bd9Sstevel@tonic-gate 26207c478bd9Sstevel@tonic-gate ENTRY_NP(kdi_get_stick) 26217c478bd9Sstevel@tonic-gate rd STICK, %g1 26227c478bd9Sstevel@tonic-gate stx %g1, [%o0] 26237c478bd9Sstevel@tonic-gate retl 26247c478bd9Sstevel@tonic-gate mov %g0, %o0 26257c478bd9Sstevel@tonic-gate SET_SIZE(kdi_get_stick) 26267c478bd9Sstevel@tonic-gate 26277c478bd9Sstevel@tonic-gate#endif /* lint */ 26287c478bd9Sstevel@tonic-gate 26297c478bd9Sstevel@tonic-gate#if defined(lint) 26307c478bd9Sstevel@tonic-gate/* 26317c478bd9Sstevel@tonic-gate * Invalidate the specified line from the D$. 26327c478bd9Sstevel@tonic-gate * 26337c478bd9Sstevel@tonic-gate * Register usage: 26347c478bd9Sstevel@tonic-gate * %o0 - index for the invalidation, specifies DC_way and DC_addr 26357c478bd9Sstevel@tonic-gate * 26367c478bd9Sstevel@tonic-gate * ASI_DC_TAG, 0x47, is used in the following manner. A 64-bit value is 26377c478bd9Sstevel@tonic-gate * stored to a particular DC_way and DC_addr in ASI_DC_TAG. 26387c478bd9Sstevel@tonic-gate * 26397c478bd9Sstevel@tonic-gate * The format of the stored 64-bit value is: 26407c478bd9Sstevel@tonic-gate * 26417c478bd9Sstevel@tonic-gate * +----------+--------+----------+ 26427c478bd9Sstevel@tonic-gate * | Reserved | DC_tag | DC_valid | 26437c478bd9Sstevel@tonic-gate * +----------+--------+----------+ 26447c478bd9Sstevel@tonic-gate * 63 31 30 1 0 26457c478bd9Sstevel@tonic-gate * 26467c478bd9Sstevel@tonic-gate * DC_tag is the 30-bit physical tag of the associated line. 26477c478bd9Sstevel@tonic-gate * DC_valid is the 1-bit valid field for both the physical and snoop tags. 26487c478bd9Sstevel@tonic-gate * 26497c478bd9Sstevel@tonic-gate * The format of the 64-bit DC_way and DC_addr into ASI_DC_TAG is: 26507c478bd9Sstevel@tonic-gate * 26517c478bd9Sstevel@tonic-gate * +----------+--------+----------+----------+ 26527c478bd9Sstevel@tonic-gate * | Reserved | DC_way | DC_addr | Reserved | 26537c478bd9Sstevel@tonic-gate * +----------+--------+----------+----------+ 26547c478bd9Sstevel@tonic-gate * 63 16 15 14 13 5 4 0 26557c478bd9Sstevel@tonic-gate * 26567c478bd9Sstevel@tonic-gate * DC_way is a 2-bit index that selects one of the 4 ways. 26577c478bd9Sstevel@tonic-gate * DC_addr is a 9-bit index that selects one of 512 tag/valid fields. 26587c478bd9Sstevel@tonic-gate * 26597c478bd9Sstevel@tonic-gate * Setting the DC_valid bit to zero for the specified DC_way and 26607c478bd9Sstevel@tonic-gate * DC_addr index into the D$ results in an invalidation of a D$ line. 26617c478bd9Sstevel@tonic-gate */ 26627c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 26637c478bd9Sstevel@tonic-gatevoid 26647c478bd9Sstevel@tonic-gatedcache_inval_line(int index) 26657c478bd9Sstevel@tonic-gate{ 26667c478bd9Sstevel@tonic-gate} 26677c478bd9Sstevel@tonic-gate#else /* lint */ 26687c478bd9Sstevel@tonic-gate ENTRY(dcache_inval_line) 26697c478bd9Sstevel@tonic-gate sll %o0, 5, %o0 ! shift index into DC_way and DC_addr 26707c478bd9Sstevel@tonic-gate stxa %g0, [%o0]ASI_DC_TAG ! zero the DC_valid and DC_tag bits 26717c478bd9Sstevel@tonic-gate membar #Sync 26727c478bd9Sstevel@tonic-gate retl 26737c478bd9Sstevel@tonic-gate nop 26747c478bd9Sstevel@tonic-gate SET_SIZE(dcache_inval_line) 26757c478bd9Sstevel@tonic-gate#endif /* lint */ 26767c478bd9Sstevel@tonic-gate 26777c478bd9Sstevel@tonic-gate#if defined(lint) 26787c478bd9Sstevel@tonic-gate/* 26797c478bd9Sstevel@tonic-gate * Invalidate the entire I$ 26807c478bd9Sstevel@tonic-gate * 26817c478bd9Sstevel@tonic-gate * Register usage: 26827c478bd9Sstevel@tonic-gate * %o0 - specifies IC_way, IC_addr, IC_tag 26837c478bd9Sstevel@tonic-gate * %o1 - scratch 26847c478bd9Sstevel@tonic-gate * %o2 - used to save and restore DCU value 26857c478bd9Sstevel@tonic-gate * %o3 - scratch 26867c478bd9Sstevel@tonic-gate * %o5 - used to save and restore PSTATE 26877c478bd9Sstevel@tonic-gate * 26887c478bd9Sstevel@tonic-gate * Due to the behavior of the I$ control logic when accessing ASI_IC_TAG, 26897c478bd9Sstevel@tonic-gate * the I$ should be turned off. Accesses to ASI_IC_TAG may collide and 26907c478bd9Sstevel@tonic-gate * block out snoops and invalidates to the I$, causing I$ consistency 26917c478bd9Sstevel@tonic-gate * to be broken. Before turning on the I$, all I$ lines must be invalidated. 26927c478bd9Sstevel@tonic-gate * 26937c478bd9Sstevel@tonic-gate * ASI_IC_TAG, 0x67, is used in the following manner. A 64-bit value is 26947c478bd9Sstevel@tonic-gate * stored to a particular IC_way, IC_addr, IC_tag in ASI_IC_TAG. The 26957c478bd9Sstevel@tonic-gate * info below describes store (write) use of ASI_IC_TAG. Note that read 26967c478bd9Sstevel@tonic-gate * use of ASI_IC_TAG behaves differently. 26977c478bd9Sstevel@tonic-gate * 26987c478bd9Sstevel@tonic-gate * The format of the stored 64-bit value is: 26997c478bd9Sstevel@tonic-gate * 27007c478bd9Sstevel@tonic-gate * +----------+--------+---------------+-----------+ 27017c478bd9Sstevel@tonic-gate * | Reserved | Valid | IC_vpred<7:0> | Undefined | 27027c478bd9Sstevel@tonic-gate * +----------+--------+---------------+-----------+ 27037c478bd9Sstevel@tonic-gate * 63 55 54 53 46 45 0 27047c478bd9Sstevel@tonic-gate * 27057c478bd9Sstevel@tonic-gate * Valid is the 1-bit valid field for both the physical and snoop tags. 27067c478bd9Sstevel@tonic-gate * IC_vpred is the 8-bit LPB bits for 8 instructions starting at 27077c478bd9Sstevel@tonic-gate * the 32-byte boundary aligned address specified by IC_addr. 27087c478bd9Sstevel@tonic-gate * 27097c478bd9Sstevel@tonic-gate * The format of the 64-bit IC_way, IC_addr, IC_tag into ASI_IC_TAG is: 27107c478bd9Sstevel@tonic-gate * 27117c478bd9Sstevel@tonic-gate * +----------+--------+---------+--------+---------+ 27127c478bd9Sstevel@tonic-gate * | Reserved | IC_way | IC_addr | IC_tag |Reserved | 27137c478bd9Sstevel@tonic-gate * +----------+--------+---------+--------+---------+ 27147c478bd9Sstevel@tonic-gate * 63 16 15 14 13 5 4 3 2 0 27157c478bd9Sstevel@tonic-gate * 27167c478bd9Sstevel@tonic-gate * IC_way is a 2-bit index that selects one of the 4 ways. 27177c478bd9Sstevel@tonic-gate * IC_addr[13:6] is an 8-bit index that selects one of 256 valid fields. 27187c478bd9Sstevel@tonic-gate * IC_addr[5] is a "don't care" for a store. 27197c478bd9Sstevel@tonic-gate * IC_tag set to 2 specifies that the stored value is to be interpreted 27207c478bd9Sstevel@tonic-gate * as containing Valid and IC_vpred as described above. 27217c478bd9Sstevel@tonic-gate * 27227c478bd9Sstevel@tonic-gate * Setting the Valid bit to zero for the specified IC_way and 27237c478bd9Sstevel@tonic-gate * IC_addr index into the I$ results in an invalidation of an I$ line. 27247c478bd9Sstevel@tonic-gate */ 27257c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 27267c478bd9Sstevel@tonic-gatevoid 27277c478bd9Sstevel@tonic-gateicache_inval_all(void) 27287c478bd9Sstevel@tonic-gate{ 27297c478bd9Sstevel@tonic-gate} 27307c478bd9Sstevel@tonic-gate#else /* lint */ 27317c478bd9Sstevel@tonic-gate ENTRY(icache_inval_all) 27327c478bd9Sstevel@tonic-gate rdpr %pstate, %o5 27337c478bd9Sstevel@tonic-gate andn %o5, PSTATE_IE, %o3 27347c478bd9Sstevel@tonic-gate wrpr %g0, %o3, %pstate ! clear IE bit 27357c478bd9Sstevel@tonic-gate 27367c478bd9Sstevel@tonic-gate GET_CPU_PRIVATE_PTR(%g0, %o0, %o2, icache_inval_all_1); 27377c478bd9Sstevel@tonic-gate ld [%o0 + CHPR_ICACHE_LINESIZE], %o1 27387c478bd9Sstevel@tonic-gate ba,pt %icc, 2f 27397c478bd9Sstevel@tonic-gate ld [%o0 + CHPR_ICACHE_SIZE], %o0 27407c478bd9Sstevel@tonic-gateicache_inval_all_1: 27417c478bd9Sstevel@tonic-gate ASM_LD(%o0, icache_size) 27427c478bd9Sstevel@tonic-gate ASM_LD(%o1, icache_linesize) 27437c478bd9Sstevel@tonic-gate2: 27447c478bd9Sstevel@tonic-gate CH_ICACHE_FLUSHALL(%o0, %o1, %o2, %o4) 27457c478bd9Sstevel@tonic-gate 27467c478bd9Sstevel@tonic-gate retl 27477c478bd9Sstevel@tonic-gate wrpr %g0, %o5, %pstate ! restore earlier pstate 27487c478bd9Sstevel@tonic-gate SET_SIZE(icache_inval_all) 27497c478bd9Sstevel@tonic-gate#endif /* lint */ 27507c478bd9Sstevel@tonic-gate 27517c478bd9Sstevel@tonic-gate 27527c478bd9Sstevel@tonic-gate#if defined(lint) 27537c478bd9Sstevel@tonic-gate/* ARGSUSED */ 27547c478bd9Sstevel@tonic-gatevoid 27557c478bd9Sstevel@tonic-gatecache_scrubreq_tl1(uint64_t inum, uint64_t index) 27567c478bd9Sstevel@tonic-gate{ 27577c478bd9Sstevel@tonic-gate} 27587c478bd9Sstevel@tonic-gate 27597c478bd9Sstevel@tonic-gate#else /* lint */ 27607c478bd9Sstevel@tonic-gate/* 27617c478bd9Sstevel@tonic-gate * cache_scrubreq_tl1 is the crosstrap handler called on offlined cpus via a 27627c478bd9Sstevel@tonic-gate * crosstrap. It atomically increments the outstanding request counter and, 27637c478bd9Sstevel@tonic-gate * if there was not already an outstanding request, branches to setsoftint_tl1 2764b0fc0e77Sgovinda * to enqueue an intr_vec for the given inum. 27657c478bd9Sstevel@tonic-gate */ 27667c478bd9Sstevel@tonic-gate 27677c478bd9Sstevel@tonic-gate ! Register usage: 27687c478bd9Sstevel@tonic-gate ! 27697c478bd9Sstevel@tonic-gate ! Arguments: 27707c478bd9Sstevel@tonic-gate ! %g1 - inum 27717c478bd9Sstevel@tonic-gate ! %g2 - index into chsm_outstanding array 27727c478bd9Sstevel@tonic-gate ! 27737c478bd9Sstevel@tonic-gate ! Internal: 27747c478bd9Sstevel@tonic-gate ! %g2, %g3, %g5 - scratch 27757c478bd9Sstevel@tonic-gate ! %g4 - ptr. to scrub_misc chsm_outstanding[index]. 27767c478bd9Sstevel@tonic-gate ! %g6 - setsoftint_tl1 address 27777c478bd9Sstevel@tonic-gate 27787c478bd9Sstevel@tonic-gate ENTRY_NP(cache_scrubreq_tl1) 27797c478bd9Sstevel@tonic-gate mulx %g2, CHSM_OUTSTANDING_INCR, %g2 27807c478bd9Sstevel@tonic-gate set CHPR_SCRUB_MISC + CHSM_OUTSTANDING, %g3 27817c478bd9Sstevel@tonic-gate add %g2, %g3, %g2 27827c478bd9Sstevel@tonic-gate GET_CPU_PRIVATE_PTR(%g2, %g4, %g5, 1f); 27837c478bd9Sstevel@tonic-gate ld [%g4], %g2 ! cpu's chsm_outstanding[index] 27847c478bd9Sstevel@tonic-gate ! 27857c478bd9Sstevel@tonic-gate ! no need to use atomic instructions for the following 27867c478bd9Sstevel@tonic-gate ! increment - we're at tl1 27877c478bd9Sstevel@tonic-gate ! 27887c478bd9Sstevel@tonic-gate add %g2, 0x1, %g3 2789b0fc0e77Sgovinda brnz,pn %g2, 1f ! no need to enqueue more intr_vec 27907c478bd9Sstevel@tonic-gate st %g3, [%g4] ! delay - store incremented counter 27917c478bd9Sstevel@tonic-gate ASM_JMP(%g6, setsoftint_tl1) 27927c478bd9Sstevel@tonic-gate ! not reached 27937c478bd9Sstevel@tonic-gate1: 27947c478bd9Sstevel@tonic-gate retry 27957c478bd9Sstevel@tonic-gate SET_SIZE(cache_scrubreq_tl1) 27967c478bd9Sstevel@tonic-gate 27977c478bd9Sstevel@tonic-gate#endif /* lint */ 27987c478bd9Sstevel@tonic-gate 27997c478bd9Sstevel@tonic-gate 28007c478bd9Sstevel@tonic-gate#if defined(lint) 28017c478bd9Sstevel@tonic-gate 28027c478bd9Sstevel@tonic-gate/* ARGSUSED */ 28037c478bd9Sstevel@tonic-gatevoid 28047c478bd9Sstevel@tonic-gateget_cpu_error_state(ch_cpu_errors_t *cpu_error_regs) 28057c478bd9Sstevel@tonic-gate{} 28067c478bd9Sstevel@tonic-gate 28077c478bd9Sstevel@tonic-gate#else /* lint */ 28087c478bd9Sstevel@tonic-gate 28097c478bd9Sstevel@tonic-gate/* 28107c478bd9Sstevel@tonic-gate * Get the error state for the processor. 28117c478bd9Sstevel@tonic-gate * Note that this must not be used at TL>0 28127c478bd9Sstevel@tonic-gate */ 28137c478bd9Sstevel@tonic-gate ENTRY(get_cpu_error_state) 28147c478bd9Sstevel@tonic-gate#if defined(CHEETAH_PLUS) 28157c478bd9Sstevel@tonic-gate set ASI_SHADOW_REG_VA, %o2 28167c478bd9Sstevel@tonic-gate ldxa [%o2]ASI_AFSR, %o1 ! shadow afsr reg 28177c478bd9Sstevel@tonic-gate stx %o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR] 28187c478bd9Sstevel@tonic-gate ldxa [%o2]ASI_AFAR, %o1 ! shadow afar reg 28197c478bd9Sstevel@tonic-gate stx %o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFAR] 28207c478bd9Sstevel@tonic-gate GET_CPU_IMPL(%o3) ! Only panther has AFSR_EXT registers 28217c478bd9Sstevel@tonic-gate cmp %o3, PANTHER_IMPL 28227c478bd9Sstevel@tonic-gate bne,a 1f 28237c478bd9Sstevel@tonic-gate stx %g0, [%o0 + CH_CPU_ERRORS_AFSR_EXT] ! zero for non-PN 28247c478bd9Sstevel@tonic-gate set ASI_AFSR_EXT_VA, %o2 28257c478bd9Sstevel@tonic-gate ldxa [%o2]ASI_AFSR, %o1 ! afsr_ext reg 28267c478bd9Sstevel@tonic-gate stx %o1, [%o0 + CH_CPU_ERRORS_AFSR_EXT] 28277c478bd9Sstevel@tonic-gate set ASI_SHADOW_AFSR_EXT_VA, %o2 28287c478bd9Sstevel@tonic-gate ldxa [%o2]ASI_AFSR, %o1 ! shadow afsr_ext reg 28297c478bd9Sstevel@tonic-gate stx %o1, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT] 28307c478bd9Sstevel@tonic-gate b 2f 28317c478bd9Sstevel@tonic-gate nop 28327c478bd9Sstevel@tonic-gate1: 28337c478bd9Sstevel@tonic-gate stx %g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT] ! zero for non-PN 28347c478bd9Sstevel@tonic-gate2: 28357c478bd9Sstevel@tonic-gate#else /* CHEETAH_PLUS */ 28367c478bd9Sstevel@tonic-gate stx %g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR] 28377c478bd9Sstevel@tonic-gate stx %g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFAR] 28387c478bd9Sstevel@tonic-gate stx %g0, [%o0 + CH_CPU_ERRORS_AFSR_EXT] 28397c478bd9Sstevel@tonic-gate stx %g0, [%o0 + CH_CPU_ERRORS_SHADOW_AFSR_EXT] 28407c478bd9Sstevel@tonic-gate#endif /* CHEETAH_PLUS */ 28417c478bd9Sstevel@tonic-gate#if defined(SERRANO) 28427c478bd9Sstevel@tonic-gate /* 28437c478bd9Sstevel@tonic-gate * Serrano has an afar2 which captures the address on FRC/FRU errors. 28447c478bd9Sstevel@tonic-gate * We save this in the afar2 of the register save area. 28457c478bd9Sstevel@tonic-gate */ 28467c478bd9Sstevel@tonic-gate set ASI_MCU_AFAR2_VA, %o2 28477c478bd9Sstevel@tonic-gate ldxa [%o2]ASI_MCU_CTRL, %o1 28487c478bd9Sstevel@tonic-gate stx %o1, [%o0 + CH_CPU_ERRORS_AFAR2] 28497c478bd9Sstevel@tonic-gate#endif /* SERRANO */ 28507c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_AFSR, %o1 ! primary afsr reg 28517c478bd9Sstevel@tonic-gate stx %o1, [%o0 + CH_CPU_ERRORS_AFSR] 28527c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_AFAR, %o1 ! primary afar reg 28537c478bd9Sstevel@tonic-gate retl 28547c478bd9Sstevel@tonic-gate stx %o1, [%o0 + CH_CPU_ERRORS_AFAR] 28557c478bd9Sstevel@tonic-gate SET_SIZE(get_cpu_error_state) 28567c478bd9Sstevel@tonic-gate#endif /* lint */ 28577c478bd9Sstevel@tonic-gate 28587c478bd9Sstevel@tonic-gate#if defined(lint) 28597c478bd9Sstevel@tonic-gate 28607c478bd9Sstevel@tonic-gate/* 28617c478bd9Sstevel@tonic-gate * Check a page of memory for errors. 28627c478bd9Sstevel@tonic-gate * 28637c478bd9Sstevel@tonic-gate * Load each 64 byte block from physical memory. 28647c478bd9Sstevel@tonic-gate * Check AFSR after each load to see if an error 28657c478bd9Sstevel@tonic-gate * was caused. If so, log/scrub that error. 28667c478bd9Sstevel@tonic-gate * 28677c478bd9Sstevel@tonic-gate * Used to determine if a page contains 28687c478bd9Sstevel@tonic-gate * CEs when CEEN is disabled. 28697c478bd9Sstevel@tonic-gate */ 28707c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 28717c478bd9Sstevel@tonic-gatevoid 28727c478bd9Sstevel@tonic-gatecpu_check_block(caddr_t va, uint_t psz) 28737c478bd9Sstevel@tonic-gate{} 28747c478bd9Sstevel@tonic-gate 28757c478bd9Sstevel@tonic-gate#else /* lint */ 28767c478bd9Sstevel@tonic-gate 28777c478bd9Sstevel@tonic-gate ENTRY(cpu_check_block) 28787c478bd9Sstevel@tonic-gate ! 28797c478bd9Sstevel@tonic-gate ! get a new window with room for the error regs 28807c478bd9Sstevel@tonic-gate ! 28817c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME + CH_CPU_ERROR_SIZE), %sp 28827c478bd9Sstevel@tonic-gate srl %i1, 6, %l4 ! clear top bits of psz 28837c478bd9Sstevel@tonic-gate ! and divide by 64 28847c478bd9Sstevel@tonic-gate rd %fprs, %l2 ! store FP 28857c478bd9Sstevel@tonic-gate wr %g0, FPRS_FEF, %fprs ! enable FP 28867c478bd9Sstevel@tonic-gate1: 28877c478bd9Sstevel@tonic-gate ldda [%i0]ASI_BLK_P, %d0 ! load a block 28887c478bd9Sstevel@tonic-gate membar #Sync 28897c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_AFSR, %l3 ! read afsr reg 28907c478bd9Sstevel@tonic-gate brz,a,pt %l3, 2f ! check for error 28917c478bd9Sstevel@tonic-gate nop 28927c478bd9Sstevel@tonic-gate 28937c478bd9Sstevel@tonic-gate ! 28947c478bd9Sstevel@tonic-gate ! if error, read the error regs and log it 28957c478bd9Sstevel@tonic-gate ! 28967c478bd9Sstevel@tonic-gate call get_cpu_error_state 28977c478bd9Sstevel@tonic-gate add %fp, STACK_BIAS - CH_CPU_ERROR_SIZE, %o0 28987c478bd9Sstevel@tonic-gate 28997c478bd9Sstevel@tonic-gate ! 29007c478bd9Sstevel@tonic-gate ! cpu_ce_detected(ch_cpu_errors_t *, flag) 29017c478bd9Sstevel@tonic-gate ! 29027c478bd9Sstevel@tonic-gate call cpu_ce_detected ! log the error 29037c478bd9Sstevel@tonic-gate mov CE_CEEN_TIMEOUT, %o1 29047c478bd9Sstevel@tonic-gate2: 29057c478bd9Sstevel@tonic-gate dec %l4 ! next 64-byte block 29067c478bd9Sstevel@tonic-gate brnz,a,pt %l4, 1b 29077c478bd9Sstevel@tonic-gate add %i0, 64, %i0 ! increment block addr 29087c478bd9Sstevel@tonic-gate 29097c478bd9Sstevel@tonic-gate wr %l2, %g0, %fprs ! restore FP 29107c478bd9Sstevel@tonic-gate ret 29117c478bd9Sstevel@tonic-gate restore 29127c478bd9Sstevel@tonic-gate 29137c478bd9Sstevel@tonic-gate SET_SIZE(cpu_check_block) 29147c478bd9Sstevel@tonic-gate 29157c478bd9Sstevel@tonic-gate#endif /* lint */ 29167c478bd9Sstevel@tonic-gate 29177c478bd9Sstevel@tonic-gate#if defined(lint) 29187c478bd9Sstevel@tonic-gate 29197c478bd9Sstevel@tonic-gate/* 29207c478bd9Sstevel@tonic-gate * Perform a cpu logout called from C. This is used where we did not trap 29217c478bd9Sstevel@tonic-gate * for the error but still want to gather "what we can". Caller must make 29227c478bd9Sstevel@tonic-gate * sure cpu private area exists and that the indicated logout area is free 29237c478bd9Sstevel@tonic-gate * for use, and that we are unable to migrate cpus. 29247c478bd9Sstevel@tonic-gate */ 29257c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 29267c478bd9Sstevel@tonic-gatevoid 29277c478bd9Sstevel@tonic-gatecpu_delayed_logout(uint64_t afar, ch_cpu_logout_t *clop) 29287c478bd9Sstevel@tonic-gate{ } 29297c478bd9Sstevel@tonic-gate 29307c478bd9Sstevel@tonic-gate#else 29317c478bd9Sstevel@tonic-gate ENTRY(cpu_delayed_logout) 29327c478bd9Sstevel@tonic-gate rdpr %pstate, %o2 29337c478bd9Sstevel@tonic-gate andn %o2, PSTATE_IE, %o2 29347c478bd9Sstevel@tonic-gate wrpr %g0, %o2, %pstate ! disable interrupts 29357c478bd9Sstevel@tonic-gate PARK_SIBLING_CORE(%o2, %o3, %o4) ! %o2 has DCU value 29367c478bd9Sstevel@tonic-gate add %o1, CH_CLO_DATA + CH_CHD_EC_DATA, %o1 29377c478bd9Sstevel@tonic-gate rd %asi, %g1 29387c478bd9Sstevel@tonic-gate wr %g0, ASI_P, %asi 29397c478bd9Sstevel@tonic-gate GET_ECACHE_DTAGS(%o0, %o1, %o3, %o4, %o5) 29407c478bd9Sstevel@tonic-gate wr %g1, %asi 29417c478bd9Sstevel@tonic-gate UNPARK_SIBLING_CORE(%o2, %o3, %o4) ! can use %o2 again 29427c478bd9Sstevel@tonic-gate rdpr %pstate, %o2 29437c478bd9Sstevel@tonic-gate or %o2, PSTATE_IE, %o2 29447c478bd9Sstevel@tonic-gate wrpr %g0, %o2, %pstate 29457c478bd9Sstevel@tonic-gate retl 29467c478bd9Sstevel@tonic-gate nop 29477c478bd9Sstevel@tonic-gate SET_SIZE(cpu_delayed_logout) 29487c478bd9Sstevel@tonic-gate 29497c478bd9Sstevel@tonic-gate#endif /* lint */ 29507c478bd9Sstevel@tonic-gate 29517c478bd9Sstevel@tonic-gate#if defined(lint) 29527c478bd9Sstevel@tonic-gate 29537c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 29547c478bd9Sstevel@tonic-gateint 29557c478bd9Sstevel@tonic-gatedtrace_blksuword32(uintptr_t addr, uint32_t *data, int tryagain) 29567c478bd9Sstevel@tonic-gate{ return (0); } 29577c478bd9Sstevel@tonic-gate 29587c478bd9Sstevel@tonic-gate#else 29597c478bd9Sstevel@tonic-gate 29607c478bd9Sstevel@tonic-gate ENTRY(dtrace_blksuword32) 29617c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME + 4), %sp 29627c478bd9Sstevel@tonic-gate 29637c478bd9Sstevel@tonic-gate rdpr %pstate, %l1 29647c478bd9Sstevel@tonic-gate andn %l1, PSTATE_IE, %l2 ! disable interrupts to 29657c478bd9Sstevel@tonic-gate wrpr %g0, %l2, %pstate ! protect our FPU diddling 29667c478bd9Sstevel@tonic-gate 29677c478bd9Sstevel@tonic-gate rd %fprs, %l0 29687c478bd9Sstevel@tonic-gate andcc %l0, FPRS_FEF, %g0 29697c478bd9Sstevel@tonic-gate bz,a,pt %xcc, 1f ! if the fpu is disabled 29707c478bd9Sstevel@tonic-gate wr %g0, FPRS_FEF, %fprs ! ... enable the fpu 29717c478bd9Sstevel@tonic-gate 29727c478bd9Sstevel@tonic-gate st %f0, [%fp + STACK_BIAS - 4] ! save %f0 to the stack 29737c478bd9Sstevel@tonic-gate1: 29747c478bd9Sstevel@tonic-gate set 0f, %l5 29757c478bd9Sstevel@tonic-gate /* 29767c478bd9Sstevel@tonic-gate * We're about to write a block full or either total garbage 29777c478bd9Sstevel@tonic-gate * (not kernel data, don't worry) or user floating-point data 29787c478bd9Sstevel@tonic-gate * (so it only _looks_ like garbage). 29797c478bd9Sstevel@tonic-gate */ 29807c478bd9Sstevel@tonic-gate ld [%i1], %f0 ! modify the block 29817c478bd9Sstevel@tonic-gate membar #Sync 29827c478bd9Sstevel@tonic-gate stn %l5, [THREAD_REG + T_LOFAULT] ! set up the lofault handler 29837c478bd9Sstevel@tonic-gate stda %d0, [%i0]ASI_BLK_COMMIT_S ! store the modified block 29847c478bd9Sstevel@tonic-gate membar #Sync 29857c478bd9Sstevel@tonic-gate stn %g0, [THREAD_REG + T_LOFAULT] ! remove the lofault handler 29867c478bd9Sstevel@tonic-gate 29877c478bd9Sstevel@tonic-gate bz,a,pt %xcc, 1f 29887c478bd9Sstevel@tonic-gate wr %g0, %l0, %fprs ! restore %fprs 29897c478bd9Sstevel@tonic-gate 29907c478bd9Sstevel@tonic-gate ld [%fp + STACK_BIAS - 4], %f0 ! restore %f0 29917c478bd9Sstevel@tonic-gate1: 29927c478bd9Sstevel@tonic-gate 29937c478bd9Sstevel@tonic-gate wrpr %g0, %l1, %pstate ! restore interrupts 29947c478bd9Sstevel@tonic-gate 29957c478bd9Sstevel@tonic-gate ret 29967c478bd9Sstevel@tonic-gate restore %g0, %g0, %o0 29977c478bd9Sstevel@tonic-gate 29987c478bd9Sstevel@tonic-gate0: 29997c478bd9Sstevel@tonic-gate membar #Sync 30007c478bd9Sstevel@tonic-gate stn %g0, [THREAD_REG + T_LOFAULT] ! remove the lofault handler 30017c478bd9Sstevel@tonic-gate 30027c478bd9Sstevel@tonic-gate bz,a,pt %xcc, 1f 30037c478bd9Sstevel@tonic-gate wr %g0, %l0, %fprs ! restore %fprs 30047c478bd9Sstevel@tonic-gate 30057c478bd9Sstevel@tonic-gate ld [%fp + STACK_BIAS - 4], %f0 ! restore %f0 30067c478bd9Sstevel@tonic-gate1: 30077c478bd9Sstevel@tonic-gate 30087c478bd9Sstevel@tonic-gate wrpr %g0, %l1, %pstate ! restore interrupts 30097c478bd9Sstevel@tonic-gate 30107c478bd9Sstevel@tonic-gate /* 30117c478bd9Sstevel@tonic-gate * If tryagain is set (%i2) we tail-call dtrace_blksuword32_err() 30127c478bd9Sstevel@tonic-gate * which deals with watchpoints. Otherwise, just return -1. 30137c478bd9Sstevel@tonic-gate */ 30147c478bd9Sstevel@tonic-gate brnz,pt %i2, 1f 30157c478bd9Sstevel@tonic-gate nop 30167c478bd9Sstevel@tonic-gate ret 30177c478bd9Sstevel@tonic-gate restore %g0, -1, %o0 30187c478bd9Sstevel@tonic-gate1: 30197c478bd9Sstevel@tonic-gate call dtrace_blksuword32_err 30207c478bd9Sstevel@tonic-gate restore 30217c478bd9Sstevel@tonic-gate 30227c478bd9Sstevel@tonic-gate SET_SIZE(dtrace_blksuword32) 30237c478bd9Sstevel@tonic-gate 30247c478bd9Sstevel@tonic-gate#endif /* lint */ 30257c478bd9Sstevel@tonic-gate 30267c478bd9Sstevel@tonic-gate#ifdef CHEETAHPLUS_ERRATUM_25 30277c478bd9Sstevel@tonic-gate 30287c478bd9Sstevel@tonic-gate#if defined(lint) 30297c478bd9Sstevel@tonic-gate/* 30307c478bd9Sstevel@tonic-gate * Claim a chunk of physical address space. 30317c478bd9Sstevel@tonic-gate */ 30327c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 30337c478bd9Sstevel@tonic-gatevoid 30347c478bd9Sstevel@tonic-gateclaimlines(uint64_t pa, size_t sz, int stride) 30357c478bd9Sstevel@tonic-gate{} 30367c478bd9Sstevel@tonic-gate#else /* lint */ 30377c478bd9Sstevel@tonic-gate ENTRY(claimlines) 30387c478bd9Sstevel@tonic-gate1: 30397c478bd9Sstevel@tonic-gate subcc %o1, %o2, %o1 30407c478bd9Sstevel@tonic-gate add %o0, %o1, %o3 30417c478bd9Sstevel@tonic-gate bgeu,a,pt %xcc, 1b 30427c478bd9Sstevel@tonic-gate casxa [%o3]ASI_MEM, %g0, %g0 30437c478bd9Sstevel@tonic-gate membar #Sync 30447c478bd9Sstevel@tonic-gate retl 30457c478bd9Sstevel@tonic-gate nop 30467c478bd9Sstevel@tonic-gate SET_SIZE(claimlines) 30477c478bd9Sstevel@tonic-gate#endif /* lint */ 30487c478bd9Sstevel@tonic-gate 30497c478bd9Sstevel@tonic-gate#if defined(lint) 30507c478bd9Sstevel@tonic-gate/* 30517c478bd9Sstevel@tonic-gate * CPU feature initialization, 30527c478bd9Sstevel@tonic-gate * turn BPE off, 30537c478bd9Sstevel@tonic-gate * get device id. 30547c478bd9Sstevel@tonic-gate */ 30557c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 30567c478bd9Sstevel@tonic-gatevoid 30577c478bd9Sstevel@tonic-gatecpu_feature_init(void) 30587c478bd9Sstevel@tonic-gate{} 30597c478bd9Sstevel@tonic-gate#else /* lint */ 30607c478bd9Sstevel@tonic-gate ENTRY(cpu_feature_init) 30617c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME), %sp 30627c478bd9Sstevel@tonic-gate sethi %hi(cheetah_bpe_off), %o0 30637c478bd9Sstevel@tonic-gate ld [%o0 + %lo(cheetah_bpe_off)], %o0 30647c478bd9Sstevel@tonic-gate brz %o0, 1f 30657c478bd9Sstevel@tonic-gate nop 30667c478bd9Sstevel@tonic-gate rd ASR_DISPATCH_CONTROL, %o0 30677c478bd9Sstevel@tonic-gate andn %o0, ASR_DISPATCH_CONTROL_BPE, %o0 30687c478bd9Sstevel@tonic-gate wr %o0, 0, ASR_DISPATCH_CONTROL 30697c478bd9Sstevel@tonic-gate1: 30707c478bd9Sstevel@tonic-gate ! 30717c478bd9Sstevel@tonic-gate ! get the device_id and store the device_id 30727c478bd9Sstevel@tonic-gate ! in the appropriate cpunodes structure 30737c478bd9Sstevel@tonic-gate ! given the cpus index 30747c478bd9Sstevel@tonic-gate ! 30757c478bd9Sstevel@tonic-gate CPU_INDEX(%o0, %o1) 30767c478bd9Sstevel@tonic-gate mulx %o0, CPU_NODE_SIZE, %o0 30777c478bd9Sstevel@tonic-gate set cpunodes + DEVICE_ID, %o1 30787c478bd9Sstevel@tonic-gate ldxa [%g0] ASI_DEVICE_SERIAL_ID, %o2 30797c478bd9Sstevel@tonic-gate stx %o2, [%o0 + %o1] 30807c478bd9Sstevel@tonic-gate#ifdef CHEETAHPLUS_ERRATUM_34 30817c478bd9Sstevel@tonic-gate ! 30827c478bd9Sstevel@tonic-gate ! apply Cheetah+ erratum 34 workaround 30837c478bd9Sstevel@tonic-gate ! 30847c478bd9Sstevel@tonic-gate call itlb_erratum34_fixup 30857c478bd9Sstevel@tonic-gate nop 308619f938d5Sjfrank call dtlb_erratum34_fixup 308719f938d5Sjfrank nop 30887c478bd9Sstevel@tonic-gate#endif /* CHEETAHPLUS_ERRATUM_34 */ 30897c478bd9Sstevel@tonic-gate ret 30907c478bd9Sstevel@tonic-gate restore 30917c478bd9Sstevel@tonic-gate SET_SIZE(cpu_feature_init) 30927c478bd9Sstevel@tonic-gate#endif /* lint */ 30937c478bd9Sstevel@tonic-gate 30947c478bd9Sstevel@tonic-gate#if defined(lint) 30957c478bd9Sstevel@tonic-gate/* 30967c478bd9Sstevel@tonic-gate * Copy a tsb entry atomically, from src to dest. 30977c478bd9Sstevel@tonic-gate * src must be 128 bit aligned. 30987c478bd9Sstevel@tonic-gate */ 30997c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 31007c478bd9Sstevel@tonic-gatevoid 31017c478bd9Sstevel@tonic-gatecopy_tsb_entry(uintptr_t src, uintptr_t dest) 31027c478bd9Sstevel@tonic-gate{} 31037c478bd9Sstevel@tonic-gate#else /* lint */ 31047c478bd9Sstevel@tonic-gate ENTRY(copy_tsb_entry) 31057c478bd9Sstevel@tonic-gate ldda [%o0]ASI_NQUAD_LD, %o2 ! %o2 = tag, %o3 = data 31067c478bd9Sstevel@tonic-gate stx %o2, [%o1] 31077c478bd9Sstevel@tonic-gate stx %o3, [%o1 + 8 ] 31087c478bd9Sstevel@tonic-gate retl 31097c478bd9Sstevel@tonic-gate nop 31107c478bd9Sstevel@tonic-gate SET_SIZE(copy_tsb_entry) 31117c478bd9Sstevel@tonic-gate#endif /* lint */ 31127c478bd9Sstevel@tonic-gate 31137c478bd9Sstevel@tonic-gate#endif /* CHEETAHPLUS_ERRATUM_25 */ 31147c478bd9Sstevel@tonic-gate 31157c478bd9Sstevel@tonic-gate#ifdef CHEETAHPLUS_ERRATUM_34 31167c478bd9Sstevel@tonic-gate 31177c478bd9Sstevel@tonic-gate#if defined(lint) 31187c478bd9Sstevel@tonic-gate 31197c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 31207c478bd9Sstevel@tonic-gatevoid 31217c478bd9Sstevel@tonic-gateitlb_erratum34_fixup(void) 31227c478bd9Sstevel@tonic-gate{} 31237c478bd9Sstevel@tonic-gate 31247c478bd9Sstevel@tonic-gate#else /* lint */ 31257c478bd9Sstevel@tonic-gate 31267c478bd9Sstevel@tonic-gate ! 31277c478bd9Sstevel@tonic-gate ! In Cheetah+ erratum 34, under certain conditions an ITLB locked 31287c478bd9Sstevel@tonic-gate ! index 0 TTE will erroneously be displaced when a new TTE is 31297c478bd9Sstevel@tonic-gate ! loaded via ASI_ITLB_IN. In order to avoid cheetah+ erratum 34, 31307c478bd9Sstevel@tonic-gate ! locked index 0 TTEs must be relocated. 31317c478bd9Sstevel@tonic-gate ! 31327c478bd9Sstevel@tonic-gate ! NOTE: Care must be taken to avoid an ITLB miss in this routine. 31337c478bd9Sstevel@tonic-gate ! 31347c478bd9Sstevel@tonic-gate ENTRY_NP(itlb_erratum34_fixup) 31357c478bd9Sstevel@tonic-gate rdpr %pstate, %o3 31367c478bd9Sstevel@tonic-gate#ifdef DEBUG 31371e2e7a75Shuah PANIC_IF_INTR_DISABLED_PSTR(%o3, u3_di_label1, %g1) 31387c478bd9Sstevel@tonic-gate#endif /* DEBUG */ 31397c478bd9Sstevel@tonic-gate wrpr %o3, PSTATE_IE, %pstate ! Disable interrupts 31407c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_ITLB_ACCESS, %o1 ! %o1 = entry 0 data 31417c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_ITLB_TAGREAD, %o2 ! %o2 = entry 0 tag 31427c478bd9Sstevel@tonic-gate 31437c478bd9Sstevel@tonic-gate cmp %o1, %g0 ! Is this entry valid? 31447c478bd9Sstevel@tonic-gate bge %xcc, 1f 31457c478bd9Sstevel@tonic-gate andcc %o1, TTE_LCK_INT, %g0 ! Is this entry locked? 31467c478bd9Sstevel@tonic-gate bnz %icc, 2f 31477c478bd9Sstevel@tonic-gate nop 31487c478bd9Sstevel@tonic-gate1: 31497c478bd9Sstevel@tonic-gate retl ! Nope, outta here... 31507c478bd9Sstevel@tonic-gate wrpr %g0, %o3, %pstate ! Enable interrupts 31517c478bd9Sstevel@tonic-gate2: 31527c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %o4 31537c478bd9Sstevel@tonic-gate stxa %g0, [%o2]ASI_ITLB_DEMAP ! Flush this mapping 31547c478bd9Sstevel@tonic-gate flush %o4 ! Flush required for I-MMU 31557c478bd9Sstevel@tonic-gate ! 31567c478bd9Sstevel@tonic-gate ! Start search from index 1 up. This is because the kernel force 31577c478bd9Sstevel@tonic-gate ! loads its text page at index 15 in sfmmu_kernel_remap() and we 31587c478bd9Sstevel@tonic-gate ! don't want our relocated entry evicted later. 31597c478bd9Sstevel@tonic-gate ! 31607c478bd9Sstevel@tonic-gate ! NOTE: We assume that we'll be successful in finding an unlocked 31617c478bd9Sstevel@tonic-gate ! or invalid entry. If that isn't the case there are bound to 31627c478bd9Sstevel@tonic-gate ! bigger problems. 31637c478bd9Sstevel@tonic-gate ! 31647c478bd9Sstevel@tonic-gate set (1 << 3), %g3 31657c478bd9Sstevel@tonic-gate3: 31667c478bd9Sstevel@tonic-gate ldxa [%g3]ASI_ITLB_ACCESS, %o4 ! Load TTE from t16 31677c478bd9Sstevel@tonic-gate ! 31687c478bd9Sstevel@tonic-gate ! If this entry isn't valid, we'll choose to displace it (regardless 31697c478bd9Sstevel@tonic-gate ! of the lock bit). 31707c478bd9Sstevel@tonic-gate ! 31717c478bd9Sstevel@tonic-gate cmp %o4, %g0 ! TTE is > 0 iff not valid 31727c478bd9Sstevel@tonic-gate bge %xcc, 4f ! If invalid, go displace 31737c478bd9Sstevel@tonic-gate andcc %o4, TTE_LCK_INT, %g0 ! Check for lock bit 31747c478bd9Sstevel@tonic-gate bnz,a %icc, 3b ! If locked, look at next 31757c478bd9Sstevel@tonic-gate add %g3, (1 << 3), %g3 ! entry 31767c478bd9Sstevel@tonic-gate4: 31777c478bd9Sstevel@tonic-gate ! 31787c478bd9Sstevel@tonic-gate ! We found an unlocked or invalid entry; we'll explicitly load 31797c478bd9Sstevel@tonic-gate ! the former index 0 entry here. 31807c478bd9Sstevel@tonic-gate ! 31817c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %o4 31827c478bd9Sstevel@tonic-gate set MMU_TAG_ACCESS, %g4 31837c478bd9Sstevel@tonic-gate stxa %o2, [%g4]ASI_IMMU 31847c478bd9Sstevel@tonic-gate stxa %o1, [%g3]ASI_ITLB_ACCESS 31857c478bd9Sstevel@tonic-gate flush %o4 ! Flush required for I-MMU 31867c478bd9Sstevel@tonic-gate retl 31877c478bd9Sstevel@tonic-gate wrpr %g0, %o3, %pstate ! Enable interrupts 31887c478bd9Sstevel@tonic-gate SET_SIZE(itlb_erratum34_fixup) 31897c478bd9Sstevel@tonic-gate 31907c478bd9Sstevel@tonic-gate#endif /* lint */ 31917c478bd9Sstevel@tonic-gate 319219f938d5Sjfrank#if defined(lint) 319319f938d5Sjfrank 319419f938d5Sjfrank/*ARGSUSED*/ 319519f938d5Sjfrankvoid 319619f938d5Sjfrankdtlb_erratum34_fixup(void) 319719f938d5Sjfrank{} 319819f938d5Sjfrank 319919f938d5Sjfrank#else /* lint */ 320019f938d5Sjfrank 320119f938d5Sjfrank ! 320219f938d5Sjfrank ! In Cheetah+ erratum 34, under certain conditions a DTLB locked 320319f938d5Sjfrank ! index 0 TTE will erroneously be displaced when a new TTE is 320419f938d5Sjfrank ! loaded. In order to avoid cheetah+ erratum 34, locked index 0 320519f938d5Sjfrank ! TTEs must be relocated. 320619f938d5Sjfrank ! 320719f938d5Sjfrank ENTRY_NP(dtlb_erratum34_fixup) 320819f938d5Sjfrank rdpr %pstate, %o3 320919f938d5Sjfrank#ifdef DEBUG 321019f938d5Sjfrank PANIC_IF_INTR_DISABLED_PSTR(%o3, u3_di_label2, %g1) 321119f938d5Sjfrank#endif /* DEBUG */ 321219f938d5Sjfrank wrpr %o3, PSTATE_IE, %pstate ! Disable interrupts 321319f938d5Sjfrank ldxa [%g0]ASI_DTLB_ACCESS, %o1 ! %o1 = entry 0 data 321419f938d5Sjfrank ldxa [%g0]ASI_DTLB_TAGREAD, %o2 ! %o2 = entry 0 tag 321519f938d5Sjfrank 321619f938d5Sjfrank cmp %o1, %g0 ! Is this entry valid? 321719f938d5Sjfrank bge %xcc, 1f 321819f938d5Sjfrank andcc %o1, TTE_LCK_INT, %g0 ! Is this entry locked? 321919f938d5Sjfrank bnz %icc, 2f 322019f938d5Sjfrank nop 322119f938d5Sjfrank1: 322219f938d5Sjfrank retl ! Nope, outta here... 322319f938d5Sjfrank wrpr %g0, %o3, %pstate ! Enable interrupts 322419f938d5Sjfrank2: 322519f938d5Sjfrank stxa %g0, [%o2]ASI_DTLB_DEMAP ! Flush this mapping 322619f938d5Sjfrank membar #Sync 322719f938d5Sjfrank ! 322819f938d5Sjfrank ! Start search from index 1 up. 322919f938d5Sjfrank ! 323019f938d5Sjfrank ! NOTE: We assume that we'll be successful in finding an unlocked 323119f938d5Sjfrank ! or invalid entry. If that isn't the case there are bound to 323219f938d5Sjfrank ! bigger problems. 323319f938d5Sjfrank ! 323419f938d5Sjfrank set (1 << 3), %g3 323519f938d5Sjfrank3: 323619f938d5Sjfrank ldxa [%g3]ASI_DTLB_ACCESS, %o4 ! Load TTE from t16 323719f938d5Sjfrank ! 323819f938d5Sjfrank ! If this entry isn't valid, we'll choose to displace it (regardless 323919f938d5Sjfrank ! of the lock bit). 324019f938d5Sjfrank ! 324119f938d5Sjfrank cmp %o4, %g0 ! TTE is > 0 iff not valid 324219f938d5Sjfrank bge %xcc, 4f ! If invalid, go displace 324319f938d5Sjfrank andcc %o4, TTE_LCK_INT, %g0 ! Check for lock bit 324419f938d5Sjfrank bnz,a %icc, 3b ! If locked, look at next 324519f938d5Sjfrank add %g3, (1 << 3), %g3 ! entry 324619f938d5Sjfrank4: 324719f938d5Sjfrank ! 324819f938d5Sjfrank ! We found an unlocked or invalid entry; we'll explicitly load 324919f938d5Sjfrank ! the former index 0 entry here. 325019f938d5Sjfrank ! 325119f938d5Sjfrank set MMU_TAG_ACCESS, %g4 325219f938d5Sjfrank stxa %o2, [%g4]ASI_DMMU 325319f938d5Sjfrank stxa %o1, [%g3]ASI_DTLB_ACCESS 325419f938d5Sjfrank membar #Sync 325519f938d5Sjfrank retl 325619f938d5Sjfrank wrpr %g0, %o3, %pstate ! Enable interrupts 325719f938d5Sjfrank SET_SIZE(dtlb_erratum34_fixup) 325819f938d5Sjfrank 325919f938d5Sjfrank#endif /* lint */ 326019f938d5Sjfrank 32617c478bd9Sstevel@tonic-gate#endif /* CHEETAHPLUS_ERRATUM_34 */ 32627c478bd9Sstevel@tonic-gate 3263