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 5b0fc0e77Sgovinda * Common Development and Distribution License (the "License"). 6b0fc0e77Sgovinda * 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/* 229d0d62adSJason Beloro * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate#if defined(lint) 277c478bd9Sstevel@tonic-gate#include <sys/types.h> 287c478bd9Sstevel@tonic-gate#include <sys/thread.h> 297c478bd9Sstevel@tonic-gate#else /* lint */ 307c478bd9Sstevel@tonic-gate#include "assym.h" 317c478bd9Sstevel@tonic-gate#endif /* lint */ 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 347c478bd9Sstevel@tonic-gate#include <sys/machthread.h> 357c478bd9Sstevel@tonic-gate#include <sys/machcpuvar.h> 367c478bd9Sstevel@tonic-gate#include <sys/intreg.h> 377c478bd9Sstevel@tonic-gate#include <sys/cmn_err.h> 387c478bd9Sstevel@tonic-gate#include <sys/ftrace.h> 397c478bd9Sstevel@tonic-gate#include <sys/machasi.h> 40ad559ebfSwh94709#include <sys/scb.h> 417c478bd9Sstevel@tonic-gate#include <sys/error.h> 4205d3dc4bSpaulsan#include <sys/mmu.h> 4305d3dc4bSpaulsan#include <vm/hat_sfmmu.h> 447c478bd9Sstevel@tonic-gate#define INTR_REPORT_SIZE 64 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 477c478bd9Sstevel@tonic-gate#include <sys/traptrace.h> 487c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */ 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate#if defined(lint) 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gatevoid 537c478bd9Sstevel@tonic-gatecpu_mondo(void) 547c478bd9Sstevel@tonic-gate{} 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate#else /* lint */ 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate/* 607c478bd9Sstevel@tonic-gate * (TT 0x7c, TL>0) CPU Mondo Queue Handler 617c478bd9Sstevel@tonic-gate * Globals are the Interrupt Globals. 627c478bd9Sstevel@tonic-gate */ 637c478bd9Sstevel@tonic-gate ENTRY_NP(cpu_mondo) 647c478bd9Sstevel@tonic-gate ! 657c478bd9Sstevel@tonic-gate ! Register Usage:- 667c478bd9Sstevel@tonic-gate ! %g5 PC for fasttrap TL>0 handler 677c478bd9Sstevel@tonic-gate ! %g1 arg 1 687c478bd9Sstevel@tonic-gate ! %g2 arg 2 697c478bd9Sstevel@tonic-gate ! %g3 queue base VA 707c478bd9Sstevel@tonic-gate ! %g4 queue size mask 717c478bd9Sstevel@tonic-gate ! %g6 head ptr 727c478bd9Sstevel@tonic-gate ! %g7 tail ptr 737c478bd9Sstevel@tonic-gate mov CPU_MONDO_Q_HD, %g3 747c478bd9Sstevel@tonic-gate ldxa [%g3]ASI_QUEUE, %g6 ! %g6 = head ptr 757c478bd9Sstevel@tonic-gate mov CPU_MONDO_Q_TL, %g4 767c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_QUEUE, %g7 ! %g7 = tail ptr 777c478bd9Sstevel@tonic-gate cmp %g6, %g7 7805d3dc4bSpaulsan be,pn %xcc, 3f ! head == tail 797c478bd9Sstevel@tonic-gate nop 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate CPU_ADDR(%g1,%g2) 827c478bd9Sstevel@tonic-gate add %g1, CPU_MCPU, %g2 837c478bd9Sstevel@tonic-gate ldx [%g2 + MCPU_CPU_Q_BASE], %g3 ! %g3 = queue base PA 847c478bd9Sstevel@tonic-gate ldx [%g2 + MCPU_CPU_Q_SIZE], %g4 ! queue size 857c478bd9Sstevel@tonic-gate sub %g4, 1, %g4 ! %g4 = queue size mask 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate ! Load interrupt receive data registers 1 and 2 to fetch 887c478bd9Sstevel@tonic-gate ! the arguments for the fast trap handler. 897c478bd9Sstevel@tonic-gate ! 907c478bd9Sstevel@tonic-gate ! XXX - Since the data words in the interrupt report are not defined yet 917c478bd9Sstevel@tonic-gate ! we assume that the consective words contain valid data and preserve 927c478bd9Sstevel@tonic-gate ! sun4u's xcall mondo arguments. 937c478bd9Sstevel@tonic-gate ! Register usage: 947c478bd9Sstevel@tonic-gate ! %g5 PC for fasttrap TL>0 handler 957c478bd9Sstevel@tonic-gate ! %g1 arg 1 967c478bd9Sstevel@tonic-gate ! %g2 arg 2 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate ldxa [%g3 + %g6]ASI_MEM, %g5 ! get PC from q base + head 997c478bd9Sstevel@tonic-gate add %g6, 0x8, %g6 ! inc head 1007c478bd9Sstevel@tonic-gate ldxa [%g3 + %g6]ASI_MEM, %g1 ! read data word 1 1017c478bd9Sstevel@tonic-gate add %g6, 0x8, %g6 ! inc head 1027c478bd9Sstevel@tonic-gate ldxa [%g3 + %g6]ASI_MEM, %g2 ! read data word 2 1037c478bd9Sstevel@tonic-gate add %g6, (INTR_REPORT_SIZE - 16) , %g6 ! inc head to next record 1047c478bd9Sstevel@tonic-gate and %g6, %g4, %g6 ! and size mask for wrap around 1057c478bd9Sstevel@tonic-gate mov CPU_MONDO_Q_HD, %g3 1067c478bd9Sstevel@tonic-gate stxa %g6, [%g3]ASI_QUEUE ! store head pointer 1077c478bd9Sstevel@tonic-gate membar #Sync 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 1107c478bd9Sstevel@tonic-gate TRACE_PTR(%g4, %g6) 111*023e71deSHaik Aftandilian GET_TRACE_TICK(%g6, %g3) 1127c478bd9Sstevel@tonic-gate stxa %g6, [%g4 + TRAP_ENT_TICK]%asi 1137c478bd9Sstevel@tonic-gate TRACE_SAVE_TL_GL_REGS(%g4, %g6) 1147c478bd9Sstevel@tonic-gate rdpr %tt, %g6 1157c478bd9Sstevel@tonic-gate stha %g6, [%g4 + TRAP_ENT_TT]%asi 1167c478bd9Sstevel@tonic-gate rdpr %tpc, %g6 1177c478bd9Sstevel@tonic-gate stna %g6, [%g4 + TRAP_ENT_TPC]%asi 1187c478bd9Sstevel@tonic-gate rdpr %tstate, %g6 1197c478bd9Sstevel@tonic-gate stxa %g6, [%g4 + TRAP_ENT_TSTATE]%asi 1207c478bd9Sstevel@tonic-gate stna %sp, [%g4 + TRAP_ENT_SP]%asi 1217c478bd9Sstevel@tonic-gate stna %g5, [%g4 + TRAP_ENT_TR]%asi ! pc of the TL>0 handler 1227c478bd9Sstevel@tonic-gate stna %g1, [%g4 + TRAP_ENT_F1]%asi ! arg1 1237c478bd9Sstevel@tonic-gate stna %g2, [%g4 + TRAP_ENT_F3]%asi ! arg2 1247c478bd9Sstevel@tonic-gate mov CPU_MONDO_Q_HD, %g6 1257c478bd9Sstevel@tonic-gate ldxa [%g6]ASI_QUEUE, %g6 ! new head offset 1267c478bd9Sstevel@tonic-gate stna %g6, [%g4 + TRAP_ENT_F2]%asi 1277c478bd9Sstevel@tonic-gate stna %g7, [%g4 + TRAP_ENT_F4]%asi ! tail offset 1287c478bd9Sstevel@tonic-gate TRACE_NEXT(%g4, %g6, %g3) 1297c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */ 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate /* 1327c478bd9Sstevel@tonic-gate * For now catch invalid PC being passed via cpu_mondo queue 1337c478bd9Sstevel@tonic-gate */ 1347c478bd9Sstevel@tonic-gate set KERNELBASE, %g4 1357c478bd9Sstevel@tonic-gate cmp %g5, %g4 13605d3dc4bSpaulsan bl,pn %xcc, 2f ! branch if bad %pc 1377c478bd9Sstevel@tonic-gate nop 1387c478bd9Sstevel@tonic-gate 13905d3dc4bSpaulsan 14005d3dc4bSpaulsan /* 14105d3dc4bSpaulsan * If this platform supports shared contexts and we are jumping 14205d3dc4bSpaulsan * to OBP code, then we need to invalidate both contexts to prevent OBP 14305d3dc4bSpaulsan * from corrupting the shared context registers. 14405d3dc4bSpaulsan * 14505d3dc4bSpaulsan * If shared contexts are not supported then the next two instructions 14605d3dc4bSpaulsan * will be patched with: 14705d3dc4bSpaulsan * 14805d3dc4bSpaulsan * jmp %g5 14905d3dc4bSpaulsan * nop 15005d3dc4bSpaulsan * 15105d3dc4bSpaulsan */ 15205d3dc4bSpaulsan .global sfmmu_shctx_cpu_mondo_patch 15305d3dc4bSpaulsansfmmu_shctx_cpu_mondo_patch: 15405d3dc4bSpaulsan set OFW_START_ADDR, %g4 ! Check if this a call into OBP? 15505d3dc4bSpaulsan cmp %g5, %g4 15605d3dc4bSpaulsan bl,pt %xcc, 1f 15705d3dc4bSpaulsan nop 15805d3dc4bSpaulsan set OFW_END_ADDR, %g4 15905d3dc4bSpaulsan cmp %g5, %g4 16005d3dc4bSpaulsan bg,pn %xcc, 1f 16105d3dc4bSpaulsan nop 16205d3dc4bSpaulsan mov MMU_PCONTEXT, %g3 16305d3dc4bSpaulsan ldxa [%g3]ASI_MMU_CTX, %g4 16405d3dc4bSpaulsan cmp %g4, INVALID_CONTEXT ! Check if we are in kernel mode 16505d3dc4bSpaulsan ble,pn %xcc, 1f ! or the primary context is invalid 16605d3dc4bSpaulsan nop 16705d3dc4bSpaulsan set INVALID_CONTEXT, %g4 ! Invalidate contexts - compatability 16805d3dc4bSpaulsan stxa %g4, [%g3]ASI_MMU_CTX ! mode ensures shared contexts are also 16905d3dc4bSpaulsan mov MMU_SCONTEXT, %g3 ! invalidated. 17005d3dc4bSpaulsan stxa %g4, [%g3]ASI_MMU_CTX 17105d3dc4bSpaulsan membar #Sync 17205d3dc4bSpaulsan mov %o0, %g3 ! save output regs 17305d3dc4bSpaulsan mov %o1, %g4 17405d3dc4bSpaulsan mov %o5, %g6 17505d3dc4bSpaulsan clr %o0 ! Invalidate tsbs, set ntsb = 0 17605d3dc4bSpaulsan clr %o1 ! and HV_TSB_INFO_PA = 0 17705d3dc4bSpaulsan mov MMU_TSB_CTXNON0, %o5 17805d3dc4bSpaulsan ta FAST_TRAP ! set TSB info for user process 17905d3dc4bSpaulsan brnz,a,pn %o0, ptl1_panic 18005d3dc4bSpaulsan mov PTL1_BAD_HCALL, %g1 18105d3dc4bSpaulsan mov %g3, %o0 ! restore output regs 18205d3dc4bSpaulsan mov %g4, %o1 18305d3dc4bSpaulsan mov %g6, %o5 18405d3dc4bSpaulsan1: 1857c478bd9Sstevel@tonic-gate jmp %g5 ! jump to traphandler 1867c478bd9Sstevel@tonic-gate nop 18705d3dc4bSpaulsan2: 1887c478bd9Sstevel@tonic-gate ! invalid trap handler, discard it for now 1897c478bd9Sstevel@tonic-gate set cpu_mondo_inval, %g4 1907c478bd9Sstevel@tonic-gate ldx [%g4], %g5 1917c478bd9Sstevel@tonic-gate inc %g5 1927c478bd9Sstevel@tonic-gate stx %g5, [%g4] 19305d3dc4bSpaulsan3: 1947c478bd9Sstevel@tonic-gate retry 1957c478bd9Sstevel@tonic-gate /* Never Reached */ 1967c478bd9Sstevel@tonic-gate SET_SIZE(cpu_mondo) 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate#endif /* lint */ 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate#if defined(lint) 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gatevoid 2037c478bd9Sstevel@tonic-gatedev_mondo(void) 2047c478bd9Sstevel@tonic-gate{} 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate#else /* lint */ 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate/* 2107c478bd9Sstevel@tonic-gate * (TT 0x7d, TL>0) Dev Mondo Queue Handler 2117c478bd9Sstevel@tonic-gate * Globals are the Interrupt Globals. 2127c478bd9Sstevel@tonic-gate * We only process one interrupt at a time causing us to keep 2137c478bd9Sstevel@tonic-gate * taking this trap till the queue is empty. 2147c478bd9Sstevel@tonic-gate * We really should drain the whole queue for better performance 2157c478bd9Sstevel@tonic-gate * but this will do for now. 2167c478bd9Sstevel@tonic-gate */ 2177c478bd9Sstevel@tonic-gate ENTRY_NP(dev_mondo) 2187c478bd9Sstevel@tonic-gate ! 2197c478bd9Sstevel@tonic-gate ! Register Usage:- 2207c478bd9Sstevel@tonic-gate ! %g5 PC for fasttrap TL>0 handler 2217c478bd9Sstevel@tonic-gate ! %g1 arg 1 2227c478bd9Sstevel@tonic-gate ! %g2 arg 2 2237c478bd9Sstevel@tonic-gate ! %g3 queue base PA 2247c478bd9Sstevel@tonic-gate ! %g4 queue size mask 2257c478bd9Sstevel@tonic-gate ! %g6 head ptr 2267c478bd9Sstevel@tonic-gate ! %g7 tail ptr 2277c478bd9Sstevel@tonic-gate mov DEV_MONDO_Q_HD, %g3 2287c478bd9Sstevel@tonic-gate ldxa [%g3]ASI_QUEUE, %g6 ! %g6 = head ptr 2297c478bd9Sstevel@tonic-gate mov DEV_MONDO_Q_TL, %g4 2307c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_QUEUE, %g7 ! %g7 = tail ptr 2317c478bd9Sstevel@tonic-gate cmp %g6, %g7 2327c478bd9Sstevel@tonic-gate be,pn %xcc, 0f ! head == tail 2337c478bd9Sstevel@tonic-gate nop 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate CPU_ADDR(%g1,%g2) 2367c478bd9Sstevel@tonic-gate add %g1, CPU_MCPU, %g2 2377c478bd9Sstevel@tonic-gate ldx [%g2 + MCPU_DEV_Q_BASE], %g3 ! %g3 = queue base PA 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate ! Register usage: 2407c478bd9Sstevel@tonic-gate ! %g5 - inum 2417c478bd9Sstevel@tonic-gate ! %g1 - cpu struct pointer used below in TRAPTRACE 2427c478bd9Sstevel@tonic-gate ! 2437c478bd9Sstevel@tonic-gate ldxa [%g3 + %g6]ASI_MEM, %g5 ! get inum from q base + head 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate ! 2467c478bd9Sstevel@tonic-gate ! We verify that inum is valid ( < MAXVNUM). If it is greater 247b0fc0e77Sgovinda ! than MAXVNUM, we let setvecint_tl1 take care of it. 2487c478bd9Sstevel@tonic-gate ! 2497c478bd9Sstevel@tonic-gate set MAXIVNUM, %g4 2507c478bd9Sstevel@tonic-gate cmp %g5, %g4 2517c478bd9Sstevel@tonic-gate bgeu,a,pn %xcc, 1f 2527c478bd9Sstevel@tonic-gate ldx [%g2 + MCPU_DEV_Q_SIZE], %g4 ! queue size - delay slot 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate ! 2557c478bd9Sstevel@tonic-gate ! Copy 64-byte payload to the *iv_payload if it is not NULL 2567c478bd9Sstevel@tonic-gate ! 257b0fc0e77Sgovinda set intr_vec_table, %g1 ! %g1 = intr_vec_table 258b0fc0e77Sgovinda sll %g5, CPTRSHIFT, %g7 ! %g7 = offset to inum entry 259b0fc0e77Sgovinda ! in the intr_vec_table 260b0fc0e77Sgovinda add %g1, %g7, %g7 ! %g7 = &intr_vec_table[inum] 261b0fc0e77Sgovinda ldn [%g7], %g1 ! %g1 = ptr to intr_vec_t (iv) 26225293bedSgovinda 26325293bedSgovinda ! 26425293bedSgovinda ! Verify the pointer to first intr_vec_t for a given inum and 26525293bedSgovinda ! it should not be NULL. If this pointer is NULL, then it is a 26625293bedSgovinda ! spurious interrupt. In this case, just call setvecint_tl1 and 26725293bedSgovinda ! it will handle this spurious interrupt. 26825293bedSgovinda ! 26925293bedSgovinda brz,a,pn %g1, 1f ! if %g1 is NULL 27025293bedSgovinda ldx [%g2 + MCPU_DEV_Q_SIZE], %g4 ! queue size - delay slot 27125293bedSgovinda 272b0fc0e77Sgovinda ldx [%g1 + IV_PAYLOAD_BUF], %g1 ! %g1 = iv->iv_payload_buf 2737c478bd9Sstevel@tonic-gate brz,a,pt %g1, 1f ! if it is NULL 2747c478bd9Sstevel@tonic-gate ldx [%g2 + MCPU_DEV_Q_SIZE], %g4 ! queue size - delay slot 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate ! 2777c478bd9Sstevel@tonic-gate ! Now move 64 byte payload from mondo queue to buf 2787c478bd9Sstevel@tonic-gate ! 2797c478bd9Sstevel@tonic-gate mov %g6, %g7 ! %g7 = head ptr 2807c478bd9Sstevel@tonic-gate ldxa [%g3 + %g7]ASI_MEM, %g4 2817c478bd9Sstevel@tonic-gate stx %g4, [%g1 + 0] ! byte 0 - 7 2827c478bd9Sstevel@tonic-gate add %g7, 8, %g7 2837c478bd9Sstevel@tonic-gate ldxa [%g3 + %g7]ASI_MEM, %g4 2847c478bd9Sstevel@tonic-gate stx %g4, [%g1 + 8] ! byte 8 - 15 2857c478bd9Sstevel@tonic-gate add %g7, 8, %g7 2867c478bd9Sstevel@tonic-gate ldxa [%g3 + %g7]ASI_MEM, %g4 2877c478bd9Sstevel@tonic-gate stx %g4, [%g1 + 16] ! byte 16 - 23 2887c478bd9Sstevel@tonic-gate add %g7, 8, %g7 2897c478bd9Sstevel@tonic-gate ldxa [%g3 + %g7]ASI_MEM, %g4 2907c478bd9Sstevel@tonic-gate stx %g4, [%g1 + 24] ! byte 24 - 31 2917c478bd9Sstevel@tonic-gate add %g7, 8, %g7 2927c478bd9Sstevel@tonic-gate ldxa [%g3 + %g7]ASI_MEM, %g4 2937c478bd9Sstevel@tonic-gate stx %g4, [%g1 + 32] ! byte 32 - 39 2947c478bd9Sstevel@tonic-gate add %g7, 8, %g7 2957c478bd9Sstevel@tonic-gate ldxa [%g3 + %g7]ASI_MEM, %g4 2967c478bd9Sstevel@tonic-gate stx %g4, [%g1 + 40] ! byte 40 - 47 2977c478bd9Sstevel@tonic-gate add %g7, 8, %g7 2987c478bd9Sstevel@tonic-gate ldxa [%g3 + %g7]ASI_MEM, %g4 2997c478bd9Sstevel@tonic-gate stx %g4, [%g1 + 48] ! byte 48 - 55 3007c478bd9Sstevel@tonic-gate add %g7, 8, %g7 3017c478bd9Sstevel@tonic-gate ldxa [%g3 + %g7]ASI_MEM, %g4 3027c478bd9Sstevel@tonic-gate stx %g4, [%g1 + 56] ! byte 56 - 63 3037c478bd9Sstevel@tonic-gate ldx [%g2 + MCPU_DEV_Q_SIZE], %g4 ! queue size 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate1: sub %g4, 1, %g4 ! %g4 = queue size mask 3067c478bd9Sstevel@tonic-gate add %g6, INTR_REPORT_SIZE , %g6 ! inc head to next record 3077c478bd9Sstevel@tonic-gate and %g6, %g4, %g6 ! and mask for wrap around 3087c478bd9Sstevel@tonic-gate mov DEV_MONDO_Q_HD, %g3 3097c478bd9Sstevel@tonic-gate stxa %g6, [%g3]ASI_QUEUE ! increment head offset 3107c478bd9Sstevel@tonic-gate membar #Sync 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE 3137c478bd9Sstevel@tonic-gate TRACE_PTR(%g4, %g6) 314*023e71deSHaik Aftandilian GET_TRACE_TICK(%g6, %g3) 3157c478bd9Sstevel@tonic-gate stxa %g6, [%g4 + TRAP_ENT_TICK]%asi 3167c478bd9Sstevel@tonic-gate TRACE_SAVE_TL_GL_REGS(%g4, %g6) 3177c478bd9Sstevel@tonic-gate rdpr %tt, %g6 3187c478bd9Sstevel@tonic-gate stha %g6, [%g4 + TRAP_ENT_TT]%asi 3197c478bd9Sstevel@tonic-gate rdpr %tpc, %g6 3207c478bd9Sstevel@tonic-gate stna %g6, [%g4 + TRAP_ENT_TPC]%asi 3217c478bd9Sstevel@tonic-gate rdpr %tstate, %g6 3227c478bd9Sstevel@tonic-gate stxa %g6, [%g4 + TRAP_ENT_TSTATE]%asi 3237c478bd9Sstevel@tonic-gate ! move head to sp 3247c478bd9Sstevel@tonic-gate ldx [%g2 + MCPU_DEV_Q_BASE], %g6 3257c478bd9Sstevel@tonic-gate stna %g6, [%g4 + TRAP_ENT_SP]%asi ! Device Queue Base PA 3267c478bd9Sstevel@tonic-gate stna %g5, [%g4 + TRAP_ENT_TR]%asi ! Inum 3277c478bd9Sstevel@tonic-gate mov DEV_MONDO_Q_HD, %g6 3287c478bd9Sstevel@tonic-gate ldxa [%g6]ASI_QUEUE, %g6 ! New head offset 3297c478bd9Sstevel@tonic-gate stna %g6, [%g4 + TRAP_ENT_F1]%asi 3307c478bd9Sstevel@tonic-gate ldx [%g2 + MCPU_DEV_Q_SIZE], %g6 3317c478bd9Sstevel@tonic-gate stna %g6, [%g4 + TRAP_ENT_F2]%asi ! Q Size 3327c478bd9Sstevel@tonic-gate stna %g7, [%g4 + TRAP_ENT_F3]%asi ! tail offset 3337c478bd9Sstevel@tonic-gate stna %g0, [%g4 + TRAP_ENT_F4]%asi 3347c478bd9Sstevel@tonic-gate TRACE_NEXT(%g4, %g6, %g3) 3357c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */ 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate ! 338b0fc0e77Sgovinda ! setvecint_tl1 will do all the work, and finish with a retry 3397c478bd9Sstevel@tonic-gate ! 340b0fc0e77Sgovinda ba,pt %xcc, setvecint_tl1 341b0fc0e77Sgovinda mov %g5, %g1 ! setvecint_tl1 expects inum in %g1 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate0: retry 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate /* Never Reached */ 3467c478bd9Sstevel@tonic-gate SET_SIZE(dev_mondo) 3477c478bd9Sstevel@tonic-gate#endif /* lint */ 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate#if defined(lint) 3507c478bd9Sstevel@tonic-gateuint64_t cpu_mondo_inval; 3517c478bd9Sstevel@tonic-gate#else /* lint */ 3527c478bd9Sstevel@tonic-gate .seg ".data" 3537c478bd9Sstevel@tonic-gate .global cpu_mondo_inval 3547c478bd9Sstevel@tonic-gate .align 8 3557c478bd9Sstevel@tonic-gatecpu_mondo_inval: 3567c478bd9Sstevel@tonic-gate .skip 8 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate .seg ".text" 3597c478bd9Sstevel@tonic-gate#endif /* lint */ 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate#if defined(lint) 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gatevoid 3657c478bd9Sstevel@tonic-gateresumable_error(void) 3667c478bd9Sstevel@tonic-gate{} 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate#else /* lint */ 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate/* 3717c478bd9Sstevel@tonic-gate * (TT 0x7e, TL>0) Resumeable Error Queue Handler 3727c478bd9Sstevel@tonic-gate * We keep a shadow copy of the queue in kernel buf. 3737c478bd9Sstevel@tonic-gate * Read the resumable queue head and tail offset 3747c478bd9Sstevel@tonic-gate * If there are entries on the queue, move them to 3757c478bd9Sstevel@tonic-gate * the kernel buf, which is next to the resumable 3767c478bd9Sstevel@tonic-gate * queue in the memory. Call C routine to process. 3777c478bd9Sstevel@tonic-gate */ 3787c478bd9Sstevel@tonic-gate ENTRY_NP(resumable_error) 3797c478bd9Sstevel@tonic-gate mov CPU_RQ_HD, %g4 3807c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_QUEUE, %g2 ! %g2 = Q head offset 3817c478bd9Sstevel@tonic-gate mov CPU_RQ_TL, %g4 3827c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_QUEUE, %g3 ! %g3 = Q tail offset 3837c478bd9Sstevel@tonic-gate mov %g2, %g6 ! save head in %g2 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate cmp %g6, %g3 3867c478bd9Sstevel@tonic-gate be,pn %xcc, 0f ! head == tail 3877c478bd9Sstevel@tonic-gate nop 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g4) ! %g1 = cpu struct addr 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate2: set CPU_RQ_BASE_OFF, %g4 3927c478bd9Sstevel@tonic-gate ldx [%g1 + %g4], %g4 ! %g4 = queue base PA 3937c478bd9Sstevel@tonic-gate add %g6, %g4, %g4 ! %g4 = PA of ER in Q 3947c478bd9Sstevel@tonic-gate set CPU_RQ_SIZE, %g7 3957c478bd9Sstevel@tonic-gate add %g4, %g7, %g7 ! %g7=PA of ER in kernel buf 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate ldxa [%g7]ASI_MEM, %g5 ! %g5=first 8 byte of ER buf 3987c478bd9Sstevel@tonic-gate cmp 0, %g5 3997c478bd9Sstevel@tonic-gate bne,pn %xcc, 1f ! first 8 byte is not 0 4007c478bd9Sstevel@tonic-gate nop 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate /* Now we can move 64 bytes from queue to buf */ 4037c478bd9Sstevel@tonic-gate set 0, %g5 4047c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 4057c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 0 - 7 4067c478bd9Sstevel@tonic-gate add %g5, 8, %g5 4077c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 4087c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 8 - 15 4097c478bd9Sstevel@tonic-gate add %g5, 8, %g5 4107c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 4117c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 16 - 23 4127c478bd9Sstevel@tonic-gate add %g5, 8, %g5 4137c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 4147c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 24 - 31 4157c478bd9Sstevel@tonic-gate add %g5, 8, %g5 4167c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 4177c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 32 - 39 4187c478bd9Sstevel@tonic-gate add %g5, 8, %g5 4197c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 4207c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 40 - 47 4217c478bd9Sstevel@tonic-gate add %g5, 8, %g5 4227c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 4237c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 48 - 55 4247c478bd9Sstevel@tonic-gate add %g5, 8, %g5 4257c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 4267c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 56 - 63 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate set CPU_RQ_SIZE, %g5 ! %g5 = queue size 4297c478bd9Sstevel@tonic-gate sub %g5, 1, %g5 ! %g5 = queu size mask 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate add %g6, Q_ENTRY_SIZE, %g6 ! increment q head to next 4327c478bd9Sstevel@tonic-gate and %g6, %g5, %g6 ! size mask for warp around 4337c478bd9Sstevel@tonic-gate cmp %g6, %g3 ! head == tail ?? 4347c478bd9Sstevel@tonic-gate 4357c478bd9Sstevel@tonic-gate bne,pn %xcc, 2b ! still have more to process 4367c478bd9Sstevel@tonic-gate nop 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate /* 4397c478bd9Sstevel@tonic-gate * head equals to tail now, we can update the queue head 4407c478bd9Sstevel@tonic-gate * and call sys_trap 4417c478bd9Sstevel@tonic-gate */ 4427c478bd9Sstevel@tonic-gate mov CPU_RQ_HD, %g4 4437c478bd9Sstevel@tonic-gate stxa %g6, [%g4]ASI_QUEUE ! update head offset 4442f0fcb93SJason Beloro membar #Sync 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate /* 447f2e043f1Sdavemq * Call sys_trap at PIL 14 unless we're already at PIL 15. %g2.l is 448f2e043f1Sdavemq * head offset(arg2) and %g3 is tail 4497c478bd9Sstevel@tonic-gate * offset(arg3). 4507c478bd9Sstevel@tonic-gate */ 4517c478bd9Sstevel@tonic-gate set process_resumable_error, %g1 452f2e043f1Sdavemq rdpr %pil, %g4 453f2e043f1Sdavemq cmp %g4, PIL_14 4547c478bd9Sstevel@tonic-gate ba sys_trap 455f2e043f1Sdavemq movl %icc, PIL_14, %g4 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate /* 4587c478bd9Sstevel@tonic-gate * We are here because the C routine is not able to process 4597c478bd9Sstevel@tonic-gate * errors in time. So the first 8 bytes of ER in buf has not 4607c478bd9Sstevel@tonic-gate * been cleared. We update head to tail and call sys_trap to 4617c478bd9Sstevel@tonic-gate * print out an error message 4627c478bd9Sstevel@tonic-gate */ 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate1: mov CPU_RQ_HD, %g4 4657c478bd9Sstevel@tonic-gate stxa %g3, [%g4]ASI_QUEUE ! set head equal to tail 4662f0fcb93SJason Beloro membar #Sync 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate /* 4697c478bd9Sstevel@tonic-gate * Set %g2 to %g6, which is current head offset. %g2 4707c478bd9Sstevel@tonic-gate * is arg2 of the C routine. %g3 is the tail offset, 4717c478bd9Sstevel@tonic-gate * which is arg3 of the C routine. 472f2e043f1Sdavemq * Call rq_overflow at PIL 14 unless we're already at PIL 15. 4737c478bd9Sstevel@tonic-gate */ 4747c478bd9Sstevel@tonic-gate mov %g6, %g2 4757c478bd9Sstevel@tonic-gate set rq_overflow, %g1 476f2e043f1Sdavemq rdpr %pil, %g4 477f2e043f1Sdavemq cmp %g4, PIL_14 4787c478bd9Sstevel@tonic-gate ba sys_trap 479f2e043f1Sdavemq movl %icc, PIL_14, %g4 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate0: retry 4827c478bd9Sstevel@tonic-gate 4837c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 4847c478bd9Sstevel@tonic-gate SET_SIZE(resumable_error) 4857c478bd9Sstevel@tonic-gate#endif /* lint */ 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate#if defined(lint) 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gatevoid 4907c478bd9Sstevel@tonic-gatenonresumable_error(void) 4917c478bd9Sstevel@tonic-gate{} 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate#else /* lint */ 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate/* 4967c478bd9Sstevel@tonic-gate * (TT 0x7f, TL>0) Non-resumeable Error Queue Handler 4977c478bd9Sstevel@tonic-gate * We keep a shadow copy of the queue in kernel buf. 4987c478bd9Sstevel@tonic-gate * Read non-resumable queue head and tail offset 4997c478bd9Sstevel@tonic-gate * If there are entries on the queue, move them to 5007c478bd9Sstevel@tonic-gate * the kernel buf, which is next to the non-resumable 5017c478bd9Sstevel@tonic-gate * queue in the memory. Call C routine to process. 5027c478bd9Sstevel@tonic-gate */ 5037c478bd9Sstevel@tonic-gate ENTRY_NP(nonresumable_error) 5047c478bd9Sstevel@tonic-gate mov CPU_NRQ_HD, %g4 5057c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_QUEUE, %g2 ! %g2 = Q head offset 5067c478bd9Sstevel@tonic-gate mov CPU_NRQ_TL, %g4 5077c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_QUEUE, %g3 ! %g3 = Q tail offset 5087c478bd9Sstevel@tonic-gate 50918aea0b1Swh94709 cmp %g2, %g3 5107c478bd9Sstevel@tonic-gate be,pn %xcc, 0f ! head == tail 5117c478bd9Sstevel@tonic-gate nop 5127c478bd9Sstevel@tonic-gate 51318aea0b1Swh94709 /* force %gl to 1 as sys_trap requires */ 51418aea0b1Swh94709 wrpr %g0, 1, %gl 51518aea0b1Swh94709 mov CPU_NRQ_HD, %g4 51618aea0b1Swh94709 ldxa [%g4]ASI_QUEUE, %g2 ! %g2 = Q head offset 51718aea0b1Swh94709 mov CPU_NRQ_TL, %g4 51818aea0b1Swh94709 ldxa [%g4]ASI_QUEUE, %g3 ! %g3 = Q tail offset 51918aea0b1Swh94709 mov %g2, %g6 ! save head in %g2 52018aea0b1Swh94709 52118aea0b1Swh94709 CPU_PADDR(%g1, %g4) ! %g1 = cpu struct paddr 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate2: set CPU_NRQ_BASE_OFF, %g4 52418aea0b1Swh94709 ldxa [%g1 + %g4]ASI_MEM, %g4 ! %g4 = queue base PA 5257c478bd9Sstevel@tonic-gate add %g6, %g4, %g4 ! %g4 = PA of ER in Q 5267c478bd9Sstevel@tonic-gate set CPU_NRQ_SIZE, %g7 5277c478bd9Sstevel@tonic-gate add %g4, %g7, %g7 ! %g7 = PA of ER in kernel buf 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate ldxa [%g7]ASI_MEM, %g5 ! %g5 = first 8 byte of ER buf 5307c478bd9Sstevel@tonic-gate cmp 0, %g5 5317c478bd9Sstevel@tonic-gate bne,pn %xcc, 1f ! first 8 byte is not 0 5327c478bd9Sstevel@tonic-gate nop 5337c478bd9Sstevel@tonic-gate 5349d0d62adSJason Beloro /* Now we can move 64 bytes from queue to buf */ 5357c478bd9Sstevel@tonic-gate set 0, %g5 5367c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 5377c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 0 - 7 5387c478bd9Sstevel@tonic-gate add %g5, 8, %g5 5397c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 5407c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 8 - 15 5417c478bd9Sstevel@tonic-gate add %g5, 8, %g5 5427c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 5437c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 16 - 23 5449d0d62adSJason Beloro add %g5, 8, %g5 5457c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 5467c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 24 - 31 5477c478bd9Sstevel@tonic-gate add %g5, 8, %g5 5487c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 5497c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 32 - 39 5507c478bd9Sstevel@tonic-gate add %g5, 8, %g5 5517c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 5527c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 40 - 47 5539d0d62adSJason Beloro add %g5, 8, %g5 5547c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 5557c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 48 - 55 5567c478bd9Sstevel@tonic-gate add %g5, 8, %g5 5577c478bd9Sstevel@tonic-gate ldxa [%g4 + %g5]ASI_MEM, %g1 5587c478bd9Sstevel@tonic-gate stxa %g1, [%g7 + %g5]ASI_MEM ! byte 56 - 63 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate set CPU_NRQ_SIZE, %g5 ! %g5 = queue size 5617c478bd9Sstevel@tonic-gate sub %g5, 1, %g5 ! %g5 = queu size mask 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate add %g6, Q_ENTRY_SIZE, %g6 ! increment q head to next 5647c478bd9Sstevel@tonic-gate and %g6, %g5, %g6 ! size mask for warp around 5657c478bd9Sstevel@tonic-gate cmp %g6, %g3 ! head == tail ?? 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate bne,pn %xcc, 2b ! still have more to process 5687c478bd9Sstevel@tonic-gate nop 5697c478bd9Sstevel@tonic-gate 5707c478bd9Sstevel@tonic-gate /* 5717c478bd9Sstevel@tonic-gate * head equals to tail now, we can update the queue head 5727c478bd9Sstevel@tonic-gate * and call sys_trap 5737c478bd9Sstevel@tonic-gate */ 5747c478bd9Sstevel@tonic-gate mov CPU_NRQ_HD, %g4 5757c478bd9Sstevel@tonic-gate stxa %g6, [%g4]ASI_QUEUE ! update head offset 5762f0fcb93SJason Beloro membar #Sync 5772f0fcb93SJason Beloro 5782f0fcb93SJason Beloro /* 5797c478bd9Sstevel@tonic-gate * Call sys_trap. %g2 is TL(arg2), %g3 is head and tail 5807c478bd9Sstevel@tonic-gate * offset(arg3). 5817c478bd9Sstevel@tonic-gate * %g3 looks like following: 5827c478bd9Sstevel@tonic-gate * +--------------------+--------------------+ 5837c478bd9Sstevel@tonic-gate * | tail offset | head offset | 5847c478bd9Sstevel@tonic-gate * +--------------------+--------------------+ 5857c478bd9Sstevel@tonic-gate * 63 32 31 0 586f2e043f1Sdavemq * 587f2e043f1Sdavemq * Run at PIL 14 unless we're already at PIL 15. 5887c478bd9Sstevel@tonic-gate */ 5899d0d62adSJason Beloro sllx %g3, 32, %g3 ! %g3.h = tail offset 5907c478bd9Sstevel@tonic-gate or %g3, %g2, %g3 ! %g3.l = head offset 5917c478bd9Sstevel@tonic-gate rdpr %tl, %g2 ! %g2 = current tl 592ad559ebfSwh94709 593ad559ebfSwh94709 /* 594ad559ebfSwh94709 * Now check if the first error that sent us here was caused 595ad559ebfSwh94709 * in user's SPILL/FILL trap. If it was, we call sys_trap to 596ad559ebfSwh94709 * kill the user process. Several considerations: 597ad559ebfSwh94709 * - If multiple nonresumable errors happen, we only check the 598ad559ebfSwh94709 * first one. Nonresumable errors cause system either panic 599ad559ebfSwh94709 * or kill the user process. So the system has already 600ad559ebfSwh94709 * panic'ed or killed user process after processing the first 601ad559ebfSwh94709 * error. Therefore, no need to check if other error packet 602ad559ebfSwh94709 * for this type of error. 603ad559ebfSwh94709 * - Errors happen in user's SPILL/FILL trap will bring us at 604ad559ebfSwh94709 * TL = 2. 605ad559ebfSwh94709 * - We need to lower TL to 1 to get the trap type and tstate. 606ad559ebfSwh94709 * We don't go back to TL = 2 so no need to save states. 607ad559ebfSwh94709 */ 608ad559ebfSwh94709 cmp %g2, 2 609ad559ebfSwh94709 bne,pt %xcc, 3f ! if tl != 2 610ad559ebfSwh94709 nop 611ad559ebfSwh94709 /* Check to see if the trap pc is in a window spill/fill handling */ 612ad559ebfSwh94709 rdpr %tpc, %g4 613ad559ebfSwh94709 /* tpc should be in the trap table */ 614ad559ebfSwh94709 set trap_table, %g5 615ad559ebfSwh94709 cmp %g4, %g5 616ad559ebfSwh94709 blu,pt %xcc, 3f 617ad559ebfSwh94709 nop 618ad559ebfSwh94709 set etrap_table, %g5 619ad559ebfSwh94709 cmp %g4, %g5 620ad559ebfSwh94709 bgeu,pt %xcc, 3f 621ad559ebfSwh94709 nop 622ad559ebfSwh94709 /* Set tl to 1 in order to read tt[1] and tstate[1] */ 623ad559ebfSwh94709 wrpr %g0, 1, %tl 624ad559ebfSwh94709 rdpr %tt, %g4 ! %g4 = tt[1] 625ad559ebfSwh94709 /* Check if tt[1] is a window trap */ 626ad559ebfSwh94709 and %g4, WTRAP_TTMASK, %g4 627ad559ebfSwh94709 cmp %g4, WTRAP_TYPE 628ad559ebfSwh94709 bne,pt %xcc, 3f 629ad559ebfSwh94709 nop 630ad559ebfSwh94709 rdpr %tstate, %g5 ! %g5 = tstate[1] 631ad559ebfSwh94709 btst TSTATE_PRIV, %g5 632ad559ebfSwh94709 bnz %xcc, 3f ! Is it from user code? 633ad559ebfSwh94709 nop 634ad559ebfSwh94709 /* 635ad559ebfSwh94709 * Now we know the error happened in user's SPILL/FILL trap. 636ad559ebfSwh94709 * Turn on the user spill/fill flag in %g2 637ad559ebfSwh94709 */ 638ad559ebfSwh94709 mov 1, %g4 639ad559ebfSwh94709 sllx %g4, ERRH_U_SPILL_FILL_SHIFT, %g4 640ad559ebfSwh94709 or %g2, %g4, %g2 ! turn on flag in %g2 641ad559ebfSwh94709 642ad559ebfSwh947093: sub %g2, 1, %g2 ! %g2.l = previous tl 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate set process_nonresumable_error, %g1 645f2e043f1Sdavemq rdpr %pil, %g4 646f2e043f1Sdavemq cmp %g4, PIL_14 6477c478bd9Sstevel@tonic-gate ba sys_trap 648f2e043f1Sdavemq movl %icc, PIL_14, %g4 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate /* 6517c478bd9Sstevel@tonic-gate * We are here because the C routine is not able to process 6527c478bd9Sstevel@tonic-gate * errors in time. So the first 8 bytes of ER in buf has not 65318aea0b1Swh94709 * been cleared. We call sys_trap to panic. 65418aea0b1Swh94709 * Run at PIL 14 unless we're already at PIL 15. 6557c478bd9Sstevel@tonic-gate */ 65618aea0b1Swh947091: set nrq_overflow, %g1 65718aea0b1Swh94709 rdpr %pil, %g4 65818aea0b1Swh94709 cmp %g4, PIL_14 65918aea0b1Swh94709 ba sys_trap 66018aea0b1Swh94709 movl %icc, PIL_14, %g4 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate0: retry 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 6657c478bd9Sstevel@tonic-gate SET_SIZE(nonresumable_error) 6667c478bd9Sstevel@tonic-gate#endif /* lint */ 667