125cf1a30Sjl139090/* 225cf1a30Sjl139090 * CDDL HEADER START 325cf1a30Sjl139090 * 425cf1a30Sjl139090 * The contents of this file are subject to the terms of the 525cf1a30Sjl139090 * Common Development and Distribution License (the "License"). 625cf1a30Sjl139090 * You may not use this file except in compliance with the License. 725cf1a30Sjl139090 * 825cf1a30Sjl139090 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 925cf1a30Sjl139090 * or http://www.opensolaris.org/os/licensing. 1025cf1a30Sjl139090 * See the License for the specific language governing permissions 1125cf1a30Sjl139090 * and limitations under the License. 1225cf1a30Sjl139090 * 1325cf1a30Sjl139090 * When distributing Covered Code, include this CDDL HEADER in each 1425cf1a30Sjl139090 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1525cf1a30Sjl139090 * If applicable, add the following below this CDDL HEADER, with the 1625cf1a30Sjl139090 * fields enclosed by brackets "[]" replaced with your own identifying 1725cf1a30Sjl139090 * information: Portions Copyright [yyyy] [name of copyright owner] 1825cf1a30Sjl139090 * 1925cf1a30Sjl139090 * CDDL HEADER END 2025cf1a30Sjl139090 */ 2125cf1a30Sjl139090/* 22*c9d93b53SJames Anderson * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2325cf1a30Sjl139090 * Use is subject to license terms. 2425cf1a30Sjl139090 * 2525cf1a30Sjl139090 * Assembly code support for the Olympus-C module 2625cf1a30Sjl139090 */ 2725cf1a30Sjl139090 2825cf1a30Sjl139090#if !defined(lint) 2925cf1a30Sjl139090#include "assym.h" 3025cf1a30Sjl139090#endif /* lint */ 3125cf1a30Sjl139090 3225cf1a30Sjl139090#include <sys/asm_linkage.h> 3325cf1a30Sjl139090#include <sys/mmu.h> 3425cf1a30Sjl139090#include <vm/hat_sfmmu.h> 3525cf1a30Sjl139090#include <sys/machparam.h> 3625cf1a30Sjl139090#include <sys/machcpuvar.h> 3725cf1a30Sjl139090#include <sys/machthread.h> 3825cf1a30Sjl139090#include <sys/machtrap.h> 3925cf1a30Sjl139090#include <sys/privregs.h> 4025cf1a30Sjl139090#include <sys/asm_linkage.h> 4125cf1a30Sjl139090#include <sys/trap.h> 4225cf1a30Sjl139090#include <sys/opl_olympus_regs.h> 4325cf1a30Sjl139090#include <sys/opl_module.h> 4425cf1a30Sjl139090#include <sys/xc_impl.h> 4525cf1a30Sjl139090#include <sys/intreg.h> 4625cf1a30Sjl139090#include <sys/async.h> 4725cf1a30Sjl139090#include <sys/clock.h> 4825cf1a30Sjl139090#include <sys/cmpregs.h> 4925cf1a30Sjl139090 5025cf1a30Sjl139090#ifdef TRAPTRACE 5125cf1a30Sjl139090#include <sys/traptrace.h> 5225cf1a30Sjl139090#endif /* TRAPTRACE */ 5325cf1a30Sjl139090 5425cf1a30Sjl139090/* 5525cf1a30Sjl139090 * Macro that flushes the entire Ecache. 5625cf1a30Sjl139090 * 5725cf1a30Sjl139090 * arg1 = ecache size 5825cf1a30Sjl139090 * arg2 = ecache linesize 5925cf1a30Sjl139090 * arg3 = ecache flush address - Not used for olympus-C 6025cf1a30Sjl139090 */ 6125cf1a30Sjl139090#define ECACHE_FLUSHALL(arg1, arg2, arg3, tmp1) \ 6225cf1a30Sjl139090 mov ASI_L2_CTRL_U2_FLUSH, arg1; \ 6325cf1a30Sjl139090 mov ASI_L2_CTRL_RW_ADDR, arg2; \ 6425cf1a30Sjl139090 stxa arg1, [arg2]ASI_L2_CTRL 6525cf1a30Sjl139090 6625cf1a30Sjl139090/* 6725cf1a30Sjl139090 * SPARC64-VI MMU and Cache operations. 6825cf1a30Sjl139090 */ 6925cf1a30Sjl139090 7025cf1a30Sjl139090#if defined(lint) 7125cf1a30Sjl139090 7225cf1a30Sjl139090/* ARGSUSED */ 7325cf1a30Sjl139090void 741e2e7a75Shuahvtag_flushpage(caddr_t vaddr, uint64_t sfmmup) 7525cf1a30Sjl139090{} 7625cf1a30Sjl139090 7725cf1a30Sjl139090#else /* lint */ 7825cf1a30Sjl139090 7925cf1a30Sjl139090 ENTRY_NP(vtag_flushpage) 8025cf1a30Sjl139090 /* 8125cf1a30Sjl139090 * flush page from the tlb 8225cf1a30Sjl139090 * 8325cf1a30Sjl139090 * %o0 = vaddr 841e2e7a75Shuah * %o1 = sfmmup 8525cf1a30Sjl139090 */ 8625cf1a30Sjl139090 rdpr %pstate, %o5 8725cf1a30Sjl139090#ifdef DEBUG 881e2e7a75Shuah PANIC_IF_INTR_DISABLED_PSTR(%o5, opl_di_l3, %g1) 8925cf1a30Sjl139090#endif /* DEBUG */ 9025cf1a30Sjl139090 /* 9125cf1a30Sjl139090 * disable ints 9225cf1a30Sjl139090 */ 9325cf1a30Sjl139090 andn %o5, PSTATE_IE, %o4 9425cf1a30Sjl139090 wrpr %o4, 0, %pstate 9525cf1a30Sjl139090 9625cf1a30Sjl139090 /* 9725cf1a30Sjl139090 * Then, blow out the tlb 9825cf1a30Sjl139090 * Interrupts are disabled to prevent the primary ctx register 9925cf1a30Sjl139090 * from changing underneath us. 10025cf1a30Sjl139090 */ 1011e2e7a75Shuah sethi %hi(ksfmmup), %o3 1021e2e7a75Shuah ldx [%o3 + %lo(ksfmmup)], %o3 1031e2e7a75Shuah cmp %o3, %o1 1041e2e7a75Shuah bne,pt %xcc, 1f ! if not kernel as, go to 1 10525cf1a30Sjl139090 sethi %hi(FLUSH_ADDR), %o3 10625cf1a30Sjl139090 /* 1071e2e7a75Shuah * For Kernel demaps use primary. type = page implicitly 10825cf1a30Sjl139090 */ 10925cf1a30Sjl139090 stxa %g0, [%o0]ASI_DTLB_DEMAP /* dmmu flush for KCONTEXT */ 11025cf1a30Sjl139090 stxa %g0, [%o0]ASI_ITLB_DEMAP /* immu flush for KCONTEXT */ 11125cf1a30Sjl139090 flush %o3 1121e2e7a75Shuah retl 1131e2e7a75Shuah wrpr %g0, %o5, %pstate /* enable interrupts */ 11425cf1a30Sjl1390901: 11525cf1a30Sjl139090 /* 11625cf1a30Sjl139090 * User demap. We need to set the primary context properly. 11725cf1a30Sjl139090 * Secondary context cannot be used for SPARC64-VI IMMU. 11825cf1a30Sjl139090 * %o0 = vaddr 1191e2e7a75Shuah * %o1 = sfmmup 12025cf1a30Sjl139090 * %o3 = FLUSH_ADDR 12125cf1a30Sjl139090 */ 1221e2e7a75Shuah SFMMU_CPU_CNUM(%o1, %g1, %g2) ! %g1 = sfmmu cnum on this CPU 1231e2e7a75Shuah 1241e2e7a75Shuah ldub [%o1 + SFMMU_CEXT], %o4 ! %o4 = sfmmup->sfmmu_cext 12525cf1a30Sjl139090 sll %o4, CTXREG_EXT_SHIFT, %o4 126febcc4a5Sjimand or %g1, %o4, %g1 ! %g1 = primary pgsz | cnum 1271e2e7a75Shuah 12825cf1a30Sjl139090 wrpr %g0, 1, %tl 12925cf1a30Sjl139090 set MMU_PCONTEXT, %o4 13025cf1a30Sjl139090 or DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %o0, %o0 1311e2e7a75Shuah ldxa [%o4]ASI_DMMU, %o2 ! %o2 = save old ctxnum 132febcc4a5Sjimand srlx %o2, CTXREG_NEXT_SHIFT, %o1 ! need to preserve nucleus pgsz 133febcc4a5Sjimand sllx %o1, CTXREG_NEXT_SHIFT, %o1 ! %o1 = nucleus pgsz 134febcc4a5Sjimand or %g1, %o1, %g1 ! %g1 = nucleus pgsz | primary pgsz | cnum 1351e2e7a75Shuah stxa %g1, [%o4]ASI_DMMU ! wr new ctxum 1361e2e7a75Shuah 13725cf1a30Sjl139090 stxa %g0, [%o0]ASI_DTLB_DEMAP 13825cf1a30Sjl139090 stxa %g0, [%o0]ASI_ITLB_DEMAP 13925cf1a30Sjl139090 stxa %o2, [%o4]ASI_DMMU /* restore old ctxnum */ 14025cf1a30Sjl139090 flush %o3 14125cf1a30Sjl139090 wrpr %g0, 0, %tl 1421e2e7a75Shuah 14325cf1a30Sjl139090 retl 14425cf1a30Sjl139090 wrpr %g0, %o5, %pstate /* enable interrupts */ 14525cf1a30Sjl139090 SET_SIZE(vtag_flushpage) 14625cf1a30Sjl139090 14725cf1a30Sjl139090#endif /* lint */ 14825cf1a30Sjl139090 14925cf1a30Sjl139090 15025cf1a30Sjl139090#if defined(lint) 15125cf1a30Sjl139090 15225cf1a30Sjl139090void 15325cf1a30Sjl139090vtag_flushall(void) 15425cf1a30Sjl139090{} 15525cf1a30Sjl139090 15625cf1a30Sjl139090#else /* lint */ 15725cf1a30Sjl139090 15825cf1a30Sjl139090 ENTRY_NP2(vtag_flushall, demap_all) 15925cf1a30Sjl139090 /* 16025cf1a30Sjl139090 * flush the tlb 16125cf1a30Sjl139090 */ 16225cf1a30Sjl139090 sethi %hi(FLUSH_ADDR), %o3 16325cf1a30Sjl139090 set DEMAP_ALL_TYPE, %g1 16425cf1a30Sjl139090 stxa %g0, [%g1]ASI_DTLB_DEMAP 16525cf1a30Sjl139090 stxa %g0, [%g1]ASI_ITLB_DEMAP 16625cf1a30Sjl139090 flush %o3 16725cf1a30Sjl139090 retl 16825cf1a30Sjl139090 nop 16925cf1a30Sjl139090 SET_SIZE(demap_all) 17025cf1a30Sjl139090 SET_SIZE(vtag_flushall) 17125cf1a30Sjl139090 17225cf1a30Sjl139090#endif /* lint */ 17325cf1a30Sjl139090 17425cf1a30Sjl139090 17525cf1a30Sjl139090#if defined(lint) 17625cf1a30Sjl139090 17725cf1a30Sjl139090/* ARGSUSED */ 17825cf1a30Sjl139090void 1791e2e7a75Shuahvtag_flushpage_tl1(uint64_t vaddr, uint64_t sfmmup) 18025cf1a30Sjl139090{} 18125cf1a30Sjl139090 18225cf1a30Sjl139090#else /* lint */ 18325cf1a30Sjl139090 18425cf1a30Sjl139090 ENTRY_NP(vtag_flushpage_tl1) 18525cf1a30Sjl139090 /* 18625cf1a30Sjl139090 * x-trap to flush page from tlb and tsb 18725cf1a30Sjl139090 * 18825cf1a30Sjl139090 * %g1 = vaddr, zero-extended on 32-bit kernel 1891e2e7a75Shuah * %g2 = sfmmup 19025cf1a30Sjl139090 * 19125cf1a30Sjl139090 * assumes TSBE_TAG = 0 19225cf1a30Sjl139090 */ 19325cf1a30Sjl139090 srln %g1, MMU_PAGESHIFT, %g1 1941e2e7a75Shuah 1951e2e7a75Shuah sethi %hi(ksfmmup), %g3 1961e2e7a75Shuah ldx [%g3 + %lo(ksfmmup)], %g3 1971e2e7a75Shuah cmp %g3, %g2 1981e2e7a75Shuah bne,pt %xcc, 1f ! if not kernel as, go to 1 19925cf1a30Sjl139090 slln %g1, MMU_PAGESHIFT, %g1 /* g1 = vaddr */ 20025cf1a30Sjl139090 20125cf1a30Sjl139090 /* We need to demap in the kernel context */ 20225cf1a30Sjl139090 or DEMAP_NUCLEUS | DEMAP_PAGE_TYPE, %g1, %g1 20325cf1a30Sjl139090 stxa %g0, [%g1]ASI_DTLB_DEMAP 20425cf1a30Sjl139090 stxa %g0, [%g1]ASI_ITLB_DEMAP 20525cf1a30Sjl139090 retry 20625cf1a30Sjl1390901: 20725cf1a30Sjl139090 /* We need to demap in a user context */ 20825cf1a30Sjl139090 or DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %g1, %g1 2091e2e7a75Shuah 2101e2e7a75Shuah SFMMU_CPU_CNUM(%g2, %g6, %g3) ! %g6 = sfmmu cnum on this CPU 2111e2e7a75Shuah 2121e2e7a75Shuah ldub [%g2 + SFMMU_CEXT], %g4 ! %g4 = sfmmup->cext 21325cf1a30Sjl139090 sll %g4, CTXREG_EXT_SHIFT, %g4 214febcc4a5Sjimand or %g6, %g4, %g6 ! %g6 = primary pgsz | cnum 21525cf1a30Sjl139090 21625cf1a30Sjl139090 set MMU_PCONTEXT, %g4 217febcc4a5Sjimand ldxa [%g4]ASI_DMMU, %g5 ! %g5 = save old ctxnum 218febcc4a5Sjimand srlx %g5, CTXREG_NEXT_SHIFT, %g2 ! %g2 = nucleus pgsz 219febcc4a5Sjimand sllx %g2, CTXREG_NEXT_SHIFT, %g2 ! preserve nucleus pgsz 220febcc4a5Sjimand or %g6, %g2, %g6 ! %g6 = nucleus pgsz | primary pgsz | cnum 221febcc4a5Sjimand stxa %g6, [%g4]ASI_DMMU ! wr new ctxum 22225cf1a30Sjl139090 stxa %g0, [%g1]ASI_DTLB_DEMAP 22325cf1a30Sjl139090 stxa %g0, [%g1]ASI_ITLB_DEMAP 224febcc4a5Sjimand stxa %g5, [%g4]ASI_DMMU ! restore old ctxnum 22525cf1a30Sjl139090 retry 22625cf1a30Sjl139090 SET_SIZE(vtag_flushpage_tl1) 22725cf1a30Sjl139090 22825cf1a30Sjl139090#endif /* lint */ 22925cf1a30Sjl139090 2301e2e7a75Shuah 23125cf1a30Sjl139090#if defined(lint) 23225cf1a30Sjl139090 23325cf1a30Sjl139090/* ARGSUSED */ 23425cf1a30Sjl139090void 2351e2e7a75Shuahvtag_flush_pgcnt_tl1(uint64_t vaddr, uint64_t sfmmup_pgcnt) 23625cf1a30Sjl139090{} 23725cf1a30Sjl139090 23825cf1a30Sjl139090#else /* lint */ 23925cf1a30Sjl139090 24025cf1a30Sjl139090 ENTRY_NP(vtag_flush_pgcnt_tl1) 24125cf1a30Sjl139090 /* 24225cf1a30Sjl139090 * x-trap to flush pgcnt MMU_PAGESIZE pages from tlb 24325cf1a30Sjl139090 * 24425cf1a30Sjl139090 * %g1 = vaddr, zero-extended on 32-bit kernel 2451e2e7a75Shuah * %g2 = <sfmmup58|pgcnt6> 24625cf1a30Sjl139090 * 24725cf1a30Sjl139090 * NOTE: this handler relies on the fact that no 24825cf1a30Sjl139090 * interrupts or traps can occur during the loop 24925cf1a30Sjl139090 * issuing the TLB_DEMAP operations. It is assumed 25025cf1a30Sjl139090 * that interrupts are disabled and this code is 25125cf1a30Sjl139090 * fetching from the kernel locked text address. 25225cf1a30Sjl139090 * 25325cf1a30Sjl139090 * assumes TSBE_TAG = 0 25425cf1a30Sjl139090 */ 2551e2e7a75Shuah set SFMMU_PGCNT_MASK, %g4 2561e2e7a75Shuah and %g4, %g2, %g3 /* g3 = pgcnt - 1 */ 2571e2e7a75Shuah add %g3, 1, %g3 /* g3 = pgcnt */ 2581e2e7a75Shuah 2591e2e7a75Shuah andn %g2, SFMMU_PGCNT_MASK, %g2 /* g2 = sfmmup */ 26025cf1a30Sjl139090 srln %g1, MMU_PAGESHIFT, %g1 2611e2e7a75Shuah 2621e2e7a75Shuah sethi %hi(ksfmmup), %g4 2631e2e7a75Shuah ldx [%g4 + %lo(ksfmmup)], %g4 2641e2e7a75Shuah cmp %g4, %g2 2651e2e7a75Shuah bne,pn %xcc, 1f /* if not kernel as, go to 1 */ 26625cf1a30Sjl139090 slln %g1, MMU_PAGESHIFT, %g1 /* g1 = vaddr */ 26725cf1a30Sjl139090 26825cf1a30Sjl139090 /* We need to demap in the kernel context */ 26925cf1a30Sjl139090 or DEMAP_NUCLEUS | DEMAP_PAGE_TYPE, %g1, %g1 27025cf1a30Sjl139090 set MMU_PAGESIZE, %g2 /* g2 = pgsize */ 2711e2e7a75Shuah sethi %hi(FLUSH_ADDR), %g5 27225cf1a30Sjl1390904: 27325cf1a30Sjl139090 stxa %g0, [%g1]ASI_DTLB_DEMAP 27425cf1a30Sjl139090 stxa %g0, [%g1]ASI_ITLB_DEMAP 2751e2e7a75Shuah flush %g5 ! flush required by immu 2761e2e7a75Shuah 27725cf1a30Sjl139090 deccc %g3 /* decr pgcnt */ 27825cf1a30Sjl139090 bnz,pt %icc,4b 27925cf1a30Sjl139090 add %g1, %g2, %g1 /* next page */ 28025cf1a30Sjl139090 retry 28125cf1a30Sjl1390901: 2821e2e7a75Shuah /* 2831e2e7a75Shuah * We need to demap in a user context 2841e2e7a75Shuah * 2851e2e7a75Shuah * g2 = sfmmup 2861e2e7a75Shuah * g3 = pgcnt 2871e2e7a75Shuah */ 2881e2e7a75Shuah SFMMU_CPU_CNUM(%g2, %g5, %g6) ! %g5 = sfmmu cnum on this CPU 2891e2e7a75Shuah 29025cf1a30Sjl139090 or DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %g1, %g1 2911e2e7a75Shuah 2921e2e7a75Shuah ldub [%g2 + SFMMU_CEXT], %g4 ! %g4 = sfmmup->cext 29325cf1a30Sjl139090 sll %g4, CTXREG_EXT_SHIFT, %g4 2941e2e7a75Shuah or %g5, %g4, %g5 29525cf1a30Sjl139090 29625cf1a30Sjl139090 set MMU_PCONTEXT, %g4 2971e2e7a75Shuah ldxa [%g4]ASI_DMMU, %g6 /* rd old ctxnum */ 298febcc4a5Sjimand srlx %g6, CTXREG_NEXT_SHIFT, %g2 /* %g2 = nucleus pgsz */ 299febcc4a5Sjimand sllx %g2, CTXREG_NEXT_SHIFT, %g2 /* preserve nucleus pgsz */ 300febcc4a5Sjimand or %g5, %g2, %g5 /* %g5 = nucleus pgsz | primary pgsz | cnum */ 3011e2e7a75Shuah stxa %g5, [%g4]ASI_DMMU /* wr new ctxum */ 30225cf1a30Sjl139090 30325cf1a30Sjl139090 set MMU_PAGESIZE, %g2 /* g2 = pgsize */ 3041e2e7a75Shuah sethi %hi(FLUSH_ADDR), %g5 30525cf1a30Sjl1390903: 30625cf1a30Sjl139090 stxa %g0, [%g1]ASI_DTLB_DEMAP 30725cf1a30Sjl139090 stxa %g0, [%g1]ASI_ITLB_DEMAP 3081e2e7a75Shuah flush %g5 ! flush required by immu 3091e2e7a75Shuah 31025cf1a30Sjl139090 deccc %g3 /* decr pgcnt */ 31125cf1a30Sjl139090 bnz,pt %icc,3b 31225cf1a30Sjl139090 add %g1, %g2, %g1 /* next page */ 31325cf1a30Sjl139090 3141e2e7a75Shuah stxa %g6, [%g4]ASI_DMMU /* restore old ctxnum */ 31525cf1a30Sjl139090 retry 31625cf1a30Sjl139090 SET_SIZE(vtag_flush_pgcnt_tl1) 31725cf1a30Sjl139090 31825cf1a30Sjl139090#endif /* lint */ 31925cf1a30Sjl139090 32025cf1a30Sjl139090 32125cf1a30Sjl139090#if defined(lint) 32225cf1a30Sjl139090 32325cf1a30Sjl139090/*ARGSUSED*/ 32425cf1a30Sjl139090void 32525cf1a30Sjl139090vtag_flushall_tl1(uint64_t dummy1, uint64_t dummy2) 32625cf1a30Sjl139090{} 32725cf1a30Sjl139090 32825cf1a30Sjl139090#else /* lint */ 32925cf1a30Sjl139090 33025cf1a30Sjl139090 ENTRY_NP(vtag_flushall_tl1) 33125cf1a30Sjl139090 /* 33225cf1a30Sjl139090 * x-trap to flush tlb 33325cf1a30Sjl139090 */ 33425cf1a30Sjl139090 set DEMAP_ALL_TYPE, %g4 33525cf1a30Sjl139090 stxa %g0, [%g4]ASI_DTLB_DEMAP 33625cf1a30Sjl139090 stxa %g0, [%g4]ASI_ITLB_DEMAP 33725cf1a30Sjl139090 retry 33825cf1a30Sjl139090 SET_SIZE(vtag_flushall_tl1) 33925cf1a30Sjl139090 34025cf1a30Sjl139090#endif /* lint */ 34125cf1a30Sjl139090 34225cf1a30Sjl139090 34325cf1a30Sjl139090/* 34425cf1a30Sjl139090 * VAC (virtual address conflict) does not apply to OPL. 34525cf1a30Sjl139090 * VAC resolution is managed by the Olympus processor hardware. 34625cf1a30Sjl139090 * As a result, all OPL VAC flushing routines are no-ops. 34725cf1a30Sjl139090 */ 34825cf1a30Sjl139090 34925cf1a30Sjl139090#if defined(lint) 35025cf1a30Sjl139090 35125cf1a30Sjl139090/* ARGSUSED */ 35225cf1a30Sjl139090void 35325cf1a30Sjl139090vac_flushpage(pfn_t pfnum, int vcolor) 35425cf1a30Sjl139090{} 35525cf1a30Sjl139090 35625cf1a30Sjl139090#else /* lint */ 35725cf1a30Sjl139090 35825cf1a30Sjl139090 ENTRY(vac_flushpage) 35925cf1a30Sjl139090 retl 36025cf1a30Sjl139090 nop 36125cf1a30Sjl139090 SET_SIZE(vac_flushpage) 36225cf1a30Sjl139090 36325cf1a30Sjl139090#endif /* lint */ 36425cf1a30Sjl139090 36525cf1a30Sjl139090#if defined(lint) 36625cf1a30Sjl139090 36725cf1a30Sjl139090/* ARGSUSED */ 36825cf1a30Sjl139090void 36925cf1a30Sjl139090vac_flushpage_tl1(uint64_t pfnum, uint64_t vcolor) 37025cf1a30Sjl139090{} 37125cf1a30Sjl139090 37225cf1a30Sjl139090#else /* lint */ 37325cf1a30Sjl139090 37425cf1a30Sjl139090 ENTRY_NP(vac_flushpage_tl1) 37525cf1a30Sjl139090 retry 37625cf1a30Sjl139090 SET_SIZE(vac_flushpage_tl1) 37725cf1a30Sjl139090 37825cf1a30Sjl139090#endif /* lint */ 37925cf1a30Sjl139090 38025cf1a30Sjl139090 38125cf1a30Sjl139090#if defined(lint) 38225cf1a30Sjl139090 38325cf1a30Sjl139090/* ARGSUSED */ 38425cf1a30Sjl139090void 38525cf1a30Sjl139090vac_flushcolor(int vcolor, pfn_t pfnum) 38625cf1a30Sjl139090{} 38725cf1a30Sjl139090 38825cf1a30Sjl139090#else /* lint */ 38925cf1a30Sjl139090 39025cf1a30Sjl139090 ENTRY(vac_flushcolor) 39125cf1a30Sjl139090 retl 39225cf1a30Sjl139090 nop 39325cf1a30Sjl139090 SET_SIZE(vac_flushcolor) 39425cf1a30Sjl139090 39525cf1a30Sjl139090#endif /* lint */ 39625cf1a30Sjl139090 39725cf1a30Sjl139090 39825cf1a30Sjl139090 39925cf1a30Sjl139090#if defined(lint) 40025cf1a30Sjl139090 40125cf1a30Sjl139090/* ARGSUSED */ 40225cf1a30Sjl139090void 40325cf1a30Sjl139090vac_flushcolor_tl1(uint64_t vcolor, uint64_t pfnum) 40425cf1a30Sjl139090{} 40525cf1a30Sjl139090 40625cf1a30Sjl139090#else /* lint */ 40725cf1a30Sjl139090 40825cf1a30Sjl139090 ENTRY(vac_flushcolor_tl1) 40925cf1a30Sjl139090 retry 41025cf1a30Sjl139090 SET_SIZE(vac_flushcolor_tl1) 41125cf1a30Sjl139090 41225cf1a30Sjl139090#endif /* lint */ 41325cf1a30Sjl139090 41425cf1a30Sjl139090#if defined(lint) 41525cf1a30Sjl139090 41625cf1a30Sjl139090int 41725cf1a30Sjl139090idsr_busy(void) 41825cf1a30Sjl139090{ 41925cf1a30Sjl139090 return (0); 42025cf1a30Sjl139090} 42125cf1a30Sjl139090 42225cf1a30Sjl139090#else /* lint */ 42325cf1a30Sjl139090 42425cf1a30Sjl139090/* 42525cf1a30Sjl139090 * Determine whether or not the IDSR is busy. 42625cf1a30Sjl139090 * Entry: no arguments 42725cf1a30Sjl139090 * Returns: 1 if busy, 0 otherwise 42825cf1a30Sjl139090 */ 42925cf1a30Sjl139090 ENTRY(idsr_busy) 43025cf1a30Sjl139090 ldxa [%g0]ASI_INTR_DISPATCH_STATUS, %g1 43125cf1a30Sjl139090 clr %o0 43225cf1a30Sjl139090 btst IDSR_BUSY, %g1 43325cf1a30Sjl139090 bz,a,pt %xcc, 1f 43425cf1a30Sjl139090 mov 1, %o0 43525cf1a30Sjl1390901: 43625cf1a30Sjl139090 retl 43725cf1a30Sjl139090 nop 43825cf1a30Sjl139090 SET_SIZE(idsr_busy) 43925cf1a30Sjl139090 44025cf1a30Sjl139090#endif /* lint */ 44125cf1a30Sjl139090 44225cf1a30Sjl139090#if defined(lint) 44325cf1a30Sjl139090 44425cf1a30Sjl139090/* ARGSUSED */ 44525cf1a30Sjl139090void 44625cf1a30Sjl139090init_mondo(xcfunc_t *func, uint64_t arg1, uint64_t arg2) 44725cf1a30Sjl139090{} 44825cf1a30Sjl139090 44925cf1a30Sjl139090/* ARGSUSED */ 45025cf1a30Sjl139090void 45125cf1a30Sjl139090init_mondo_nocheck(xcfunc_t *func, uint64_t arg1, uint64_t arg2) 45225cf1a30Sjl139090{} 45325cf1a30Sjl139090 45425cf1a30Sjl139090#else /* lint */ 45525cf1a30Sjl139090 45625cf1a30Sjl139090 .global _dispatch_status_busy 45725cf1a30Sjl139090_dispatch_status_busy: 45825cf1a30Sjl139090 .asciz "ASI_INTR_DISPATCH_STATUS error: busy" 45925cf1a30Sjl139090 .align 4 46025cf1a30Sjl139090 46125cf1a30Sjl139090/* 46225cf1a30Sjl139090 * Setup interrupt dispatch data registers 46325cf1a30Sjl139090 * Entry: 46425cf1a30Sjl139090 * %o0 - function or inumber to call 46525cf1a30Sjl139090 * %o1, %o2 - arguments (2 uint64_t's) 46625cf1a30Sjl139090 */ 46725cf1a30Sjl139090 .seg "text" 46825cf1a30Sjl139090 46925cf1a30Sjl139090 ENTRY(init_mondo) 47025cf1a30Sjl139090#ifdef DEBUG 47125cf1a30Sjl139090 ! 47225cf1a30Sjl139090 ! IDSR should not be busy at the moment 47325cf1a30Sjl139090 ! 47425cf1a30Sjl139090 ldxa [%g0]ASI_INTR_DISPATCH_STATUS, %g1 47525cf1a30Sjl139090 btst IDSR_BUSY, %g1 47625cf1a30Sjl139090 bz,pt %xcc, 1f 47725cf1a30Sjl139090 nop 47825cf1a30Sjl139090 sethi %hi(_dispatch_status_busy), %o0 47925cf1a30Sjl139090 call panic 48025cf1a30Sjl139090 or %o0, %lo(_dispatch_status_busy), %o0 48125cf1a30Sjl139090#endif /* DEBUG */ 48225cf1a30Sjl139090 48325cf1a30Sjl139090 ALTENTRY(init_mondo_nocheck) 48425cf1a30Sjl139090 ! 48525cf1a30Sjl139090 ! interrupt vector dispatch data reg 0 48625cf1a30Sjl139090 ! 48725cf1a30Sjl1390901: 48825cf1a30Sjl139090 mov IDDR_0, %g1 48925cf1a30Sjl139090 mov IDDR_1, %g2 49025cf1a30Sjl139090 mov IDDR_2, %g3 49125cf1a30Sjl139090 stxa %o0, [%g1]ASI_INTR_DISPATCH 49225cf1a30Sjl139090 49325cf1a30Sjl139090 ! 49425cf1a30Sjl139090 ! interrupt vector dispatch data reg 1 49525cf1a30Sjl139090 ! 49625cf1a30Sjl139090 stxa %o1, [%g2]ASI_INTR_DISPATCH 49725cf1a30Sjl139090 49825cf1a30Sjl139090 ! 49925cf1a30Sjl139090 ! interrupt vector dispatch data reg 2 50025cf1a30Sjl139090 ! 50125cf1a30Sjl139090 stxa %o2, [%g3]ASI_INTR_DISPATCH 50225cf1a30Sjl139090 50325cf1a30Sjl139090 membar #Sync 50425cf1a30Sjl139090 retl 50525cf1a30Sjl139090 nop 50625cf1a30Sjl139090 SET_SIZE(init_mondo_nocheck) 50725cf1a30Sjl139090 SET_SIZE(init_mondo) 50825cf1a30Sjl139090 50925cf1a30Sjl139090#endif /* lint */ 51025cf1a30Sjl139090 51125cf1a30Sjl139090 51225cf1a30Sjl139090#if defined(lint) 51325cf1a30Sjl139090 51425cf1a30Sjl139090/* ARGSUSED */ 51525cf1a30Sjl139090void 51625cf1a30Sjl139090shipit(int upaid, int bn) 51725cf1a30Sjl139090{ return; } 51825cf1a30Sjl139090 51925cf1a30Sjl139090#else /* lint */ 52025cf1a30Sjl139090 52125cf1a30Sjl139090/* 52225cf1a30Sjl139090 * Ship mondo to aid using busy/nack pair bn 52325cf1a30Sjl139090 */ 52425cf1a30Sjl139090 ENTRY_NP(shipit) 52525cf1a30Sjl139090 sll %o0, IDCR_PID_SHIFT, %g1 ! IDCR<23:14> = agent id 52625cf1a30Sjl139090 sll %o1, IDCR_BN_SHIFT, %g2 ! IDCR<28:24> = b/n pair 52725cf1a30Sjl139090 or %g1, IDCR_OFFSET, %g1 ! IDCR<13:0> = 0x70 52825cf1a30Sjl139090 or %g1, %g2, %g1 52925cf1a30Sjl139090 stxa %g0, [%g1]ASI_INTR_DISPATCH ! interrupt vector dispatch 53025cf1a30Sjl139090 membar #Sync 53125cf1a30Sjl139090 retl 53225cf1a30Sjl139090 nop 53325cf1a30Sjl139090 SET_SIZE(shipit) 53425cf1a30Sjl139090 53525cf1a30Sjl139090#endif /* lint */ 53625cf1a30Sjl139090 53725cf1a30Sjl139090 53825cf1a30Sjl139090#if defined(lint) 53925cf1a30Sjl139090 54025cf1a30Sjl139090/* ARGSUSED */ 54125cf1a30Sjl139090void 54225cf1a30Sjl139090flush_instr_mem(caddr_t vaddr, size_t len) 54325cf1a30Sjl139090{} 54425cf1a30Sjl139090 54525cf1a30Sjl139090#else /* lint */ 54625cf1a30Sjl139090 54725cf1a30Sjl139090/* 54825cf1a30Sjl139090 * flush_instr_mem: 54925cf1a30Sjl139090 * Flush 1 page of the I-$ starting at vaddr 55025cf1a30Sjl139090 * %o0 vaddr 55125cf1a30Sjl139090 * %o1 bytes to be flushed 55225cf1a30Sjl139090 * 55325cf1a30Sjl139090 * SPARC64-VI maintains consistency of the on-chip Instruction Cache with 55425cf1a30Sjl139090 * the stores from all processors so that a FLUSH instruction is only needed 55525cf1a30Sjl139090 * to ensure pipeline is consistent. This means a single flush is sufficient at 55625cf1a30Sjl139090 * the end of a sequence of stores that updates the instruction stream to 55725cf1a30Sjl139090 * ensure correct operation. 55825cf1a30Sjl139090 */ 55925cf1a30Sjl139090 56025cf1a30Sjl139090 ENTRY(flush_instr_mem) 56163360950Smp204432 flush %o0 ! address irrelevant 56225cf1a30Sjl139090 retl 56325cf1a30Sjl139090 nop 56425cf1a30Sjl139090 SET_SIZE(flush_instr_mem) 56525cf1a30Sjl139090 56625cf1a30Sjl139090#endif /* lint */ 56725cf1a30Sjl139090 56825cf1a30Sjl139090 56925cf1a30Sjl139090/* 57025cf1a30Sjl139090 * flush_ecache: 57125cf1a30Sjl139090 * %o0 - 64 bit physical address 57225cf1a30Sjl139090 * %o1 - ecache size 57325cf1a30Sjl139090 * %o2 - ecache linesize 57425cf1a30Sjl139090 */ 57525cf1a30Sjl139090#if defined(lint) 57625cf1a30Sjl139090 57725cf1a30Sjl139090/*ARGSUSED*/ 57825cf1a30Sjl139090void 57925cf1a30Sjl139090flush_ecache(uint64_t physaddr, size_t ecache_size, size_t ecache_linesize) 58025cf1a30Sjl139090{} 58125cf1a30Sjl139090 58225cf1a30Sjl139090#else /* !lint */ 58325cf1a30Sjl139090 58425cf1a30Sjl139090 ENTRY(flush_ecache) 58525cf1a30Sjl139090 58625cf1a30Sjl139090 /* 58725cf1a30Sjl139090 * Flush the entire Ecache. 58825cf1a30Sjl139090 */ 58925cf1a30Sjl139090 ECACHE_FLUSHALL(%o1, %o2, %o0, %o4) 59025cf1a30Sjl139090 retl 59125cf1a30Sjl139090 nop 59225cf1a30Sjl139090 SET_SIZE(flush_ecache) 59325cf1a30Sjl139090 59425cf1a30Sjl139090#endif /* lint */ 59525cf1a30Sjl139090 59625cf1a30Sjl139090#if defined(lint) 59725cf1a30Sjl139090 59825cf1a30Sjl139090/*ARGSUSED*/ 59925cf1a30Sjl139090void 60025cf1a30Sjl139090kdi_flush_idcache(int dcache_size, int dcache_lsize, int icache_size, 60125cf1a30Sjl139090 int icache_lsize) 60225cf1a30Sjl139090{ 60325cf1a30Sjl139090} 60425cf1a30Sjl139090 60525cf1a30Sjl139090#else /* lint */ 60625cf1a30Sjl139090 60725cf1a30Sjl139090 /* 60825cf1a30Sjl139090 * I/D cache flushing is not needed for OPL processors 60925cf1a30Sjl139090 */ 61025cf1a30Sjl139090 ENTRY(kdi_flush_idcache) 61125cf1a30Sjl139090 retl 61225cf1a30Sjl139090 nop 61325cf1a30Sjl139090 SET_SIZE(kdi_flush_idcache) 61425cf1a30Sjl139090 61525cf1a30Sjl139090#endif /* lint */ 61625cf1a30Sjl139090 61725cf1a30Sjl139090#ifdef TRAPTRACE 61825cf1a30Sjl139090/* 61925cf1a30Sjl139090 * Simplified trap trace macro for OPL. Adapted from us3. 62025cf1a30Sjl139090 */ 62125cf1a30Sjl139090#define OPL_TRAPTRACE(ptr, scr1, scr2, label) \ 62225cf1a30Sjl139090 CPU_INDEX(scr1, ptr); \ 62325cf1a30Sjl139090 sll scr1, TRAPTR_SIZE_SHIFT, scr1; \ 62425cf1a30Sjl139090 set trap_trace_ctl, ptr; \ 62525cf1a30Sjl139090 add ptr, scr1, scr1; \ 62625cf1a30Sjl139090 ld [scr1 + TRAPTR_LIMIT], ptr; \ 62725cf1a30Sjl139090 tst ptr; \ 62825cf1a30Sjl139090 be,pn %icc, label/**/1; \ 62925cf1a30Sjl139090 ldx [scr1 + TRAPTR_PBASE], ptr; \ 63025cf1a30Sjl139090 ld [scr1 + TRAPTR_OFFSET], scr1; \ 63125cf1a30Sjl139090 add ptr, scr1, ptr; \ 63225cf1a30Sjl139090 rd %asi, scr2; \ 63325cf1a30Sjl139090 wr %g0, TRAPTR_ASI, %asi; \ 63425cf1a30Sjl139090 rd STICK, scr1; \ 63525cf1a30Sjl139090 stxa scr1, [ptr + TRAP_ENT_TICK]%asi; \ 63625cf1a30Sjl139090 rdpr %tl, scr1; \ 63725cf1a30Sjl139090 stha scr1, [ptr + TRAP_ENT_TL]%asi; \ 63825cf1a30Sjl139090 rdpr %tt, scr1; \ 63925cf1a30Sjl139090 stha scr1, [ptr + TRAP_ENT_TT]%asi; \ 64025cf1a30Sjl139090 rdpr %tpc, scr1; \ 64125cf1a30Sjl139090 stna scr1, [ptr + TRAP_ENT_TPC]%asi; \ 64225cf1a30Sjl139090 rdpr %tstate, scr1; \ 64325cf1a30Sjl139090 stxa scr1, [ptr + TRAP_ENT_TSTATE]%asi; \ 64425cf1a30Sjl139090 stna %sp, [ptr + TRAP_ENT_SP]%asi; \ 64525cf1a30Sjl139090 stna %g0, [ptr + TRAP_ENT_TR]%asi; \ 64625cf1a30Sjl139090 stna %g0, [ptr + TRAP_ENT_F1]%asi; \ 64725cf1a30Sjl139090 stna %g0, [ptr + TRAP_ENT_F2]%asi; \ 64825cf1a30Sjl139090 stna %g0, [ptr + TRAP_ENT_F3]%asi; \ 64925cf1a30Sjl139090 stna %g0, [ptr + TRAP_ENT_F4]%asi; \ 65025cf1a30Sjl139090 wr %g0, scr2, %asi; \ 65125cf1a30Sjl139090 CPU_INDEX(ptr, scr1); \ 65225cf1a30Sjl139090 sll ptr, TRAPTR_SIZE_SHIFT, ptr; \ 65325cf1a30Sjl139090 set trap_trace_ctl, scr1; \ 65425cf1a30Sjl139090 add scr1, ptr, ptr; \ 65525cf1a30Sjl139090 ld [ptr + TRAPTR_OFFSET], scr1; \ 65625cf1a30Sjl139090 ld [ptr + TRAPTR_LIMIT], scr2; \ 65725cf1a30Sjl139090 st scr1, [ptr + TRAPTR_LAST_OFFSET]; \ 65825cf1a30Sjl139090 add scr1, TRAP_ENT_SIZE, scr1; \ 65925cf1a30Sjl139090 sub scr2, TRAP_ENT_SIZE, scr2; \ 66025cf1a30Sjl139090 cmp scr1, scr2; \ 66125cf1a30Sjl139090 movge %icc, 0, scr1; \ 66225cf1a30Sjl139090 st scr1, [ptr + TRAPTR_OFFSET]; \ 66325cf1a30Sjl139090label/**/1: 66425cf1a30Sjl139090#endif /* TRAPTRACE */ 66525cf1a30Sjl139090 66625cf1a30Sjl139090 66725cf1a30Sjl139090 66825cf1a30Sjl139090/* 66925cf1a30Sjl139090 * Macros facilitating error handling. 67025cf1a30Sjl139090 */ 67125cf1a30Sjl139090 67225cf1a30Sjl139090/* 67325cf1a30Sjl139090 * Save alternative global registers reg1, reg2, reg3 67425cf1a30Sjl139090 * to scratchpad registers 1, 2, 3 respectively. 67525cf1a30Sjl139090 */ 67625cf1a30Sjl139090#define OPL_SAVE_GLOBAL(reg1, reg2, reg3) \ 67725cf1a30Sjl139090 stxa reg1, [%g0]ASI_SCRATCHPAD ;\ 67825cf1a30Sjl139090 mov OPL_SCRATCHPAD_SAVE_AG2, reg1 ;\ 67925cf1a30Sjl139090 stxa reg2, [reg1]ASI_SCRATCHPAD ;\ 68025cf1a30Sjl139090 mov OPL_SCRATCHPAD_SAVE_AG3, reg1 ;\ 68125cf1a30Sjl139090 stxa reg3, [reg1]ASI_SCRATCHPAD 68225cf1a30Sjl139090 68325cf1a30Sjl139090/* 68425cf1a30Sjl139090 * Restore alternative global registers reg1, reg2, reg3 68525cf1a30Sjl139090 * from scratchpad registers 1, 2, 3 respectively. 68625cf1a30Sjl139090 */ 68725cf1a30Sjl139090#define OPL_RESTORE_GLOBAL(reg1, reg2, reg3) \ 68825cf1a30Sjl139090 mov OPL_SCRATCHPAD_SAVE_AG3, reg1 ;\ 68925cf1a30Sjl139090 ldxa [reg1]ASI_SCRATCHPAD, reg3 ;\ 69025cf1a30Sjl139090 mov OPL_SCRATCHPAD_SAVE_AG2, reg1 ;\ 69125cf1a30Sjl139090 ldxa [reg1]ASI_SCRATCHPAD, reg2 ;\ 69225cf1a30Sjl139090 ldxa [%g0]ASI_SCRATCHPAD, reg1 69325cf1a30Sjl139090 69425cf1a30Sjl139090/* 69525cf1a30Sjl139090 * Logs value `val' into the member `offset' of a structure 69625cf1a30Sjl139090 * at physical address `pa' 69725cf1a30Sjl139090 */ 69825cf1a30Sjl139090#define LOG_REG(pa, offset, val) \ 69925cf1a30Sjl139090 add pa, offset, pa ;\ 70025cf1a30Sjl139090 stxa val, [pa]ASI_MEM 70125cf1a30Sjl139090 70225cf1a30Sjl139090#define FLUSH_ALL_TLB(tmp1) \ 70325cf1a30Sjl139090 set DEMAP_ALL_TYPE, tmp1 ;\ 70425cf1a30Sjl139090 stxa %g0, [tmp1]ASI_ITLB_DEMAP ;\ 70525cf1a30Sjl139090 stxa %g0, [tmp1]ASI_DTLB_DEMAP ;\ 70625cf1a30Sjl139090 sethi %hi(FLUSH_ADDR), tmp1 ;\ 70725cf1a30Sjl139090 flush tmp1 70825cf1a30Sjl139090 70925cf1a30Sjl139090/* 71025cf1a30Sjl139090 * Extracts the Physaddr to Logging Buffer field of the OPL_SCRATCHPAD_ERRLOG 71125cf1a30Sjl139090 * scratch register by zeroing all other fields. Result is in pa. 71225cf1a30Sjl139090 */ 71325cf1a30Sjl139090#define LOG_ADDR(pa) \ 71425cf1a30Sjl139090 mov OPL_SCRATCHPAD_ERRLOG, pa ;\ 71525cf1a30Sjl139090 ldxa [pa]ASI_SCRATCHPAD, pa ;\ 71625cf1a30Sjl139090 sllx pa, 64-ERRLOG_REG_EIDR_SHIFT, pa ;\ 71725cf1a30Sjl139090 srlx pa, 64-ERRLOG_REG_EIDR_SHIFT+ERRLOG_REG_ERR_SHIFT, pa ;\ 71825cf1a30Sjl139090 sllx pa, ERRLOG_REG_ERR_SHIFT, pa 71925cf1a30Sjl139090 72025cf1a30Sjl139090/* 72125cf1a30Sjl139090 * Advance the per-cpu error log buffer pointer to the next 72225cf1a30Sjl139090 * ERRLOG_SZ entry, making sure that it will modulo (wraparound) 72325cf1a30Sjl139090 * ERRLOG_BUFSIZ boundary. The args logpa, bufmask, tmp are 72425cf1a30Sjl139090 * unused input registers for this macro. 72525cf1a30Sjl139090 * 72625cf1a30Sjl139090 * Algorithm: 72725cf1a30Sjl139090 * 1. logpa = contents of errorlog scratchpad register 72825cf1a30Sjl139090 * 2. bufmask = ERRLOG_BUFSIZ - 1 72925cf1a30Sjl139090 * 3. tmp = logpa & ~(bufmask) (tmp is now logbase) 73025cf1a30Sjl139090 * 4. logpa += ERRLOG_SZ 73125cf1a30Sjl139090 * 5. logpa = logpa & bufmask (get new offset to logbase) 73225cf1a30Sjl139090 * 4. logpa = tmp | logpa 73325cf1a30Sjl139090 * 7. write logpa back into errorlog scratchpad register 73425cf1a30Sjl139090 * 73525cf1a30Sjl139090 * new logpa = (logpa & ~bufmask) | ((logpa + ERRLOG_SZ) & bufmask) 73625cf1a30Sjl139090 * 73725cf1a30Sjl139090 */ 73825cf1a30Sjl139090#define UPDATE_LOGADD(logpa, bufmask, tmp) \ 73925cf1a30Sjl139090 set OPL_SCRATCHPAD_ERRLOG, tmp ;\ 74025cf1a30Sjl139090 ldxa [tmp]ASI_SCRATCHPAD, logpa ;\ 74125cf1a30Sjl139090 set (ERRLOG_BUFSZ-1), bufmask ;\ 74225cf1a30Sjl139090 andn logpa, bufmask, tmp ;\ 74325cf1a30Sjl139090 add logpa, ERRLOG_SZ, logpa ;\ 74425cf1a30Sjl139090 and logpa, bufmask, logpa ;\ 74525cf1a30Sjl139090 or tmp, logpa, logpa ;\ 74625cf1a30Sjl139090 set OPL_SCRATCHPAD_ERRLOG, tmp ;\ 74725cf1a30Sjl139090 stxa logpa, [tmp]ASI_SCRATCHPAD 74825cf1a30Sjl139090 74925cf1a30Sjl139090/* Log error status registers into the log buffer */ 75025cf1a30Sjl139090#define LOG_SYNC_REG(sfsr, sfar, tmp) \ 75125cf1a30Sjl139090 LOG_ADDR(tmp) ;\ 75225cf1a30Sjl139090 LOG_REG(tmp, LOG_SFSR_OFF, sfsr) ;\ 75325cf1a30Sjl139090 LOG_ADDR(tmp) ;\ 75425cf1a30Sjl139090 mov tmp, sfsr ;\ 75525cf1a30Sjl139090 LOG_REG(tmp, LOG_SFAR_OFF, sfar) ;\ 75625cf1a30Sjl139090 rd STICK, sfar ;\ 75725cf1a30Sjl139090 mov sfsr, tmp ;\ 75825cf1a30Sjl139090 LOG_REG(tmp, LOG_STICK_OFF, sfar) ;\ 75925cf1a30Sjl139090 rdpr %tl, tmp ;\ 76025cf1a30Sjl139090 sllx tmp, 32, sfar ;\ 76125cf1a30Sjl139090 rdpr %tt, tmp ;\ 76225cf1a30Sjl139090 or sfar, tmp, sfar ;\ 76325cf1a30Sjl139090 mov sfsr, tmp ;\ 76425cf1a30Sjl139090 LOG_REG(tmp, LOG_TL_OFF, sfar) ;\ 76525cf1a30Sjl139090 set OPL_SCRATCHPAD_ERRLOG, tmp ;\ 76625cf1a30Sjl139090 ldxa [tmp]ASI_SCRATCHPAD, sfar ;\ 76725cf1a30Sjl139090 mov sfsr, tmp ;\ 76825cf1a30Sjl139090 LOG_REG(tmp, LOG_ASI3_OFF, sfar) ;\ 76925cf1a30Sjl139090 rdpr %tpc, sfar ;\ 77025cf1a30Sjl139090 mov sfsr, tmp ;\ 77125cf1a30Sjl139090 LOG_REG(tmp, LOG_TPC_OFF, sfar) ;\ 77225cf1a30Sjl139090 UPDATE_LOGADD(sfsr, sfar, tmp) 77325cf1a30Sjl139090 77425cf1a30Sjl139090#define LOG_UGER_REG(uger, tmp, tmp2) \ 77525cf1a30Sjl139090 LOG_ADDR(tmp) ;\ 77625cf1a30Sjl139090 mov tmp, tmp2 ;\ 77725cf1a30Sjl139090 LOG_REG(tmp2, LOG_UGER_OFF, uger) ;\ 77825cf1a30Sjl139090 mov tmp, uger ;\ 77925cf1a30Sjl139090 rd STICK, tmp2 ;\ 78025cf1a30Sjl139090 LOG_REG(tmp, LOG_STICK_OFF, tmp2) ;\ 78125cf1a30Sjl139090 rdpr %tl, tmp ;\ 78225cf1a30Sjl139090 sllx tmp, 32, tmp2 ;\ 78325cf1a30Sjl139090 rdpr %tt, tmp ;\ 78425cf1a30Sjl139090 or tmp2, tmp, tmp2 ;\ 78525cf1a30Sjl139090 mov uger, tmp ;\ 78625cf1a30Sjl139090 LOG_REG(tmp, LOG_TL_OFF, tmp2) ;\ 78725cf1a30Sjl139090 set OPL_SCRATCHPAD_ERRLOG, tmp2 ;\ 78825cf1a30Sjl139090 ldxa [tmp2]ASI_SCRATCHPAD, tmp2 ;\ 78925cf1a30Sjl139090 mov uger, tmp ;\ 79025cf1a30Sjl139090 LOG_REG(tmp, LOG_ASI3_OFF, tmp2) ;\ 79125cf1a30Sjl139090 rdpr %tstate, tmp2 ;\ 79225cf1a30Sjl139090 mov uger, tmp ;\ 79325cf1a30Sjl139090 LOG_REG(tmp, LOG_TSTATE_OFF, tmp2) ;\ 79425cf1a30Sjl139090 rdpr %tpc, tmp2 ;\ 79525cf1a30Sjl139090 mov uger, tmp ;\ 79625cf1a30Sjl139090 LOG_REG(tmp, LOG_TPC_OFF, tmp2) ;\ 79725cf1a30Sjl139090 UPDATE_LOGADD(uger, tmp, tmp2) 79825cf1a30Sjl139090 79925cf1a30Sjl139090/* 80025cf1a30Sjl139090 * Scrub the STICK_COMPARE register to clear error by updating 80125cf1a30Sjl139090 * it to a reasonable value for interrupt generation. 80225cf1a30Sjl139090 * Ensure that we observe the CPU_ENABLE flag so that we 80325cf1a30Sjl139090 * don't accidentally enable TICK interrupt in STICK_COMPARE 80425cf1a30Sjl139090 * i.e. no clock interrupt will be generated if CPU_ENABLE flag 80525cf1a30Sjl139090 * is off. 80625cf1a30Sjl139090 */ 80725cf1a30Sjl139090#define UPDATE_STICK_COMPARE(tmp1, tmp2) \ 80825cf1a30Sjl139090 CPU_ADDR(tmp1, tmp2) ;\ 80925cf1a30Sjl139090 lduh [tmp1 + CPU_FLAGS], tmp2 ;\ 81025cf1a30Sjl139090 andcc tmp2, CPU_ENABLE, %g0 ;\ 81125cf1a30Sjl139090 set OPL_UGER_STICK_DIFF, tmp2 ;\ 81225cf1a30Sjl139090 rd STICK, tmp1 ;\ 81325cf1a30Sjl139090 add tmp1, tmp2, tmp1 ;\ 81425cf1a30Sjl139090 mov 1, tmp2 ;\ 81525cf1a30Sjl139090 sllx tmp2, TICKINT_DIS_SHFT, tmp2 ;\ 81625cf1a30Sjl139090 or tmp1, tmp2, tmp2 ;\ 81725cf1a30Sjl139090 movnz %xcc, tmp1, tmp2 ;\ 81825cf1a30Sjl139090 wr tmp2, %g0, STICK_COMPARE 81925cf1a30Sjl139090 82025cf1a30Sjl139090/* 82125cf1a30Sjl139090 * Reset registers that may be corrupted by IAUG_CRE error. 82225cf1a30Sjl139090 * To update interrupt handling related registers force the 82325cf1a30Sjl139090 * clock interrupt. 82425cf1a30Sjl139090 */ 82525cf1a30Sjl139090#define IAG_CRE(tmp1, tmp2) \ 82625cf1a30Sjl139090 set OPL_SCRATCHPAD_ERRLOG, tmp1 ;\ 82725cf1a30Sjl139090 ldxa [tmp1]ASI_SCRATCHPAD, tmp1 ;\ 82825cf1a30Sjl139090 srlx tmp1, ERRLOG_REG_EIDR_SHIFT, tmp1 ;\ 82925cf1a30Sjl139090 set ERRLOG_REG_EIDR_MASK, tmp2 ;\ 83025cf1a30Sjl139090 and tmp1, tmp2, tmp1 ;\ 83125cf1a30Sjl139090 stxa tmp1, [%g0]ASI_EIDR ;\ 83225cf1a30Sjl139090 wr %g0, 0, SOFTINT ;\ 83325cf1a30Sjl139090 sethi %hi(hres_last_tick), tmp1 ;\ 83425cf1a30Sjl139090 ldx [tmp1 + %lo(hres_last_tick)], tmp1 ;\ 83525cf1a30Sjl139090 set OPL_UGER_STICK_DIFF, tmp2 ;\ 83625cf1a30Sjl139090 add tmp1, tmp2, tmp1 ;\ 83725cf1a30Sjl139090 wr tmp1, %g0, STICK ;\ 83825cf1a30Sjl139090 UPDATE_STICK_COMPARE(tmp1, tmp2) 83925cf1a30Sjl139090 84025cf1a30Sjl139090 84125cf1a30Sjl139090#define CLEAR_FPREGS(tmp) \ 84225cf1a30Sjl139090 wr %g0, FPRS_FEF, %fprs ;\ 84325cf1a30Sjl139090 wr %g0, %g0, %gsr ;\ 84425cf1a30Sjl139090 sethi %hi(opl_clr_freg), tmp ;\ 84525cf1a30Sjl139090 or tmp, %lo(opl_clr_freg), tmp ;\ 84625cf1a30Sjl139090 ldx [tmp], %fsr ;\ 84725cf1a30Sjl139090 fzero %d0 ;\ 84825cf1a30Sjl139090 fzero %d2 ;\ 84925cf1a30Sjl139090 fzero %d4 ;\ 85025cf1a30Sjl139090 fzero %d6 ;\ 85125cf1a30Sjl139090 fzero %d8 ;\ 85225cf1a30Sjl139090 fzero %d10 ;\ 85325cf1a30Sjl139090 fzero %d12 ;\ 85425cf1a30Sjl139090 fzero %d14 ;\ 85525cf1a30Sjl139090 fzero %d16 ;\ 85625cf1a30Sjl139090 fzero %d18 ;\ 85725cf1a30Sjl139090 fzero %d20 ;\ 85825cf1a30Sjl139090 fzero %d22 ;\ 85925cf1a30Sjl139090 fzero %d24 ;\ 86025cf1a30Sjl139090 fzero %d26 ;\ 86125cf1a30Sjl139090 fzero %d28 ;\ 86225cf1a30Sjl139090 fzero %d30 ;\ 86325cf1a30Sjl139090 fzero %d32 ;\ 86425cf1a30Sjl139090 fzero %d34 ;\ 86525cf1a30Sjl139090 fzero %d36 ;\ 86625cf1a30Sjl139090 fzero %d38 ;\ 86725cf1a30Sjl139090 fzero %d40 ;\ 86825cf1a30Sjl139090 fzero %d42 ;\ 86925cf1a30Sjl139090 fzero %d44 ;\ 87025cf1a30Sjl139090 fzero %d46 ;\ 87125cf1a30Sjl139090 fzero %d48 ;\ 87225cf1a30Sjl139090 fzero %d50 ;\ 87325cf1a30Sjl139090 fzero %d52 ;\ 87425cf1a30Sjl139090 fzero %d54 ;\ 87525cf1a30Sjl139090 fzero %d56 ;\ 87625cf1a30Sjl139090 fzero %d58 ;\ 87725cf1a30Sjl139090 fzero %d60 ;\ 87825cf1a30Sjl139090 fzero %d62 ;\ 87925cf1a30Sjl139090 wr %g0, %g0, %fprs 88025cf1a30Sjl139090 88125cf1a30Sjl139090#define CLEAR_GLOBALS() \ 88225cf1a30Sjl139090 mov %g0, %g1 ;\ 88325cf1a30Sjl139090 mov %g0, %g2 ;\ 88425cf1a30Sjl139090 mov %g0, %g3 ;\ 88525cf1a30Sjl139090 mov %g0, %g4 ;\ 88625cf1a30Sjl139090 mov %g0, %g5 ;\ 88725cf1a30Sjl139090 mov %g0, %g6 ;\ 88825cf1a30Sjl139090 mov %g0, %g7 88925cf1a30Sjl139090 89025cf1a30Sjl139090/* 89125cf1a30Sjl139090 * We do not clear the alternative globals here because they 89225cf1a30Sjl139090 * are scratch registers, i.e. there is no code that reads from 89325cf1a30Sjl139090 * them without write to them firstly. In other words every 89425cf1a30Sjl139090 * read always follows write that makes extra write to the 89525cf1a30Sjl139090 * alternative globals unnecessary. 89625cf1a30Sjl139090 */ 89725cf1a30Sjl139090#define CLEAR_GEN_REGS(tmp1, label) \ 89825cf1a30Sjl139090 set TSTATE_KERN, tmp1 ;\ 89925cf1a30Sjl139090 wrpr %g0, tmp1, %tstate ;\ 90025cf1a30Sjl139090 mov %g0, %y ;\ 90125cf1a30Sjl139090 mov %g0, %asi ;\ 90225cf1a30Sjl139090 mov %g0, %ccr ;\ 90325cf1a30Sjl139090 mov %g0, %l0 ;\ 90425cf1a30Sjl139090 mov %g0, %l1 ;\ 90525cf1a30Sjl139090 mov %g0, %l2 ;\ 90625cf1a30Sjl139090 mov %g0, %l3 ;\ 90725cf1a30Sjl139090 mov %g0, %l4 ;\ 90825cf1a30Sjl139090 mov %g0, %l5 ;\ 90925cf1a30Sjl139090 mov %g0, %l6 ;\ 91025cf1a30Sjl139090 mov %g0, %l7 ;\ 91125cf1a30Sjl139090 mov %g0, %i0 ;\ 91225cf1a30Sjl139090 mov %g0, %i1 ;\ 91325cf1a30Sjl139090 mov %g0, %i2 ;\ 91425cf1a30Sjl139090 mov %g0, %i3 ;\ 91525cf1a30Sjl139090 mov %g0, %i4 ;\ 91625cf1a30Sjl139090 mov %g0, %i5 ;\ 91725cf1a30Sjl139090 mov %g0, %i6 ;\ 91825cf1a30Sjl139090 mov %g0, %i7 ;\ 91925cf1a30Sjl139090 mov %g0, %o1 ;\ 92025cf1a30Sjl139090 mov %g0, %o2 ;\ 92125cf1a30Sjl139090 mov %g0, %o3 ;\ 92225cf1a30Sjl139090 mov %g0, %o4 ;\ 92325cf1a30Sjl139090 mov %g0, %o5 ;\ 92425cf1a30Sjl139090 mov %g0, %o6 ;\ 92525cf1a30Sjl139090 mov %g0, %o7 ;\ 92625cf1a30Sjl139090 mov %g0, %o0 ;\ 92725cf1a30Sjl139090 mov %g0, %g4 ;\ 92825cf1a30Sjl139090 mov %g0, %g5 ;\ 92925cf1a30Sjl139090 mov %g0, %g6 ;\ 93025cf1a30Sjl139090 mov %g0, %g7 ;\ 93125cf1a30Sjl139090 rdpr %tl, tmp1 ;\ 93225cf1a30Sjl139090 cmp tmp1, 1 ;\ 93325cf1a30Sjl139090 be,pt %xcc, label/**/1 ;\ 93425cf1a30Sjl139090 rdpr %pstate, tmp1 ;\ 93525cf1a30Sjl139090 wrpr tmp1, PSTATE_AG|PSTATE_IG, %pstate ;\ 93625cf1a30Sjl139090 CLEAR_GLOBALS() ;\ 93725cf1a30Sjl139090 rdpr %pstate, tmp1 ;\ 93825cf1a30Sjl139090 wrpr tmp1, PSTATE_IG|PSTATE_MG, %pstate ;\ 93925cf1a30Sjl139090 CLEAR_GLOBALS() ;\ 94025cf1a30Sjl139090 rdpr %pstate, tmp1 ;\ 94125cf1a30Sjl139090 wrpr tmp1, PSTATE_MG|PSTATE_AG, %pstate ;\ 94225cf1a30Sjl139090 ba,pt %xcc, label/**/2 ;\ 94325cf1a30Sjl139090 nop ;\ 94425cf1a30Sjl139090label/**/1: ;\ 94525cf1a30Sjl139090 wrpr tmp1, PSTATE_AG, %pstate ;\ 94625cf1a30Sjl139090 CLEAR_GLOBALS() ;\ 94725cf1a30Sjl139090 rdpr %pstate, tmp1 ;\ 94825cf1a30Sjl139090 wrpr tmp1, PSTATE_AG, %pstate ;\ 94925cf1a30Sjl139090label/**/2: 95025cf1a30Sjl139090 95125cf1a30Sjl139090 95225cf1a30Sjl139090/* 95325cf1a30Sjl139090 * Reset all window related registers 95425cf1a30Sjl139090 */ 95525cf1a30Sjl139090#define RESET_WINREG(tmp) \ 95625cf1a30Sjl139090 sethi %hi(nwin_minus_one), tmp ;\ 95725cf1a30Sjl139090 ld [tmp + %lo(nwin_minus_one)], tmp ;\ 95825cf1a30Sjl139090 wrpr %g0, tmp, %cwp ;\ 95925cf1a30Sjl139090 wrpr %g0, tmp, %cleanwin ;\ 96025cf1a30Sjl139090 sub tmp, 1, tmp ;\ 96125cf1a30Sjl139090 wrpr %g0, tmp, %cansave ;\ 96225cf1a30Sjl139090 wrpr %g0, %g0, %canrestore ;\ 96325cf1a30Sjl139090 wrpr %g0, %g0, %otherwin ;\ 96425cf1a30Sjl139090 wrpr %g0, PIL_MAX, %pil ;\ 96525cf1a30Sjl139090 wrpr %g0, WSTATE_KERN, %wstate 96625cf1a30Sjl139090 96725cf1a30Sjl139090 96825cf1a30Sjl139090#define RESET_PREV_TSTATE(tmp1, tmp2, label) \ 96925cf1a30Sjl139090 rdpr %tl, tmp1 ;\ 97025cf1a30Sjl139090 subcc tmp1, 1, tmp1 ;\ 97125cf1a30Sjl139090 bz,pt %xcc, label/**/1 ;\ 97225cf1a30Sjl139090 nop ;\ 97325cf1a30Sjl139090 wrpr tmp1, %g0, %tl ;\ 97425cf1a30Sjl139090 set TSTATE_KERN, tmp2 ;\ 97525cf1a30Sjl139090 wrpr tmp2, %g0, %tstate ;\ 97625cf1a30Sjl139090 wrpr %g0, %g0, %tpc ;\ 97725cf1a30Sjl139090 wrpr %g0, %g0, %tnpc ;\ 97825cf1a30Sjl139090 add tmp1, 1, tmp1 ;\ 97925cf1a30Sjl139090 wrpr tmp1, %g0, %tl ;\ 98025cf1a30Sjl139090label/**/1: 98125cf1a30Sjl139090 98225cf1a30Sjl139090 98325cf1a30Sjl139090/* 98425cf1a30Sjl139090 * %pstate, %pc, %npc are propagated to %tstate, %tpc, %tnpc, 98525cf1a30Sjl139090 * and we reset these regiseter here. 98625cf1a30Sjl139090 */ 98725cf1a30Sjl139090#define RESET_CUR_TSTATE(tmp) \ 98825cf1a30Sjl139090 set TSTATE_KERN, tmp ;\ 98925cf1a30Sjl139090 wrpr %g0, tmp, %tstate ;\ 99025cf1a30Sjl139090 wrpr %g0, 0, %tpc ;\ 99125cf1a30Sjl139090 wrpr %g0, 0, %tnpc ;\ 99225cf1a30Sjl139090 RESET_WINREG(tmp) 99325cf1a30Sjl139090 99425cf1a30Sjl139090/* 99525cf1a30Sjl139090 * In case of urgent errors some MMU registers may be 99625cf1a30Sjl139090 * corrupted, so we set here some reasonable values for 997f7832c8dShyw * them. Note that resetting MMU registers also reset the context 998f7832c8dShyw * info, we will need to reset the window registers to prevent 9993cbfd4cfSjimand * spill/fill that depends on context info for correct behaviour. 10003cbfd4cfSjimand * Note that the TLBs must be flushed before programming the context 10013cbfd4cfSjimand * registers. 100225cf1a30Sjl139090 */ 100325cf1a30Sjl139090 100425cf1a30Sjl139090#if !defined(lint) 100525cf1a30Sjl139090#define RESET_MMU_REGS(tmp1, tmp2, tmp3) \ 10063cbfd4cfSjimand FLUSH_ALL_TLB(tmp1) ;\ 100725cf1a30Sjl139090 set MMU_PCONTEXT, tmp1 ;\ 10083cbfd4cfSjimand sethi %hi(kcontextreg), tmp2 ;\ 10093cbfd4cfSjimand ldx [tmp2 + %lo(kcontextreg)], tmp2 ;\ 10103cbfd4cfSjimand stxa tmp2, [tmp1]ASI_DMMU ;\ 101125cf1a30Sjl139090 set MMU_SCONTEXT, tmp1 ;\ 10123cbfd4cfSjimand stxa tmp2, [tmp1]ASI_DMMU ;\ 101325cf1a30Sjl139090 sethi %hi(ktsb_base), tmp1 ;\ 101425cf1a30Sjl139090 ldx [tmp1 + %lo(ktsb_base)], tmp2 ;\ 101525cf1a30Sjl139090 mov MMU_TSB, tmp3 ;\ 101625cf1a30Sjl139090 stxa tmp2, [tmp3]ASI_IMMU ;\ 101725cf1a30Sjl139090 stxa tmp2, [tmp3]ASI_DMMU ;\ 1018f7832c8dShyw membar #Sync ;\ 1019f7832c8dShyw RESET_WINREG(tmp1) 102025cf1a30Sjl139090 102125cf1a30Sjl139090#define RESET_TSB_TAGPTR(tmp) \ 102225cf1a30Sjl139090 set MMU_TAG_ACCESS, tmp ;\ 102325cf1a30Sjl139090 stxa %g0, [tmp]ASI_IMMU ;\ 102425cf1a30Sjl139090 stxa %g0, [tmp]ASI_DMMU ;\ 102525cf1a30Sjl139090 membar #Sync 102625cf1a30Sjl139090#endif /* lint */ 102725cf1a30Sjl139090 102825cf1a30Sjl139090/* 1029e98fafb9Sjl139090 * In case of errors in the MMU_TSB_PREFETCH registers we have to 1030e98fafb9Sjl139090 * reset them. We can use "0" as the reset value, this way we set 1031e98fafb9Sjl139090 * the "V" bit of the registers to 0, which will disable the prefetch 1032e98fafb9Sjl139090 * so the values of the other fields are irrelevant. 1033e98fafb9Sjl139090 */ 1034e98fafb9Sjl139090#if !defined(lint) 1035e98fafb9Sjl139090#define RESET_TSB_PREFETCH(tmp) \ 1036e98fafb9Sjl139090 set VA_UTSBPREF_8K, tmp ;\ 1037e98fafb9Sjl139090 stxa %g0, [tmp]ASI_ITSB_PREFETCH ;\ 1038e98fafb9Sjl139090 set VA_UTSBPREF_4M, tmp ;\ 1039e98fafb9Sjl139090 stxa %g0, [tmp]ASI_ITSB_PREFETCH ;\ 1040e98fafb9Sjl139090 set VA_KTSBPREF_8K, tmp ;\ 1041e98fafb9Sjl139090 stxa %g0, [tmp]ASI_ITSB_PREFETCH ;\ 1042e98fafb9Sjl139090 set VA_KTSBPREF_4M, tmp ;\ 1043e98fafb9Sjl139090 stxa %g0, [tmp]ASI_ITSB_PREFETCH ;\ 1044e98fafb9Sjl139090 set VA_UTSBPREF_8K, tmp ;\ 1045e98fafb9Sjl139090 stxa %g0, [tmp]ASI_DTSB_PREFETCH ;\ 1046e98fafb9Sjl139090 set VA_UTSBPREF_4M, tmp ;\ 1047e98fafb9Sjl139090 stxa %g0, [tmp]ASI_DTSB_PREFETCH ;\ 1048e98fafb9Sjl139090 set VA_KTSBPREF_8K, tmp ;\ 1049e98fafb9Sjl139090 stxa %g0, [tmp]ASI_DTSB_PREFETCH ;\ 1050e98fafb9Sjl139090 set VA_KTSBPREF_4M, tmp ;\ 1051e98fafb9Sjl139090 stxa %g0, [tmp]ASI_DTSB_PREFETCH 1052e98fafb9Sjl139090#endif /* lint */ 1053e98fafb9Sjl139090 1054e98fafb9Sjl139090/* 1055e98fafb9Sjl139090 * In case of errors in the MMU_SHARED_CONTEXT register we have to 1056e98fafb9Sjl139090 * reset its value. We can use "0" as the reset value, it will put 1057e98fafb9Sjl139090 * 0 in the IV field disabling the shared context support, and 1058e98fafb9Sjl139090 * making values of all the other fields of the register irrelevant. 1059e98fafb9Sjl139090 */ 1060e98fafb9Sjl139090#if !defined(lint) 1061e98fafb9Sjl139090#define RESET_SHARED_CTXT(tmp) \ 1062e98fafb9Sjl139090 set MMU_SHARED_CONTEXT, tmp ;\ 1063e98fafb9Sjl139090 stxa %g0, [tmp]ASI_DMMU 1064e98fafb9Sjl139090#endif /* lint */ 1065e98fafb9Sjl139090 1066e98fafb9Sjl139090/* 106725cf1a30Sjl139090 * RESET_TO_PRIV() 106825cf1a30Sjl139090 * 106925cf1a30Sjl139090 * In many cases, we need to force the thread into privilege mode because 107025cf1a30Sjl139090 * privilege mode is only thing in which the system continue to work 107125cf1a30Sjl139090 * due to undeterminable user mode information that come from register 107225cf1a30Sjl139090 * corruption. 107325cf1a30Sjl139090 * 107425cf1a30Sjl139090 * - opl_uger_ctxt 107525cf1a30Sjl139090 * If the error is secondary TSB related register parity, we have no idea 107625cf1a30Sjl139090 * what value is supposed to be for it. 107725cf1a30Sjl139090 * 107825cf1a30Sjl139090 * The below three cases %tstate is not accessible until it is overwritten 107925cf1a30Sjl139090 * with some value, so we have no clue if the thread was running on user mode 108025cf1a30Sjl139090 * or not 108125cf1a30Sjl139090 * - opl_uger_pstate 108225cf1a30Sjl139090 * If the error is %pstate parity, it propagates to %tstate. 108325cf1a30Sjl139090 * - opl_uger_tstate 108425cf1a30Sjl139090 * No need to say the reason 108525cf1a30Sjl139090 * - opl_uger_r 108625cf1a30Sjl139090 * If the error is %ccr or %asi parity, it propagates to %tstate 108725cf1a30Sjl139090 * 108825cf1a30Sjl139090 * For the above four cases, user mode info may not be available for 108925cf1a30Sjl139090 * sys_trap() and user_trap() to work consistently. So we have to force 109025cf1a30Sjl139090 * the thread into privilege mode. 109125cf1a30Sjl139090 * 109225cf1a30Sjl139090 * Forcing the thread to privilege mode requires forcing 109325cf1a30Sjl139090 * regular %g7 to be CPU_THREAD. Because if it was running on user mode, 109425cf1a30Sjl139090 * %g7 will be set in user_trap(). Also since the %sp may be in 109525cf1a30Sjl139090 * an inconsistent state, we need to do a stack reset and switch to 109625cf1a30Sjl139090 * something we know i.e. current thread's kernel stack. 109725cf1a30Sjl139090 * We also reset the window registers and MMU registers just to 109825cf1a30Sjl139090 * make sure. 109925cf1a30Sjl139090 * 110025cf1a30Sjl139090 * To set regular %g7, we need to clear PSTATE_AG bit and need to 110125cf1a30Sjl139090 * use one local register. Note that we are panicking and will never 110225cf1a30Sjl139090 * unwind back so it is ok to clobber a local. 110325cf1a30Sjl139090 * 110425cf1a30Sjl139090 * If the thread was running in user mode, the %tpc value itself might be 110525cf1a30Sjl139090 * within the range of OBP addresses. %tpc must be forced to be zero to prevent 110625cf1a30Sjl139090 * sys_trap() from going to prom_trap() 110725cf1a30Sjl139090 * 110825cf1a30Sjl139090 */ 110925cf1a30Sjl139090#define RESET_TO_PRIV(tmp, tmp1, tmp2, local) \ 111025cf1a30Sjl139090 RESET_MMU_REGS(tmp, tmp1, tmp2) ;\ 111125cf1a30Sjl139090 CPU_ADDR(tmp, tmp1) ;\ 111225cf1a30Sjl139090 ldx [tmp + CPU_THREAD], local ;\ 111325cf1a30Sjl139090 ldx [local + T_STACK], tmp ;\ 111425cf1a30Sjl139090 sub tmp, STACK_BIAS, %sp ;\ 111525cf1a30Sjl139090 rdpr %pstate, tmp ;\ 111625cf1a30Sjl139090 wrpr tmp, PSTATE_AG, %pstate ;\ 111725cf1a30Sjl139090 mov local, %g7 ;\ 111825cf1a30Sjl139090 rdpr %pstate, local ;\ 111925cf1a30Sjl139090 wrpr local, PSTATE_AG, %pstate ;\ 112025cf1a30Sjl139090 wrpr %g0, 1, %tl ;\ 112125cf1a30Sjl139090 set TSTATE_KERN, tmp ;\ 112225cf1a30Sjl139090 rdpr %cwp, tmp1 ;\ 112325cf1a30Sjl139090 or tmp, tmp1, tmp ;\ 112425cf1a30Sjl139090 wrpr tmp, %g0, %tstate ;\ 112525cf1a30Sjl139090 wrpr %g0, %tpc 112625cf1a30Sjl139090 112725cf1a30Sjl139090 112825cf1a30Sjl139090#if defined(lint) 112925cf1a30Sjl139090 113025cf1a30Sjl139090void 113125cf1a30Sjl139090ce_err(void) 113225cf1a30Sjl139090{} 113325cf1a30Sjl139090 113425cf1a30Sjl139090#else /* lint */ 113525cf1a30Sjl139090 113625cf1a30Sjl139090/* 113725cf1a30Sjl139090 * We normally don't expect CE traps since we disable the 113825cf1a30Sjl139090 * 0x63 trap reporting at the start of day. There is a 113925cf1a30Sjl139090 * small window before we disable them, so let check for 114025cf1a30Sjl139090 * it. Otherwise, panic. 114125cf1a30Sjl139090 */ 114225cf1a30Sjl139090 114325cf1a30Sjl139090 .align 128 114425cf1a30Sjl139090 ENTRY_NP(ce_err) 114525cf1a30Sjl139090 mov AFSR_ECR, %g1 114625cf1a30Sjl139090 ldxa [%g1]ASI_ECR, %g1 114725cf1a30Sjl139090 andcc %g1, ASI_ECR_RTE_UE | ASI_ECR_RTE_CEDG, %g0 114825cf1a30Sjl139090 bz,pn %xcc, 1f 114925cf1a30Sjl139090 nop 115025cf1a30Sjl139090 retry 115125cf1a30Sjl1390901: 115225cf1a30Sjl139090 /* 115325cf1a30Sjl139090 * We did disabled the 0x63 trap reporting. 115425cf1a30Sjl139090 * This shouldn't happen - panic. 115525cf1a30Sjl139090 */ 115625cf1a30Sjl139090 set trap, %g1 115725cf1a30Sjl139090 rdpr %tt, %g3 115825cf1a30Sjl139090 sethi %hi(sys_trap), %g5 115925cf1a30Sjl139090 jmp %g5 + %lo(sys_trap) 116025cf1a30Sjl139090 sub %g0, 1, %g4 116125cf1a30Sjl139090 SET_SIZE(ce_err) 116225cf1a30Sjl139090 116325cf1a30Sjl139090#endif /* lint */ 116425cf1a30Sjl139090 116525cf1a30Sjl139090 116625cf1a30Sjl139090#if defined(lint) 116725cf1a30Sjl139090 116825cf1a30Sjl139090void 116925cf1a30Sjl139090ce_err_tl1(void) 117025cf1a30Sjl139090{} 117125cf1a30Sjl139090 117225cf1a30Sjl139090#else /* lint */ 117325cf1a30Sjl139090 117425cf1a30Sjl139090/* 117525cf1a30Sjl139090 * We don't use trap for CE detection. 117625cf1a30Sjl139090 */ 117725cf1a30Sjl139090 ENTRY_NP(ce_err_tl1) 117825cf1a30Sjl139090 set trap, %g1 117925cf1a30Sjl139090 rdpr %tt, %g3 118025cf1a30Sjl139090 sethi %hi(sys_trap), %g5 118125cf1a30Sjl139090 jmp %g5 + %lo(sys_trap) 118225cf1a30Sjl139090 sub %g0, 1, %g4 118325cf1a30Sjl139090 SET_SIZE(ce_err_tl1) 118425cf1a30Sjl139090 118525cf1a30Sjl139090#endif /* lint */ 118625cf1a30Sjl139090 118725cf1a30Sjl139090 118825cf1a30Sjl139090#if defined(lint) 118925cf1a30Sjl139090 119025cf1a30Sjl139090void 119125cf1a30Sjl139090async_err(void) 119225cf1a30Sjl139090{} 119325cf1a30Sjl139090 119425cf1a30Sjl139090#else /* lint */ 119525cf1a30Sjl139090 119625cf1a30Sjl139090/* 119725cf1a30Sjl139090 * async_err is the default handler for IAE/DAE traps. 119825cf1a30Sjl139090 * For OPL, we patch in the right handler at start of day. 119925cf1a30Sjl139090 * But if a IAE/DAE trap get generated before the handler 120025cf1a30Sjl139090 * is patched, panic. 120125cf1a30Sjl139090 */ 120225cf1a30Sjl139090 ENTRY_NP(async_err) 120325cf1a30Sjl139090 set trap, %g1 120425cf1a30Sjl139090 rdpr %tt, %g3 120525cf1a30Sjl139090 sethi %hi(sys_trap), %g5 120625cf1a30Sjl139090 jmp %g5 + %lo(sys_trap) 120725cf1a30Sjl139090 sub %g0, 1, %g4 120825cf1a30Sjl139090 SET_SIZE(async_err) 120925cf1a30Sjl139090 121025cf1a30Sjl139090#endif /* lint */ 121125cf1a30Sjl139090 121225cf1a30Sjl139090#if defined(lint) 121325cf1a30Sjl139090void 121425cf1a30Sjl139090opl_sync_trap(void) 121525cf1a30Sjl139090{} 121625cf1a30Sjl139090#else /* lint */ 121725cf1a30Sjl139090 121825cf1a30Sjl139090 .seg ".data" 121925cf1a30Sjl139090 .global opl_clr_freg 122025cf1a30Sjl139090 .global opl_cpu0_err_log 122125cf1a30Sjl139090 122225cf1a30Sjl139090 .align 16 122325cf1a30Sjl139090opl_clr_freg: 122425cf1a30Sjl139090 .word 0 122525cf1a30Sjl139090 .align 16 122625cf1a30Sjl139090 122725cf1a30Sjl139090 .align MMU_PAGESIZE 122825cf1a30Sjl139090opl_cpu0_err_log: 122925cf1a30Sjl139090 .skip MMU_PAGESIZE 123025cf1a30Sjl139090 123125cf1a30Sjl139090/* 123225cf1a30Sjl139090 * Common synchronous error trap handler (tt=0xA, 0x32) 123325cf1a30Sjl139090 * All TL=0 and TL>0 0xA and 0x32 traps vector to this handler. 123425cf1a30Sjl139090 * The error handling can be best summarized as follows: 123525cf1a30Sjl139090 * 0. Do TRAPTRACE if enabled. 123625cf1a30Sjl139090 * 1. Save globals %g1, %g2 & %g3 onto the scratchpad regs. 123725cf1a30Sjl139090 * 2. The SFSR register is read and verified as valid by checking 123825cf1a30Sjl139090 * SFSR.FV bit being set. If the SFSR.FV is not set, the 123925cf1a30Sjl139090 * error cases cannot be decoded/determined and the SFPAR 124025cf1a30Sjl139090 * register that contain the physical faultaddr is also 124125cf1a30Sjl139090 * not valid. Also the SPFAR is only valid for UE/TO/BERR error 124225cf1a30Sjl139090 * cases. Assuming the SFSR.FV is valid: 124325cf1a30Sjl139090 * - BERR(bus error)/TO(timeout)/UE case 124425cf1a30Sjl139090 * If any of these error cases are detected, read the SFPAR 124525cf1a30Sjl139090 * to get the faultaddress. Generate ereport. 124625cf1a30Sjl139090 * - TLB Parity case (only recoverable case) 124725cf1a30Sjl139090 * For DAE, read SFAR for the faultaddress. For IAE, 124825cf1a30Sjl139090 * use %tpc for faultaddress (SFAR is not valid in IAE) 124925cf1a30Sjl139090 * Flush all the tlbs. 125025cf1a30Sjl139090 * Subtract one from the recoverable error count stored in 125125cf1a30Sjl139090 * the error log scratch register. If the threshold limit 125225cf1a30Sjl139090 * is reached (zero) - generate ereport. Else 125325cf1a30Sjl139090 * restore globals and retry (no ereport is generated). 125425cf1a30Sjl139090 * - TLB Multiple hits 125525cf1a30Sjl139090 * For DAE, read SFAR for the faultaddress. For IAE, 125625cf1a30Sjl139090 * use %tpc for faultaddress (SFAR is not valid in IAE). 125725cf1a30Sjl139090 * Flush all tlbs and generate ereport. 125825cf1a30Sjl139090 * 3. TL=0 and TL>0 considerations 125925cf1a30Sjl139090 * - Since both TL=0 & TL>1 traps are made to vector into 126025cf1a30Sjl139090 * the same handler, the underlying assumption/design here is 126125cf1a30Sjl139090 * that any nested error condition (if happens) occurs only 126225cf1a30Sjl139090 * in the handler and the system is assumed to eventually 126325cf1a30Sjl139090 * Red-mode. With this philosophy in mind, the recoverable 126425cf1a30Sjl139090 * TLB Parity error case never check the TL level before it 126525cf1a30Sjl139090 * retry. Note that this is ok for the TL>1 case (assuming we 126625cf1a30Sjl139090 * don't have a nested error) since we always save the globals 126725cf1a30Sjl139090 * %g1, %g2 & %g3 whenever we enter this trap handler. 126825cf1a30Sjl139090 * - Additional TL=0 vs TL>1 handling includes: 126925cf1a30Sjl139090 * - For UE error occuring under TL>1, special handling 127025cf1a30Sjl139090 * is added to prevent the unlikely chance of a cpu-lockup 127125cf1a30Sjl139090 * when a UE was originally detected in user stack and 127225cf1a30Sjl139090 * the spill trap handler taken from sys_trap() so happened 127325cf1a30Sjl139090 * to reference the same UE location. Under the above 127425cf1a30Sjl139090 * condition (TL>1 and UE error), paranoid code is added 127525cf1a30Sjl139090 * to reset window regs so that spill traps can't happen 127625cf1a30Sjl139090 * during the unwind back to TL=0 handling. 127725cf1a30Sjl139090 * Note that we can do that because we are not returning 127825cf1a30Sjl139090 * back. 127925cf1a30Sjl139090 * 4. Ereport generation. 128025cf1a30Sjl139090 * - Ereport generation is performed when we unwind to the TL=0 128125cf1a30Sjl139090 * handling code via sys_trap(). on_trap()/lofault protection 128225cf1a30Sjl139090 * will apply there. 128325cf1a30Sjl139090 * 128425cf1a30Sjl139090 */ 128525cf1a30Sjl139090 ENTRY_NP(opl_sync_trap) 128625cf1a30Sjl139090#ifdef TRAPTRACE 128725cf1a30Sjl139090 OPL_TRAPTRACE(%g1, %g2, %g3, opl_sync_trap_lb) 128825cf1a30Sjl139090 rdpr %tt, %g1 128925cf1a30Sjl139090#endif /* TRAPTRACE */ 129025cf1a30Sjl139090 cmp %g1, T_INSTR_ERROR 129125cf1a30Sjl139090 bne,pt %xcc, 0f 129225cf1a30Sjl139090 mov MMU_SFSR, %g3 129325cf1a30Sjl139090 ldxa [%g3]ASI_IMMU, %g1 ! IAE trap case tt = 0xa 129425cf1a30Sjl139090 andcc %g1, SFSR_FV, %g0 129525cf1a30Sjl139090 bz,a,pn %xcc, 2f ! Branch if SFSR is invalid and 129625cf1a30Sjl139090 rdpr %tpc, %g2 ! use %tpc for faultaddr instead 129725cf1a30Sjl139090 129825cf1a30Sjl139090 sethi %hi(SFSR_UE|SFSR_BERR|SFSR_TO), %g3 129925cf1a30Sjl139090 andcc %g1, %g3, %g0 ! Check for UE/BERR/TO errors 130025cf1a30Sjl139090 bz,a,pt %xcc, 1f ! Branch if not UE/BERR/TO and 130125cf1a30Sjl139090 rdpr %tpc, %g2 ! use %tpc as faultaddr 130225cf1a30Sjl139090 set OPL_MMU_SFPAR, %g3 ! In the UE/BERR/TO cases, use 130325cf1a30Sjl139090 ba,pt %xcc, 2f ! SFPAR as faultaddr 130425cf1a30Sjl139090 ldxa [%g3]ASI_IMMU, %g2 130525cf1a30Sjl1390900: 130625cf1a30Sjl139090 ldxa [%g3]ASI_DMMU, %g1 ! DAE trap case tt = 0x32 130725cf1a30Sjl139090 andcc %g1, SFSR_FV, %g0 130825cf1a30Sjl139090 bnz,pt %xcc, 7f ! branch if SFSR.FV is valid 130925cf1a30Sjl139090 mov MMU_SFAR, %g2 ! set %g2 to use SFAR 131025cf1a30Sjl139090 ba,pt %xcc, 2f ! SFSR.FV is not valid, read SFAR 131125cf1a30Sjl139090 ldxa [%g2]ASI_DMMU, %g2 ! for faultaddr 131225cf1a30Sjl1390907: 131325cf1a30Sjl139090 sethi %hi(SFSR_UE|SFSR_BERR|SFSR_TO), %g3 131425cf1a30Sjl139090 andcc %g1, %g3, %g0 ! Check UE/BERR/TO for valid SFPAR 131525cf1a30Sjl139090 movnz %xcc, OPL_MMU_SFPAR, %g2 ! Use SFPAR instead of SFAR for 131625cf1a30Sjl139090 ldxa [%g2]ASI_DMMU, %g2 ! faultaddr 131725cf1a30Sjl1390901: 131825cf1a30Sjl139090 sethi %hi(SFSR_TLB_PRT), %g3 131925cf1a30Sjl139090 andcc %g1, %g3, %g0 132025cf1a30Sjl139090 bz,pt %xcc, 8f ! branch for TLB multi-hit check 132125cf1a30Sjl139090 nop 132225cf1a30Sjl139090 /* 132325cf1a30Sjl139090 * This is the TLB parity error case and it is the 132425cf1a30Sjl139090 * only retryable error case. 132525cf1a30Sjl139090 * Only %g1, %g2 and %g3 are allowed 132625cf1a30Sjl139090 */ 132725cf1a30Sjl139090 FLUSH_ALL_TLB(%g3) 132825cf1a30Sjl139090 set OPL_SCRATCHPAD_ERRLOG, %g3 132925cf1a30Sjl139090 ldxa [%g3]ASI_SCRATCHPAD, %g3 ! Read errlog scratchreg 133025cf1a30Sjl139090 and %g3, ERRLOG_REG_NUMERR_MASK, %g3! Extract the error count 133125cf1a30Sjl139090 subcc %g3, 1, %g0 ! Subtract one from the count 133225cf1a30Sjl139090 bz,pn %xcc, 2f ! too many TLB parity errs in a certain 133325cf1a30Sjl139090 nop ! period, branch to generate ereport 133425cf1a30Sjl139090 LOG_SYNC_REG(%g1, %g2, %g3) ! Record into the error log 133525cf1a30Sjl139090 set OPL_SCRATCHPAD_ERRLOG, %g3 133625cf1a30Sjl139090 ldxa [%g3]ASI_SCRATCHPAD, %g2 133725cf1a30Sjl139090 sub %g2, 1, %g2 ! decrement error counter by 1 133825cf1a30Sjl139090 stxa %g2, [%g3]ASI_SCRATCHPAD ! update the errlog scratchreg 133925cf1a30Sjl139090 OPL_RESTORE_GLOBAL(%g1, %g2, %g3) 134025cf1a30Sjl139090 retry 134125cf1a30Sjl1390908: 134225cf1a30Sjl139090 sethi %hi(SFSR_TLB_MUL), %g3 134325cf1a30Sjl139090 andcc %g1, %g3, %g0 134425cf1a30Sjl139090 bz,pt %xcc, 2f ! check for the TLB multi-hit errors 134525cf1a30Sjl139090 nop 134625cf1a30Sjl139090 FLUSH_ALL_TLB(%g3) 134725cf1a30Sjl1390902: 134825cf1a30Sjl139090 /* 134925cf1a30Sjl139090 * non-retryable error handling 135025cf1a30Sjl139090 * now we can use other registers since 135125cf1a30Sjl139090 * we will not be returning back 135225cf1a30Sjl139090 */ 135325cf1a30Sjl139090 mov %g1, %g5 ! %g5 = SFSR 135425cf1a30Sjl139090 mov %g2, %g6 ! %g6 = SFPAR or SFAR/tpc 135525cf1a30Sjl139090 LOG_SYNC_REG(%g1, %g2, %g3) ! Record into the error log 135625cf1a30Sjl139090 135725cf1a30Sjl139090 /* 135825cf1a30Sjl139090 * Special case for UE on user stack. 135925cf1a30Sjl139090 * There is a possibility that the same error may come back here 136025cf1a30Sjl139090 * by touching the same UE in spill trap handler taken from 136125cf1a30Sjl139090 * sys_trap(). It ends up with an infinite loop causing a cpu lockup. 136225cf1a30Sjl139090 * Conditions for this handling this case are: 136325cf1a30Sjl139090 * - SFSR_FV is valid and SFSR_UE is set 136425cf1a30Sjl139090 * - we are at TL > 1 136525cf1a30Sjl139090 * If the above conditions are true, we force %cansave to be a 136625cf1a30Sjl139090 * big number to prevent spill trap in sys_trap(). Note that 136725cf1a30Sjl139090 * we will not be returning back. 136825cf1a30Sjl139090 */ 136925cf1a30Sjl139090 rdpr %tt, %g4 ! %g4 == ttype 137025cf1a30Sjl139090 rdpr %tl, %g1 ! %g1 == tl 137125cf1a30Sjl139090 cmp %g1, 1 ! Check if TL == 1 137225cf1a30Sjl139090 be,pt %xcc, 3f ! branch if we came from TL=0 137325cf1a30Sjl139090 nop 137425cf1a30Sjl139090 andcc %g5, SFSR_FV, %g0 ! see if SFSR.FV is valid 137525cf1a30Sjl139090 bz,pn %xcc, 4f ! branch, checking UE is meaningless 137625cf1a30Sjl139090 sethi %hi(SFSR_UE), %g2 137725cf1a30Sjl139090 andcc %g5, %g2, %g0 ! check for UE 137825cf1a30Sjl139090 bz,pt %xcc, 4f ! branch if not UE 137925cf1a30Sjl139090 nop 138025cf1a30Sjl139090 RESET_WINREG(%g1) ! reset windows to prevent spills 138125cf1a30Sjl1390904: 13822dd3029aSjimand RESET_USER_RTT_REGS(%g2, %g3, opl_sync_trap_resetskip) 13832dd3029aSjimandopl_sync_trap_resetskip: 138425cf1a30Sjl139090 mov %g5, %g3 ! pass SFSR to the 3rd arg 138525cf1a30Sjl139090 mov %g6, %g2 ! pass SFAR to the 2nd arg 138625cf1a30Sjl139090 set opl_cpu_isync_tl1_error, %g1 138725cf1a30Sjl139090 set opl_cpu_dsync_tl1_error, %g6 138825cf1a30Sjl139090 cmp %g4, T_INSTR_ERROR 138925cf1a30Sjl139090 movne %icc, %g6, %g1 139025cf1a30Sjl139090 ba,pt %icc, 6f 139125cf1a30Sjl139090 nop 139225cf1a30Sjl1390903: 139325cf1a30Sjl139090 mov %g5, %g3 ! pass SFSR to the 3rd arg 139425cf1a30Sjl139090 mov %g6, %g2 ! pass SFAR to the 2nd arg 139525cf1a30Sjl139090 set opl_cpu_isync_tl0_error, %g1 139625cf1a30Sjl139090 set opl_cpu_dsync_tl0_error, %g6 139725cf1a30Sjl139090 cmp %g4, T_INSTR_ERROR 139825cf1a30Sjl139090 movne %icc, %g6, %g1 139925cf1a30Sjl1390906: 140025cf1a30Sjl139090 sethi %hi(sys_trap), %g5 140125cf1a30Sjl139090 jmp %g5 + %lo(sys_trap) 140225cf1a30Sjl139090 mov PIL_15, %g4 140325cf1a30Sjl139090 SET_SIZE(opl_sync_trap) 140425cf1a30Sjl139090#endif /* lint */ 140525cf1a30Sjl139090 140625cf1a30Sjl139090#if defined(lint) 140725cf1a30Sjl139090void 140825cf1a30Sjl139090opl_uger_trap(void) 140925cf1a30Sjl139090{} 141025cf1a30Sjl139090#else /* lint */ 141125cf1a30Sjl139090/* 141225cf1a30Sjl139090 * Common Urgent error trap handler (tt=0x40) 141325cf1a30Sjl139090 * All TL=0 and TL>0 0x40 traps vector to this handler. 141425cf1a30Sjl139090 * The error handling can be best summarized as follows: 141525cf1a30Sjl139090 * 1. Read the Urgent error status register (UGERSR) 141625cf1a30Sjl139090 * Faultaddress is N/A here and it is not collected. 141725cf1a30Sjl139090 * 2. Check to see if we have a multiple errors case 141825cf1a30Sjl139090 * If so, we enable WEAK_ED (weak error detection) bit 141925cf1a30Sjl139090 * to prevent any potential error storms and branch directly 142025cf1a30Sjl139090 * to generate ereport. (we don't decode/handle individual 142125cf1a30Sjl139090 * error cases when we get a multiple error situation) 142225cf1a30Sjl139090 * 3. Now look for the recoverable error cases which include 142325cf1a30Sjl139090 * IUG_DTLB, IUG_ITLB or COREERR errors. If any of the 142425cf1a30Sjl139090 * recoverable errors are detected, do the following: 142525cf1a30Sjl139090 * - Flush all tlbs. 142625cf1a30Sjl139090 * - Verify that we came from TL=0, if not, generate 142725cf1a30Sjl139090 * ereport. Note that the reason we don't recover 142825cf1a30Sjl139090 * at TL>0 is because the AGs might be corrupted or 142925cf1a30Sjl139090 * inconsistent. We can't save/restore them into 143025cf1a30Sjl139090 * the scratchpad regs like we did for opl_sync_trap(). 143125cf1a30Sjl139090 * - Check the INSTEND[5:4] bits in the UGERSR. If the 143225cf1a30Sjl139090 * value is 0x3 (11b), this error is not recoverable. 143325cf1a30Sjl139090 * Generate ereport. 143425cf1a30Sjl139090 * - Subtract one from the recoverable error count stored in 143525cf1a30Sjl139090 * the error log scratch register. If the threshold limit 143625cf1a30Sjl139090 * is reached (zero) - generate ereport. 143725cf1a30Sjl139090 * - If the count is within the limit, update the count 143825cf1a30Sjl139090 * in the error log register (subtract one). Log the error 143925cf1a30Sjl139090 * info in the log buffer. Capture traptrace if enabled. 144025cf1a30Sjl139090 * Retry (no ereport generated) 144125cf1a30Sjl139090 * 4. The rest of the error cases are unrecoverable and will 144225cf1a30Sjl139090 * be handled according (flushing regs, etc as required). 144325cf1a30Sjl139090 * For details on these error cases (UGER_CRE, UGER_CTXT, etc..) 144425cf1a30Sjl139090 * consult the OPL cpu/mem philosophy doc. 144525cf1a30Sjl139090 * Ereport will be generated for these errors. 144625cf1a30Sjl139090 * 5. Ereport generation. 144725cf1a30Sjl139090 * - Ereport generation for urgent error trap always 144825cf1a30Sjl139090 * result in a panic when we unwind to the TL=0 handling 144925cf1a30Sjl139090 * code via sys_trap(). on_trap()/lofault protection do 145025cf1a30Sjl139090 * not apply there. 145125cf1a30Sjl139090 */ 145225cf1a30Sjl139090 ENTRY_NP(opl_uger_trap) 145325cf1a30Sjl139090 set ASI_UGERSR, %g2 145425cf1a30Sjl139090 ldxa [%g2]ASI_AFSR, %g1 ! Read the UGERSR reg 145525cf1a30Sjl139090 145625cf1a30Sjl139090 set UGESR_MULTI, %g2 145725cf1a30Sjl139090 andcc %g1, %g2, %g0 ! Check for Multi-errs 145825cf1a30Sjl139090 bz,pt %xcc, opl_uger_is_recover ! branch if not Multi-errs 145925cf1a30Sjl139090 nop 146025cf1a30Sjl139090 set AFSR_ECR, %g2 146125cf1a30Sjl139090 ldxa [%g2]ASI_AFSR, %g3 ! Enable Weak error 146225cf1a30Sjl139090 or %g3, ASI_ECR_WEAK_ED, %g3 ! detect mode to prevent 146325cf1a30Sjl139090 stxa %g3, [%g2]ASI_AFSR ! potential error storms 146425cf1a30Sjl139090 ba %xcc, opl_uger_panic1 146525cf1a30Sjl139090 nop 146625cf1a30Sjl139090 146725cf1a30Sjl139090opl_uger_is_recover: 146825cf1a30Sjl139090 set UGESR_CAN_RECOVER, %g2 ! Check for recoverable 146925cf1a30Sjl139090 andcc %g1, %g2, %g0 ! errors i.e.IUG_DTLB, 147025cf1a30Sjl139090 bz,pt %xcc, opl_uger_cre ! IUG_ITLB or COREERR 147125cf1a30Sjl139090 nop 147225cf1a30Sjl139090 147325cf1a30Sjl139090 /* 147425cf1a30Sjl139090 * Fall thru to handle recoverable case 147525cf1a30Sjl139090 * Need to do the following additional checks to determine 147625cf1a30Sjl139090 * if this is indeed recoverable. 147725cf1a30Sjl139090 * 1. Error trap came from TL=0 and 147825cf1a30Sjl139090 * 2. INSTEND[5:4] bits in UGERSR is not 0x3 147925cf1a30Sjl139090 * 3. Recoverable error count limit not reached 148025cf1a30Sjl139090 * 148125cf1a30Sjl139090 */ 148225cf1a30Sjl139090 FLUSH_ALL_TLB(%g3) 148325cf1a30Sjl139090 rdpr %tl, %g3 ! Read TL 148425cf1a30Sjl139090 cmp %g3, 1 ! Check if we came from TL=0 148525cf1a30Sjl139090 bne,pt %xcc, opl_uger_panic ! branch if came from TL>0 148625cf1a30Sjl139090 nop 148725cf1a30Sjl139090 srlx %g1, 4, %g2 ! shift INSTEND[5:4] -> [1:0] 148825cf1a30Sjl139090 and %g2, 3, %g2 ! extract the shifted [1:0] bits 148925cf1a30Sjl139090 cmp %g2, 3 ! check if INSTEND is recoverable 149025cf1a30Sjl139090 be,pt %xcc, opl_uger_panic ! panic if ([1:0] = 11b) 149125cf1a30Sjl139090 nop 149225cf1a30Sjl139090 set OPL_SCRATCHPAD_ERRLOG, %g3 149325cf1a30Sjl139090 ldxa [%g3]ASI_SCRATCHPAD, %g2 ! Read errlog scratch reg 149425cf1a30Sjl139090 and %g2, ERRLOG_REG_NUMERR_MASK, %g3! Extract error count and 149525cf1a30Sjl139090 subcc %g3, 1, %g3 ! subtract one from it 149625cf1a30Sjl139090 bz,pt %xcc, opl_uger_panic ! If count reached zero, too many 149725cf1a30Sjl139090 nop ! errors, branch to generate ereport 149825cf1a30Sjl139090 sub %g2, 1, %g2 ! Subtract one from the count 149925cf1a30Sjl139090 set OPL_SCRATCHPAD_ERRLOG, %g3 ! and write back the updated 150025cf1a30Sjl139090 stxa %g2, [%g3]ASI_SCRATCHPAD ! count into the errlog reg 150125cf1a30Sjl139090 LOG_UGER_REG(%g1, %g2, %g3) ! Log the error info 150225cf1a30Sjl139090#ifdef TRAPTRACE 150325cf1a30Sjl139090 OPL_TRAPTRACE(%g1, %g2, %g3, opl_uger_trap_lb) 150425cf1a30Sjl139090#endif /* TRAPTRACE */ 150525cf1a30Sjl139090 retry ! retry - no ereport 150625cf1a30Sjl139090 150725cf1a30Sjl139090 /* 150825cf1a30Sjl139090 * Process the rest of the unrecoverable error cases 150925cf1a30Sjl139090 * All error cases below ultimately branch to either 151025cf1a30Sjl139090 * opl_uger_panic or opl_uger_panic1. 151125cf1a30Sjl139090 * opl_uger_panic1 is the same as opl_uger_panic except 151225cf1a30Sjl139090 * for the additional execution of the RESET_TO_PRIV() 151325cf1a30Sjl139090 * macro that does a heavy handed reset. Read the 151425cf1a30Sjl139090 * comments for RESET_TO_PRIV() macro for more info. 151525cf1a30Sjl139090 */ 151625cf1a30Sjl139090opl_uger_cre: 151725cf1a30Sjl139090 set UGESR_IAUG_CRE, %g2 151825cf1a30Sjl139090 andcc %g1, %g2, %g0 151925cf1a30Sjl139090 bz,pt %xcc, opl_uger_ctxt 152025cf1a30Sjl139090 nop 152125cf1a30Sjl139090 IAG_CRE(%g2, %g3) 152225cf1a30Sjl139090 set AFSR_ECR, %g2 152325cf1a30Sjl139090 ldxa [%g2]ASI_AFSR, %g3 152425cf1a30Sjl139090 or %g3, ASI_ECR_WEAK_ED, %g3 152525cf1a30Sjl139090 stxa %g3, [%g2]ASI_AFSR 152625cf1a30Sjl139090 ba %xcc, opl_uger_panic 152725cf1a30Sjl139090 nop 152825cf1a30Sjl139090 152925cf1a30Sjl139090opl_uger_ctxt: 153025cf1a30Sjl139090 set UGESR_IAUG_TSBCTXT, %g2 153125cf1a30Sjl139090 andcc %g1, %g2, %g0 153225cf1a30Sjl139090 bz,pt %xcc, opl_uger_tsbp 153325cf1a30Sjl139090 nop 1534e98fafb9Sjl139090 GET_CPU_IMPL(%g2) 1535e98fafb9Sjl139090 cmp %g2, JUPITER_IMPL 1536e98fafb9Sjl139090 bne %xcc, 1f 1537e98fafb9Sjl139090 nop 1538e98fafb9Sjl139090 RESET_SHARED_CTXT(%g2) 1539e98fafb9Sjl1390901: 154025cf1a30Sjl139090 RESET_MMU_REGS(%g2, %g3, %g4) 154125cf1a30Sjl139090 ba %xcc, opl_uger_panic 154225cf1a30Sjl139090 nop 154325cf1a30Sjl139090 154425cf1a30Sjl139090opl_uger_tsbp: 154525cf1a30Sjl139090 set UGESR_IUG_TSBP, %g2 154625cf1a30Sjl139090 andcc %g1, %g2, %g0 154725cf1a30Sjl139090 bz,pt %xcc, opl_uger_pstate 154825cf1a30Sjl139090 nop 1549e98fafb9Sjl139090 GET_CPU_IMPL(%g2) 1550e98fafb9Sjl139090 cmp %g2, JUPITER_IMPL 1551e98fafb9Sjl139090 bne %xcc, 1f 1552e98fafb9Sjl139090 nop 1553e98fafb9Sjl139090 RESET_TSB_PREFETCH(%g2) 1554e98fafb9Sjl1390901: 155525cf1a30Sjl139090 RESET_TSB_TAGPTR(%g2) 1556f7832c8dShyw 1557f7832c8dShyw /* 1558f7832c8dShyw * IUG_TSBP error may corrupt MMU registers 1559f7832c8dShyw * Reset them here. 1560f7832c8dShyw */ 1561f7832c8dShyw RESET_MMU_REGS(%g2, %g3, %g4) 156225cf1a30Sjl139090 ba %xcc, opl_uger_panic 156325cf1a30Sjl139090 nop 156425cf1a30Sjl139090 156525cf1a30Sjl139090opl_uger_pstate: 156625cf1a30Sjl139090 set UGESR_IUG_PSTATE, %g2 156725cf1a30Sjl139090 andcc %g1, %g2, %g0 156825cf1a30Sjl139090 bz,pt %xcc, opl_uger_tstate 156925cf1a30Sjl139090 nop 157025cf1a30Sjl139090 RESET_CUR_TSTATE(%g2) 157125cf1a30Sjl139090 ba %xcc, opl_uger_panic1 157225cf1a30Sjl139090 nop 157325cf1a30Sjl139090 157425cf1a30Sjl139090opl_uger_tstate: 157525cf1a30Sjl139090 set UGESR_IUG_TSTATE, %g2 157625cf1a30Sjl139090 andcc %g1, %g2, %g0 157725cf1a30Sjl139090 bz,pt %xcc, opl_uger_f 157825cf1a30Sjl139090 nop 157925cf1a30Sjl139090 RESET_PREV_TSTATE(%g2, %g3, opl_uger_tstate_1) 158025cf1a30Sjl139090 ba %xcc, opl_uger_panic1 158125cf1a30Sjl139090 nop 158225cf1a30Sjl139090 158325cf1a30Sjl139090opl_uger_f: 158425cf1a30Sjl139090 set UGESR_IUG_F, %g2 158525cf1a30Sjl139090 andcc %g1, %g2, %g0 158625cf1a30Sjl139090 bz,pt %xcc, opl_uger_r 158725cf1a30Sjl139090 nop 158825cf1a30Sjl139090 CLEAR_FPREGS(%g2) 158925cf1a30Sjl139090 ba %xcc, opl_uger_panic 159025cf1a30Sjl139090 nop 159125cf1a30Sjl139090 159225cf1a30Sjl139090opl_uger_r: 159325cf1a30Sjl139090 set UGESR_IUG_R, %g2 159425cf1a30Sjl139090 andcc %g1, %g2, %g0 159525cf1a30Sjl139090 bz,pt %xcc, opl_uger_panic1 159625cf1a30Sjl139090 nop 159725cf1a30Sjl139090 CLEAR_GEN_REGS(%g2, opl_uger_r_1) 159825cf1a30Sjl139090 ba %xcc, opl_uger_panic1 159925cf1a30Sjl139090 nop 160025cf1a30Sjl139090 160125cf1a30Sjl139090opl_uger_panic: 160225cf1a30Sjl139090 mov %g1, %g2 ! %g2 = arg #1 160325cf1a30Sjl139090 LOG_UGER_REG(%g1, %g3, %g4) 160425cf1a30Sjl139090 ba %xcc, opl_uger_panic_cmn 160525cf1a30Sjl139090 nop 160625cf1a30Sjl139090 160725cf1a30Sjl139090opl_uger_panic1: 160825cf1a30Sjl139090 mov %g1, %g2 ! %g2 = arg #1 160925cf1a30Sjl139090 LOG_UGER_REG(%g1, %g3, %g4) 161025cf1a30Sjl139090 RESET_TO_PRIV(%g1, %g3, %g4, %l0) 161125cf1a30Sjl139090 161225cf1a30Sjl139090 /* 161325cf1a30Sjl139090 * Set up the argument for sys_trap. 161425cf1a30Sjl139090 * %g2 = arg #1 already set above 161525cf1a30Sjl139090 */ 161625cf1a30Sjl139090opl_uger_panic_cmn: 16172dd3029aSjimand RESET_USER_RTT_REGS(%g4, %g5, opl_uger_panic_resetskip) 16182dd3029aSjimandopl_uger_panic_resetskip: 161925cf1a30Sjl139090 rdpr %tl, %g3 ! arg #2 162025cf1a30Sjl139090 set opl_cpu_urgent_error, %g1 ! pc 162125cf1a30Sjl139090 sethi %hi(sys_trap), %g5 162225cf1a30Sjl139090 jmp %g5 + %lo(sys_trap) 162325cf1a30Sjl139090 mov PIL_15, %g4 162425cf1a30Sjl139090 SET_SIZE(opl_uger_trap) 162525cf1a30Sjl139090#endif /* lint */ 162625cf1a30Sjl139090 162725cf1a30Sjl139090#if defined(lint) 162850eff769Smb158278void 162950eff769Smb158278opl_ta3_trap(void) 163050eff769Smb158278{} 163150eff769Smb158278void 163250eff769Smb158278opl_cleanw_subr(void) 163350eff769Smb158278{} 163450eff769Smb158278#else /* lint */ 163550eff769Smb158278/* 163650eff769Smb158278 * OPL ta3 support (note please, that win_reg 163750eff769Smb158278 * area size for each cpu is 2^7 bytes) 163850eff769Smb158278 */ 163950eff769Smb158278 164050eff769Smb158278#define RESTORE_WREGS(tmp1, tmp2) \ 164150eff769Smb158278 CPU_INDEX(tmp1, tmp2) ;\ 164250eff769Smb158278 sethi %hi(opl_ta3_save), tmp2 ;\ 164350eff769Smb158278 ldx [tmp2 +%lo(opl_ta3_save)], tmp2 ;\ 164450eff769Smb158278 sllx tmp1, 7, tmp1 ;\ 164550eff769Smb158278 add tmp2, tmp1, tmp2 ;\ 164650eff769Smb158278 ldx [tmp2 + 0], %l0 ;\ 164750eff769Smb158278 ldx [tmp2 + 8], %l1 ;\ 164850eff769Smb158278 ldx [tmp2 + 16], %l2 ;\ 164950eff769Smb158278 ldx [tmp2 + 24], %l3 ;\ 165050eff769Smb158278 ldx [tmp2 + 32], %l4 ;\ 165150eff769Smb158278 ldx [tmp2 + 40], %l5 ;\ 165250eff769Smb158278 ldx [tmp2 + 48], %l6 ;\ 165350eff769Smb158278 ldx [tmp2 + 56], %l7 ;\ 165450eff769Smb158278 ldx [tmp2 + 64], %i0 ;\ 165550eff769Smb158278 ldx [tmp2 + 72], %i1 ;\ 165650eff769Smb158278 ldx [tmp2 + 80], %i2 ;\ 165750eff769Smb158278 ldx [tmp2 + 88], %i3 ;\ 165850eff769Smb158278 ldx [tmp2 + 96], %i4 ;\ 165950eff769Smb158278 ldx [tmp2 + 104], %i5 ;\ 166050eff769Smb158278 ldx [tmp2 + 112], %i6 ;\ 166150eff769Smb158278 ldx [tmp2 + 120], %i7 166250eff769Smb158278 166350eff769Smb158278#define SAVE_WREGS(tmp1, tmp2) \ 166450eff769Smb158278 CPU_INDEX(tmp1, tmp2) ;\ 166550eff769Smb158278 sethi %hi(opl_ta3_save), tmp2 ;\ 166650eff769Smb158278 ldx [tmp2 +%lo(opl_ta3_save)], tmp2 ;\ 166750eff769Smb158278 sllx tmp1, 7, tmp1 ;\ 166850eff769Smb158278 add tmp2, tmp1, tmp2 ;\ 166950eff769Smb158278 stx %l0, [tmp2 + 0] ;\ 167050eff769Smb158278 stx %l1, [tmp2 + 8] ;\ 167150eff769Smb158278 stx %l2, [tmp2 + 16] ;\ 167250eff769Smb158278 stx %l3, [tmp2 + 24] ;\ 167350eff769Smb158278 stx %l4, [tmp2 + 32] ;\ 167450eff769Smb158278 stx %l5, [tmp2 + 40] ;\ 167550eff769Smb158278 stx %l6, [tmp2 + 48] ;\ 167650eff769Smb158278 stx %l7, [tmp2 + 56] ;\ 167750eff769Smb158278 stx %i0, [tmp2 + 64] ;\ 167850eff769Smb158278 stx %i1, [tmp2 + 72] ;\ 167950eff769Smb158278 stx %i2, [tmp2 + 80] ;\ 168050eff769Smb158278 stx %i3, [tmp2 + 88] ;\ 168150eff769Smb158278 stx %i4, [tmp2 + 96] ;\ 168250eff769Smb158278 stx %i5, [tmp2 + 104] ;\ 168350eff769Smb158278 stx %i6, [tmp2 + 112] ;\ 168450eff769Smb158278 stx %i7, [tmp2 + 120] 168550eff769Smb158278 168650eff769Smb158278 168750eff769Smb158278/* 168850eff769Smb158278 * The purpose of this function is to make sure that the restore 168950eff769Smb158278 * instruction after the flushw does not cause a fill trap. The sun4u 169050eff769Smb158278 * fill trap handler can not handle a tlb fault of an unmapped stack 169150eff769Smb158278 * except at the restore instruction at user_rtt. On OPL systems the 169250eff769Smb158278 * stack can get unmapped between the flushw and restore instructions 169350eff769Smb158278 * since multiple strands share the tlb. 169450eff769Smb158278 */ 169550eff769Smb158278 ENTRY_NP(opl_ta3_trap) 169650eff769Smb158278 set trap, %g1 169750eff769Smb158278 mov T_FLUSHW, %g3 169850eff769Smb158278 sub %g0, 1, %g4 169950eff769Smb158278 rdpr %cwp, %g5 170050eff769Smb158278 SAVE_WREGS(%g2, %g6) 170150eff769Smb158278 save 170250eff769Smb158278 flushw 170350eff769Smb158278 rdpr %cwp, %g6 170450eff769Smb158278 wrpr %g5, %cwp 170550eff769Smb158278 RESTORE_WREGS(%g2, %g5) 170650eff769Smb158278 wrpr %g6, %cwp 170750eff769Smb158278 restored 170850eff769Smb158278 restore 170950eff769Smb158278 171050eff769Smb158278 ba,a fast_trap_done 171150eff769Smb158278 SET_SIZE(opl_ta3_trap) 171250eff769Smb158278 171350eff769Smb158278 ENTRY_NP(opl_cleanw_subr) 171450eff769Smb158278 set trap, %g1 171550eff769Smb158278 mov T_FLUSHW, %g3 171650eff769Smb158278 sub %g0, 1, %g4 171750eff769Smb158278 rdpr %cwp, %g5 171850eff769Smb158278 SAVE_WREGS(%g2, %g6) 171950eff769Smb158278 save 172050eff769Smb158278 flushw 172150eff769Smb158278 rdpr %cwp, %g6 172250eff769Smb158278 wrpr %g5, %cwp 172350eff769Smb158278 RESTORE_WREGS(%g2, %g5) 172450eff769Smb158278 wrpr %g6, %cwp 172550eff769Smb158278 restored 172650eff769Smb158278 restore 172750eff769Smb158278 jmp %g7 172850eff769Smb158278 nop 172950eff769Smb158278 SET_SIZE(opl_cleanw_subr) 173050eff769Smb158278#endif /* lint */ 173150eff769Smb158278 173250eff769Smb158278#if defined(lint) 173325cf1a30Sjl139090 173425cf1a30Sjl139090void 173525cf1a30Sjl139090opl_serr_instr(void) 173625cf1a30Sjl139090{} 173725cf1a30Sjl139090 173825cf1a30Sjl139090#else /* lint */ 173925cf1a30Sjl139090/* 174025cf1a30Sjl139090 * The actual trap handler for tt=0x0a, and tt=0x32 174125cf1a30Sjl139090 */ 174225cf1a30Sjl139090 ENTRY_NP(opl_serr_instr) 174325cf1a30Sjl139090 OPL_SAVE_GLOBAL(%g1,%g2,%g3) 174425cf1a30Sjl139090 sethi %hi(opl_sync_trap), %g3 174525cf1a30Sjl139090 jmp %g3 + %lo(opl_sync_trap) 174625cf1a30Sjl139090 rdpr %tt, %g1 174725cf1a30Sjl139090 .align 32 174825cf1a30Sjl139090 SET_SIZE(opl_serr_instr) 174925cf1a30Sjl139090 175025cf1a30Sjl139090#endif /* lint */ 175125cf1a30Sjl139090 175225cf1a30Sjl139090#if defined(lint) 175325cf1a30Sjl139090 175425cf1a30Sjl139090void 175525cf1a30Sjl139090opl_ugerr_instr(void) 175625cf1a30Sjl139090{} 175725cf1a30Sjl139090 175825cf1a30Sjl139090#else /* lint */ 175925cf1a30Sjl139090/* 176025cf1a30Sjl139090 * The actual trap handler for tt=0x40 176125cf1a30Sjl139090 */ 176225cf1a30Sjl139090 ENTRY_NP(opl_ugerr_instr) 176325cf1a30Sjl139090 sethi %hi(opl_uger_trap), %g3 176425cf1a30Sjl139090 jmp %g3 + %lo(opl_uger_trap) 176525cf1a30Sjl139090 nop 176625cf1a30Sjl139090 .align 32 176725cf1a30Sjl139090 SET_SIZE(opl_ugerr_instr) 176825cf1a30Sjl139090 176925cf1a30Sjl139090#endif /* lint */ 177025cf1a30Sjl139090 177125cf1a30Sjl139090#if defined(lint) 177250eff769Smb158278 177350eff769Smb158278void 177450eff769Smb158278opl_ta3_instr(void) 177550eff769Smb158278{} 177650eff769Smb158278 177750eff769Smb158278#else /* lint */ 177850eff769Smb158278/* 177950eff769Smb158278 * The actual trap handler for tt=0x103 (flushw) 178050eff769Smb158278 */ 178150eff769Smb158278 ENTRY_NP(opl_ta3_instr) 178250eff769Smb158278 sethi %hi(opl_ta3_trap), %g3 178350eff769Smb158278 jmp %g3 + %lo(opl_ta3_trap) 178450eff769Smb158278 nop 178550eff769Smb158278 .align 32 178650eff769Smb158278 SET_SIZE(opl_ta3_instr) 178750eff769Smb158278 178850eff769Smb158278#endif /* lint */ 178950eff769Smb158278 179050eff769Smb158278#if defined(lint) 179150eff769Smb158278 179250eff769Smb158278void 179350eff769Smb158278opl_ta4_instr(void) 179450eff769Smb158278{} 179550eff769Smb158278 179650eff769Smb158278#else /* lint */ 179750eff769Smb158278/* 179850eff769Smb158278 * The patch for the .clean_windows code 179950eff769Smb158278 */ 180050eff769Smb158278 ENTRY_NP(opl_ta4_instr) 180150eff769Smb158278 sethi %hi(opl_cleanw_subr), %g3 180250eff769Smb158278 add %g3, %lo(opl_cleanw_subr), %g3 180350eff769Smb158278 jmpl %g3, %g7 180450eff769Smb158278 add %g7, 8, %g7 180550eff769Smb158278 nop 180650eff769Smb158278 nop 180750eff769Smb158278 nop 180850eff769Smb158278 SET_SIZE(opl_ta4_instr) 180950eff769Smb158278 181050eff769Smb158278#endif /* lint */ 181150eff769Smb158278 181250eff769Smb158278#if defined(lint) 181325cf1a30Sjl139090/* 181425cf1a30Sjl139090 * Get timestamp (stick). 181525cf1a30Sjl139090 */ 181625cf1a30Sjl139090/* ARGSUSED */ 181725cf1a30Sjl139090void 181825cf1a30Sjl139090stick_timestamp(int64_t *ts) 181925cf1a30Sjl139090{ 182025cf1a30Sjl139090} 182125cf1a30Sjl139090 182225cf1a30Sjl139090#else /* lint */ 182325cf1a30Sjl139090 182425cf1a30Sjl139090 ENTRY_NP(stick_timestamp) 182525cf1a30Sjl139090 rd STICK, %g1 ! read stick reg 182625cf1a30Sjl139090 sllx %g1, 1, %g1 182725cf1a30Sjl139090 srlx %g1, 1, %g1 ! clear npt bit 182825cf1a30Sjl139090 182925cf1a30Sjl139090 retl 183025cf1a30Sjl139090 stx %g1, [%o0] ! store the timestamp 183125cf1a30Sjl139090 SET_SIZE(stick_timestamp) 183225cf1a30Sjl139090 183325cf1a30Sjl139090#endif /* lint */ 183425cf1a30Sjl139090 183525cf1a30Sjl139090 183625cf1a30Sjl139090#if defined(lint) 183725cf1a30Sjl139090/* 183825cf1a30Sjl139090 * Set STICK adjusted by skew. 183925cf1a30Sjl139090 */ 184025cf1a30Sjl139090/* ARGSUSED */ 184125cf1a30Sjl139090void 184225cf1a30Sjl139090stick_adj(int64_t skew) 184325cf1a30Sjl139090{ 184425cf1a30Sjl139090} 184525cf1a30Sjl139090 184625cf1a30Sjl139090#else /* lint */ 184725cf1a30Sjl139090 184825cf1a30Sjl139090 ENTRY_NP(stick_adj) 184925cf1a30Sjl139090 rdpr %pstate, %g1 ! save processor state 185025cf1a30Sjl139090 andn %g1, PSTATE_IE, %g3 185125cf1a30Sjl139090 ba 1f ! cache align stick adj 185225cf1a30Sjl139090 wrpr %g0, %g3, %pstate ! turn off interrupts 185325cf1a30Sjl139090 185425cf1a30Sjl139090 .align 16 185525cf1a30Sjl1390901: nop 185625cf1a30Sjl139090 185725cf1a30Sjl139090 rd STICK, %g4 ! read stick reg 185825cf1a30Sjl139090 add %g4, %o0, %o1 ! adjust stick with skew 185925cf1a30Sjl139090 wr %o1, %g0, STICK ! write stick reg 186025cf1a30Sjl139090 186125cf1a30Sjl139090 retl 186225cf1a30Sjl139090 wrpr %g1, %pstate ! restore processor state 186325cf1a30Sjl139090 SET_SIZE(stick_adj) 186425cf1a30Sjl139090 186525cf1a30Sjl139090#endif /* lint */ 186625cf1a30Sjl139090 186725cf1a30Sjl139090#if defined(lint) 186825cf1a30Sjl139090/* 186925cf1a30Sjl139090 * Debugger-specific stick retrieval 187025cf1a30Sjl139090 */ 187125cf1a30Sjl139090/*ARGSUSED*/ 187225cf1a30Sjl139090int 187325cf1a30Sjl139090kdi_get_stick(uint64_t *stickp) 187425cf1a30Sjl139090{ 187525cf1a30Sjl139090 return (0); 187625cf1a30Sjl139090} 187725cf1a30Sjl139090 187825cf1a30Sjl139090#else /* lint */ 187925cf1a30Sjl139090 188025cf1a30Sjl139090 ENTRY_NP(kdi_get_stick) 188125cf1a30Sjl139090 rd STICK, %g1 188225cf1a30Sjl139090 stx %g1, [%o0] 188325cf1a30Sjl139090 retl 188425cf1a30Sjl139090 mov %g0, %o0 188525cf1a30Sjl139090 SET_SIZE(kdi_get_stick) 188625cf1a30Sjl139090 188725cf1a30Sjl139090#endif /* lint */ 188825cf1a30Sjl139090 188925cf1a30Sjl139090#if defined(lint) 189025cf1a30Sjl139090 189125cf1a30Sjl139090/*ARGSUSED*/ 189225cf1a30Sjl139090int 189325cf1a30Sjl139090dtrace_blksuword32(uintptr_t addr, uint32_t *data, int tryagain) 189425cf1a30Sjl139090{ return (0); } 189525cf1a30Sjl139090 189625cf1a30Sjl139090#else 189725cf1a30Sjl139090 189825cf1a30Sjl139090 ENTRY(dtrace_blksuword32) 189925cf1a30Sjl139090 save %sp, -SA(MINFRAME + 4), %sp 190025cf1a30Sjl139090 190125cf1a30Sjl139090 rdpr %pstate, %l1 190225cf1a30Sjl139090 andn %l1, PSTATE_IE, %l2 ! disable interrupts to 190325cf1a30Sjl139090 wrpr %g0, %l2, %pstate ! protect our FPU diddling 190425cf1a30Sjl139090 190525cf1a30Sjl139090 rd %fprs, %l0 190625cf1a30Sjl139090 andcc %l0, FPRS_FEF, %g0 190725cf1a30Sjl139090 bz,a,pt %xcc, 1f ! if the fpu is disabled 190825cf1a30Sjl139090 wr %g0, FPRS_FEF, %fprs ! ... enable the fpu 190925cf1a30Sjl139090 191025cf1a30Sjl139090 st %f0, [%fp + STACK_BIAS - 4] ! save %f0 to the stack 191125cf1a30Sjl1390901: 191225cf1a30Sjl139090 set 0f, %l5 191325cf1a30Sjl139090 /* 191425cf1a30Sjl139090 * We're about to write a block full or either total garbage 191525cf1a30Sjl139090 * (not kernel data, don't worry) or user floating-point data 191625cf1a30Sjl139090 * (so it only _looks_ like garbage). 191725cf1a30Sjl139090 */ 191825cf1a30Sjl139090 ld [%i1], %f0 ! modify the block 191925cf1a30Sjl139090 membar #Sync 192025cf1a30Sjl139090 stn %l5, [THREAD_REG + T_LOFAULT] ! set up the lofault handler 192125cf1a30Sjl139090 stda %d0, [%i0]ASI_BLK_COMMIT_S ! store the modified block 192225cf1a30Sjl139090 membar #Sync 1923f7832c8dShyw flush %i0 ! flush instruction pipeline 192425cf1a30Sjl139090 stn %g0, [THREAD_REG + T_LOFAULT] ! remove the lofault handler 192525cf1a30Sjl139090 192625cf1a30Sjl139090 bz,a,pt %xcc, 1f 192725cf1a30Sjl139090 wr %g0, %l0, %fprs ! restore %fprs 192825cf1a30Sjl139090 192925cf1a30Sjl139090 ld [%fp + STACK_BIAS - 4], %f0 ! restore %f0 193025cf1a30Sjl1390901: 193125cf1a30Sjl139090 193225cf1a30Sjl139090 wrpr %g0, %l1, %pstate ! restore interrupts 193325cf1a30Sjl139090 193425cf1a30Sjl139090 ret 193525cf1a30Sjl139090 restore %g0, %g0, %o0 193625cf1a30Sjl139090 193725cf1a30Sjl1390900: 193825cf1a30Sjl139090 membar #Sync 193925cf1a30Sjl139090 stn %g0, [THREAD_REG + T_LOFAULT] ! remove the lofault handler 194025cf1a30Sjl139090 194125cf1a30Sjl139090 bz,a,pt %xcc, 1f 194225cf1a30Sjl139090 wr %g0, %l0, %fprs ! restore %fprs 194325cf1a30Sjl139090 194425cf1a30Sjl139090 ld [%fp + STACK_BIAS - 4], %f0 ! restore %f0 194525cf1a30Sjl1390901: 194625cf1a30Sjl139090 194725cf1a30Sjl139090 wrpr %g0, %l1, %pstate ! restore interrupts 194825cf1a30Sjl139090 194925cf1a30Sjl139090 /* 195025cf1a30Sjl139090 * If tryagain is set (%i2) we tail-call dtrace_blksuword32_err() 195125cf1a30Sjl139090 * which deals with watchpoints. Otherwise, just return -1. 195225cf1a30Sjl139090 */ 195325cf1a30Sjl139090 brnz,pt %i2, 1f 195425cf1a30Sjl139090 nop 195525cf1a30Sjl139090 ret 195625cf1a30Sjl139090 restore %g0, -1, %o0 195725cf1a30Sjl1390901: 195825cf1a30Sjl139090 call dtrace_blksuword32_err 195925cf1a30Sjl139090 restore 196025cf1a30Sjl139090 196125cf1a30Sjl139090 SET_SIZE(dtrace_blksuword32) 196225cf1a30Sjl139090#endif /* lint */ 196325cf1a30Sjl139090 196425cf1a30Sjl139090#if defined(lint) 196525cf1a30Sjl139090/*ARGSUSED*/ 196625cf1a30Sjl139090void 196725cf1a30Sjl139090ras_cntr_reset(void *arg) 196825cf1a30Sjl139090{ 196925cf1a30Sjl139090} 197025cf1a30Sjl139090#else 197125cf1a30Sjl139090 ENTRY_NP(ras_cntr_reset) 197225cf1a30Sjl139090 set OPL_SCRATCHPAD_ERRLOG, %o1 197325cf1a30Sjl139090 ldxa [%o1]ASI_SCRATCHPAD, %o0 197425cf1a30Sjl139090 or %o0, ERRLOG_REG_NUMERR_MASK, %o0 197525cf1a30Sjl139090 retl 197625cf1a30Sjl139090 stxa %o0, [%o1]ASI_SCRATCHPAD 197725cf1a30Sjl139090 SET_SIZE(ras_cntr_reset) 197825cf1a30Sjl139090#endif /* lint */ 197925cf1a30Sjl139090 198025cf1a30Sjl139090#if defined(lint) 198125cf1a30Sjl139090/* ARGSUSED */ 198225cf1a30Sjl139090void 198325cf1a30Sjl139090opl_error_setup(uint64_t cpu_err_log_pa) 198425cf1a30Sjl139090{ 198525cf1a30Sjl139090} 198625cf1a30Sjl139090 198725cf1a30Sjl139090#else /* lint */ 198825cf1a30Sjl139090 ENTRY_NP(opl_error_setup) 198925cf1a30Sjl139090 /* 199025cf1a30Sjl139090 * Initialize the error log scratchpad register 199125cf1a30Sjl139090 */ 199225cf1a30Sjl139090 ldxa [%g0]ASI_EIDR, %o2 199325cf1a30Sjl139090 sethi %hi(ERRLOG_REG_EIDR_MASK), %o1 199425cf1a30Sjl139090 or %o1, %lo(ERRLOG_REG_EIDR_MASK), %o1 199525cf1a30Sjl139090 and %o2, %o1, %o3 199625cf1a30Sjl139090 sllx %o3, ERRLOG_REG_EIDR_SHIFT, %o2 199725cf1a30Sjl139090 or %o2, %o0, %o3 199825cf1a30Sjl139090 or %o3, ERRLOG_REG_NUMERR_MASK, %o0 199925cf1a30Sjl139090 set OPL_SCRATCHPAD_ERRLOG, %o1 200025cf1a30Sjl139090 stxa %o0, [%o1]ASI_SCRATCHPAD 200125cf1a30Sjl139090 /* 200225cf1a30Sjl139090 * Disable all restrainable error traps 200325cf1a30Sjl139090 */ 200425cf1a30Sjl139090 mov AFSR_ECR, %o1 200525cf1a30Sjl139090 ldxa [%o1]ASI_AFSR, %o0 200625cf1a30Sjl139090 andn %o0, ASI_ECR_RTE_UE|ASI_ECR_RTE_CEDG, %o0 200725cf1a30Sjl139090 retl 200825cf1a30Sjl139090 stxa %o0, [%o1]ASI_AFSR 200925cf1a30Sjl139090 SET_SIZE(opl_error_setup) 201025cf1a30Sjl139090#endif /* lint */ 201125cf1a30Sjl139090 201225cf1a30Sjl139090#if defined(lint) 201325cf1a30Sjl139090/* ARGSUSED */ 201425cf1a30Sjl139090void 2015*c9d93b53SJames Andersoncpu_early_feature_init(void) 201625cf1a30Sjl139090{ 201725cf1a30Sjl139090} 201825cf1a30Sjl139090#else /* lint */ 2019*c9d93b53SJames Anderson ENTRY_NP(cpu_early_feature_init) 202025cf1a30Sjl139090 /* 202125cf1a30Sjl139090 * Enable MMU translating multiple page sizes for 202225cf1a30Sjl139090 * sITLB and sDTLB. 202325cf1a30Sjl139090 */ 202425cf1a30Sjl139090 mov LSU_MCNTL, %o0 202525cf1a30Sjl139090 ldxa [%o0] ASI_MCNTL, %o1 202625cf1a30Sjl139090 or %o1, MCNTL_MPG_SITLB | MCNTL_MPG_SDTLB, %o1 202725cf1a30Sjl139090 stxa %o1, [%o0] ASI_MCNTL 2028*c9d93b53SJames Anderson /* 2029*c9d93b53SJames Anderson * Demap all previous entries. 2030*c9d93b53SJames Anderson */ 2031*c9d93b53SJames Anderson sethi %hi(FLUSH_ADDR), %o1 2032*c9d93b53SJames Anderson set DEMAP_ALL_TYPE, %o0 2033*c9d93b53SJames Anderson stxa %g0, [%o0]ASI_DTLB_DEMAP 2034*c9d93b53SJames Anderson stxa %g0, [%o0]ASI_ITLB_DEMAP 2035*c9d93b53SJames Anderson retl 2036*c9d93b53SJames Anderson flush %o1 2037*c9d93b53SJames Anderson SET_SIZE(cpu_early_feature_init) 203825cf1a30Sjl139090#endif /* lint */ 203925cf1a30Sjl139090 204025cf1a30Sjl139090#if defined(lint) 204125cf1a30Sjl139090/* 204225cf1a30Sjl139090 * This function is called for each (enabled) CPU. We use it to 204325cf1a30Sjl139090 * initialize error handling related registers. 204425cf1a30Sjl139090 */ 204525cf1a30Sjl139090/*ARGSUSED*/ 204625cf1a30Sjl139090void 204725cf1a30Sjl139090cpu_feature_init(void) 204825cf1a30Sjl139090{} 204925cf1a30Sjl139090#else /* lint */ 205025cf1a30Sjl139090 ENTRY(cpu_feature_init) 205125cf1a30Sjl139090 ! 205225cf1a30Sjl139090 ! get the device_id and store the device_id 205325cf1a30Sjl139090 ! in the appropriate cpunodes structure 205425cf1a30Sjl139090 ! given the cpus index 205525cf1a30Sjl139090 ! 205625cf1a30Sjl139090 CPU_INDEX(%o0, %o1) 205725cf1a30Sjl139090 mulx %o0, CPU_NODE_SIZE, %o0 205825cf1a30Sjl139090 set cpunodes + DEVICE_ID, %o1 205925cf1a30Sjl139090 ldxa [%g0] ASI_DEVICE_SERIAL_ID, %o2 206025cf1a30Sjl139090 stx %o2, [%o0 + %o1] 206125cf1a30Sjl139090 ! 206225cf1a30Sjl139090 ! initialize CPU registers 206325cf1a30Sjl139090 ! 206425cf1a30Sjl139090 ba opl_cpu_reg_init 206525cf1a30Sjl139090 nop 206625cf1a30Sjl139090 SET_SIZE(cpu_feature_init) 206725cf1a30Sjl139090#endif /* lint */ 206825cf1a30Sjl139090 206925cf1a30Sjl139090#if defined(lint) 207025cf1a30Sjl139090 207125cf1a30Sjl139090void 207225cf1a30Sjl139090cpu_cleartickpnt(void) 207325cf1a30Sjl139090{} 207425cf1a30Sjl139090 207525cf1a30Sjl139090#else /* lint */ 207625cf1a30Sjl139090 /* 207725cf1a30Sjl139090 * Clear the NPT (non-privileged trap) bit in the %tick/%stick 207825cf1a30Sjl139090 * registers. In an effort to make the change in the 207925cf1a30Sjl139090 * tick/stick counter as consistent as possible, we disable 208025cf1a30Sjl139090 * all interrupts while we're changing the registers. We also 208125cf1a30Sjl139090 * ensure that the read and write instructions are in the same 208225cf1a30Sjl139090 * line in the instruction cache. 208325cf1a30Sjl139090 */ 208425cf1a30Sjl139090 ENTRY_NP(cpu_clearticknpt) 208525cf1a30Sjl139090 rdpr %pstate, %g1 /* save processor state */ 208625cf1a30Sjl139090 andn %g1, PSTATE_IE, %g3 /* turn off */ 208725cf1a30Sjl139090 wrpr %g0, %g3, %pstate /* interrupts */ 208825cf1a30Sjl139090 rdpr %tick, %g2 /* get tick register */ 208925cf1a30Sjl139090 brgez,pn %g2, 1f /* if NPT bit off, we're done */ 209025cf1a30Sjl139090 mov 1, %g3 /* create mask */ 209125cf1a30Sjl139090 sllx %g3, 63, %g3 /* for NPT bit */ 209225cf1a30Sjl139090 ba,a,pt %xcc, 2f 209325cf1a30Sjl139090 .align 8 /* Ensure rd/wr in same i$ line */ 209425cf1a30Sjl1390902: 209525cf1a30Sjl139090 rdpr %tick, %g2 /* get tick register */ 209625cf1a30Sjl139090 wrpr %g3, %g2, %tick /* write tick register, */ 209725cf1a30Sjl139090 /* clearing NPT bit */ 209825cf1a30Sjl1390901: 209925cf1a30Sjl139090 rd STICK, %g2 /* get stick register */ 210025cf1a30Sjl139090 brgez,pn %g2, 3f /* if NPT bit off, we're done */ 210125cf1a30Sjl139090 mov 1, %g3 /* create mask */ 210225cf1a30Sjl139090 sllx %g3, 63, %g3 /* for NPT bit */ 210325cf1a30Sjl139090 ba,a,pt %xcc, 4f 210425cf1a30Sjl139090 .align 8 /* Ensure rd/wr in same i$ line */ 210525cf1a30Sjl1390904: 210625cf1a30Sjl139090 rd STICK, %g2 /* get stick register */ 210725cf1a30Sjl139090 wr %g3, %g2, STICK /* write stick register, */ 210825cf1a30Sjl139090 /* clearing NPT bit */ 210925cf1a30Sjl1390903: 211025cf1a30Sjl139090 jmp %g4 + 4 211125cf1a30Sjl139090 wrpr %g0, %g1, %pstate /* restore processor state */ 211225cf1a30Sjl139090 211325cf1a30Sjl139090 SET_SIZE(cpu_clearticknpt) 211425cf1a30Sjl139090 211525cf1a30Sjl139090#endif /* lint */ 211625cf1a30Sjl139090 211725cf1a30Sjl139090#if defined(lint) 211825cf1a30Sjl139090 211925cf1a30Sjl139090void 212025cf1a30Sjl139090cpu_halt_cpu(void) 212125cf1a30Sjl139090{} 212225cf1a30Sjl139090 212325cf1a30Sjl139090void 212425cf1a30Sjl139090cpu_smt_pause(void) 212525cf1a30Sjl139090{} 212625cf1a30Sjl139090 212725cf1a30Sjl139090#else /* lint */ 212825cf1a30Sjl139090 212925cf1a30Sjl139090 /* 213025cf1a30Sjl139090 * Halt the current strand with the suspend instruction. 213125cf1a30Sjl139090 * The compiler/asm currently does not support this suspend 213225cf1a30Sjl139090 * instruction mnemonic, use byte code for now. 213325cf1a30Sjl139090 */ 213425cf1a30Sjl139090 ENTRY_NP(cpu_halt_cpu) 213525cf1a30Sjl139090 .word 0x81b01040 213625cf1a30Sjl139090 retl 213725cf1a30Sjl139090 nop 213825cf1a30Sjl139090 SET_SIZE(cpu_halt_cpu) 213925cf1a30Sjl139090 214025cf1a30Sjl139090 /* 214125cf1a30Sjl139090 * Pause the current strand with the sleep instruction. 214225cf1a30Sjl139090 * The compiler/asm currently does not support this sleep 214325cf1a30Sjl139090 * instruction mnemonic, use byte code for now. 214425cf1a30Sjl139090 */ 214525cf1a30Sjl139090 ENTRY_NP(cpu_smt_pause) 214625cf1a30Sjl139090 .word 0x81b01060 214725cf1a30Sjl139090 retl 214825cf1a30Sjl139090 nop 214925cf1a30Sjl139090 SET_SIZE(cpu_smt_pause) 215025cf1a30Sjl139090 215125cf1a30Sjl139090#endif /* lint */ 2152