17c478bd9Sstevel@tonic-gate/* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57bebe46cSjc25722 * Common Development and Distribution License (the "License"). 67bebe46cSjc25722 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate/* 227bebe46cSjc25722 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate * 257c478bd9Sstevel@tonic-gate * Assembly code support for the Cheetah+ module 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate#pragma ident "%Z%%M% %I% %E% SMI" 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate#if !defined(lint) 317c478bd9Sstevel@tonic-gate#include "assym.h" 327c478bd9Sstevel@tonic-gate#endif /* lint */ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 357c478bd9Sstevel@tonic-gate#include <sys/mmu.h> 367c478bd9Sstevel@tonic-gate#include <vm/hat_sfmmu.h> 377c478bd9Sstevel@tonic-gate#include <sys/machparam.h> 387c478bd9Sstevel@tonic-gate#include <sys/machcpuvar.h> 397c478bd9Sstevel@tonic-gate#include <sys/machthread.h> 407c478bd9Sstevel@tonic-gate#include <sys/machtrap.h> 417c478bd9Sstevel@tonic-gate#include <sys/privregs.h> 427c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 437c478bd9Sstevel@tonic-gate#include <sys/trap.h> 447c478bd9Sstevel@tonic-gate#include <sys/cheetahregs.h> 457c478bd9Sstevel@tonic-gate#include <sys/us3_module.h> 467c478bd9Sstevel@tonic-gate#include <sys/xc_impl.h> 477c478bd9Sstevel@tonic-gate#include <sys/intreg.h> 487c478bd9Sstevel@tonic-gate#include <sys/async.h> 497c478bd9Sstevel@tonic-gate#include <sys/clock.h> 507c478bd9Sstevel@tonic-gate#include <sys/cheetahasm.h> 517bebe46cSjc25722#include <sys/cmpregs.h> 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 547c478bd9Sstevel@tonic-gate#include <sys/traptrace.h> 557c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */ 567c478bd9Sstevel@tonic-gate 577bebe46cSjc25722 587c478bd9Sstevel@tonic-gate#if !defined(lint) 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate/* BEGIN CSTYLED */ 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate/* 637c478bd9Sstevel@tonic-gate * Cheetah+ version to reflush an Ecache line by index. 647c478bd9Sstevel@tonic-gate * 657c478bd9Sstevel@tonic-gate * By default we assume the Ecache is 2-way so we flush both 667c478bd9Sstevel@tonic-gate * ways. Even if the cache is direct-mapped no harm will come 677c478bd9Sstevel@tonic-gate * from performing the flush twice, apart from perhaps a performance 687c478bd9Sstevel@tonic-gate * penalty. 697c478bd9Sstevel@tonic-gate * 707c478bd9Sstevel@tonic-gate * XXX - scr2 not used. 717c478bd9Sstevel@tonic-gate */ 727c478bd9Sstevel@tonic-gate#define ECACHE_REFLUSH_LINE(ec_set_size, index, scr2) \ 737c478bd9Sstevel@tonic-gate ldxa [index]ASI_EC_DIAG, %g0; \ 747c478bd9Sstevel@tonic-gate ldxa [index + ec_set_size]ASI_EC_DIAG, %g0; 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate/* 777c478bd9Sstevel@tonic-gate * Cheetah+ version of ecache_flush_line. Uses Cheetah+ Ecache Displacement 787c478bd9Sstevel@tonic-gate * Flush feature. 797c478bd9Sstevel@tonic-gate */ 807c478bd9Sstevel@tonic-gate#define ECACHE_FLUSH_LINE(physaddr, ec_set_size, scr1, scr2) \ 817c478bd9Sstevel@tonic-gate sub ec_set_size, 1, scr1; \ 827c478bd9Sstevel@tonic-gate and physaddr, scr1, scr1; \ 837c478bd9Sstevel@tonic-gate set CHP_ECACHE_IDX_DISP_FLUSH, scr2; \ 847c478bd9Sstevel@tonic-gate or scr2, scr1, scr1; \ 857c478bd9Sstevel@tonic-gate ECACHE_REFLUSH_LINE(ec_set_size, scr1, scr2) 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate/* END CSTYLED */ 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate/* 907c478bd9Sstevel@tonic-gate * Panther version to reflush a line from both the L2 cache and L3 917c478bd9Sstevel@tonic-gate * cache by the respective indexes. Flushes all ways of the line from 927c478bd9Sstevel@tonic-gate * each cache. 937c478bd9Sstevel@tonic-gate * 947c478bd9Sstevel@tonic-gate * l2_index Index into the L2$ of the line to be flushed. This 957c478bd9Sstevel@tonic-gate * register will not be modified by this routine. 967c478bd9Sstevel@tonic-gate * l3_index Index into the L3$ of the line to be flushed. This 977c478bd9Sstevel@tonic-gate * register will not be modified by this routine. 987c478bd9Sstevel@tonic-gate * scr2 scratch register. 997c478bd9Sstevel@tonic-gate * scr3 scratch register. 1007c478bd9Sstevel@tonic-gate * 1017c478bd9Sstevel@tonic-gate */ 1027c478bd9Sstevel@tonic-gate#define PN_ECACHE_REFLUSH_LINE(l2_index, l3_index, scr2, scr3) \ 1037c478bd9Sstevel@tonic-gate set PN_L2_MAX_SET, scr2; \ 1047c478bd9Sstevel@tonic-gate set PN_L2_SET_SIZE, scr3; \ 1057c478bd9Sstevel@tonic-gate1: \ 1067c478bd9Sstevel@tonic-gate ldxa [l2_index + scr2]ASI_L2_TAG, %g0; \ 1077c478bd9Sstevel@tonic-gate cmp scr2, %g0; \ 1087c478bd9Sstevel@tonic-gate bg,a 1b; \ 1097c478bd9Sstevel@tonic-gate sub scr2, scr3, scr2; \ 1107bebe46cSjc25722 mov 6, scr2; \ 1117bebe46cSjc257227: \ 1127bebe46cSjc25722 cmp scr2, %g0; \ 1137bebe46cSjc25722 bg,a 7b; \ 1147bebe46cSjc25722 sub scr2, 1, scr2; \ 1157c478bd9Sstevel@tonic-gate set PN_L3_MAX_SET, scr2; \ 1167c478bd9Sstevel@tonic-gate set PN_L3_SET_SIZE, scr3; \ 1177c478bd9Sstevel@tonic-gate2: \ 1187c478bd9Sstevel@tonic-gate ldxa [l3_index + scr2]ASI_EC_DIAG, %g0; \ 1197c478bd9Sstevel@tonic-gate cmp scr2, %g0; \ 1207c478bd9Sstevel@tonic-gate bg,a 2b; \ 1217c478bd9Sstevel@tonic-gate sub scr2, scr3, scr2; 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate/* 1247c478bd9Sstevel@tonic-gate * Panther version of ecache_flush_line. Flushes the line corresponding 1257c478bd9Sstevel@tonic-gate * to physaddr from both the L2 cache and the L3 cache. 1267c478bd9Sstevel@tonic-gate * 1277c478bd9Sstevel@tonic-gate * physaddr Input: Physical address to flush. 1287c478bd9Sstevel@tonic-gate * Output: Physical address to flush (preserved). 1297c478bd9Sstevel@tonic-gate * l2_idx_out Input: scratch register. 1307c478bd9Sstevel@tonic-gate * Output: Index into the L2$ of the line to be flushed. 1317c478bd9Sstevel@tonic-gate * l3_idx_out Input: scratch register. 1327c478bd9Sstevel@tonic-gate * Output: Index into the L3$ of the line to be flushed. 1337c478bd9Sstevel@tonic-gate * scr3 scratch register. 1347c478bd9Sstevel@tonic-gate * scr4 scratch register. 1357c478bd9Sstevel@tonic-gate * 1367c478bd9Sstevel@tonic-gate */ 1377c478bd9Sstevel@tonic-gate#define PN_ECACHE_FLUSH_LINE(physaddr, l2_idx_out, l3_idx_out, scr3, scr4) \ 1387c478bd9Sstevel@tonic-gate set PN_L3_SET_SIZE, l2_idx_out; \ 1397c478bd9Sstevel@tonic-gate sub l2_idx_out, 1, l2_idx_out; \ 1407c478bd9Sstevel@tonic-gate and physaddr, l2_idx_out, l3_idx_out; \ 1417c478bd9Sstevel@tonic-gate set PN_L3_IDX_DISP_FLUSH, l2_idx_out; \ 1427c478bd9Sstevel@tonic-gate or l2_idx_out, l3_idx_out, l3_idx_out; \ 1437c478bd9Sstevel@tonic-gate set PN_L2_SET_SIZE, l2_idx_out; \ 1447c478bd9Sstevel@tonic-gate sub l2_idx_out, 1, l2_idx_out; \ 1457c478bd9Sstevel@tonic-gate and physaddr, l2_idx_out, l2_idx_out; \ 1467c478bd9Sstevel@tonic-gate set PN_L2_IDX_DISP_FLUSH, scr3; \ 1477c478bd9Sstevel@tonic-gate or l2_idx_out, scr3, l2_idx_out; \ 1487c478bd9Sstevel@tonic-gate PN_ECACHE_REFLUSH_LINE(l2_idx_out, l3_idx_out, scr3, scr4) 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate#endif /* !lint */ 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate/* 1537c478bd9Sstevel@tonic-gate * Fast ECC error at TL>0 handler 1547c478bd9Sstevel@tonic-gate * We get here via trap 70 at TL>0->Software trap 0 at TL>0. We enter 1557c478bd9Sstevel@tonic-gate * this routine with %g1 and %g2 already saved in %tpc, %tnpc and %tstate. 1567c478bd9Sstevel@tonic-gate * For a complete description of the Fast ECC at TL>0 handling see the 1577c478bd9Sstevel@tonic-gate * comment block "Cheetah/Cheetah+ Fast ECC at TL>0 trap strategy" in 1587c478bd9Sstevel@tonic-gate * us3_common_asm.s 1597c478bd9Sstevel@tonic-gate */ 1607c478bd9Sstevel@tonic-gate#if defined(lint) 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gatevoid 1637c478bd9Sstevel@tonic-gatefast_ecc_tl1_err(void) 1647c478bd9Sstevel@tonic-gate{} 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate#else /* lint */ 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate .section ".text" 1697c478bd9Sstevel@tonic-gate .align 64 1707c478bd9Sstevel@tonic-gate ENTRY_NP(fast_ecc_tl1_err) 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate /* 1737c478bd9Sstevel@tonic-gate * This macro turns off the D$/I$ if they are on and saves their 1747c478bd9Sstevel@tonic-gate * original state in ch_err_tl1_tmp, saves all the %g registers in the 1757c478bd9Sstevel@tonic-gate * ch_err_tl1_data structure, updates the ch_err_tl1_flags and saves 1767c478bd9Sstevel@tonic-gate * the %tpc in ch_err_tl1_tpc. At the end of this macro, %g1 will 1777c478bd9Sstevel@tonic-gate * point to the ch_err_tl1_data structure and the original D$/I$ state 1787c478bd9Sstevel@tonic-gate * will be saved in ch_err_tl1_tmp. All %g registers except for %g1 1797c478bd9Sstevel@tonic-gate * will be available. 1807c478bd9Sstevel@tonic-gate */ 1817c478bd9Sstevel@tonic-gate CH_ERR_TL1_FECC_ENTER; 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate /* 1847c478bd9Sstevel@tonic-gate * Get the diagnostic logout data. %g4 must be initialized to 1857c478bd9Sstevel@tonic-gate * current CEEN state, %g5 must point to logout structure in 1867c478bd9Sstevel@tonic-gate * ch_err_tl1_data_t. %g3 will contain the nesting count upon 1877c478bd9Sstevel@tonic-gate * return. 1887c478bd9Sstevel@tonic-gate */ 1897c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_ESTATE_ERR, %g4 1907c478bd9Sstevel@tonic-gate and %g4, EN_REG_CEEN, %g4 1917c478bd9Sstevel@tonic-gate add %g1, CH_ERR_TL1_LOGOUT, %g5 1927c478bd9Sstevel@tonic-gate DO_TL1_CPU_LOGOUT(%g3, %g2, %g4, %g5, %g6, %g3, %g4) 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate /* 1957c478bd9Sstevel@tonic-gate * If the logout nesting count is exceeded, we're probably 1967c478bd9Sstevel@tonic-gate * not making any progress, try to panic instead. 1977c478bd9Sstevel@tonic-gate */ 1987c478bd9Sstevel@tonic-gate cmp %g3, CLO_NESTING_MAX 1997c478bd9Sstevel@tonic-gate bge fecc_tl1_err 2007c478bd9Sstevel@tonic-gate nop 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate /* 2037c478bd9Sstevel@tonic-gate * Save the current CEEN and NCEEN state in %g7 and turn them off 2047c478bd9Sstevel@tonic-gate * before flushing the Ecache. 2057c478bd9Sstevel@tonic-gate */ 2067c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_ESTATE_ERR, %g7 2077c478bd9Sstevel@tonic-gate andn %g7, EN_REG_CEEN | EN_REG_NCEEN, %g5 2087c478bd9Sstevel@tonic-gate stxa %g5, [%g0]ASI_ESTATE_ERR 2097c478bd9Sstevel@tonic-gate membar #Sync 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate /* 2127c478bd9Sstevel@tonic-gate * Flush the Ecache, using the largest possible cache size with the 2137c478bd9Sstevel@tonic-gate * smallest possible line size since we can't get the actual sizes 2147c478bd9Sstevel@tonic-gate * from the cpu_node due to DTLB misses. 2157c478bd9Sstevel@tonic-gate */ 2167c478bd9Sstevel@tonic-gate PN_L2_FLUSHALL(%g3, %g4, %g5) 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate set CH_ECACHE_MAX_SIZE, %g4 2197c478bd9Sstevel@tonic-gate set CH_ECACHE_MIN_LSIZE, %g5 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate GET_CPU_IMPL(%g6) 2227c478bd9Sstevel@tonic-gate cmp %g6, PANTHER_IMPL 2237c478bd9Sstevel@tonic-gate bne %xcc, 2f 2247c478bd9Sstevel@tonic-gate nop 2257c478bd9Sstevel@tonic-gate set PN_L3_SIZE, %g4 2267c478bd9Sstevel@tonic-gate2: 2277c478bd9Sstevel@tonic-gate mov %g6, %g3 2287c478bd9Sstevel@tonic-gate CHP_ECACHE_FLUSHALL(%g4, %g5, %g3) 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate /* 2317c478bd9Sstevel@tonic-gate * Restore CEEN and NCEEN to the previous state. 2327c478bd9Sstevel@tonic-gate */ 2337c478bd9Sstevel@tonic-gate stxa %g7, [%g0]ASI_ESTATE_ERR 2347c478bd9Sstevel@tonic-gate membar #Sync 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate /* 2377c478bd9Sstevel@tonic-gate * If we turned off the D$, then flush it and turn it back on. 2387c478bd9Sstevel@tonic-gate */ 2397c478bd9Sstevel@tonic-gate ldxa [%g1 + CH_ERR_TL1_TMP]%asi, %g3 2407c478bd9Sstevel@tonic-gate andcc %g3, CH_ERR_TSTATE_DC_ON, %g0 2417c478bd9Sstevel@tonic-gate bz %xcc, 3f 2427c478bd9Sstevel@tonic-gate nop 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate /* 2457c478bd9Sstevel@tonic-gate * Flush the D$. 2467c478bd9Sstevel@tonic-gate */ 2477c478bd9Sstevel@tonic-gate ASM_LD(%g4, dcache_size) 2487c478bd9Sstevel@tonic-gate ASM_LD(%g5, dcache_linesize) 2497c478bd9Sstevel@tonic-gate CH_DCACHE_FLUSHALL(%g4, %g5, %g6) 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate /* 2527c478bd9Sstevel@tonic-gate * Turn the D$ back on. 2537c478bd9Sstevel@tonic-gate */ 2547c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_DCU, %g3 2557c478bd9Sstevel@tonic-gate or %g3, DCU_DC, %g3 2567c478bd9Sstevel@tonic-gate stxa %g3, [%g0]ASI_DCU 2577c478bd9Sstevel@tonic-gate membar #Sync 2587c478bd9Sstevel@tonic-gate3: 2597c478bd9Sstevel@tonic-gate /* 2607c478bd9Sstevel@tonic-gate * If we turned off the I$, then flush it and turn it back on. 2617c478bd9Sstevel@tonic-gate */ 2627c478bd9Sstevel@tonic-gate ldxa [%g1 + CH_ERR_TL1_TMP]%asi, %g3 2637c478bd9Sstevel@tonic-gate andcc %g3, CH_ERR_TSTATE_IC_ON, %g0 2647c478bd9Sstevel@tonic-gate bz %xcc, 4f 2657c478bd9Sstevel@tonic-gate nop 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate /* 2687c478bd9Sstevel@tonic-gate * Flush the I$. Panther has different I$ parameters, and we 2697c478bd9Sstevel@tonic-gate * can't access the logout I$ params without possibly generating 2707c478bd9Sstevel@tonic-gate * a MMU miss. 2717c478bd9Sstevel@tonic-gate */ 2727c478bd9Sstevel@tonic-gate GET_CPU_IMPL(%g6) 2737c478bd9Sstevel@tonic-gate set PN_ICACHE_SIZE, %g3 2747c478bd9Sstevel@tonic-gate set CH_ICACHE_SIZE, %g4 2757c478bd9Sstevel@tonic-gate mov CH_ICACHE_LSIZE, %g5 2767c478bd9Sstevel@tonic-gate cmp %g6, PANTHER_IMPL 2777c478bd9Sstevel@tonic-gate movz %xcc, %g3, %g4 2787c478bd9Sstevel@tonic-gate movz %xcc, PN_ICACHE_LSIZE, %g5 2797c478bd9Sstevel@tonic-gate CH_ICACHE_FLUSHALL(%g4, %g5, %g6, %g3) 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate /* 2827c478bd9Sstevel@tonic-gate * Turn the I$ back on. Changing DCU_IC requires flush. 2837c478bd9Sstevel@tonic-gate */ 2847c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_DCU, %g3 2857c478bd9Sstevel@tonic-gate or %g3, DCU_IC, %g3 2867c478bd9Sstevel@tonic-gate stxa %g3, [%g0]ASI_DCU 2877c478bd9Sstevel@tonic-gate flush %g0 2887c478bd9Sstevel@tonic-gate4: 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 2917c478bd9Sstevel@tonic-gate /* 2927c478bd9Sstevel@tonic-gate * Get current trap trace entry physical pointer. 2937c478bd9Sstevel@tonic-gate */ 2947c478bd9Sstevel@tonic-gate CPU_INDEX(%g6, %g5) 2957c478bd9Sstevel@tonic-gate sll %g6, TRAPTR_SIZE_SHIFT, %g6 2967c478bd9Sstevel@tonic-gate set trap_trace_ctl, %g5 2977c478bd9Sstevel@tonic-gate add %g6, %g5, %g6 2987c478bd9Sstevel@tonic-gate ld [%g6 + TRAPTR_LIMIT], %g5 2997c478bd9Sstevel@tonic-gate tst %g5 3007c478bd9Sstevel@tonic-gate be %icc, skip_traptrace 3017c478bd9Sstevel@tonic-gate nop 3027c478bd9Sstevel@tonic-gate ldx [%g6 + TRAPTR_PBASE], %g5 3037c478bd9Sstevel@tonic-gate ld [%g6 + TRAPTR_OFFSET], %g4 3047c478bd9Sstevel@tonic-gate add %g5, %g4, %g5 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate /* 3077c478bd9Sstevel@tonic-gate * Create trap trace entry. 3087c478bd9Sstevel@tonic-gate */ 3097c478bd9Sstevel@tonic-gate rd %asi, %g7 3107c478bd9Sstevel@tonic-gate wr %g0, TRAPTR_ASI, %asi 3117c478bd9Sstevel@tonic-gate rd STICK, %g4 3127c478bd9Sstevel@tonic-gate stxa %g4, [%g5 + TRAP_ENT_TICK]%asi 3137c478bd9Sstevel@tonic-gate rdpr %tl, %g4 3147c478bd9Sstevel@tonic-gate stha %g4, [%g5 + TRAP_ENT_TL]%asi 3157c478bd9Sstevel@tonic-gate rdpr %tt, %g4 3167c478bd9Sstevel@tonic-gate stha %g4, [%g5 + TRAP_ENT_TT]%asi 3177c478bd9Sstevel@tonic-gate rdpr %tpc, %g4 3187c478bd9Sstevel@tonic-gate stna %g4, [%g5 + TRAP_ENT_TPC]%asi 3197c478bd9Sstevel@tonic-gate rdpr %tstate, %g4 3207c478bd9Sstevel@tonic-gate stxa %g4, [%g5 + TRAP_ENT_TSTATE]%asi 3217c478bd9Sstevel@tonic-gate stna %sp, [%g5 + TRAP_ENT_SP]%asi 3227c478bd9Sstevel@tonic-gate stna %g0, [%g5 + TRAP_ENT_TR]%asi 3237c478bd9Sstevel@tonic-gate wr %g0, %g7, %asi 3247c478bd9Sstevel@tonic-gate ldxa [%g1 + CH_ERR_TL1_SDW_AFAR]%asi, %g3 3257c478bd9Sstevel@tonic-gate ldxa [%g1 + CH_ERR_TL1_SDW_AFSR]%asi, %g4 3267c478bd9Sstevel@tonic-gate wr %g0, TRAPTR_ASI, %asi 3277c478bd9Sstevel@tonic-gate stna %g3, [%g5 + TRAP_ENT_F1]%asi 3287c478bd9Sstevel@tonic-gate stna %g4, [%g5 + TRAP_ENT_F2]%asi 3297c478bd9Sstevel@tonic-gate wr %g0, %g7, %asi 3307c478bd9Sstevel@tonic-gate ldxa [%g1 + CH_ERR_TL1_AFAR]%asi, %g3 3317c478bd9Sstevel@tonic-gate ldxa [%g1 + CH_ERR_TL1_AFSR]%asi, %g4 3327c478bd9Sstevel@tonic-gate wr %g0, TRAPTR_ASI, %asi 3337c478bd9Sstevel@tonic-gate stna %g3, [%g5 + TRAP_ENT_F3]%asi 3347c478bd9Sstevel@tonic-gate stna %g4, [%g5 + TRAP_ENT_F4]%asi 3357c478bd9Sstevel@tonic-gate wr %g0, %g7, %asi 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate /* 3387c478bd9Sstevel@tonic-gate * Advance trap trace pointer. 3397c478bd9Sstevel@tonic-gate */ 3407c478bd9Sstevel@tonic-gate ld [%g6 + TRAPTR_OFFSET], %g5 3417c478bd9Sstevel@tonic-gate ld [%g6 + TRAPTR_LIMIT], %g4 3427c478bd9Sstevel@tonic-gate st %g5, [%g6 + TRAPTR_LAST_OFFSET] 3437c478bd9Sstevel@tonic-gate add %g5, TRAP_ENT_SIZE, %g5 3447c478bd9Sstevel@tonic-gate sub %g4, TRAP_ENT_SIZE, %g4 3457c478bd9Sstevel@tonic-gate cmp %g5, %g4 3467c478bd9Sstevel@tonic-gate movge %icc, 0, %g5 3477c478bd9Sstevel@tonic-gate st %g5, [%g6 + TRAPTR_OFFSET] 3487c478bd9Sstevel@tonic-gateskip_traptrace: 3497c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */ 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate /* 3527c478bd9Sstevel@tonic-gate * If nesting count is not zero, skip all the AFSR/AFAR 3537c478bd9Sstevel@tonic-gate * handling and just do the necessary cache-flushing. 3547c478bd9Sstevel@tonic-gate */ 3557c478bd9Sstevel@tonic-gate ldxa [%g1 + CH_ERR_TL1_NEST_CNT]%asi, %g2 3567c478bd9Sstevel@tonic-gate brnz %g2, 6f 3577c478bd9Sstevel@tonic-gate nop 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate /* 3607c478bd9Sstevel@tonic-gate * If a UCU or L3_UCU followed by a WDU has occurred go ahead 3617c478bd9Sstevel@tonic-gate * and panic since a UE will occur (on the retry) before the 362*9ed9f144Skwmc * UCU and WDU messages are enqueued. On a Panther processor, 363*9ed9f144Skwmc * we need to also see an L3_WDU before panicking. Note that 364*9ed9f144Skwmc * we avoid accessing the _EXT ASIs if not on a Panther. 3657c478bd9Sstevel@tonic-gate */ 3667c478bd9Sstevel@tonic-gate ldxa [%g1 + CH_ERR_TL1_SDW_AFSR]%asi, %g3 3677c478bd9Sstevel@tonic-gate set 1, %g4 3687c478bd9Sstevel@tonic-gate sllx %g4, C_AFSR_UCU_SHIFT, %g4 3697c478bd9Sstevel@tonic-gate btst %g4, %g3 ! UCU in original shadow AFSR? 3707c478bd9Sstevel@tonic-gate bnz %xcc, 5f 371*9ed9f144Skwmc nop 372*9ed9f144Skwmc GET_CPU_IMPL(%g6) 373*9ed9f144Skwmc cmp %g6, PANTHER_IMPL 374*9ed9f144Skwmc bne %xcc, 6f ! not Panther, no UCU, skip the rest 375*9ed9f144Skwmc nop 3767c478bd9Sstevel@tonic-gate ldxa [%g1 + CH_ERR_TL1_SDW_AFSR_EXT]%asi, %g3 377*9ed9f144Skwmc btst C_AFSR_L3_UCU, %g3 ! L3_UCU in original shadow AFSR_EXT? 378*9ed9f144Skwmc bz %xcc, 6f ! neither UCU nor L3_UCU was seen 3797c478bd9Sstevel@tonic-gate nop 3807c478bd9Sstevel@tonic-gate5: 3817c478bd9Sstevel@tonic-gate ldxa [%g1 + CH_ERR_TL1_AFSR]%asi, %g4 ! original AFSR 3827c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_AFSR, %g3 ! current AFSR 3837c478bd9Sstevel@tonic-gate or %g3, %g4, %g3 ! %g3 = original + current AFSR 3847c478bd9Sstevel@tonic-gate set 1, %g4 3857c478bd9Sstevel@tonic-gate sllx %g4, C_AFSR_WDU_SHIFT, %g4 3867c478bd9Sstevel@tonic-gate btst %g4, %g3 ! WDU in original or current AFSR? 387*9ed9f144Skwmc bz %xcc, 6f ! no WDU, skip remaining tests 3887c478bd9Sstevel@tonic-gate nop 389*9ed9f144Skwmc GET_CPU_IMPL(%g6) 390*9ed9f144Skwmc cmp %g6, PANTHER_IMPL 391*9ed9f144Skwmc bne %xcc, fecc_tl1_err ! if not Panther, panic (saw UCU, WDU) 392*9ed9f144Skwmc nop 393*9ed9f144Skwmc ldxa [%g1 + CH_ERR_TL1_SDW_AFSR_EXT]%asi, %g4 ! original AFSR_EXT 394*9ed9f144Skwmc set ASI_AFSR_EXT_VA, %g6 ! ASI of current AFSR_EXT 395*9ed9f144Skwmc ldxa [%g6]ASI_AFSR, %g3 ! value of current AFSR_EXT 396*9ed9f144Skwmc or %g3, %g4, %g3 ! %g3 = original + current AFSR_EXT 397*9ed9f144Skwmc btst C_AFSR_L3_WDU, %g3 ! L3_WDU in original or current AFSR? 398*9ed9f144Skwmc bnz %xcc, fecc_tl1_err ! panic (saw L3_WDU and UCU or L3_UCU) 399*9ed9f144Skwmc nop 4007c478bd9Sstevel@tonic-gate6: 4017c478bd9Sstevel@tonic-gate /* 4027c478bd9Sstevel@tonic-gate * We fall into this macro if we've successfully logged the error in 4037c478bd9Sstevel@tonic-gate * the ch_err_tl1_data structure and want the PIL15 softint to pick 4047c478bd9Sstevel@tonic-gate * it up and log it. %g1 must point to the ch_err_tl1_data structure. 4057c478bd9Sstevel@tonic-gate * Restores the %g registers and issues retry. 4067c478bd9Sstevel@tonic-gate */ 4077c478bd9Sstevel@tonic-gate CH_ERR_TL1_EXIT; 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate /* 4107c478bd9Sstevel@tonic-gate * Establish panic exit label. 4117c478bd9Sstevel@tonic-gate */ 4127c478bd9Sstevel@tonic-gate CH_ERR_TL1_PANIC_EXIT(fecc_tl1_err); 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate SET_SIZE(fast_ecc_tl1_err) 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate#endif /* lint */ 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate#if defined(lint) 4207c478bd9Sstevel@tonic-gate/* 4217c478bd9Sstevel@tonic-gate * scrubphys - Pass in the aligned physical memory address 4227c478bd9Sstevel@tonic-gate * that you want to scrub, along with the ecache set size. 4237c478bd9Sstevel@tonic-gate * 4247c478bd9Sstevel@tonic-gate * 1) Displacement flush the E$ line corresponding to %addr. 4257c478bd9Sstevel@tonic-gate * The first ldxa guarantees that the %addr is no longer in 4267c478bd9Sstevel@tonic-gate * M, O, or E (goes to I or S (if instruction fetch also happens). 4277c478bd9Sstevel@tonic-gate * 2) "Write" the data using a CAS %addr,%g0,%g0. 4287c478bd9Sstevel@tonic-gate * The casxa guarantees a transition from I to M or S to M. 4297c478bd9Sstevel@tonic-gate * 3) Displacement flush the E$ line corresponding to %addr. 4307c478bd9Sstevel@tonic-gate * The second ldxa pushes the M line out of the ecache, into the 4317c478bd9Sstevel@tonic-gate * writeback buffers, on the way to memory. 4327c478bd9Sstevel@tonic-gate * 4) The "membar #Sync" pushes the cache line out of the writeback 4337c478bd9Sstevel@tonic-gate * buffers onto the bus, on the way to dram finally. 4347c478bd9Sstevel@tonic-gate * 4357c478bd9Sstevel@tonic-gate * This is a modified version of the algorithm suggested by Gary Lauterbach. 4367c478bd9Sstevel@tonic-gate * In theory the CAS %addr,%g0,%g0 is supposed to mark the addr's cache line 4377c478bd9Sstevel@tonic-gate * as modified, but then we found out that for spitfire, if it misses in the 4387c478bd9Sstevel@tonic-gate * E$ it will probably install as an M, but if it hits in the E$, then it 4397c478bd9Sstevel@tonic-gate * will stay E, if the store doesn't happen. So the first displacement flush 4407c478bd9Sstevel@tonic-gate * should ensure that the CAS will miss in the E$. Arrgh. 4417c478bd9Sstevel@tonic-gate */ 4427c478bd9Sstevel@tonic-gate/* ARGSUSED */ 4437c478bd9Sstevel@tonic-gatevoid 4447c478bd9Sstevel@tonic-gatescrubphys(uint64_t paddr, int ecache_set_size) 4457c478bd9Sstevel@tonic-gate{} 4467c478bd9Sstevel@tonic-gate 4477c478bd9Sstevel@tonic-gate#else /* lint */ 4487c478bd9Sstevel@tonic-gate ENTRY(scrubphys) 4497c478bd9Sstevel@tonic-gate rdpr %pstate, %o4 4507c478bd9Sstevel@tonic-gate andn %o4, PSTATE_IE | PSTATE_AM, %o5 4517c478bd9Sstevel@tonic-gate wrpr %o5, %g0, %pstate ! clear IE, AM bits 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate GET_CPU_IMPL(%o5) ! Panther Ecache is flushed differently 4547c478bd9Sstevel@tonic-gate cmp %o5, PANTHER_IMPL 4557c478bd9Sstevel@tonic-gate bne scrubphys_1 4567c478bd9Sstevel@tonic-gate nop 4577c478bd9Sstevel@tonic-gate PN_ECACHE_FLUSH_LINE(%o0, %o1, %o2, %o3, %o5) 4587c478bd9Sstevel@tonic-gate casxa [%o0]ASI_MEM, %g0, %g0 4597c478bd9Sstevel@tonic-gate PN_ECACHE_REFLUSH_LINE(%o1, %o2, %o3, %o0) 4607c478bd9Sstevel@tonic-gate b scrubphys_2 4617c478bd9Sstevel@tonic-gate nop 4627c478bd9Sstevel@tonic-gatescrubphys_1: 4637c478bd9Sstevel@tonic-gate ECACHE_FLUSH_LINE(%o0, %o1, %o2, %o3) 4647c478bd9Sstevel@tonic-gate casxa [%o0]ASI_MEM, %g0, %g0 4657c478bd9Sstevel@tonic-gate ECACHE_REFLUSH_LINE(%o1, %o2, %o3) 4667c478bd9Sstevel@tonic-gatescrubphys_2: 4677c478bd9Sstevel@tonic-gate wrpr %g0, %o4, %pstate ! restore earlier pstate register value 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate retl 4707c478bd9Sstevel@tonic-gate membar #Sync ! move the data out of the load buffer 4717c478bd9Sstevel@tonic-gate SET_SIZE(scrubphys) 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate#endif /* lint */ 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate#if defined(lint) 4777c478bd9Sstevel@tonic-gate/* 478750ba224Sanbui * clearphys - Pass in the physical memory address of the checkblock 479750ba224Sanbui * that you want to push out, cleared with a recognizable pattern, 480750ba224Sanbui * from the ecache. 481750ba224Sanbui * 482750ba224Sanbui * To ensure that the ecc gets recalculated after the bad data is cleared, 483750ba224Sanbui * we must write out enough data to fill the w$ line (64 bytes). So we read 484750ba224Sanbui * in an entire ecache subblock's worth of data, and write it back out. 485750ba224Sanbui * Then we overwrite the 16 bytes of bad data with the pattern. 4867c478bd9Sstevel@tonic-gate */ 4877c478bd9Sstevel@tonic-gate/* ARGSUSED */ 4887c478bd9Sstevel@tonic-gatevoid 4897c478bd9Sstevel@tonic-gateclearphys(uint64_t paddr, int ecache_set_size, int ecache_linesize) 4907c478bd9Sstevel@tonic-gate{ 4917c478bd9Sstevel@tonic-gate} 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate#else /* lint */ 4947c478bd9Sstevel@tonic-gate ENTRY(clearphys) 4957c478bd9Sstevel@tonic-gate /* turn off IE, AM bits */ 4967c478bd9Sstevel@tonic-gate rdpr %pstate, %o4 4977c478bd9Sstevel@tonic-gate andn %o4, PSTATE_IE | PSTATE_AM, %o5 4987c478bd9Sstevel@tonic-gate wrpr %o5, %g0, %pstate 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate /* turn off NCEEN */ 5017c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_ESTATE_ERR, %o5 5027c478bd9Sstevel@tonic-gate andn %o5, EN_REG_NCEEN, %o3 5037c478bd9Sstevel@tonic-gate stxa %o3, [%g0]ASI_ESTATE_ERR 5047c478bd9Sstevel@tonic-gate membar #Sync 5057c478bd9Sstevel@tonic-gate 506750ba224Sanbui /* align address passed with 64 bytes subblock size */ 507750ba224Sanbui mov CH_ECACHE_SUBBLK_SIZE, %o2 508750ba224Sanbui andn %o0, (CH_ECACHE_SUBBLK_SIZE - 1), %g1 509750ba224Sanbui 510750ba224Sanbui /* move the good data into the W$ */ 5117c478bd9Sstevel@tonic-gateclearphys_1: 5127c478bd9Sstevel@tonic-gate subcc %o2, 8, %o2 513750ba224Sanbui ldxa [%g1 + %o2]ASI_MEM, %g2 5147c478bd9Sstevel@tonic-gate bge clearphys_1 515750ba224Sanbui stxa %g2, [%g1 + %o2]ASI_MEM 516750ba224Sanbui 517750ba224Sanbui /* now overwrite the bad data */ 518750ba224Sanbui setx 0xbadecc00badecc01, %g1, %g2 519750ba224Sanbui stxa %g2, [%o0]ASI_MEM 520750ba224Sanbui mov 8, %g1 521750ba224Sanbui stxa %g2, [%o0 + %g1]ASI_MEM 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate GET_CPU_IMPL(%o3) ! Panther Ecache is flushed differently 5247c478bd9Sstevel@tonic-gate cmp %o3, PANTHER_IMPL 5257c478bd9Sstevel@tonic-gate bne clearphys_2 5267c478bd9Sstevel@tonic-gate nop 5277c478bd9Sstevel@tonic-gate PN_ECACHE_FLUSH_LINE(%o0, %o1, %o2, %o3, %g1) 5287c478bd9Sstevel@tonic-gate casxa [%o0]ASI_MEM, %g0, %g0 5297c478bd9Sstevel@tonic-gate PN_ECACHE_REFLUSH_LINE(%o1, %o2, %o3, %o0) 5307c478bd9Sstevel@tonic-gate b clearphys_3 5317c478bd9Sstevel@tonic-gate nop 5327c478bd9Sstevel@tonic-gateclearphys_2: 5337c478bd9Sstevel@tonic-gate ECACHE_FLUSH_LINE(%o0, %o1, %o2, %o3) 5347c478bd9Sstevel@tonic-gate casxa [%o0]ASI_MEM, %g0, %g0 5357c478bd9Sstevel@tonic-gate ECACHE_REFLUSH_LINE(%o1, %o2, %o3) 5367c478bd9Sstevel@tonic-gateclearphys_3: 5377c478bd9Sstevel@tonic-gate /* clear the AFSR */ 5387c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_AFSR, %o1 5397c478bd9Sstevel@tonic-gate stxa %o1, [%g0]ASI_AFSR 5407c478bd9Sstevel@tonic-gate membar #Sync 5417c478bd9Sstevel@tonic-gate 5427c478bd9Sstevel@tonic-gate /* turn NCEEN back on */ 5437c478bd9Sstevel@tonic-gate stxa %o5, [%g0]ASI_ESTATE_ERR 5447c478bd9Sstevel@tonic-gate membar #Sync 5457c478bd9Sstevel@tonic-gate 5467c478bd9Sstevel@tonic-gate /* return and re-enable IE and AM */ 5477c478bd9Sstevel@tonic-gate retl 5487c478bd9Sstevel@tonic-gate wrpr %g0, %o4, %pstate 5497c478bd9Sstevel@tonic-gate SET_SIZE(clearphys) 5507c478bd9Sstevel@tonic-gate 5517c478bd9Sstevel@tonic-gate#endif /* lint */ 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate#if defined(lint) 5557c478bd9Sstevel@tonic-gate/* 5567c478bd9Sstevel@tonic-gate * Cheetah+ Ecache displacement flush the specified line from the E$ 5577c478bd9Sstevel@tonic-gate * 5587c478bd9Sstevel@tonic-gate * For Panther, this means flushing the specified line from both the 5597c478bd9Sstevel@tonic-gate * L2 cache and L3 cache. 5607c478bd9Sstevel@tonic-gate * 5617c478bd9Sstevel@tonic-gate * Register usage: 5627c478bd9Sstevel@tonic-gate * %o0 - 64 bit physical address for flushing 5637c478bd9Sstevel@tonic-gate * %o1 - Ecache set size 5647c478bd9Sstevel@tonic-gate */ 5657c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 5667c478bd9Sstevel@tonic-gatevoid 5677c478bd9Sstevel@tonic-gateecache_flush_line(uint64_t flushaddr, int ec_set_size) 5687c478bd9Sstevel@tonic-gate{ 5697c478bd9Sstevel@tonic-gate} 5707c478bd9Sstevel@tonic-gate#else /* lint */ 5717c478bd9Sstevel@tonic-gate ENTRY(ecache_flush_line) 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate GET_CPU_IMPL(%o3) ! Panther Ecache is flushed differently 5747c478bd9Sstevel@tonic-gate cmp %o3, PANTHER_IMPL 5757c478bd9Sstevel@tonic-gate bne ecache_flush_line_1 5767c478bd9Sstevel@tonic-gate nop 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate PN_ECACHE_FLUSH_LINE(%o0, %o1, %o2, %o3, %o4) 5797c478bd9Sstevel@tonic-gate b ecache_flush_line_2 5807c478bd9Sstevel@tonic-gate nop 5817c478bd9Sstevel@tonic-gateecache_flush_line_1: 5827c478bd9Sstevel@tonic-gate ECACHE_FLUSH_LINE(%o0, %o1, %o2, %o3) 5837c478bd9Sstevel@tonic-gateecache_flush_line_2: 5847c478bd9Sstevel@tonic-gate retl 5857c478bd9Sstevel@tonic-gate nop 5867c478bd9Sstevel@tonic-gate SET_SIZE(ecache_flush_line) 5877c478bd9Sstevel@tonic-gate#endif /* lint */ 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate#if defined(lint) 5907c478bd9Sstevel@tonic-gatevoid 5917c478bd9Sstevel@tonic-gateset_afsr_ext(uint64_t afsr_ext) 5927c478bd9Sstevel@tonic-gate{ 5937c478bd9Sstevel@tonic-gate afsr_ext = afsr_ext; 5947c478bd9Sstevel@tonic-gate} 5957c478bd9Sstevel@tonic-gate#else /* lint */ 5967c478bd9Sstevel@tonic-gate 5977c478bd9Sstevel@tonic-gate ENTRY(set_afsr_ext) 5987c478bd9Sstevel@tonic-gate set ASI_AFSR_EXT_VA, %o1 5997c478bd9Sstevel@tonic-gate stxa %o0, [%o1]ASI_AFSR ! afsr_ext reg 6007c478bd9Sstevel@tonic-gate membar #Sync 6017c478bd9Sstevel@tonic-gate retl 6027c478bd9Sstevel@tonic-gate nop 6037c478bd9Sstevel@tonic-gate SET_SIZE(set_afsr_ext) 6047c478bd9Sstevel@tonic-gate 6057c478bd9Sstevel@tonic-gate#endif /* lint */ 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate 6087c478bd9Sstevel@tonic-gate#if defined(lint) 6097c478bd9Sstevel@tonic-gate/* 6107c478bd9Sstevel@tonic-gate * The CPU jumps here from the MMU exception handler if an ITLB parity 6117c478bd9Sstevel@tonic-gate * error is detected and we are running on Panther. 6127c478bd9Sstevel@tonic-gate * 6137c478bd9Sstevel@tonic-gate * In this routine we collect diagnostic information and write it to our 6147c478bd9Sstevel@tonic-gate * logout structure (if possible) and clear all ITLB entries that may have 6157c478bd9Sstevel@tonic-gate * caused our parity trap. 6167c478bd9Sstevel@tonic-gate * Then we call cpu_tlb_parity_error via systrap in order to drop down to TL0 6177c478bd9Sstevel@tonic-gate * and log any error messages. As for parameters to cpu_tlb_parity_error, we 6187c478bd9Sstevel@tonic-gate * send two: 6197c478bd9Sstevel@tonic-gate * 6207c478bd9Sstevel@tonic-gate * %g2 - Contains the VA whose lookup in the ITLB caused the parity error 6217c478bd9Sstevel@tonic-gate * %g3 - Contains the tlo_info field of the pn_tlb_logout logout struct, 6227c478bd9Sstevel@tonic-gate * regardless of whether or not we actually used the logout struct. 6237c478bd9Sstevel@tonic-gate * 6247c478bd9Sstevel@tonic-gate * In the TL0 handler (cpu_tlb_parity_error) we will compare those two 6257c478bd9Sstevel@tonic-gate * parameters to the data contained in the logout structure in order to 6267c478bd9Sstevel@tonic-gate * determine whether the logout information is valid for this particular 6277c478bd9Sstevel@tonic-gate * error or not. 6287c478bd9Sstevel@tonic-gate */ 6297c478bd9Sstevel@tonic-gatevoid 6307c478bd9Sstevel@tonic-gateitlb_parity_trap(void) 6317c478bd9Sstevel@tonic-gate{} 6327c478bd9Sstevel@tonic-gate 6337c478bd9Sstevel@tonic-gate#else /* lint */ 6347c478bd9Sstevel@tonic-gate 6357c478bd9Sstevel@tonic-gate ENTRY_NP(itlb_parity_trap) 6367c478bd9Sstevel@tonic-gate /* 6377c478bd9Sstevel@tonic-gate * Collect important information about the trap which will be 6387c478bd9Sstevel@tonic-gate * used as a parameter to the TL0 handler. 6397c478bd9Sstevel@tonic-gate */ 6407c478bd9Sstevel@tonic-gate wr %g0, ASI_IMMU, %asi 6417c478bd9Sstevel@tonic-gate rdpr %tpc, %g2 ! VA that caused the IMMU trap 6427c478bd9Sstevel@tonic-gate ldxa [MMU_TAG_ACCESS_EXT]%asi, %g3 ! read the trap VA page size 6437c478bd9Sstevel@tonic-gate set PN_ITLB_PGSZ_MASK, %g4 6447c478bd9Sstevel@tonic-gate and %g3, %g4, %g3 6457c478bd9Sstevel@tonic-gate ldxa [MMU_TAG_ACCESS]%asi, %g4 6467c478bd9Sstevel@tonic-gate set TAGREAD_CTX_MASK, %g5 6477c478bd9Sstevel@tonic-gate and %g4, %g5, %g4 6487c478bd9Sstevel@tonic-gate or %g4, %g3, %g3 ! 'or' in the trap context and 6497c478bd9Sstevel@tonic-gate mov 1, %g4 ! add the IMMU flag to complete 6507c478bd9Sstevel@tonic-gate sllx %g4, PN_TLO_INFO_IMMU_SHIFT, %g4 6517c478bd9Sstevel@tonic-gate or %g4, %g3, %g3 ! the tlo_info field for logout 6527c478bd9Sstevel@tonic-gate stxa %g0,[MMU_SFSR]%asi ! clear the SFSR 6537c478bd9Sstevel@tonic-gate membar #Sync 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate /* 6567c478bd9Sstevel@tonic-gate * at this point: 6577c478bd9Sstevel@tonic-gate * %g2 - contains the VA whose lookup caused the trap 6587c478bd9Sstevel@tonic-gate * %g3 - contains the tlo_info field 6597c478bd9Sstevel@tonic-gate * 6607c478bd9Sstevel@tonic-gate * Next, we calculate the TLB index value for the failing VA. 6617c478bd9Sstevel@tonic-gate */ 6627c478bd9Sstevel@tonic-gate mov %g2, %g4 ! We need the ITLB index 6637c478bd9Sstevel@tonic-gate set PN_ITLB_PGSZ_MASK, %g5 6647c478bd9Sstevel@tonic-gate and %g3, %g5, %g5 6657c478bd9Sstevel@tonic-gate srlx %g5, PN_ITLB_PGSZ_SHIFT, %g5 6667c478bd9Sstevel@tonic-gate PN_GET_TLB_INDEX(%g4, %g5) ! %g4 has the index 6677c478bd9Sstevel@tonic-gate sllx %g4, PN_TLB_ACC_IDX_SHIFT, %g4 ! shift the index into place 6687c478bd9Sstevel@tonic-gate set PN_ITLB_T512, %g5 6697c478bd9Sstevel@tonic-gate or %g4, %g5, %g4 ! and add in the TLB ID 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate /* 6727c478bd9Sstevel@tonic-gate * at this point: 6737c478bd9Sstevel@tonic-gate * %g2 - contains the VA whose lookup caused the trap 6747c478bd9Sstevel@tonic-gate * %g3 - contains the tlo_info field 6757c478bd9Sstevel@tonic-gate * %g4 - contains the TLB access index value for the 6767c478bd9Sstevel@tonic-gate * VA/PgSz in question 6777c478bd9Sstevel@tonic-gate * 6787c478bd9Sstevel@tonic-gate * Check to see if the logout structure is available. 6797c478bd9Sstevel@tonic-gate */ 6807c478bd9Sstevel@tonic-gate set CHPR_TLB_LOGOUT, %g6 6817c478bd9Sstevel@tonic-gate GET_CPU_PRIVATE_PTR(%g6, %g1, %g5, itlb_parity_trap_1) 6827c478bd9Sstevel@tonic-gate set LOGOUT_INVALID_U32, %g6 6837c478bd9Sstevel@tonic-gate sllx %g6, 32, %g6 ! if our logout structure is 6847c478bd9Sstevel@tonic-gate set LOGOUT_INVALID_L32, %g5 ! unavailable or if it is 6857c478bd9Sstevel@tonic-gate or %g5, %g6, %g5 ! already being used, then we 6867c478bd9Sstevel@tonic-gate ldx [%g1 + PN_TLO_ADDR], %g6 ! don't collect any diagnostic 6877c478bd9Sstevel@tonic-gate cmp %g6, %g5 ! information before clearing 6887c478bd9Sstevel@tonic-gate bne itlb_parity_trap_1 ! and logging the error. 6897c478bd9Sstevel@tonic-gate nop 6907c478bd9Sstevel@tonic-gate 6917c478bd9Sstevel@tonic-gate /* 6927c478bd9Sstevel@tonic-gate * Record the logout information. %g4 contains our index + TLB ID 6937c478bd9Sstevel@tonic-gate * for use in ASI_ITLB_ACCESS and ASI_ITLB_TAGREAD. %g1 contains 6947c478bd9Sstevel@tonic-gate * the pointer to our logout struct. 6957c478bd9Sstevel@tonic-gate */ 6967c478bd9Sstevel@tonic-gate stx %g3, [%g1 + PN_TLO_INFO] 6977c478bd9Sstevel@tonic-gate stx %g2, [%g1 + PN_TLO_ADDR] 6987c478bd9Sstevel@tonic-gate stx %g2, [%g1 + PN_TLO_PC] ! %tpc == fault addr for IMMU 6997c478bd9Sstevel@tonic-gate 7007c478bd9Sstevel@tonic-gate add %g1, PN_TLO_ITLB_TTE, %g1 ! move up the pointer 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_ITLB_ACCESS, %g5 ! read the data 7037c478bd9Sstevel@tonic-gate stx %g5, [%g1 + CH_TLO_TTE_DATA] ! store it away 7047c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_ITLB_TAGREAD, %g5 ! read the tag 7057c478bd9Sstevel@tonic-gate stx %g5, [%g1 + CH_TLO_TTE_TAG] ! store it away 7067c478bd9Sstevel@tonic-gate 7077c478bd9Sstevel@tonic-gate set PN_TLB_ACC_WAY_BIT, %g6 ! same thing again for way 1 7087c478bd9Sstevel@tonic-gate or %g4, %g6, %g4 7097c478bd9Sstevel@tonic-gate add %g1, CH_TLO_TTE_SIZE, %g1 ! move up the pointer 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_ITLB_ACCESS, %g5 ! read the data 7127c478bd9Sstevel@tonic-gate stx %g5, [%g1 + CH_TLO_TTE_DATA] ! store it away 7137c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_ITLB_TAGREAD, %g5 ! read the tag 7147c478bd9Sstevel@tonic-gate stx %g5, [%g1 + CH_TLO_TTE_TAG] ! store it away 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate andn %g4, %g6, %g4 ! back to way 0 7177c478bd9Sstevel@tonic-gate 7187c478bd9Sstevel@tonic-gateitlb_parity_trap_1: 7197c478bd9Sstevel@tonic-gate /* 7207c478bd9Sstevel@tonic-gate * at this point: 7217c478bd9Sstevel@tonic-gate * %g2 - contains the VA whose lookup caused the trap 7227c478bd9Sstevel@tonic-gate * %g3 - contains the tlo_info field 7237c478bd9Sstevel@tonic-gate * %g4 - contains the TLB access index value for the 7247c478bd9Sstevel@tonic-gate * VA/PgSz in question 7257c478bd9Sstevel@tonic-gate * 7267c478bd9Sstevel@tonic-gate * Here we will clear the errors from the TLB. 7277c478bd9Sstevel@tonic-gate */ 7287c478bd9Sstevel@tonic-gate set MMU_TAG_ACCESS, %g5 ! We write a TTE tag value of 7297c478bd9Sstevel@tonic-gate stxa %g0, [%g5]ASI_IMMU ! 0 as it will be invalid. 7307c478bd9Sstevel@tonic-gate stxa %g0, [%g4]ASI_ITLB_ACCESS ! Write the data and tag 7317c478bd9Sstevel@tonic-gate membar #Sync 7327c478bd9Sstevel@tonic-gate 7337c478bd9Sstevel@tonic-gate set PN_TLB_ACC_WAY_BIT, %g6 ! same thing again for way 1 7347c478bd9Sstevel@tonic-gate or %g4, %g6, %g4 7357c478bd9Sstevel@tonic-gate 7367c478bd9Sstevel@tonic-gate stxa %g0, [%g4]ASI_ITLB_ACCESS ! Write same data and tag 7377c478bd9Sstevel@tonic-gate membar #Sync 7387c478bd9Sstevel@tonic-gate 7397c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %g6 ! PRM says we need to issue a 7407c478bd9Sstevel@tonic-gate flush %g6 ! flush after writing MMU regs 7417c478bd9Sstevel@tonic-gate 7427c478bd9Sstevel@tonic-gate /* 7437c478bd9Sstevel@tonic-gate * at this point: 7447c478bd9Sstevel@tonic-gate * %g2 - contains the VA whose lookup caused the trap 7457c478bd9Sstevel@tonic-gate * %g3 - contains the tlo_info field 7467c478bd9Sstevel@tonic-gate * 7477c478bd9Sstevel@tonic-gate * Call cpu_tlb_parity_error via systrap at PIL 14 unless we're 7487c478bd9Sstevel@tonic-gate * already at PIL 15. */ 7497c478bd9Sstevel@tonic-gate set cpu_tlb_parity_error, %g1 7507c478bd9Sstevel@tonic-gate rdpr %pil, %g4 7517c478bd9Sstevel@tonic-gate cmp %g4, PIL_14 7527c478bd9Sstevel@tonic-gate movl %icc, PIL_14, %g4 7537c478bd9Sstevel@tonic-gate ba sys_trap 7547c478bd9Sstevel@tonic-gate nop 7557c478bd9Sstevel@tonic-gate SET_SIZE(itlb_parity_trap) 7567c478bd9Sstevel@tonic-gate 7577c478bd9Sstevel@tonic-gate#endif /* lint */ 7587c478bd9Sstevel@tonic-gate 7597c478bd9Sstevel@tonic-gate#if defined(lint) 7607c478bd9Sstevel@tonic-gate/* 7617c478bd9Sstevel@tonic-gate * The CPU jumps here from the MMU exception handler if a DTLB parity 7627c478bd9Sstevel@tonic-gate * error is detected and we are running on Panther. 7637c478bd9Sstevel@tonic-gate * 7647c478bd9Sstevel@tonic-gate * In this routine we collect diagnostic information and write it to our 7657c478bd9Sstevel@tonic-gate * logout structure (if possible) and clear all DTLB entries that may have 7667c478bd9Sstevel@tonic-gate * caused our parity trap. 7677c478bd9Sstevel@tonic-gate * Then we call cpu_tlb_parity_error via systrap in order to drop down to TL0 7687c478bd9Sstevel@tonic-gate * and log any error messages. As for parameters to cpu_tlb_parity_error, we 7697c478bd9Sstevel@tonic-gate * send two: 7707c478bd9Sstevel@tonic-gate * 7717c478bd9Sstevel@tonic-gate * %g2 - Contains the VA whose lookup in the DTLB caused the parity error 7727c478bd9Sstevel@tonic-gate * %g3 - Contains the tlo_info field of the pn_tlb_logout logout struct, 7737c478bd9Sstevel@tonic-gate * regardless of whether or not we actually used the logout struct. 7747c478bd9Sstevel@tonic-gate * 7757c478bd9Sstevel@tonic-gate * In the TL0 handler (cpu_tlb_parity_error) we will compare those two 7767c478bd9Sstevel@tonic-gate * parameters to the data contained in the logout structure in order to 7777c478bd9Sstevel@tonic-gate * determine whether the logout information is valid for this particular 7787c478bd9Sstevel@tonic-gate * error or not. 7797c478bd9Sstevel@tonic-gate */ 7807c478bd9Sstevel@tonic-gatevoid 7817c478bd9Sstevel@tonic-gatedtlb_parity_trap(void) 7827c478bd9Sstevel@tonic-gate{} 7837c478bd9Sstevel@tonic-gate 7847c478bd9Sstevel@tonic-gate#else /* lint */ 7857c478bd9Sstevel@tonic-gate 7867c478bd9Sstevel@tonic-gate ENTRY_NP(dtlb_parity_trap) 7877c478bd9Sstevel@tonic-gate /* 7887c478bd9Sstevel@tonic-gate * Collect important information about the trap which will be 7897c478bd9Sstevel@tonic-gate * used as a parameter to the TL0 handler. 7907c478bd9Sstevel@tonic-gate */ 7917c478bd9Sstevel@tonic-gate wr %g0, ASI_DMMU, %asi 7927c478bd9Sstevel@tonic-gate ldxa [MMU_SFAR]%asi, %g2 ! VA that caused the IMMU trap 7937c478bd9Sstevel@tonic-gate ldxa [MMU_TAG_ACCESS_EXT]%asi, %g3 ! read the trap VA page sizes 7947c478bd9Sstevel@tonic-gate set PN_DTLB_PGSZ_MASK, %g4 7957c478bd9Sstevel@tonic-gate and %g3, %g4, %g3 7967c478bd9Sstevel@tonic-gate ldxa [MMU_TAG_ACCESS]%asi, %g4 7977c478bd9Sstevel@tonic-gate set TAGREAD_CTX_MASK, %g5 ! 'or' in the trap context 7987c478bd9Sstevel@tonic-gate and %g4, %g5, %g4 ! to complete the tlo_info 7997c478bd9Sstevel@tonic-gate or %g4, %g3, %g3 ! field for logout 8007c478bd9Sstevel@tonic-gate stxa %g0,[MMU_SFSR]%asi ! clear the SFSR 8017c478bd9Sstevel@tonic-gate membar #Sync 8027c478bd9Sstevel@tonic-gate 8037c478bd9Sstevel@tonic-gate /* 8047c478bd9Sstevel@tonic-gate * at this point: 8057c478bd9Sstevel@tonic-gate * %g2 - contains the VA whose lookup caused the trap 8067c478bd9Sstevel@tonic-gate * %g3 - contains the tlo_info field 8077c478bd9Sstevel@tonic-gate * 8087c478bd9Sstevel@tonic-gate * Calculate the TLB index values for the failing VA. Since the T512 8097c478bd9Sstevel@tonic-gate * TLBs can be configured for different page sizes, we need to find 8107c478bd9Sstevel@tonic-gate * the index into each one separately. 8117c478bd9Sstevel@tonic-gate */ 8127c478bd9Sstevel@tonic-gate mov %g2, %g4 ! First we get the DTLB_0 index 8137c478bd9Sstevel@tonic-gate set PN_DTLB_PGSZ0_MASK, %g5 8147c478bd9Sstevel@tonic-gate and %g3, %g5, %g5 8157c478bd9Sstevel@tonic-gate srlx %g5, PN_DTLB_PGSZ0_SHIFT, %g5 8167c478bd9Sstevel@tonic-gate PN_GET_TLB_INDEX(%g4, %g5) ! %g4 has the DTLB_0 index 8177c478bd9Sstevel@tonic-gate sllx %g4, PN_TLB_ACC_IDX_SHIFT, %g4 ! shift the index into place 8187c478bd9Sstevel@tonic-gate set PN_DTLB_T512_0, %g5 8197c478bd9Sstevel@tonic-gate or %g4, %g5, %g4 ! and add in the TLB ID 8207c478bd9Sstevel@tonic-gate 8217c478bd9Sstevel@tonic-gate mov %g2, %g7 ! Next we get the DTLB_1 index 8227c478bd9Sstevel@tonic-gate set PN_DTLB_PGSZ1_MASK, %g5 8237c478bd9Sstevel@tonic-gate and %g3, %g5, %g5 8247c478bd9Sstevel@tonic-gate srlx %g5, PN_DTLB_PGSZ1_SHIFT, %g5 8257c478bd9Sstevel@tonic-gate PN_GET_TLB_INDEX(%g7, %g5) ! %g7 has the DTLB_1 index 8267c478bd9Sstevel@tonic-gate sllx %g7, PN_TLB_ACC_IDX_SHIFT, %g7 ! shift the index into place 8277c478bd9Sstevel@tonic-gate set PN_DTLB_T512_1, %g5 8287c478bd9Sstevel@tonic-gate or %g7, %g5, %g7 ! and add in the TLB ID 8297c478bd9Sstevel@tonic-gate 8307c478bd9Sstevel@tonic-gate /* 8317c478bd9Sstevel@tonic-gate * at this point: 8327c478bd9Sstevel@tonic-gate * %g2 - contains the VA whose lookup caused the trap 8337c478bd9Sstevel@tonic-gate * %g3 - contains the tlo_info field 8347c478bd9Sstevel@tonic-gate * %g4 - contains the T512_0 access index value for the 8357c478bd9Sstevel@tonic-gate * VA/PgSz in question 8367c478bd9Sstevel@tonic-gate * %g7 - contains the T512_1 access index value for the 8377c478bd9Sstevel@tonic-gate * VA/PgSz in question 8387c478bd9Sstevel@tonic-gate * 8397c478bd9Sstevel@tonic-gate * If this trap happened at TL>0, then we don't want to mess 8407c478bd9Sstevel@tonic-gate * with the normal logout struct since that could caused a TLB 8417c478bd9Sstevel@tonic-gate * miss. 8427c478bd9Sstevel@tonic-gate */ 8437c478bd9Sstevel@tonic-gate rdpr %tl, %g6 ! read current trap level 8447c478bd9Sstevel@tonic-gate cmp %g6, 1 ! skip over the tl>1 code 8457c478bd9Sstevel@tonic-gate ble dtlb_parity_trap_1 ! if TL <= 1. 8467c478bd9Sstevel@tonic-gate nop 8477c478bd9Sstevel@tonic-gate 8487c478bd9Sstevel@tonic-gate /* 8497c478bd9Sstevel@tonic-gate * If we are here, then the trap happened at TL>1. Simply 8507c478bd9Sstevel@tonic-gate * update our tlo_info field and then skip to the TLB flush 8517c478bd9Sstevel@tonic-gate * code. 8527c478bd9Sstevel@tonic-gate */ 8537c478bd9Sstevel@tonic-gate mov 1, %g6 8547c478bd9Sstevel@tonic-gate sllx %g6, PN_TLO_INFO_TL1_SHIFT, %g6 8557c478bd9Sstevel@tonic-gate or %g6, %g3, %g3 8567c478bd9Sstevel@tonic-gate ba dtlb_parity_trap_2 8577c478bd9Sstevel@tonic-gate nop 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gatedtlb_parity_trap_1: 8607c478bd9Sstevel@tonic-gate /* 8617c478bd9Sstevel@tonic-gate * at this point: 8627c478bd9Sstevel@tonic-gate * %g2 - contains the VA whose lookup caused the trap 8637c478bd9Sstevel@tonic-gate * %g3 - contains the tlo_info field 8647c478bd9Sstevel@tonic-gate * %g4 - contains the T512_0 access index value for the 8657c478bd9Sstevel@tonic-gate * VA/PgSz in question 8667c478bd9Sstevel@tonic-gate * %g7 - contains the T512_1 access index value for the 8677c478bd9Sstevel@tonic-gate * VA/PgSz in question 8687c478bd9Sstevel@tonic-gate * 8697c478bd9Sstevel@tonic-gate * Check to see if the logout structure is available. 8707c478bd9Sstevel@tonic-gate */ 8717c478bd9Sstevel@tonic-gate set CHPR_TLB_LOGOUT, %g6 8727c478bd9Sstevel@tonic-gate GET_CPU_PRIVATE_PTR(%g6, %g1, %g5, dtlb_parity_trap_2) 8737c478bd9Sstevel@tonic-gate set LOGOUT_INVALID_U32, %g6 8747c478bd9Sstevel@tonic-gate sllx %g6, 32, %g6 ! if our logout structure is 8757c478bd9Sstevel@tonic-gate set LOGOUT_INVALID_L32, %g5 ! unavailable or if it is 8767c478bd9Sstevel@tonic-gate or %g5, %g6, %g5 ! already being used, then we 8777c478bd9Sstevel@tonic-gate ldx [%g1 + PN_TLO_ADDR], %g6 ! don't collect any diagnostic 8787c478bd9Sstevel@tonic-gate cmp %g6, %g5 ! information before clearing 8797c478bd9Sstevel@tonic-gate bne dtlb_parity_trap_2 ! and logging the error. 8807c478bd9Sstevel@tonic-gate nop 8817c478bd9Sstevel@tonic-gate 8827c478bd9Sstevel@tonic-gate /* 8837c478bd9Sstevel@tonic-gate * Record the logout information. %g4 contains our DTLB_0 8847c478bd9Sstevel@tonic-gate * index + TLB ID and %g7 contains our DTLB_1 index + TLB ID 8857c478bd9Sstevel@tonic-gate * both of which will be used for ASI_DTLB_ACCESS and 8867c478bd9Sstevel@tonic-gate * ASI_DTLB_TAGREAD. %g1 contains the pointer to our logout 8877c478bd9Sstevel@tonic-gate * struct. 8887c478bd9Sstevel@tonic-gate */ 8897c478bd9Sstevel@tonic-gate stx %g3, [%g1 + PN_TLO_INFO] 8907c478bd9Sstevel@tonic-gate stx %g2, [%g1 + PN_TLO_ADDR] 8917c478bd9Sstevel@tonic-gate rdpr %tpc, %g5 8927c478bd9Sstevel@tonic-gate stx %g5, [%g1 + PN_TLO_PC] 8937c478bd9Sstevel@tonic-gate 8947c478bd9Sstevel@tonic-gate add %g1, PN_TLO_DTLB_TTE, %g1 ! move up the pointer 8957c478bd9Sstevel@tonic-gate 8967c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_DTLB_ACCESS, %g5 ! read the data from DTLB_0 8977c478bd9Sstevel@tonic-gate stx %g5, [%g1 + CH_TLO_TTE_DATA] ! way 0 and store it away 8987c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_DTLB_TAGREAD, %g5 ! read the tag from DTLB_0 8997c478bd9Sstevel@tonic-gate stx %g5, [%g1 + CH_TLO_TTE_TAG] ! way 0 and store it away 9007c478bd9Sstevel@tonic-gate 9017c478bd9Sstevel@tonic-gate ldxa [%g7]ASI_DTLB_ACCESS, %g5 ! now repeat for DTLB_1 way 0 9027c478bd9Sstevel@tonic-gate stx %g5, [%g1 + (CH_TLO_TTE_DATA + (CH_TLO_TTE_SIZE * 2))] 9037c478bd9Sstevel@tonic-gate ldxa [%g7]ASI_DTLB_TAGREAD, %g5 9047c478bd9Sstevel@tonic-gate stx %g5, [%g1 + (CH_TLO_TTE_TAG + (CH_TLO_TTE_SIZE * 2))] 9057c478bd9Sstevel@tonic-gate 9067c478bd9Sstevel@tonic-gate set PN_TLB_ACC_WAY_BIT, %g6 ! same thing again for way 1 9077c478bd9Sstevel@tonic-gate or %g4, %g6, %g4 ! of each TLB. 9087c478bd9Sstevel@tonic-gate or %g7, %g6, %g7 9097c478bd9Sstevel@tonic-gate add %g1, CH_TLO_TTE_SIZE, %g1 ! move up the pointer 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_DTLB_ACCESS, %g5 ! read the data from DTLB_0 9127c478bd9Sstevel@tonic-gate stx %g5, [%g1 + CH_TLO_TTE_DATA] ! way 1 and store it away 9137c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_DTLB_TAGREAD, %g5 ! read the tag from DTLB_0 9147c478bd9Sstevel@tonic-gate stx %g5, [%g1 + CH_TLO_TTE_TAG] ! way 1 and store it away 9157c478bd9Sstevel@tonic-gate 9167c478bd9Sstevel@tonic-gate ldxa [%g7]ASI_DTLB_ACCESS, %g5 ! now repeat for DTLB_1 way 1 9177c478bd9Sstevel@tonic-gate stx %g5, [%g1 + (CH_TLO_TTE_DATA + (CH_TLO_TTE_SIZE * 2))] 9187c478bd9Sstevel@tonic-gate ldxa [%g7]ASI_DTLB_TAGREAD, %g5 9197c478bd9Sstevel@tonic-gate stx %g5, [%g1 + (CH_TLO_TTE_TAG + (CH_TLO_TTE_SIZE * 2))] 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate andn %g4, %g6, %g4 ! back to way 0 9227c478bd9Sstevel@tonic-gate andn %g7, %g6, %g7 ! back to way 0 9237c478bd9Sstevel@tonic-gate 9247c478bd9Sstevel@tonic-gatedtlb_parity_trap_2: 9257c478bd9Sstevel@tonic-gate /* 9267c478bd9Sstevel@tonic-gate * at this point: 9277c478bd9Sstevel@tonic-gate * %g2 - contains the VA whose lookup caused the trap 9287c478bd9Sstevel@tonic-gate * %g3 - contains the tlo_info field 9297c478bd9Sstevel@tonic-gate * %g4 - contains the T512_0 access index value for the 9307c478bd9Sstevel@tonic-gate * VA/PgSz in question 9317c478bd9Sstevel@tonic-gate * %g7 - contains the T512_1 access index value for the 9327c478bd9Sstevel@tonic-gate * VA/PgSz in question 9337c478bd9Sstevel@tonic-gate * 9347c478bd9Sstevel@tonic-gate * Here we will clear the errors from the DTLB. 9357c478bd9Sstevel@tonic-gate */ 9367c478bd9Sstevel@tonic-gate set MMU_TAG_ACCESS, %g5 ! We write a TTE tag value of 9377c478bd9Sstevel@tonic-gate stxa %g0, [%g5]ASI_DMMU ! 0 as it will be invalid. 9387c478bd9Sstevel@tonic-gate stxa %g0, [%g4]ASI_DTLB_ACCESS ! Write the data and tag. 9397c478bd9Sstevel@tonic-gate stxa %g0, [%g7]ASI_DTLB_ACCESS ! Now repeat for DTLB_1 way 0 9407c478bd9Sstevel@tonic-gate membar #Sync 9417c478bd9Sstevel@tonic-gate 9427c478bd9Sstevel@tonic-gate set PN_TLB_ACC_WAY_BIT, %g6 ! same thing again for way 1 9437c478bd9Sstevel@tonic-gate or %g4, %g6, %g4 9447c478bd9Sstevel@tonic-gate or %g7, %g6, %g7 9457c478bd9Sstevel@tonic-gate 9467c478bd9Sstevel@tonic-gate stxa %g0, [%g4]ASI_DTLB_ACCESS ! Write same data and tag. 9477c478bd9Sstevel@tonic-gate stxa %g0, [%g7]ASI_DTLB_ACCESS ! Now repeat for DTLB_1 way 0 9487c478bd9Sstevel@tonic-gate membar #Sync 9497c478bd9Sstevel@tonic-gate 9507c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %g6 ! PRM says we need to issue a 9517c478bd9Sstevel@tonic-gate flush %g6 ! flush after writing MMU regs 9527c478bd9Sstevel@tonic-gate 9537c478bd9Sstevel@tonic-gate /* 9547c478bd9Sstevel@tonic-gate * at this point: 9557c478bd9Sstevel@tonic-gate * %g2 - contains the VA whose lookup caused the trap 9567c478bd9Sstevel@tonic-gate * %g3 - contains the tlo_info field 9577c478bd9Sstevel@tonic-gate * 9587c478bd9Sstevel@tonic-gate * Call cpu_tlb_parity_error via systrap at PIL 14 unless we're 9597c478bd9Sstevel@tonic-gate * already at PIL 15. We do this even for TL>1 traps since 9607c478bd9Sstevel@tonic-gate * those will lead to a system panic. 9617c478bd9Sstevel@tonic-gate */ 9627c478bd9Sstevel@tonic-gate set cpu_tlb_parity_error, %g1 9637c478bd9Sstevel@tonic-gate rdpr %pil, %g4 9647c478bd9Sstevel@tonic-gate cmp %g4, PIL_14 9657c478bd9Sstevel@tonic-gate movl %icc, PIL_14, %g4 9667c478bd9Sstevel@tonic-gate ba sys_trap 9677c478bd9Sstevel@tonic-gate nop 9687c478bd9Sstevel@tonic-gate SET_SIZE(dtlb_parity_trap) 9697c478bd9Sstevel@tonic-gate 9707c478bd9Sstevel@tonic-gate#endif /* lint */ 9717c478bd9Sstevel@tonic-gate 9727c478bd9Sstevel@tonic-gate 9737c478bd9Sstevel@tonic-gate#if defined(lint) 9747c478bd9Sstevel@tonic-gate/* 9757c478bd9Sstevel@tonic-gate * Calculates the Panther TLB index based on a virtual address and page size 9767c478bd9Sstevel@tonic-gate * 9777c478bd9Sstevel@tonic-gate * Register usage: 9787c478bd9Sstevel@tonic-gate * %o0 - virtual address whose index we want 9797c478bd9Sstevel@tonic-gate * %o1 - Page Size of the TLB in question as encoded in the 9807c478bd9Sstevel@tonic-gate * ASI_[D|I]MMU_TAG_ACCESS_EXT register. 9817c478bd9Sstevel@tonic-gate */ 9827c478bd9Sstevel@tonic-gateuint64_t 9837c478bd9Sstevel@tonic-gatepn_get_tlb_index(uint64_t va, uint64_t pg_sz) 9847c478bd9Sstevel@tonic-gate{ 9857c478bd9Sstevel@tonic-gate return ((va + pg_sz)-(va + pg_sz)); 9867c478bd9Sstevel@tonic-gate} 9877c478bd9Sstevel@tonic-gate#else /* lint */ 9887c478bd9Sstevel@tonic-gate ENTRY(pn_get_tlb_index) 9897c478bd9Sstevel@tonic-gate 9907c478bd9Sstevel@tonic-gate PN_GET_TLB_INDEX(%o0, %o1) 9917c478bd9Sstevel@tonic-gate 9927c478bd9Sstevel@tonic-gate retl 9937c478bd9Sstevel@tonic-gate nop 9947c478bd9Sstevel@tonic-gate SET_SIZE(pn_get_tlb_index) 9957c478bd9Sstevel@tonic-gate#endif /* lint */ 9967c478bd9Sstevel@tonic-gate 9977c478bd9Sstevel@tonic-gate 9987c478bd9Sstevel@tonic-gate#if defined(lint) 9997c478bd9Sstevel@tonic-gate/* 10007c478bd9Sstevel@tonic-gate * For Panther CPUs we need to flush the IPB after any I$ or D$ 10017c478bd9Sstevel@tonic-gate * parity errors are detected. 10027c478bd9Sstevel@tonic-gate */ 10037c478bd9Sstevel@tonic-gatevoid 10047c478bd9Sstevel@tonic-gateflush_ipb(void) 10057c478bd9Sstevel@tonic-gate{ return; } 10067c478bd9Sstevel@tonic-gate 10077c478bd9Sstevel@tonic-gate#else /* lint */ 10087c478bd9Sstevel@tonic-gate 10097c478bd9Sstevel@tonic-gate ENTRY(flush_ipb) 10107c478bd9Sstevel@tonic-gate clr %o0 10117c478bd9Sstevel@tonic-gate 10127c478bd9Sstevel@tonic-gateflush_ipb_1: 10137c478bd9Sstevel@tonic-gate stxa %g0, [%o0]ASI_IPB_TAG 10147c478bd9Sstevel@tonic-gate membar #Sync 10157c478bd9Sstevel@tonic-gate cmp %o0, PN_IPB_TAG_ADDR_MAX 10167c478bd9Sstevel@tonic-gate blt flush_ipb_1 10177c478bd9Sstevel@tonic-gate add %o0, PN_IPB_TAG_ADDR_LINESIZE, %o0 10187c478bd9Sstevel@tonic-gate 10197c478bd9Sstevel@tonic-gate sethi %hi(FLUSH_ADDR), %o0 10207c478bd9Sstevel@tonic-gate flush %o0 10217c478bd9Sstevel@tonic-gate retl 10227c478bd9Sstevel@tonic-gate nop 10237c478bd9Sstevel@tonic-gate SET_SIZE(flush_ipb) 10247c478bd9Sstevel@tonic-gate 10257c478bd9Sstevel@tonic-gate#endif /* lint */ 10267bebe46cSjc25722 10277bebe46cSjc25722 1028