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 54df4bd60Sbs21162 * Common Development and Distribution License (the "License"). 64df4bd60Sbs21162 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate/* 22*023e71deSHaik Aftandilian * 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/* 277c478bd9Sstevel@tonic-gate * General assembly language routines. 287c478bd9Sstevel@tonic-gate * It is the intent of this file to contain routines that are 297c478bd9Sstevel@tonic-gate * independent of the specific kernel architecture, and those that are 307c478bd9Sstevel@tonic-gate * common across kernel architectures. 317c478bd9Sstevel@tonic-gate * As architectures diverge, and implementations of specific 327c478bd9Sstevel@tonic-gate * architecture-dependent routines change, the routines should be moved 337c478bd9Sstevel@tonic-gate * from this file into the respective ../`arch -k`/subr.s file. 347c478bd9Sstevel@tonic-gate * Or, if you want to be really nice, move them to a file whose 357c478bd9Sstevel@tonic-gate * name has something to do with the routine you are moving. 367c478bd9Sstevel@tonic-gate */ 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate#if defined(lint) 397c478bd9Sstevel@tonic-gate#include <sys/types.h> 407c478bd9Sstevel@tonic-gate#include <sys/scb.h> 417c478bd9Sstevel@tonic-gate#include <sys/systm.h> 427c478bd9Sstevel@tonic-gate#include <sys/regset.h> 437c478bd9Sstevel@tonic-gate#include <sys/sunddi.h> 447c478bd9Sstevel@tonic-gate#include <sys/lockstat.h> 457c478bd9Sstevel@tonic-gate#include <sys/dtrace.h> 464df4bd60Sbs21162#include <sys/ftrace.h> 477c478bd9Sstevel@tonic-gate#endif /* lint */ 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 507c478bd9Sstevel@tonic-gate#include <sys/privregs.h> 517c478bd9Sstevel@tonic-gate#include <sys/machparam.h> /* To get SYSBASE and PAGESIZE */ 527c478bd9Sstevel@tonic-gate#include <sys/machthread.h> 537c478bd9Sstevel@tonic-gate#include <sys/clock.h> 547c478bd9Sstevel@tonic-gate#include <sys/psr_compat.h> 557c478bd9Sstevel@tonic-gate#include <sys/isa_defs.h> 567c478bd9Sstevel@tonic-gate#include <sys/dditypes.h> 577c478bd9Sstevel@tonic-gate#include <sys/panic.h> 587c478bd9Sstevel@tonic-gate#include <sys/machlock.h> 597c478bd9Sstevel@tonic-gate#include <sys/ontrap.h> 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate#if !defined(lint) 627c478bd9Sstevel@tonic-gate#include "assym.h" 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate .seg ".text" 657c478bd9Sstevel@tonic-gate .align 4 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate/* 687c478bd9Sstevel@tonic-gate * Macro to raise processor priority level. 697c478bd9Sstevel@tonic-gate * Avoid dropping processor priority if already at high level. 707c478bd9Sstevel@tonic-gate * Also avoid going below CPU->cpu_base_spl, which could've just been set by 717c478bd9Sstevel@tonic-gate * a higher-level interrupt thread that just blocked. 727c478bd9Sstevel@tonic-gate * 737c478bd9Sstevel@tonic-gate * level can be %o0 (not other regs used here) or a constant. 747c478bd9Sstevel@tonic-gate */ 757c478bd9Sstevel@tonic-gate#define RAISE(level) \ 767c478bd9Sstevel@tonic-gate rdpr %pil, %o1; /* get current PIL */ \ 777c478bd9Sstevel@tonic-gate cmp %o1, level; /* is PIL high enough? */ \ 787c478bd9Sstevel@tonic-gate bge 1f; /* yes, return */ \ 797c478bd9Sstevel@tonic-gate nop; \ 807c478bd9Sstevel@tonic-gate wrpr %g0, PIL_MAX, %pil; /* freeze CPU_BASE_SPL */ \ 817c478bd9Sstevel@tonic-gate ldn [THREAD_REG + T_CPU], %o2; \ 827c478bd9Sstevel@tonic-gate ld [%o2 + CPU_BASE_SPL], %o2; \ 837c478bd9Sstevel@tonic-gate cmp %o2, level; /* compare new to base */ \ 847c478bd9Sstevel@tonic-gate movl %xcc, level, %o2; /* use new if base lower */ \ 857c478bd9Sstevel@tonic-gate wrpr %g0, %o2, %pil; \ 867c478bd9Sstevel@tonic-gate1: \ 877c478bd9Sstevel@tonic-gate retl; \ 887c478bd9Sstevel@tonic-gate mov %o1, %o0 /* return old PIL */ 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate/* 917c478bd9Sstevel@tonic-gate * Macro to raise processor priority level to level >= DISP_LEVEL. 927c478bd9Sstevel@tonic-gate * Doesn't require comparison to CPU->cpu_base_spl. 937c478bd9Sstevel@tonic-gate * 947c478bd9Sstevel@tonic-gate * newpil can be %o0 (not other regs used here) or a constant. 957c478bd9Sstevel@tonic-gate */ 967c478bd9Sstevel@tonic-gate#define RAISE_HIGH(level) \ 977c478bd9Sstevel@tonic-gate rdpr %pil, %o1; /* get current PIL */ \ 987c478bd9Sstevel@tonic-gate cmp %o1, level; /* is PIL high enough? */ \ 997c478bd9Sstevel@tonic-gate bge 1f; /* yes, return */ \ 1007c478bd9Sstevel@tonic-gate nop; \ 1017c478bd9Sstevel@tonic-gate wrpr %g0, level, %pil; /* use chose value */ \ 1027c478bd9Sstevel@tonic-gate1: \ 1037c478bd9Sstevel@tonic-gate retl; \ 1047c478bd9Sstevel@tonic-gate mov %o1, %o0 /* return old PIL */ 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate/* 1077c478bd9Sstevel@tonic-gate * Macro to set the priority to a specified level. 1087c478bd9Sstevel@tonic-gate * Avoid dropping the priority below CPU->cpu_base_spl. 1097c478bd9Sstevel@tonic-gate * 1107c478bd9Sstevel@tonic-gate * newpil can be %o0 (not other regs used here) or a constant with 1117c478bd9Sstevel@tonic-gate * the new PIL in the PSR_PIL field of the level arg. 1127c478bd9Sstevel@tonic-gate */ 1137c478bd9Sstevel@tonic-gate#define SETPRI(level) \ 1147c478bd9Sstevel@tonic-gate rdpr %pil, %o1; /* get current PIL */ \ 1157c478bd9Sstevel@tonic-gate wrpr %g0, PIL_MAX, %pil; /* freeze CPU_BASE_SPL */ \ 1167c478bd9Sstevel@tonic-gate ldn [THREAD_REG + T_CPU], %o2; \ 1177c478bd9Sstevel@tonic-gate ld [%o2 + CPU_BASE_SPL], %o2; \ 1187c478bd9Sstevel@tonic-gate cmp %o2, level; /* compare new to base */ \ 1197c478bd9Sstevel@tonic-gate movl %xcc, level, %o2; /* use new if base lower */ \ 1207c478bd9Sstevel@tonic-gate wrpr %g0, %o2, %pil; \ 1217c478bd9Sstevel@tonic-gate retl; \ 1227c478bd9Sstevel@tonic-gate mov %o1, %o0 /* return old PIL */ 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate/* 1257c478bd9Sstevel@tonic-gate * Macro to set the priority to a specified level at or above LOCK_LEVEL. 1267c478bd9Sstevel@tonic-gate * Doesn't require comparison to CPU->cpu_base_spl. 1277c478bd9Sstevel@tonic-gate * 1287c478bd9Sstevel@tonic-gate * newpil can be %o0 (not other regs used here) or a constant with 1297c478bd9Sstevel@tonic-gate * the new PIL in the PSR_PIL field of the level arg. 1307c478bd9Sstevel@tonic-gate */ 1317c478bd9Sstevel@tonic-gate#define SETPRI_HIGH(level) \ 1327c478bd9Sstevel@tonic-gate rdpr %pil, %o1; /* get current PIL */ \ 1337c478bd9Sstevel@tonic-gate wrpr %g0, level, %pil; \ 1347c478bd9Sstevel@tonic-gate retl; \ 1357c478bd9Sstevel@tonic-gate mov %o1, %o0 /* return old PIL */ 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate#endif /* lint */ 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate /* 1407c478bd9Sstevel@tonic-gate * Berkley 4.3 introduced symbolically named interrupt levels 1417c478bd9Sstevel@tonic-gate * as a way deal with priority in a machine independent fashion. 1427c478bd9Sstevel@tonic-gate * Numbered priorities are machine specific, and should be 1437c478bd9Sstevel@tonic-gate * discouraged where possible. 1447c478bd9Sstevel@tonic-gate * 1457c478bd9Sstevel@tonic-gate * Note, for the machine specific priorities there are 1467c478bd9Sstevel@tonic-gate * examples listed for devices that use a particular priority. 1477c478bd9Sstevel@tonic-gate * It should not be construed that all devices of that 1487c478bd9Sstevel@tonic-gate * type should be at that priority. It is currently were 1497c478bd9Sstevel@tonic-gate * the current devices fit into the priority scheme based 1507c478bd9Sstevel@tonic-gate * upon time criticalness. 1517c478bd9Sstevel@tonic-gate * 1527c478bd9Sstevel@tonic-gate * The underlying assumption of these assignments is that 1537c478bd9Sstevel@tonic-gate * SPARC9 IPL 10 is the highest level from which a device 1547c478bd9Sstevel@tonic-gate * routine can call wakeup. Devices that interrupt from higher 1557c478bd9Sstevel@tonic-gate * levels are restricted in what they can do. If they need 1567c478bd9Sstevel@tonic-gate * kernels services they should schedule a routine at a lower 1577c478bd9Sstevel@tonic-gate * level (via software interrupt) to do the required 1587c478bd9Sstevel@tonic-gate * processing. 1597c478bd9Sstevel@tonic-gate * 1607c478bd9Sstevel@tonic-gate * Examples of this higher usage: 1617c478bd9Sstevel@tonic-gate * Level Usage 1627c478bd9Sstevel@tonic-gate * 15 Asynchronous memory exceptions 1637c478bd9Sstevel@tonic-gate * 14 Profiling clock (and PROM uart polling clock) 1647c478bd9Sstevel@tonic-gate * 13 Audio device 1657c478bd9Sstevel@tonic-gate * 12 Serial ports 1667c478bd9Sstevel@tonic-gate * 11 Floppy controller 1677c478bd9Sstevel@tonic-gate * 1687c478bd9Sstevel@tonic-gate * The serial ports request lower level processing on level 6. 1697c478bd9Sstevel@tonic-gate * Audio and floppy request lower level processing on level 4. 1707c478bd9Sstevel@tonic-gate * 1717c478bd9Sstevel@tonic-gate * Also, almost all splN routines (where N is a number or a 1727c478bd9Sstevel@tonic-gate * mnemonic) will do a RAISE(), on the assumption that they are 1737c478bd9Sstevel@tonic-gate * never used to lower our priority. 1747c478bd9Sstevel@tonic-gate * The exceptions are: 1757c478bd9Sstevel@tonic-gate * spl8() Because you can't be above 15 to begin with! 1767c478bd9Sstevel@tonic-gate * splzs() Because this is used at boot time to lower our 1777c478bd9Sstevel@tonic-gate * priority, to allow the PROM to poll the uart. 1787c478bd9Sstevel@tonic-gate * spl0() Used to lower priority to 0. 1797c478bd9Sstevel@tonic-gate */ 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate#if defined(lint) 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gateint spl0(void) { return (0); } 1847c478bd9Sstevel@tonic-gateint spl6(void) { return (0); } 1857c478bd9Sstevel@tonic-gateint spl7(void) { return (0); } 1867c478bd9Sstevel@tonic-gateint spl8(void) { return (0); } 1877c478bd9Sstevel@tonic-gateint splhi(void) { return (0); } 1887c478bd9Sstevel@tonic-gateint splhigh(void) { return (0); } 1897c478bd9Sstevel@tonic-gateint splzs(void) { return (0); } 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate#else /* lint */ 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate /* locks out all interrupts, including memory errors */ 1947c478bd9Sstevel@tonic-gate ENTRY(spl8) 1957c478bd9Sstevel@tonic-gate SETPRI_HIGH(15) 1967c478bd9Sstevel@tonic-gate SET_SIZE(spl8) 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate /* just below the level that profiling runs */ 1997c478bd9Sstevel@tonic-gate ENTRY(spl7) 2007c478bd9Sstevel@tonic-gate RAISE_HIGH(13) 2017c478bd9Sstevel@tonic-gate SET_SIZE(spl7) 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate /* sun specific - highest priority onboard serial i/o zs ports */ 2047c478bd9Sstevel@tonic-gate ENTRY(splzs) 2057c478bd9Sstevel@tonic-gate SETPRI_HIGH(12) /* Can't be a RAISE, as it's used to lower us */ 2067c478bd9Sstevel@tonic-gate SET_SIZE(splzs) 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate /* 2097c478bd9Sstevel@tonic-gate * should lock out clocks and all interrupts, 2107c478bd9Sstevel@tonic-gate * as you can see, there are exceptions 2117c478bd9Sstevel@tonic-gate */ 2127c478bd9Sstevel@tonic-gate ENTRY(splhi) 2137c478bd9Sstevel@tonic-gate ALTENTRY(splhigh) 2147c478bd9Sstevel@tonic-gate ALTENTRY(spl6) 2157c478bd9Sstevel@tonic-gate ALTENTRY(i_ddi_splhigh) 2167c478bd9Sstevel@tonic-gate RAISE_HIGH(DISP_LEVEL) 2177c478bd9Sstevel@tonic-gate SET_SIZE(i_ddi_splhigh) 2187c478bd9Sstevel@tonic-gate SET_SIZE(spl6) 2197c478bd9Sstevel@tonic-gate SET_SIZE(splhigh) 2207c478bd9Sstevel@tonic-gate SET_SIZE(splhi) 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate /* allow all interrupts */ 2237c478bd9Sstevel@tonic-gate ENTRY(spl0) 2247c478bd9Sstevel@tonic-gate SETPRI(0) 2257c478bd9Sstevel@tonic-gate SET_SIZE(spl0) 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate#endif /* lint */ 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate/* 2307c478bd9Sstevel@tonic-gate * splx - set PIL back to that indicated by the old %pil passed as an argument, 2317c478bd9Sstevel@tonic-gate * or to the CPU's base priority, whichever is higher. 2327c478bd9Sstevel@tonic-gate */ 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate#if defined(lint) 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate/* ARGSUSED */ 2377c478bd9Sstevel@tonic-gatevoid 2387c478bd9Sstevel@tonic-gatesplx(int level) 2397c478bd9Sstevel@tonic-gate{} 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate#else /* lint */ 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate ENTRY(splx) 2447c478bd9Sstevel@tonic-gate ALTENTRY(i_ddi_splx) 2457c478bd9Sstevel@tonic-gate SETPRI(%o0) /* set PIL */ 2467c478bd9Sstevel@tonic-gate SET_SIZE(i_ddi_splx) 2477c478bd9Sstevel@tonic-gate SET_SIZE(splx) 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate#endif /* level */ 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate/* 2527c478bd9Sstevel@tonic-gate * splr() 2537c478bd9Sstevel@tonic-gate * 2547c478bd9Sstevel@tonic-gate * splr is like splx but will only raise the priority and never drop it 2557c478bd9Sstevel@tonic-gate * Be careful not to set priority lower than CPU->cpu_base_pri, 2567c478bd9Sstevel@tonic-gate * even though it seems we're raising the priority, it could be set higher 2577c478bd9Sstevel@tonic-gate * at any time by an interrupt routine, so we must block interrupts and 2587c478bd9Sstevel@tonic-gate * look at CPU->cpu_base_pri. 2597c478bd9Sstevel@tonic-gate */ 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate#if defined(lint) 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate/* ARGSUSED */ 2647c478bd9Sstevel@tonic-gateint 2657c478bd9Sstevel@tonic-gatesplr(int level) 2667c478bd9Sstevel@tonic-gate{ return (0); } 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate#else /* lint */ 2697c478bd9Sstevel@tonic-gate ENTRY(splr) 2707c478bd9Sstevel@tonic-gate RAISE(%o0) 2717c478bd9Sstevel@tonic-gate SET_SIZE(splr) 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate#endif /* lint */ 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate/* 2767c478bd9Sstevel@tonic-gate * on_fault() 2777c478bd9Sstevel@tonic-gate * Catch lofault faults. Like setjmp except it returns one 2787c478bd9Sstevel@tonic-gate * if code following causes uncorrectable fault. Turned off 2797c478bd9Sstevel@tonic-gate * by calling no_fault(). 2807c478bd9Sstevel@tonic-gate */ 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate#if defined(lint) 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate/* ARGSUSED */ 2857c478bd9Sstevel@tonic-gateint 2867c478bd9Sstevel@tonic-gateon_fault(label_t *ljb) 2877c478bd9Sstevel@tonic-gate{ return (0); } 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate#else /* lint */ 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate ENTRY(on_fault) 2927c478bd9Sstevel@tonic-gate membar #Sync ! sync error barrier (see copy.s) 2937c478bd9Sstevel@tonic-gate stn %o0, [THREAD_REG + T_ONFAULT] 2947c478bd9Sstevel@tonic-gate set catch_fault, %o1 2957c478bd9Sstevel@tonic-gate b setjmp ! let setjmp do the rest 2967c478bd9Sstevel@tonic-gate stn %o1, [THREAD_REG + T_LOFAULT] ! put catch_fault in t_lofault 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gatecatch_fault: 2997c478bd9Sstevel@tonic-gate save %sp, -SA(WINDOWSIZE), %sp ! goto next window so that we can rtn 3007c478bd9Sstevel@tonic-gate ldn [THREAD_REG + T_ONFAULT], %o0 3017c478bd9Sstevel@tonic-gate membar #Sync ! sync error barrier 3027c478bd9Sstevel@tonic-gate stn %g0, [THREAD_REG + T_ONFAULT] ! turn off onfault 3037c478bd9Sstevel@tonic-gate b longjmp ! let longjmp do the rest 3047c478bd9Sstevel@tonic-gate stn %g0, [THREAD_REG + T_LOFAULT] ! turn off lofault 3057c478bd9Sstevel@tonic-gate SET_SIZE(on_fault) 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate#endif /* lint */ 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate/* 3107c478bd9Sstevel@tonic-gate * no_fault() 3117c478bd9Sstevel@tonic-gate * turn off fault catching. 3127c478bd9Sstevel@tonic-gate */ 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate#if defined(lint) 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gatevoid 3177c478bd9Sstevel@tonic-gateno_fault(void) 3187c478bd9Sstevel@tonic-gate{} 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate#else /* lint */ 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate ENTRY(no_fault) 3237c478bd9Sstevel@tonic-gate membar #Sync ! sync error barrier 3247c478bd9Sstevel@tonic-gate stn %g0, [THREAD_REG + T_ONFAULT] 3257c478bd9Sstevel@tonic-gate retl 3267c478bd9Sstevel@tonic-gate stn %g0, [THREAD_REG + T_LOFAULT] ! turn off lofault 3277c478bd9Sstevel@tonic-gate SET_SIZE(no_fault) 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate#endif /* lint */ 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate/* 3327c478bd9Sstevel@tonic-gate * Default trampoline code for on_trap() (see <sys/ontrap.h>). On sparcv9, 3337c478bd9Sstevel@tonic-gate * the trap code will complete trap processing but reset the return %pc to 3347c478bd9Sstevel@tonic-gate * ot_trampoline, which will by default be set to the address of this code. 3357c478bd9Sstevel@tonic-gate * We longjmp(&curthread->t_ontrap->ot_jmpbuf) to return back to on_trap(). 3367c478bd9Sstevel@tonic-gate */ 3377c478bd9Sstevel@tonic-gate#if defined(lint) 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gatevoid 3407c478bd9Sstevel@tonic-gateon_trap_trampoline(void) 3417c478bd9Sstevel@tonic-gate{} 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate#else /* lint */ 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate ENTRY(on_trap_trampoline) 3467c478bd9Sstevel@tonic-gate ldn [THREAD_REG + T_ONTRAP], %o0 3477c478bd9Sstevel@tonic-gate b longjmp 3487c478bd9Sstevel@tonic-gate add %o0, OT_JMPBUF, %o0 3497c478bd9Sstevel@tonic-gate SET_SIZE(on_trap_trampoline) 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate#endif /* lint */ 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate/* 3547c478bd9Sstevel@tonic-gate * Push a new element on to the t_ontrap stack. Refer to <sys/ontrap.h> for 3557c478bd9Sstevel@tonic-gate * more information about the on_trap() mechanism. If the on_trap_data is the 3567c478bd9Sstevel@tonic-gate * same as the topmost stack element, we just modify that element. 3577c478bd9Sstevel@tonic-gate * On UltraSPARC, we need to issue a membar #Sync before modifying t_ontrap. 3587c478bd9Sstevel@tonic-gate * The issue barrier is defined to force all deferred errors to complete before 3597c478bd9Sstevel@tonic-gate * we go any further. We want these errors to be processed before we modify 3607c478bd9Sstevel@tonic-gate * our current error protection. 3617c478bd9Sstevel@tonic-gate */ 3627c478bd9Sstevel@tonic-gate#if defined(lint) 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 3657c478bd9Sstevel@tonic-gateint 3667c478bd9Sstevel@tonic-gateon_trap(on_trap_data_t *otp, uint_t prot) 3677c478bd9Sstevel@tonic-gate{ return (0); } 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate#else /* lint */ 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate ENTRY(on_trap) 3727c478bd9Sstevel@tonic-gate membar #Sync ! force error barrier 3737c478bd9Sstevel@tonic-gate sth %o1, [%o0 + OT_PROT] ! ot_prot = prot 3747c478bd9Sstevel@tonic-gate sth %g0, [%o0 + OT_TRAP] ! ot_trap = 0 3757c478bd9Sstevel@tonic-gate set on_trap_trampoline, %o2 ! %o2 = &on_trap_trampoline 3767c478bd9Sstevel@tonic-gate stn %o2, [%o0 + OT_TRAMPOLINE] ! ot_trampoline = %o2 3777c478bd9Sstevel@tonic-gate stn %g0, [%o0 + OT_HANDLE] ! ot_handle = NULL 3787c478bd9Sstevel@tonic-gate ldn [THREAD_REG + T_ONTRAP], %o2 ! %o2 = curthread->t_ontrap 3797c478bd9Sstevel@tonic-gate cmp %o0, %o2 ! if (otp == %o2) 3807c478bd9Sstevel@tonic-gate be 0f ! don't modify t_ontrap 3817c478bd9Sstevel@tonic-gate stn %g0, [%o0 + OT_PAD1] ! delay - ot_pad1 = NULL 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate stn %o2, [%o0 + OT_PREV] ! ot_prev = t_ontrap 3847c478bd9Sstevel@tonic-gate membar #Sync ! force error barrier 3857c478bd9Sstevel@tonic-gate stn %o0, [THREAD_REG + T_ONTRAP] ! t_ontrap = otp 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate0: b setjmp ! let setjmp do the rest 3887c478bd9Sstevel@tonic-gate add %o0, OT_JMPBUF, %o0 ! %o0 = &ot_jmpbuf 3897c478bd9Sstevel@tonic-gate SET_SIZE(on_trap) 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate#endif /* lint */ 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate/* 3947c478bd9Sstevel@tonic-gate * Setjmp and longjmp implement non-local gotos using state vectors 3957c478bd9Sstevel@tonic-gate * type label_t. 3967c478bd9Sstevel@tonic-gate */ 3977c478bd9Sstevel@tonic-gate 3987c478bd9Sstevel@tonic-gate#if defined(lint) 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate/* ARGSUSED */ 4017c478bd9Sstevel@tonic-gateint 4027c478bd9Sstevel@tonic-gatesetjmp(label_t *lp) 4037c478bd9Sstevel@tonic-gate{ return (0); } 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate#else /* lint */ 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate ENTRY(setjmp) 4087c478bd9Sstevel@tonic-gate stn %o7, [%o0 + L_PC] ! save return address 4097c478bd9Sstevel@tonic-gate stn %sp, [%o0 + L_SP] ! save stack ptr 4107c478bd9Sstevel@tonic-gate retl 4117c478bd9Sstevel@tonic-gate clr %o0 ! return 0 4127c478bd9Sstevel@tonic-gate SET_SIZE(setjmp) 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate#endif /* lint */ 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate#if defined(lint) 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate/* ARGSUSED */ 4207c478bd9Sstevel@tonic-gatevoid 4217c478bd9Sstevel@tonic-gatelongjmp(label_t *lp) 4227c478bd9Sstevel@tonic-gate{} 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate#else /* lint */ 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate ENTRY(longjmp) 4277c478bd9Sstevel@tonic-gate ! 4287c478bd9Sstevel@tonic-gate ! The following save is required so that an extra register 4297c478bd9Sstevel@tonic-gate ! window is flushed. Flushw flushes nwindows-2 4307c478bd9Sstevel@tonic-gate ! register windows. If setjmp and longjmp are called from 4317c478bd9Sstevel@tonic-gate ! within the same window, that window will not get pushed 4327c478bd9Sstevel@tonic-gate ! out onto the stack without the extra save below. Tail call 4337c478bd9Sstevel@tonic-gate ! optimization can lead to callers of longjmp executing 4347c478bd9Sstevel@tonic-gate ! from a window that could be the same as the setjmp, 4357c478bd9Sstevel@tonic-gate ! thus the need for the following save. 4367c478bd9Sstevel@tonic-gate ! 4377c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME), %sp 4387c478bd9Sstevel@tonic-gate flushw ! flush all but this window 4397c478bd9Sstevel@tonic-gate ldn [%i0 + L_PC], %i7 ! restore return addr 4407c478bd9Sstevel@tonic-gate ldn [%i0 + L_SP], %fp ! restore sp for dest on foreign stack 4417c478bd9Sstevel@tonic-gate ret ! return 1 4427c478bd9Sstevel@tonic-gate restore %g0, 1, %o0 ! takes underflow, switches stacks 4437c478bd9Sstevel@tonic-gate SET_SIZE(longjmp) 4447c478bd9Sstevel@tonic-gate 4457c478bd9Sstevel@tonic-gate#endif /* lint */ 4467c478bd9Sstevel@tonic-gate 4477c478bd9Sstevel@tonic-gate/* 4487c478bd9Sstevel@tonic-gate * movtuc(length, from, to, table) 4497c478bd9Sstevel@tonic-gate * 4507c478bd9Sstevel@tonic-gate * VAX movtuc instruction (sort of). 4517c478bd9Sstevel@tonic-gate */ 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate#if defined(lint) 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 4567c478bd9Sstevel@tonic-gateint 4577c478bd9Sstevel@tonic-gatemovtuc(size_t length, u_char *from, u_char *to, u_char table[]) 4587c478bd9Sstevel@tonic-gate{ return (0); } 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate#else /* lint */ 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate ENTRY(movtuc) 4637c478bd9Sstevel@tonic-gate tst %o0 4647c478bd9Sstevel@tonic-gate ble,pn %ncc, 2f ! check length 4657c478bd9Sstevel@tonic-gate clr %o4 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate ldub [%o1 + %o4], %g1 ! get next byte in string 4687c478bd9Sstevel@tonic-gate0: 4697c478bd9Sstevel@tonic-gate ldub [%o3 + %g1], %g1 ! get corresponding table entry 4707c478bd9Sstevel@tonic-gate tst %g1 ! escape char? 4717c478bd9Sstevel@tonic-gate bnz 1f 4727c478bd9Sstevel@tonic-gate stb %g1, [%o2 + %o4] ! delay slot, store it 4737c478bd9Sstevel@tonic-gate 4747c478bd9Sstevel@tonic-gate retl ! return (bytes moved) 4757c478bd9Sstevel@tonic-gate mov %o4, %o0 4767c478bd9Sstevel@tonic-gate1: 4777c478bd9Sstevel@tonic-gate inc %o4 ! increment index 4787c478bd9Sstevel@tonic-gate cmp %o4, %o0 ! index < length ? 4797c478bd9Sstevel@tonic-gate bl,a,pt %ncc, 0b 4807c478bd9Sstevel@tonic-gate ldub [%o1 + %o4], %g1 ! delay slot, get next byte in string 4817c478bd9Sstevel@tonic-gate2: 4827c478bd9Sstevel@tonic-gate retl ! return (bytes moved) 4837c478bd9Sstevel@tonic-gate mov %o4, %o0 4847c478bd9Sstevel@tonic-gate SET_SIZE(movtuc) 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate#endif /* lint */ 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate/* 4897c478bd9Sstevel@tonic-gate * scanc(length, string, table, mask) 4907c478bd9Sstevel@tonic-gate * 4917c478bd9Sstevel@tonic-gate * VAX scanc instruction. 4927c478bd9Sstevel@tonic-gate */ 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate#if defined(lint) 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 4977c478bd9Sstevel@tonic-gateint 4987c478bd9Sstevel@tonic-gatescanc(size_t length, u_char *string, u_char table[], u_char mask) 4997c478bd9Sstevel@tonic-gate{ return (0); } 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate#else /* lint */ 5027c478bd9Sstevel@tonic-gate 5037c478bd9Sstevel@tonic-gate ENTRY(scanc) 5047c478bd9Sstevel@tonic-gate tst %o0 5057c478bd9Sstevel@tonic-gate ble,pn %ncc, 1f ! check length 5067c478bd9Sstevel@tonic-gate clr %o4 5077c478bd9Sstevel@tonic-gate0: 5087c478bd9Sstevel@tonic-gate ldub [%o1 + %o4], %g1 ! get next byte in string 5097c478bd9Sstevel@tonic-gate cmp %o4, %o0 ! interlock slot, index < length ? 5107c478bd9Sstevel@tonic-gate ldub [%o2 + %g1], %g1 ! get corresponding table entry 5117c478bd9Sstevel@tonic-gate bge,pn %ncc, 1f ! interlock slot 5127c478bd9Sstevel@tonic-gate btst %o3, %g1 ! apply the mask 5137c478bd9Sstevel@tonic-gate bz,a 0b 5147c478bd9Sstevel@tonic-gate inc %o4 ! delay slot, increment index 5157c478bd9Sstevel@tonic-gate1: 5167c478bd9Sstevel@tonic-gate retl ! return(length - index) 5177c478bd9Sstevel@tonic-gate sub %o0, %o4, %o0 5187c478bd9Sstevel@tonic-gate SET_SIZE(scanc) 5197c478bd9Sstevel@tonic-gate 5207c478bd9Sstevel@tonic-gate#endif /* lint */ 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate/* 5237c478bd9Sstevel@tonic-gate * if a() calls b() calls caller(), 5247c478bd9Sstevel@tonic-gate * caller() returns return address in a(). 5257c478bd9Sstevel@tonic-gate */ 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate#if defined(lint) 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gatecaddr_t 5307c478bd9Sstevel@tonic-gatecaller(void) 5317c478bd9Sstevel@tonic-gate{ return (0); } 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate#else /* lint */ 5347c478bd9Sstevel@tonic-gate 5357c478bd9Sstevel@tonic-gate ENTRY(caller) 5367c478bd9Sstevel@tonic-gate retl 5377c478bd9Sstevel@tonic-gate mov %i7, %o0 5387c478bd9Sstevel@tonic-gate SET_SIZE(caller) 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate#endif /* lint */ 5417c478bd9Sstevel@tonic-gate 5427c478bd9Sstevel@tonic-gate/* 5437c478bd9Sstevel@tonic-gate * if a() calls callee(), callee() returns the 5447c478bd9Sstevel@tonic-gate * return address in a(); 5457c478bd9Sstevel@tonic-gate */ 5467c478bd9Sstevel@tonic-gate 5477c478bd9Sstevel@tonic-gate#if defined(lint) 5487c478bd9Sstevel@tonic-gate 5497c478bd9Sstevel@tonic-gatecaddr_t 5507c478bd9Sstevel@tonic-gatecallee(void) 5517c478bd9Sstevel@tonic-gate{ return (0); } 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate#else /* lint */ 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate ENTRY(callee) 5567c478bd9Sstevel@tonic-gate retl 5577c478bd9Sstevel@tonic-gate mov %o7, %o0 5587c478bd9Sstevel@tonic-gate SET_SIZE(callee) 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate#endif /* lint */ 5617c478bd9Sstevel@tonic-gate 5627c478bd9Sstevel@tonic-gate/* 5637c478bd9Sstevel@tonic-gate * return the current frame pointer 5647c478bd9Sstevel@tonic-gate */ 5657c478bd9Sstevel@tonic-gate 5667c478bd9Sstevel@tonic-gate#if defined(lint) 5677c478bd9Sstevel@tonic-gate 5687c478bd9Sstevel@tonic-gategreg_t 5697c478bd9Sstevel@tonic-gategetfp(void) 5707c478bd9Sstevel@tonic-gate{ return (0); } 5717c478bd9Sstevel@tonic-gate 5727c478bd9Sstevel@tonic-gate#else /* lint */ 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate ENTRY(getfp) 5757c478bd9Sstevel@tonic-gate retl 5767c478bd9Sstevel@tonic-gate mov %fp, %o0 5777c478bd9Sstevel@tonic-gate SET_SIZE(getfp) 5787c478bd9Sstevel@tonic-gate 5797c478bd9Sstevel@tonic-gate#endif /* lint */ 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate/* 5827c478bd9Sstevel@tonic-gate * Get vector base register 5837c478bd9Sstevel@tonic-gate */ 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate#if defined(lint) 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gategreg_t 5887c478bd9Sstevel@tonic-gategettbr(void) 5897c478bd9Sstevel@tonic-gate{ return (0); } 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate#else /* lint */ 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate ENTRY(gettbr) 5947c478bd9Sstevel@tonic-gate retl 5957c478bd9Sstevel@tonic-gate mov %tbr, %o0 5967c478bd9Sstevel@tonic-gate SET_SIZE(gettbr) 5977c478bd9Sstevel@tonic-gate 5987c478bd9Sstevel@tonic-gate#endif /* lint */ 5997c478bd9Sstevel@tonic-gate 6007c478bd9Sstevel@tonic-gate/* 6017c478bd9Sstevel@tonic-gate * Get processor state register, V9 faked to look like V8. 6027c478bd9Sstevel@tonic-gate * Note: does not provide ccr.xcc and provides FPRS.FEF instead of 6037c478bd9Sstevel@tonic-gate * PSTATE.PEF, because PSTATE.PEF is always on in order to allow the 6047c478bd9Sstevel@tonic-gate * libc_psr memcpy routines to run without hitting the fp_disabled trap. 6057c478bd9Sstevel@tonic-gate */ 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate#if defined(lint) 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gategreg_t 6107c478bd9Sstevel@tonic-gategetpsr(void) 6117c478bd9Sstevel@tonic-gate{ return (0); } 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate#else /* lint */ 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate ENTRY(getpsr) 6167c478bd9Sstevel@tonic-gate rd %ccr, %o1 ! get ccr 6177c478bd9Sstevel@tonic-gate sll %o1, PSR_ICC_SHIFT, %o0 ! move icc to V8 psr.icc 6187c478bd9Sstevel@tonic-gate rd %fprs, %o1 ! get fprs 6197c478bd9Sstevel@tonic-gate and %o1, FPRS_FEF, %o1 ! mask out dirty upper/lower 6207c478bd9Sstevel@tonic-gate sllx %o1, PSR_FPRS_FEF_SHIFT, %o1 ! shift fef to V8 psr.ef 6217c478bd9Sstevel@tonic-gate or %o0, %o1, %o0 ! or into psr.ef 6227c478bd9Sstevel@tonic-gate set V9_PSR_IMPLVER, %o1 ! SI assigned impl/ver: 0xef 6237c478bd9Sstevel@tonic-gate retl 6247c478bd9Sstevel@tonic-gate or %o0, %o1, %o0 ! or into psr.impl/ver 6257c478bd9Sstevel@tonic-gate SET_SIZE(getpsr) 6267c478bd9Sstevel@tonic-gate 6277c478bd9Sstevel@tonic-gate#endif /* lint */ 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate/* 6307c478bd9Sstevel@tonic-gate * Get current processor interrupt level 6317c478bd9Sstevel@tonic-gate */ 6327c478bd9Sstevel@tonic-gate 6337c478bd9Sstevel@tonic-gate#if defined(lint) 6347c478bd9Sstevel@tonic-gate 6357c478bd9Sstevel@tonic-gateu_int 6367c478bd9Sstevel@tonic-gategetpil(void) 6377c478bd9Sstevel@tonic-gate{ return (0); } 6387c478bd9Sstevel@tonic-gate 6397c478bd9Sstevel@tonic-gate#else /* lint */ 6407c478bd9Sstevel@tonic-gate 6417c478bd9Sstevel@tonic-gate ENTRY(getpil) 6427c478bd9Sstevel@tonic-gate retl 6437c478bd9Sstevel@tonic-gate rdpr %pil, %o0 6447c478bd9Sstevel@tonic-gate SET_SIZE(getpil) 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate#endif /* lint */ 6477c478bd9Sstevel@tonic-gate 6487c478bd9Sstevel@tonic-gate#if defined(lint) 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 6517c478bd9Sstevel@tonic-gatevoid 6527c478bd9Sstevel@tonic-gatesetpil(u_int pil) 6537c478bd9Sstevel@tonic-gate{} 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate#else /* lint */ 6567c478bd9Sstevel@tonic-gate 6577c478bd9Sstevel@tonic-gate ENTRY(setpil) 6587c478bd9Sstevel@tonic-gate retl 6597c478bd9Sstevel@tonic-gate wrpr %g0, %o0, %pil 6607c478bd9Sstevel@tonic-gate SET_SIZE(setpil) 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate#endif /* lint */ 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate/* 6667c478bd9Sstevel@tonic-gate * _insque(entryp, predp) 6677c478bd9Sstevel@tonic-gate * 6687c478bd9Sstevel@tonic-gate * Insert entryp after predp in a doubly linked list. 6697c478bd9Sstevel@tonic-gate */ 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate#if defined(lint) 6727c478bd9Sstevel@tonic-gate 6737c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 6747c478bd9Sstevel@tonic-gatevoid 6757c478bd9Sstevel@tonic-gate_insque(caddr_t entryp, caddr_t predp) 6767c478bd9Sstevel@tonic-gate{} 6777c478bd9Sstevel@tonic-gate 6787c478bd9Sstevel@tonic-gate#else /* lint */ 6797c478bd9Sstevel@tonic-gate 6807c478bd9Sstevel@tonic-gate ENTRY(_insque) 6817c478bd9Sstevel@tonic-gate ldn [%o1], %g1 ! predp->forw 6827c478bd9Sstevel@tonic-gate stn %o1, [%o0 + CPTRSIZE] ! entryp->back = predp 6837c478bd9Sstevel@tonic-gate stn %g1, [%o0] ! entryp->forw = predp->forw 6847c478bd9Sstevel@tonic-gate stn %o0, [%o1] ! predp->forw = entryp 6857c478bd9Sstevel@tonic-gate retl 6867c478bd9Sstevel@tonic-gate stn %o0, [%g1 + CPTRSIZE] ! predp->forw->back = entryp 6877c478bd9Sstevel@tonic-gate SET_SIZE(_insque) 6887c478bd9Sstevel@tonic-gate 6897c478bd9Sstevel@tonic-gate#endif /* lint */ 6907c478bd9Sstevel@tonic-gate 6917c478bd9Sstevel@tonic-gate/* 6927c478bd9Sstevel@tonic-gate * _remque(entryp) 6937c478bd9Sstevel@tonic-gate * 6947c478bd9Sstevel@tonic-gate * Remove entryp from a doubly linked list 6957c478bd9Sstevel@tonic-gate */ 6967c478bd9Sstevel@tonic-gate 6977c478bd9Sstevel@tonic-gate#if defined(lint) 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 7007c478bd9Sstevel@tonic-gatevoid 7017c478bd9Sstevel@tonic-gate_remque(caddr_t entryp) 7027c478bd9Sstevel@tonic-gate{} 7037c478bd9Sstevel@tonic-gate 7047c478bd9Sstevel@tonic-gate#else /* lint */ 7057c478bd9Sstevel@tonic-gate 7067c478bd9Sstevel@tonic-gate ENTRY(_remque) 7077c478bd9Sstevel@tonic-gate ldn [%o0], %g1 ! entryp->forw 7087c478bd9Sstevel@tonic-gate ldn [%o0 + CPTRSIZE], %g2 ! entryp->back 7097c478bd9Sstevel@tonic-gate stn %g1, [%g2] ! entryp->back->forw = entryp->forw 7107c478bd9Sstevel@tonic-gate retl 7117c478bd9Sstevel@tonic-gate stn %g2, [%g1 + CPTRSIZE] ! entryp->forw->back = entryp->back 7127c478bd9Sstevel@tonic-gate SET_SIZE(_remque) 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate#endif /* lint */ 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate 7177c478bd9Sstevel@tonic-gate/* 7187c478bd9Sstevel@tonic-gate * strlen(str) 7197c478bd9Sstevel@tonic-gate * 7207c478bd9Sstevel@tonic-gate * Returns the number of non-NULL bytes in string argument. 7217c478bd9Sstevel@tonic-gate * 7227c478bd9Sstevel@tonic-gate * XXX - why is this here, rather than the traditional file? 7237c478bd9Sstevel@tonic-gate * why does it have local labels which don't start with a `.'? 7247c478bd9Sstevel@tonic-gate */ 7257c478bd9Sstevel@tonic-gate 7267c478bd9Sstevel@tonic-gate#if defined(lint) 7277c478bd9Sstevel@tonic-gate 7287c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 7297c478bd9Sstevel@tonic-gatesize_t 7307c478bd9Sstevel@tonic-gatestrlen(const char *str) 7317c478bd9Sstevel@tonic-gate{ return (0); } 7327c478bd9Sstevel@tonic-gate 7337c478bd9Sstevel@tonic-gate#else /* lint */ 7347c478bd9Sstevel@tonic-gate 7357c478bd9Sstevel@tonic-gate ENTRY(strlen) 7367c478bd9Sstevel@tonic-gate mov %o0, %o1 7377c478bd9Sstevel@tonic-gate andcc %o1, 3, %o3 ! is src word aligned 7387c478bd9Sstevel@tonic-gate bz $nowalgnd 7397c478bd9Sstevel@tonic-gate clr %o0 ! length of non-zero bytes 7407c478bd9Sstevel@tonic-gate cmp %o3, 2 ! is src half-word aligned 7417c478bd9Sstevel@tonic-gate be $s2algn 7427c478bd9Sstevel@tonic-gate cmp %o3, 3 ! src is byte aligned 7437c478bd9Sstevel@tonic-gate ldub [%o1], %o3 ! move 1 or 3 bytes to align it 7447c478bd9Sstevel@tonic-gate inc 1, %o1 ! in either case, safe to do a byte 7457c478bd9Sstevel@tonic-gate be $s3algn 7467c478bd9Sstevel@tonic-gate tst %o3 7477c478bd9Sstevel@tonic-gate$s1algn: 7487c478bd9Sstevel@tonic-gate bnz,a $s2algn ! now go align dest 7497c478bd9Sstevel@tonic-gate inc 1, %o0 7507c478bd9Sstevel@tonic-gate b,a $done 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate$s2algn: 7537c478bd9Sstevel@tonic-gate lduh [%o1], %o3 ! know src is half-byte aligned 7547c478bd9Sstevel@tonic-gate inc 2, %o1 7557c478bd9Sstevel@tonic-gate srl %o3, 8, %o4 7567c478bd9Sstevel@tonic-gate tst %o4 ! is the first byte zero 7577c478bd9Sstevel@tonic-gate bnz,a 1f 7587c478bd9Sstevel@tonic-gate inc %o0 7597c478bd9Sstevel@tonic-gate b,a $done 7607c478bd9Sstevel@tonic-gate1: andcc %o3, 0xff, %o3 ! is the second byte zero 7617c478bd9Sstevel@tonic-gate bnz,a $nowalgnd 7627c478bd9Sstevel@tonic-gate inc %o0 7637c478bd9Sstevel@tonic-gate b,a $done 7647c478bd9Sstevel@tonic-gate$s3algn: 7657c478bd9Sstevel@tonic-gate bnz,a $nowalgnd 7667c478bd9Sstevel@tonic-gate inc 1, %o0 7677c478bd9Sstevel@tonic-gate b,a $done 7687c478bd9Sstevel@tonic-gate 7697c478bd9Sstevel@tonic-gate$nowalgnd: 7707c478bd9Sstevel@tonic-gate ! use trick to check if any read bytes of a word are zero 7717c478bd9Sstevel@tonic-gate ! the following two constants will generate "byte carries" 7727c478bd9Sstevel@tonic-gate ! and check if any bit in a byte is set, if all characters 7737c478bd9Sstevel@tonic-gate ! are 7bits (unsigned) this allways works, otherwise 7747c478bd9Sstevel@tonic-gate ! there is a specil case that rarely happens, see below 7757c478bd9Sstevel@tonic-gate 7767c478bd9Sstevel@tonic-gate set 0x7efefeff, %o3 7777c478bd9Sstevel@tonic-gate set 0x81010100, %o4 7787c478bd9Sstevel@tonic-gate 7797c478bd9Sstevel@tonic-gate3: ld [%o1], %o2 ! main loop 7807c478bd9Sstevel@tonic-gate inc 4, %o1 7817c478bd9Sstevel@tonic-gate add %o2, %o3, %o5 ! generate byte-carries 7827c478bd9Sstevel@tonic-gate xor %o5, %o2, %o5 ! see if orignal bits set 7837c478bd9Sstevel@tonic-gate and %o5, %o4, %o5 7847c478bd9Sstevel@tonic-gate cmp %o5, %o4 ! if ==, no zero bytes 7857c478bd9Sstevel@tonic-gate be,a 3b 7867c478bd9Sstevel@tonic-gate inc 4, %o0 7877c478bd9Sstevel@tonic-gate 7887c478bd9Sstevel@tonic-gate ! check for the zero byte and increment the count appropriately 7897c478bd9Sstevel@tonic-gate ! some information (the carry bit) is lost if bit 31 7907c478bd9Sstevel@tonic-gate ! was set (very rare), if this is the rare condition, 7917c478bd9Sstevel@tonic-gate ! return to the main loop again 7927c478bd9Sstevel@tonic-gate 7937c478bd9Sstevel@tonic-gate sethi %hi(0xff000000), %o5 ! mask used to test for terminator 7947c478bd9Sstevel@tonic-gate andcc %o2, %o5, %g0 ! check if first byte was zero 7957c478bd9Sstevel@tonic-gate bnz 1f 7967c478bd9Sstevel@tonic-gate srl %o5, 8, %o5 7977c478bd9Sstevel@tonic-gate$done: 7987c478bd9Sstevel@tonic-gate retl 7997c478bd9Sstevel@tonic-gate nop 8007c478bd9Sstevel@tonic-gate1: andcc %o2, %o5, %g0 ! check if second byte was zero 8017c478bd9Sstevel@tonic-gate bnz 1f 8027c478bd9Sstevel@tonic-gate srl %o5, 8, %o5 8037c478bd9Sstevel@tonic-gate$done1: 8047c478bd9Sstevel@tonic-gate retl 8057c478bd9Sstevel@tonic-gate inc %o0 8067c478bd9Sstevel@tonic-gate1: andcc %o2, %o5, %g0 ! check if third byte was zero 8077c478bd9Sstevel@tonic-gate bnz 1f 8087c478bd9Sstevel@tonic-gate andcc %o2, 0xff, %g0 ! check if last byte is zero 8097c478bd9Sstevel@tonic-gate$done2: 8107c478bd9Sstevel@tonic-gate retl 8117c478bd9Sstevel@tonic-gate inc 2, %o0 8127c478bd9Sstevel@tonic-gate1: bnz,a 3b 8137c478bd9Sstevel@tonic-gate inc 4, %o0 ! count of bytes 8147c478bd9Sstevel@tonic-gate$done3: 8157c478bd9Sstevel@tonic-gate retl 8167c478bd9Sstevel@tonic-gate inc 3, %o0 8177c478bd9Sstevel@tonic-gate SET_SIZE(strlen) 8187c478bd9Sstevel@tonic-gate 8197c478bd9Sstevel@tonic-gate#endif /* lint */ 8207c478bd9Sstevel@tonic-gate 8217c478bd9Sstevel@tonic-gate/* 8227c478bd9Sstevel@tonic-gate * Provide a C callable interface to the membar instruction. 8237c478bd9Sstevel@tonic-gate */ 8247c478bd9Sstevel@tonic-gate 8257c478bd9Sstevel@tonic-gate#if defined(lint) 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gatevoid 8287c478bd9Sstevel@tonic-gatemembar_ldld(void) 8297c478bd9Sstevel@tonic-gate{} 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gatevoid 8327c478bd9Sstevel@tonic-gatemembar_stld(void) 8337c478bd9Sstevel@tonic-gate{} 8347c478bd9Sstevel@tonic-gate 8357c478bd9Sstevel@tonic-gatevoid 8367c478bd9Sstevel@tonic-gatemembar_ldst(void) 8377c478bd9Sstevel@tonic-gate{} 8387c478bd9Sstevel@tonic-gate 8397c478bd9Sstevel@tonic-gatevoid 8407c478bd9Sstevel@tonic-gatemembar_stst(void) 8417c478bd9Sstevel@tonic-gate{} 8427c478bd9Sstevel@tonic-gate 8437c478bd9Sstevel@tonic-gatevoid 8447c478bd9Sstevel@tonic-gatemembar_ldld_ldst(void) 8457c478bd9Sstevel@tonic-gate{} 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gatevoid 8487c478bd9Sstevel@tonic-gatemembar_ldld_stld(void) 8497c478bd9Sstevel@tonic-gate{} 8507c478bd9Sstevel@tonic-gate 8517c478bd9Sstevel@tonic-gatevoid 8527c478bd9Sstevel@tonic-gatemembar_ldld_stst(void) 8537c478bd9Sstevel@tonic-gate{} 8547c478bd9Sstevel@tonic-gate 8557c478bd9Sstevel@tonic-gatevoid 8567c478bd9Sstevel@tonic-gatemembar_stld_ldld(void) 8577c478bd9Sstevel@tonic-gate{} 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gatevoid 8607c478bd9Sstevel@tonic-gatemembar_stld_ldst(void) 8617c478bd9Sstevel@tonic-gate{} 8627c478bd9Sstevel@tonic-gate 8637c478bd9Sstevel@tonic-gatevoid 8647c478bd9Sstevel@tonic-gatemembar_stld_stst(void) 8657c478bd9Sstevel@tonic-gate{} 8667c478bd9Sstevel@tonic-gate 8677c478bd9Sstevel@tonic-gatevoid 8687c478bd9Sstevel@tonic-gatemembar_ldst_ldld(void) 8697c478bd9Sstevel@tonic-gate{} 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gatevoid 8727c478bd9Sstevel@tonic-gatemembar_ldst_stld(void) 8737c478bd9Sstevel@tonic-gate{} 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gatevoid 8767c478bd9Sstevel@tonic-gatemembar_ldst_stst(void) 8777c478bd9Sstevel@tonic-gate{} 8787c478bd9Sstevel@tonic-gate 8797c478bd9Sstevel@tonic-gatevoid 8807c478bd9Sstevel@tonic-gatemembar_stst_ldld(void) 8817c478bd9Sstevel@tonic-gate{} 8827c478bd9Sstevel@tonic-gate 8837c478bd9Sstevel@tonic-gatevoid 8847c478bd9Sstevel@tonic-gatemembar_stst_stld(void) 8857c478bd9Sstevel@tonic-gate{} 8867c478bd9Sstevel@tonic-gate 8877c478bd9Sstevel@tonic-gatevoid 8887c478bd9Sstevel@tonic-gatemembar_stst_ldst(void) 8897c478bd9Sstevel@tonic-gate{} 8907c478bd9Sstevel@tonic-gate 8917c478bd9Sstevel@tonic-gatevoid 8927c478bd9Sstevel@tonic-gatemembar_lookaside(void) 8937c478bd9Sstevel@tonic-gate{} 8947c478bd9Sstevel@tonic-gate 8957c478bd9Sstevel@tonic-gatevoid 8967c478bd9Sstevel@tonic-gatemembar_memissue(void) 8977c478bd9Sstevel@tonic-gate{} 8987c478bd9Sstevel@tonic-gate 8997c478bd9Sstevel@tonic-gatevoid 9007c478bd9Sstevel@tonic-gatemembar_sync(void) 9017c478bd9Sstevel@tonic-gate{} 9027c478bd9Sstevel@tonic-gate 9037c478bd9Sstevel@tonic-gate#else 9047c478bd9Sstevel@tonic-gate ENTRY(membar_ldld) 9057c478bd9Sstevel@tonic-gate retl 9067c478bd9Sstevel@tonic-gate membar #LoadLoad 9077c478bd9Sstevel@tonic-gate SET_SIZE(membar_ldld) 9087c478bd9Sstevel@tonic-gate 9097c478bd9Sstevel@tonic-gate ENTRY(membar_stld) 9107c478bd9Sstevel@tonic-gate retl 9117c478bd9Sstevel@tonic-gate membar #StoreLoad 9127c478bd9Sstevel@tonic-gate SET_SIZE(membar_stld) 9137c478bd9Sstevel@tonic-gate 9147c478bd9Sstevel@tonic-gate ENTRY(membar_ldst) 9157c478bd9Sstevel@tonic-gate retl 9167c478bd9Sstevel@tonic-gate membar #LoadStore 9177c478bd9Sstevel@tonic-gate SET_SIZE(membar_ldst) 9187c478bd9Sstevel@tonic-gate 9197c478bd9Sstevel@tonic-gate ENTRY(membar_stst) 9207c478bd9Sstevel@tonic-gate retl 9217c478bd9Sstevel@tonic-gate membar #StoreStore 9227c478bd9Sstevel@tonic-gate SET_SIZE(membar_stst) 9237c478bd9Sstevel@tonic-gate 9247c478bd9Sstevel@tonic-gate ENTRY(membar_ldld_stld) 9257c478bd9Sstevel@tonic-gate ALTENTRY(membar_stld_ldld) 9267c478bd9Sstevel@tonic-gate retl 9277c478bd9Sstevel@tonic-gate membar #LoadLoad|#StoreLoad 9287c478bd9Sstevel@tonic-gate SET_SIZE(membar_stld_ldld) 9297c478bd9Sstevel@tonic-gate SET_SIZE(membar_ldld_stld) 9307c478bd9Sstevel@tonic-gate 9317c478bd9Sstevel@tonic-gate ENTRY(membar_ldld_ldst) 9327c478bd9Sstevel@tonic-gate ALTENTRY(membar_ldst_ldld) 9337c478bd9Sstevel@tonic-gate retl 9347c478bd9Sstevel@tonic-gate membar #LoadLoad|#LoadStore 9357c478bd9Sstevel@tonic-gate SET_SIZE(membar_ldst_ldld) 9367c478bd9Sstevel@tonic-gate SET_SIZE(membar_ldld_ldst) 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate ENTRY(membar_ldld_stst) 9397c478bd9Sstevel@tonic-gate ALTENTRY(membar_stst_ldld) 9407c478bd9Sstevel@tonic-gate retl 9417c478bd9Sstevel@tonic-gate membar #LoadLoad|#StoreStore 9427c478bd9Sstevel@tonic-gate SET_SIZE(membar_stst_ldld) 9437c478bd9Sstevel@tonic-gate SET_SIZE(membar_ldld_stst) 9447c478bd9Sstevel@tonic-gate 9457c478bd9Sstevel@tonic-gate ENTRY(membar_stld_ldst) 9467c478bd9Sstevel@tonic-gate ALTENTRY(membar_ldst_stld) 9477c478bd9Sstevel@tonic-gate retl 9487c478bd9Sstevel@tonic-gate membar #StoreLoad|#LoadStore 9497c478bd9Sstevel@tonic-gate SET_SIZE(membar_ldst_stld) 9507c478bd9Sstevel@tonic-gate SET_SIZE(membar_stld_ldst) 9517c478bd9Sstevel@tonic-gate 9527c478bd9Sstevel@tonic-gate ENTRY(membar_stld_stst) 9537c478bd9Sstevel@tonic-gate ALTENTRY(membar_stst_stld) 9547c478bd9Sstevel@tonic-gate retl 9557c478bd9Sstevel@tonic-gate membar #StoreLoad|#StoreStore 9567c478bd9Sstevel@tonic-gate SET_SIZE(membar_stst_stld) 9577c478bd9Sstevel@tonic-gate SET_SIZE(membar_stld_stst) 9587c478bd9Sstevel@tonic-gate 9597c478bd9Sstevel@tonic-gate ENTRY(membar_ldst_stst) 9607c478bd9Sstevel@tonic-gate ALTENTRY(membar_stst_ldst) 9617c478bd9Sstevel@tonic-gate retl 9627c478bd9Sstevel@tonic-gate membar #LoadStore|#StoreStore 9637c478bd9Sstevel@tonic-gate SET_SIZE(membar_stst_ldst) 9647c478bd9Sstevel@tonic-gate SET_SIZE(membar_ldst_stst) 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate ENTRY(membar_lookaside) 9677c478bd9Sstevel@tonic-gate retl 9687c478bd9Sstevel@tonic-gate membar #Lookaside 9697c478bd9Sstevel@tonic-gate SET_SIZE(membar_lookaside) 9707c478bd9Sstevel@tonic-gate 9717c478bd9Sstevel@tonic-gate ENTRY(membar_memissue) 9727c478bd9Sstevel@tonic-gate retl 9737c478bd9Sstevel@tonic-gate membar #MemIssue 9747c478bd9Sstevel@tonic-gate SET_SIZE(membar_memissue) 9757c478bd9Sstevel@tonic-gate 9767c478bd9Sstevel@tonic-gate ENTRY(membar_sync) 9777c478bd9Sstevel@tonic-gate retl 9787c478bd9Sstevel@tonic-gate membar #Sync 9797c478bd9Sstevel@tonic-gate SET_SIZE(membar_sync) 9807c478bd9Sstevel@tonic-gate 9817c478bd9Sstevel@tonic-gate#endif /* lint */ 9827c478bd9Sstevel@tonic-gate 9837c478bd9Sstevel@tonic-gate 9847c478bd9Sstevel@tonic-gate#if defined(lint) 9857c478bd9Sstevel@tonic-gate 9867c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 9877c478bd9Sstevel@tonic-gateint 9887c478bd9Sstevel@tonic-gatefuword64(const void *addr, uint64_t *dst) 9897c478bd9Sstevel@tonic-gate{ return (0); } 9907c478bd9Sstevel@tonic-gate 9917c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 9927c478bd9Sstevel@tonic-gateint 9937c478bd9Sstevel@tonic-gatefuword32(const void *addr, uint32_t *dst) 9947c478bd9Sstevel@tonic-gate{ return (0); } 9957c478bd9Sstevel@tonic-gate 9967c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 9977c478bd9Sstevel@tonic-gateint 9987c478bd9Sstevel@tonic-gatefuword16(const void *addr, uint16_t *dst) 9997c478bd9Sstevel@tonic-gate{ return (0); } 10007c478bd9Sstevel@tonic-gate 10017c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10027c478bd9Sstevel@tonic-gateint 10037c478bd9Sstevel@tonic-gatefuword8(const void *addr, uint8_t *dst) 10047c478bd9Sstevel@tonic-gate{ return (0); } 10057c478bd9Sstevel@tonic-gate 10067c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10077c478bd9Sstevel@tonic-gateint 10087c478bd9Sstevel@tonic-gatedtrace_ft_fuword64(const void *addr, uint64_t *dst) 10097c478bd9Sstevel@tonic-gate{ return (0); } 10107c478bd9Sstevel@tonic-gate 10117c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10127c478bd9Sstevel@tonic-gateint 10137c478bd9Sstevel@tonic-gatedtrace_ft_fuword32(const void *addr, uint32_t *dst) 10147c478bd9Sstevel@tonic-gate{ return (0); } 10157c478bd9Sstevel@tonic-gate 10167c478bd9Sstevel@tonic-gate#else /* lint */ 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate/* 10197c478bd9Sstevel@tonic-gate * Since all of the fuword() variants are so similar, we have a macro to spit 10207c478bd9Sstevel@tonic-gate * them out. 10217c478bd9Sstevel@tonic-gate */ 10227c478bd9Sstevel@tonic-gate 10237c478bd9Sstevel@tonic-gate#define FUWORD(NAME, LOAD, STORE, COPYOP) \ 10247c478bd9Sstevel@tonic-gate ENTRY(NAME); \ 10257c478bd9Sstevel@tonic-gate sethi %hi(1f), %o5; \ 10267c478bd9Sstevel@tonic-gate ldn [THREAD_REG + T_LOFAULT], %o3; \ 10277c478bd9Sstevel@tonic-gate or %o5, %lo(1f), %o5; \ 10287c478bd9Sstevel@tonic-gate membar #Sync; \ 10297c478bd9Sstevel@tonic-gate stn %o5, [THREAD_REG + T_LOFAULT]; \ 10307c478bd9Sstevel@tonic-gate LOAD [%o0]ASI_USER, %o2; \ 10317c478bd9Sstevel@tonic-gate membar #Sync; \ 10327c478bd9Sstevel@tonic-gate stn %o3, [THREAD_REG + T_LOFAULT]; \ 10337c478bd9Sstevel@tonic-gate mov 0, %o0; \ 10347c478bd9Sstevel@tonic-gate retl; \ 10357c478bd9Sstevel@tonic-gate STORE %o2, [%o1]; \ 10367c478bd9Sstevel@tonic-gate1: \ 10377c478bd9Sstevel@tonic-gate membar #Sync; \ 10387c478bd9Sstevel@tonic-gate stn %o3, [THREAD_REG + T_LOFAULT]; \ 10397c478bd9Sstevel@tonic-gate ldn [THREAD_REG + T_COPYOPS], %o2; \ 10407c478bd9Sstevel@tonic-gate brz %o2, 2f; \ 10417c478bd9Sstevel@tonic-gate nop; \ 10427c478bd9Sstevel@tonic-gate ldn [%o2 + COPYOP], %g1; \ 10437c478bd9Sstevel@tonic-gate jmp %g1; \ 10447c478bd9Sstevel@tonic-gate nop; \ 10457c478bd9Sstevel@tonic-gate2: \ 10467c478bd9Sstevel@tonic-gate retl; \ 10477c478bd9Sstevel@tonic-gate mov -1, %o0; \ 10487c478bd9Sstevel@tonic-gate SET_SIZE(NAME) 10497c478bd9Sstevel@tonic-gate 10507c478bd9Sstevel@tonic-gate FUWORD(fuword64, ldxa, stx, CP_FUWORD64) 10517c478bd9Sstevel@tonic-gate FUWORD(fuword32, lda, st, CP_FUWORD32) 10527c478bd9Sstevel@tonic-gate FUWORD(fuword16, lduha, sth, CP_FUWORD16) 10537c478bd9Sstevel@tonic-gate FUWORD(fuword8, lduba, stb, CP_FUWORD8) 10547c478bd9Sstevel@tonic-gate 10557c478bd9Sstevel@tonic-gate#endif /* lint */ 10567c478bd9Sstevel@tonic-gate 10577c478bd9Sstevel@tonic-gate 10587c478bd9Sstevel@tonic-gate#if defined(lint) 10597c478bd9Sstevel@tonic-gate 10607c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10617c478bd9Sstevel@tonic-gateint 10627c478bd9Sstevel@tonic-gatesuword64(void *addr, uint64_t value) 10637c478bd9Sstevel@tonic-gate{ return (0); } 10647c478bd9Sstevel@tonic-gate 10657c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10667c478bd9Sstevel@tonic-gateint 10677c478bd9Sstevel@tonic-gatesuword32(void *addr, uint32_t value) 10687c478bd9Sstevel@tonic-gate{ return (0); } 10697c478bd9Sstevel@tonic-gate 10707c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10717c478bd9Sstevel@tonic-gateint 10727c478bd9Sstevel@tonic-gatesuword16(void *addr, uint16_t value) 10737c478bd9Sstevel@tonic-gate{ return (0); } 10747c478bd9Sstevel@tonic-gate 10757c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10767c478bd9Sstevel@tonic-gateint 10777c478bd9Sstevel@tonic-gatesuword8(void *addr, uint8_t value) 10787c478bd9Sstevel@tonic-gate{ return (0); } 10797c478bd9Sstevel@tonic-gate 10807c478bd9Sstevel@tonic-gate#else /* lint */ 10817c478bd9Sstevel@tonic-gate 10827c478bd9Sstevel@tonic-gate/* 10837c478bd9Sstevel@tonic-gate * Since all of the suword() variants are so similar, we have a macro to spit 10847c478bd9Sstevel@tonic-gate * them out. 10857c478bd9Sstevel@tonic-gate */ 10867c478bd9Sstevel@tonic-gate 10877c478bd9Sstevel@tonic-gate#define SUWORD(NAME, STORE, COPYOP) \ 10887c478bd9Sstevel@tonic-gate ENTRY(NAME) \ 10897c478bd9Sstevel@tonic-gate sethi %hi(1f), %o5; \ 10907c478bd9Sstevel@tonic-gate ldn [THREAD_REG + T_LOFAULT], %o3; \ 10917c478bd9Sstevel@tonic-gate or %o5, %lo(1f), %o5; \ 10927c478bd9Sstevel@tonic-gate membar #Sync; \ 10937c478bd9Sstevel@tonic-gate stn %o5, [THREAD_REG + T_LOFAULT]; \ 10947c478bd9Sstevel@tonic-gate STORE %o1, [%o0]ASI_USER; \ 10957c478bd9Sstevel@tonic-gate membar #Sync; \ 10967c478bd9Sstevel@tonic-gate stn %o3, [THREAD_REG + T_LOFAULT]; \ 10977c478bd9Sstevel@tonic-gate retl; \ 10987c478bd9Sstevel@tonic-gate clr %o0; \ 10997c478bd9Sstevel@tonic-gate1: \ 11007c478bd9Sstevel@tonic-gate membar #Sync; \ 11017c478bd9Sstevel@tonic-gate stn %o3, [THREAD_REG + T_LOFAULT]; \ 11027c478bd9Sstevel@tonic-gate ldn [THREAD_REG + T_COPYOPS], %o2; \ 11037c478bd9Sstevel@tonic-gate brz %o2, 2f; \ 11047c478bd9Sstevel@tonic-gate nop; \ 11057c478bd9Sstevel@tonic-gate ldn [%o2 + COPYOP], %g1; \ 11067c478bd9Sstevel@tonic-gate jmp %g1; \ 11077c478bd9Sstevel@tonic-gate nop; \ 11087c478bd9Sstevel@tonic-gate2: \ 11097c478bd9Sstevel@tonic-gate retl; \ 11107c478bd9Sstevel@tonic-gate mov -1, %o0; \ 11117c478bd9Sstevel@tonic-gate SET_SIZE(NAME) 11127c478bd9Sstevel@tonic-gate 11137c478bd9Sstevel@tonic-gate SUWORD(suword64, stxa, CP_SUWORD64) 11147c478bd9Sstevel@tonic-gate SUWORD(suword32, sta, CP_SUWORD32) 11157c478bd9Sstevel@tonic-gate SUWORD(suword16, stha, CP_SUWORD16) 11167c478bd9Sstevel@tonic-gate SUWORD(suword8, stba, CP_SUWORD8) 11177c478bd9Sstevel@tonic-gate 11187c478bd9Sstevel@tonic-gate#endif /* lint */ 11197c478bd9Sstevel@tonic-gate 11207c478bd9Sstevel@tonic-gate#if defined(lint) 11217c478bd9Sstevel@tonic-gate 11227c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 11237c478bd9Sstevel@tonic-gatevoid 11247c478bd9Sstevel@tonic-gatefuword8_noerr(const void *addr, uint8_t *dst) 11257c478bd9Sstevel@tonic-gate{} 11267c478bd9Sstevel@tonic-gate 11277c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 11287c478bd9Sstevel@tonic-gatevoid 11297c478bd9Sstevel@tonic-gatefuword16_noerr(const void *addr, uint16_t *dst) 11307c478bd9Sstevel@tonic-gate{} 11317c478bd9Sstevel@tonic-gate 11327c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 11337c478bd9Sstevel@tonic-gatevoid 11347c478bd9Sstevel@tonic-gatefuword32_noerr(const void *addr, uint32_t *dst) 11357c478bd9Sstevel@tonic-gate{} 11367c478bd9Sstevel@tonic-gate 11377c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 11387c478bd9Sstevel@tonic-gatevoid 11397c478bd9Sstevel@tonic-gatefuword64_noerr(const void *addr, uint64_t *dst) 11407c478bd9Sstevel@tonic-gate{} 11417c478bd9Sstevel@tonic-gate 11427c478bd9Sstevel@tonic-gate#else /* lint */ 11437c478bd9Sstevel@tonic-gate 11447c478bd9Sstevel@tonic-gate ENTRY(fuword8_noerr) 11457c478bd9Sstevel@tonic-gate lduba [%o0]ASI_USER, %o0 11467c478bd9Sstevel@tonic-gate retl 11477c478bd9Sstevel@tonic-gate stb %o0, [%o1] 11487c478bd9Sstevel@tonic-gate SET_SIZE(fuword8_noerr) 11497c478bd9Sstevel@tonic-gate 11507c478bd9Sstevel@tonic-gate ENTRY(fuword16_noerr) 11517c478bd9Sstevel@tonic-gate lduha [%o0]ASI_USER, %o0 11527c478bd9Sstevel@tonic-gate retl 11537c478bd9Sstevel@tonic-gate sth %o0, [%o1] 11547c478bd9Sstevel@tonic-gate SET_SIZE(fuword16_noerr) 11557c478bd9Sstevel@tonic-gate 11567c478bd9Sstevel@tonic-gate ENTRY(fuword32_noerr) 11577c478bd9Sstevel@tonic-gate lda [%o0]ASI_USER, %o0 11587c478bd9Sstevel@tonic-gate retl 11597c478bd9Sstevel@tonic-gate st %o0, [%o1] 11607c478bd9Sstevel@tonic-gate SET_SIZE(fuword32_noerr) 11617c478bd9Sstevel@tonic-gate 11627c478bd9Sstevel@tonic-gate ENTRY(fuword64_noerr) 11637c478bd9Sstevel@tonic-gate ldxa [%o0]ASI_USER, %o0 11647c478bd9Sstevel@tonic-gate retl 11657c478bd9Sstevel@tonic-gate stx %o0, [%o1] 11667c478bd9Sstevel@tonic-gate SET_SIZE(fuword64_noerr) 11677c478bd9Sstevel@tonic-gate 11687c478bd9Sstevel@tonic-gate#endif /* lint */ 11697c478bd9Sstevel@tonic-gate 11707c478bd9Sstevel@tonic-gate#if defined(lint) 11717c478bd9Sstevel@tonic-gate 11727c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 11737c478bd9Sstevel@tonic-gatevoid 11747c478bd9Sstevel@tonic-gatesuword8_noerr(void *addr, uint8_t value) 11757c478bd9Sstevel@tonic-gate{} 11767c478bd9Sstevel@tonic-gate 11777c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 11787c478bd9Sstevel@tonic-gatevoid 11797c478bd9Sstevel@tonic-gatesuword16_noerr(void *addr, uint16_t value) 11807c478bd9Sstevel@tonic-gate{} 11817c478bd9Sstevel@tonic-gate 11827c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 11837c478bd9Sstevel@tonic-gatevoid 11847c478bd9Sstevel@tonic-gatesuword32_noerr(void *addr, uint32_t value) 11857c478bd9Sstevel@tonic-gate{} 11867c478bd9Sstevel@tonic-gate 11877c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 11887c478bd9Sstevel@tonic-gatevoid 11897c478bd9Sstevel@tonic-gatesuword64_noerr(void *addr, uint64_t value) 11907c478bd9Sstevel@tonic-gate{} 11917c478bd9Sstevel@tonic-gate 11927c478bd9Sstevel@tonic-gate#else /* lint */ 11937c478bd9Sstevel@tonic-gate 11947c478bd9Sstevel@tonic-gate ENTRY(suword8_noerr) 11957c478bd9Sstevel@tonic-gate retl 11967c478bd9Sstevel@tonic-gate stba %o1, [%o0]ASI_USER 11977c478bd9Sstevel@tonic-gate SET_SIZE(suword8_noerr) 11987c478bd9Sstevel@tonic-gate 11997c478bd9Sstevel@tonic-gate ENTRY(suword16_noerr) 12007c478bd9Sstevel@tonic-gate retl 12017c478bd9Sstevel@tonic-gate stha %o1, [%o0]ASI_USER 12027c478bd9Sstevel@tonic-gate SET_SIZE(suword16_noerr) 12037c478bd9Sstevel@tonic-gate 12047c478bd9Sstevel@tonic-gate ENTRY(suword32_noerr) 12057c478bd9Sstevel@tonic-gate retl 12067c478bd9Sstevel@tonic-gate sta %o1, [%o0]ASI_USER 12077c478bd9Sstevel@tonic-gate SET_SIZE(suword32_noerr) 12087c478bd9Sstevel@tonic-gate 12097c478bd9Sstevel@tonic-gate ENTRY(suword64_noerr) 12107c478bd9Sstevel@tonic-gate retl 12117c478bd9Sstevel@tonic-gate stxa %o1, [%o0]ASI_USER 12127c478bd9Sstevel@tonic-gate SET_SIZE(suword64_noerr) 12137c478bd9Sstevel@tonic-gate 12147c478bd9Sstevel@tonic-gate#endif /* lint */ 12157c478bd9Sstevel@tonic-gate 12167c478bd9Sstevel@tonic-gate#if defined(__lint) 12177c478bd9Sstevel@tonic-gate 12187c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 12197c478bd9Sstevel@tonic-gateint 12207c478bd9Sstevel@tonic-gatesubyte(void *addr, uchar_t value) 12217c478bd9Sstevel@tonic-gate{ return (0); } 12227c478bd9Sstevel@tonic-gate 12237c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 12247c478bd9Sstevel@tonic-gatevoid 12257c478bd9Sstevel@tonic-gatesubyte_noerr(void *addr, uchar_t value) 12267c478bd9Sstevel@tonic-gate{} 12277c478bd9Sstevel@tonic-gate 12287c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 12297c478bd9Sstevel@tonic-gateint 12307c478bd9Sstevel@tonic-gatefulword(const void *addr, ulong_t *valuep) 12317c478bd9Sstevel@tonic-gate{ return (0); } 12327c478bd9Sstevel@tonic-gate 12337c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 12347c478bd9Sstevel@tonic-gatevoid 12357c478bd9Sstevel@tonic-gatefulword_noerr(const void *addr, ulong_t *valuep) 12367c478bd9Sstevel@tonic-gate{} 12377c478bd9Sstevel@tonic-gate 12387c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 12397c478bd9Sstevel@tonic-gateint 12407c478bd9Sstevel@tonic-gatesulword(void *addr, ulong_t valuep) 12417c478bd9Sstevel@tonic-gate{ return (0); } 12427c478bd9Sstevel@tonic-gate 12437c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 12447c478bd9Sstevel@tonic-gatevoid 12457c478bd9Sstevel@tonic-gatesulword_noerr(void *addr, ulong_t valuep) 12467c478bd9Sstevel@tonic-gate{} 12477c478bd9Sstevel@tonic-gate 12487c478bd9Sstevel@tonic-gate#else 12497c478bd9Sstevel@tonic-gate 12507c478bd9Sstevel@tonic-gate .weak subyte 12517c478bd9Sstevel@tonic-gate subyte=suword8 12527c478bd9Sstevel@tonic-gate .weak subyte_noerr 12537c478bd9Sstevel@tonic-gate subyte_noerr=suword8_noerr 12547c478bd9Sstevel@tonic-gate#ifdef _LP64 12557c478bd9Sstevel@tonic-gate .weak fulword 12567c478bd9Sstevel@tonic-gate fulword=fuword64 12577c478bd9Sstevel@tonic-gate .weak fulword_noerr 12587c478bd9Sstevel@tonic-gate fulword_noerr=fuword64_noerr 12597c478bd9Sstevel@tonic-gate .weak sulword 12607c478bd9Sstevel@tonic-gate sulword=suword64 12617c478bd9Sstevel@tonic-gate .weak sulword_noerr 12627c478bd9Sstevel@tonic-gate sulword_noerr=suword64_noerr 12637c478bd9Sstevel@tonic-gate#else 12647c478bd9Sstevel@tonic-gate .weak fulword 12657c478bd9Sstevel@tonic-gate fulword=fuword32 12667c478bd9Sstevel@tonic-gate .weak fulword_noerr 12677c478bd9Sstevel@tonic-gate fulword_noerr=fuword32_noerr 12687c478bd9Sstevel@tonic-gate .weak sulword 12697c478bd9Sstevel@tonic-gate sulword=suword32 12707c478bd9Sstevel@tonic-gate .weak sulword_noerr 12717c478bd9Sstevel@tonic-gate sulword_noerr=suword32_noerr 12727c478bd9Sstevel@tonic-gate#endif /* LP64 */ 12737c478bd9Sstevel@tonic-gate 12747c478bd9Sstevel@tonic-gate#endif /* lint */ 12757c478bd9Sstevel@tonic-gate 1276*023e71deSHaik Aftandilian/* 1277*023e71deSHaik Aftandilian * We define rdtick here, but not for sun4v. On sun4v systems, the %tick 1278*023e71deSHaik Aftandilian * and %stick should not be read directly without considering the tick 1279*023e71deSHaik Aftandilian * and stick offset kernel variables introduced to support sun4v OS 1280*023e71deSHaik Aftandilian * suspension. 1281*023e71deSHaik Aftandilian */ 1282*023e71deSHaik Aftandilian#if !defined (sun4v) 12837c478bd9Sstevel@tonic-gate 12847c478bd9Sstevel@tonic-gate#if defined (lint) 12857c478bd9Sstevel@tonic-gate 12867c478bd9Sstevel@tonic-gatehrtime_t 12877c478bd9Sstevel@tonic-gaterdtick() 12887c478bd9Sstevel@tonic-gate{ return (0); } 12897c478bd9Sstevel@tonic-gate 1290*023e71deSHaik Aftandilian#else /* lint */ 1291*023e71deSHaik Aftandilian 12927c478bd9Sstevel@tonic-gate ENTRY(rdtick) 12937c478bd9Sstevel@tonic-gate retl 12947c478bd9Sstevel@tonic-gate rd %tick, %o0 12957c478bd9Sstevel@tonic-gate SET_SIZE(rdtick) 1296*023e71deSHaik Aftandilian 1297*023e71deSHaik Aftandilian#endif /* lint */ 1298*023e71deSHaik Aftandilian 1299*023e71deSHaik Aftandilian#endif /* !sun4v */ 13007c478bd9Sstevel@tonic-gate 13017c478bd9Sstevel@tonic-gate/* 13027c478bd9Sstevel@tonic-gate * Set tba to given address, no side effects. 13037c478bd9Sstevel@tonic-gate */ 13047c478bd9Sstevel@tonic-gate#if defined (lint) 13057c478bd9Sstevel@tonic-gate 13067c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 13077c478bd9Sstevel@tonic-gatevoid * 13087c478bd9Sstevel@tonic-gateset_tba(void *new_tba) 13097c478bd9Sstevel@tonic-gate{ return (0); } 13107c478bd9Sstevel@tonic-gate 13117c478bd9Sstevel@tonic-gate#else /* lint */ 13127c478bd9Sstevel@tonic-gate 13137c478bd9Sstevel@tonic-gate ENTRY(set_tba) 13147c478bd9Sstevel@tonic-gate mov %o0, %o1 13157c478bd9Sstevel@tonic-gate rdpr %tba, %o0 13167c478bd9Sstevel@tonic-gate wrpr %o1, %tba 13177c478bd9Sstevel@tonic-gate retl 13187c478bd9Sstevel@tonic-gate nop 13197c478bd9Sstevel@tonic-gate SET_SIZE(set_tba) 13207c478bd9Sstevel@tonic-gate 13217c478bd9Sstevel@tonic-gate#endif /* lint */ 13227c478bd9Sstevel@tonic-gate 13237c478bd9Sstevel@tonic-gate#if defined (lint) 13247c478bd9Sstevel@tonic-gate 13257c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 13267c478bd9Sstevel@tonic-gatevoid * 13277c478bd9Sstevel@tonic-gateget_tba() 13287c478bd9Sstevel@tonic-gate{ return (0); } 13297c478bd9Sstevel@tonic-gate 13307c478bd9Sstevel@tonic-gate#else /* lint */ 13317c478bd9Sstevel@tonic-gate 13327c478bd9Sstevel@tonic-gate ENTRY(get_tba) 13337c478bd9Sstevel@tonic-gate retl 13347c478bd9Sstevel@tonic-gate rdpr %tba, %o0 13357c478bd9Sstevel@tonic-gate SET_SIZE(get_tba) 13367c478bd9Sstevel@tonic-gate 13377c478bd9Sstevel@tonic-gate#endif /* lint */ 13387c478bd9Sstevel@tonic-gate 13397c478bd9Sstevel@tonic-gate#if defined(lint) || defined(__lint) 13407c478bd9Sstevel@tonic-gate 13417c478bd9Sstevel@tonic-gate/* ARGSUSED */ 13427c478bd9Sstevel@tonic-gatevoid 13437c478bd9Sstevel@tonic-gatesetpstate(u_int pstate) 13447c478bd9Sstevel@tonic-gate{} 13457c478bd9Sstevel@tonic-gate 13467c478bd9Sstevel@tonic-gate#else /* lint */ 13477c478bd9Sstevel@tonic-gate 13487c478bd9Sstevel@tonic-gate ENTRY_NP(setpstate) 13497c478bd9Sstevel@tonic-gate retl 13507c478bd9Sstevel@tonic-gate wrpr %g0, %o0, %pstate 13517c478bd9Sstevel@tonic-gate SET_SIZE(setpstate) 13527c478bd9Sstevel@tonic-gate 13537c478bd9Sstevel@tonic-gate#endif /* lint */ 13547c478bd9Sstevel@tonic-gate 13557c478bd9Sstevel@tonic-gate#if defined(lint) || defined(__lint) 13567c478bd9Sstevel@tonic-gate 13577c478bd9Sstevel@tonic-gateu_int 13587c478bd9Sstevel@tonic-gategetpstate(void) 13597c478bd9Sstevel@tonic-gate{ return(0); } 13607c478bd9Sstevel@tonic-gate 13617c478bd9Sstevel@tonic-gate#else /* lint */ 13627c478bd9Sstevel@tonic-gate 13637c478bd9Sstevel@tonic-gate ENTRY_NP(getpstate) 13647c478bd9Sstevel@tonic-gate retl 13657c478bd9Sstevel@tonic-gate rdpr %pstate, %o0 13667c478bd9Sstevel@tonic-gate SET_SIZE(getpstate) 13677c478bd9Sstevel@tonic-gate 13687c478bd9Sstevel@tonic-gate#endif /* lint */ 13697c478bd9Sstevel@tonic-gate 13707c478bd9Sstevel@tonic-gate#if defined(lint) || defined(__lint) 13717c478bd9Sstevel@tonic-gate 13727c478bd9Sstevel@tonic-gatedtrace_icookie_t 13737c478bd9Sstevel@tonic-gatedtrace_interrupt_disable(void) 13747c478bd9Sstevel@tonic-gate{ return (0); } 13757c478bd9Sstevel@tonic-gate 13767c478bd9Sstevel@tonic-gate#else /* lint */ 13777c478bd9Sstevel@tonic-gate 13787c478bd9Sstevel@tonic-gate ENTRY_NP(dtrace_interrupt_disable) 13797c478bd9Sstevel@tonic-gate rdpr %pstate, %o0 13807c478bd9Sstevel@tonic-gate andn %o0, PSTATE_IE, %o1 13817c478bd9Sstevel@tonic-gate retl 13827c478bd9Sstevel@tonic-gate wrpr %g0, %o1, %pstate 13837c478bd9Sstevel@tonic-gate SET_SIZE(dtrace_interrupt_disable) 13847c478bd9Sstevel@tonic-gate 13857c478bd9Sstevel@tonic-gate#endif /* lint */ 13867c478bd9Sstevel@tonic-gate 13877c478bd9Sstevel@tonic-gate#if defined(lint) || defined(__lint) 13887c478bd9Sstevel@tonic-gate 13897c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 13907c478bd9Sstevel@tonic-gatevoid 13917c478bd9Sstevel@tonic-gatedtrace_interrupt_enable(dtrace_icookie_t cookie) 13927c478bd9Sstevel@tonic-gate{} 13937c478bd9Sstevel@tonic-gate 13947c478bd9Sstevel@tonic-gate#else 13957c478bd9Sstevel@tonic-gate 13967c478bd9Sstevel@tonic-gate ENTRY_NP(dtrace_interrupt_enable) 13977c478bd9Sstevel@tonic-gate retl 13987c478bd9Sstevel@tonic-gate wrpr %g0, %o0, %pstate 13997c478bd9Sstevel@tonic-gate SET_SIZE(dtrace_interrupt_enable) 14007c478bd9Sstevel@tonic-gate 14017c478bd9Sstevel@tonic-gate#endif /* lint*/ 14027c478bd9Sstevel@tonic-gate 14037c478bd9Sstevel@tonic-gate#if defined(lint) 14047c478bd9Sstevel@tonic-gate 14057c478bd9Sstevel@tonic-gatevoid 14067c478bd9Sstevel@tonic-gatedtrace_membar_producer(void) 14077c478bd9Sstevel@tonic-gate{} 14087c478bd9Sstevel@tonic-gate 14097c478bd9Sstevel@tonic-gatevoid 14107c478bd9Sstevel@tonic-gatedtrace_membar_consumer(void) 14117c478bd9Sstevel@tonic-gate{} 14127c478bd9Sstevel@tonic-gate 14137c478bd9Sstevel@tonic-gate#else /* lint */ 14147c478bd9Sstevel@tonic-gate 14157c478bd9Sstevel@tonic-gate#ifdef SF_ERRATA_51 14167c478bd9Sstevel@tonic-gate .align 32 14177c478bd9Sstevel@tonic-gate ENTRY(dtrace_membar_return) 14187c478bd9Sstevel@tonic-gate retl 14197c478bd9Sstevel@tonic-gate nop 14207c478bd9Sstevel@tonic-gate SET_SIZE(dtrace_membar_return) 14217c478bd9Sstevel@tonic-gate#define DTRACE_MEMBAR_RETURN ba,pt %icc, dtrace_membar_return 14227c478bd9Sstevel@tonic-gate#else 14237c478bd9Sstevel@tonic-gate#define DTRACE_MEMBAR_RETURN retl 14247c478bd9Sstevel@tonic-gate#endif 14257c478bd9Sstevel@tonic-gate 14267c478bd9Sstevel@tonic-gate ENTRY(dtrace_membar_producer) 14277c478bd9Sstevel@tonic-gate DTRACE_MEMBAR_RETURN 14287c478bd9Sstevel@tonic-gate membar #StoreStore 14297c478bd9Sstevel@tonic-gate SET_SIZE(dtrace_membar_producer) 14307c478bd9Sstevel@tonic-gate 14317c478bd9Sstevel@tonic-gate ENTRY(dtrace_membar_consumer) 14327c478bd9Sstevel@tonic-gate DTRACE_MEMBAR_RETURN 14337c478bd9Sstevel@tonic-gate membar #LoadLoad 14347c478bd9Sstevel@tonic-gate SET_SIZE(dtrace_membar_consumer) 14357c478bd9Sstevel@tonic-gate 14367c478bd9Sstevel@tonic-gate#endif /* lint */ 14377c478bd9Sstevel@tonic-gate 14387c478bd9Sstevel@tonic-gate#if defined(lint) || defined(__lint) 14397c478bd9Sstevel@tonic-gate 14407c478bd9Sstevel@tonic-gatevoid 14417c478bd9Sstevel@tonic-gatedtrace_flush_windows(void) 14427c478bd9Sstevel@tonic-gate{} 14437c478bd9Sstevel@tonic-gate 14447c478bd9Sstevel@tonic-gate#else 14457c478bd9Sstevel@tonic-gate 14467c478bd9Sstevel@tonic-gate ENTRY_NP(dtrace_flush_windows) 14477c478bd9Sstevel@tonic-gate retl 14487c478bd9Sstevel@tonic-gate flushw 14497c478bd9Sstevel@tonic-gate SET_SIZE(dtrace_flush_windows) 14507c478bd9Sstevel@tonic-gate 14517c478bd9Sstevel@tonic-gate#endif /* lint */ 14527c478bd9Sstevel@tonic-gate 14537c478bd9Sstevel@tonic-gate#if defined(lint) 14547c478bd9Sstevel@tonic-gate 14557c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 14567c478bd9Sstevel@tonic-gateint 14577c478bd9Sstevel@tonic-gategetpcstack_top(pc_t *pcstack, int limit, uintptr_t *lastfp, pc_t *lastpc) 14587c478bd9Sstevel@tonic-gate{ 14597c478bd9Sstevel@tonic-gate return (0); 14607c478bd9Sstevel@tonic-gate} 14617c478bd9Sstevel@tonic-gate 14627c478bd9Sstevel@tonic-gate#else /* lint */ 14637c478bd9Sstevel@tonic-gate 14647c478bd9Sstevel@tonic-gate /* 14657c478bd9Sstevel@tonic-gate * %g1 pcstack 14667c478bd9Sstevel@tonic-gate * %g2 iteration count 14677c478bd9Sstevel@tonic-gate * %g3 final %fp 14687c478bd9Sstevel@tonic-gate * %g4 final %i7 14697c478bd9Sstevel@tonic-gate * %g5 saved %cwp (so we can get back to the original window) 14707c478bd9Sstevel@tonic-gate * 14717c478bd9Sstevel@tonic-gate * %o0 pcstack / return value (iteration count) 14727c478bd9Sstevel@tonic-gate * %o1 limit / saved %cansave 14737c478bd9Sstevel@tonic-gate * %o2 lastfp 14747c478bd9Sstevel@tonic-gate * %o3 lastpc 14757c478bd9Sstevel@tonic-gate * %o4 saved %canrestore 14767c478bd9Sstevel@tonic-gate * %o5 saved %pstate (to restore interrupts) 14777c478bd9Sstevel@tonic-gate * 14787c478bd9Sstevel@tonic-gate * Note: The frame pointer returned via lastfp is safe to use as 14797c478bd9Sstevel@tonic-gate * long as getpcstack_top() returns either (0) or a value less 14807c478bd9Sstevel@tonic-gate * than (limit). 14817c478bd9Sstevel@tonic-gate */ 14827c478bd9Sstevel@tonic-gate ENTRY_NP(getpcstack_top) 14837c478bd9Sstevel@tonic-gate 14847c478bd9Sstevel@tonic-gate rdpr %pstate, %o5 14857c478bd9Sstevel@tonic-gate andn %o5, PSTATE_IE, %g1 14867c478bd9Sstevel@tonic-gate wrpr %g0, %g1, %pstate ! disable interrupts 14877c478bd9Sstevel@tonic-gate 14887c478bd9Sstevel@tonic-gate mov %o0, %g1 ! we need the pcstack pointer while 14897c478bd9Sstevel@tonic-gate ! we're visiting other windows 14907c478bd9Sstevel@tonic-gate 14917c478bd9Sstevel@tonic-gate rdpr %canrestore, %g2 ! number of available windows 14927c478bd9Sstevel@tonic-gate sub %g2, 1, %g2 ! account for skipped frame 14937c478bd9Sstevel@tonic-gate cmp %g2, %o1 ! compare with limit 14947c478bd9Sstevel@tonic-gate movg %icc, %o1, %g2 ! %g2 = min(%canrestore-1, limit) 14957c478bd9Sstevel@tonic-gate 14967c478bd9Sstevel@tonic-gate brlez,a,pn %g2, 3f ! Use slow path if count <= 0 -- 14977c478bd9Sstevel@tonic-gate clr %o0 ! return zero. 14987c478bd9Sstevel@tonic-gate 14997c478bd9Sstevel@tonic-gate mov %g2, %o0 ! set up return value 15007c478bd9Sstevel@tonic-gate 15017c478bd9Sstevel@tonic-gate rdpr %cwp, %g5 ! remember the register window state 15027c478bd9Sstevel@tonic-gate rdpr %cansave, %o1 ! 'restore' changes, so we can undo 15037c478bd9Sstevel@tonic-gate rdpr %canrestore, %o4 ! its effects when we finish. 15047c478bd9Sstevel@tonic-gate 15057c478bd9Sstevel@tonic-gate restore ! skip caller's frame 15067c478bd9Sstevel@tonic-gate1: 15077c478bd9Sstevel@tonic-gate st %i7, [%g1] ! stash return address in pcstack 15087c478bd9Sstevel@tonic-gate restore ! go to the next frame 15097c478bd9Sstevel@tonic-gate subcc %g2, 1, %g2 ! decrement the count 15107c478bd9Sstevel@tonic-gate bnz,pt %icc, 1b ! loop until count reaches 0 15117c478bd9Sstevel@tonic-gate add %g1, 4, %g1 ! increment pcstack 15127c478bd9Sstevel@tonic-gate 15137c478bd9Sstevel@tonic-gate mov %i6, %g3 ! copy the final %fp and return PC 15147c478bd9Sstevel@tonic-gate mov %i7, %g4 ! aside so we can return them to our 15157c478bd9Sstevel@tonic-gate ! caller 15167c478bd9Sstevel@tonic-gate 15177c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %cwp ! jump back to the original window 15187c478bd9Sstevel@tonic-gate wrpr %g0, %o1, %cansave ! and restore the original register 15197c478bd9Sstevel@tonic-gate wrpr %g0, %o4, %canrestore ! window state. 15207c478bd9Sstevel@tonic-gate2: 15217c478bd9Sstevel@tonic-gate stn %g3, [%o2] ! store the frame pointer and pc 15227c478bd9Sstevel@tonic-gate st %g4, [%o3] ! so our caller can continue the trace 15237c478bd9Sstevel@tonic-gate 15247c478bd9Sstevel@tonic-gate retl ! return to caller 15257c478bd9Sstevel@tonic-gate wrpr %g0, %o5, %pstate ! restore interrupts 15267c478bd9Sstevel@tonic-gate 15277c478bd9Sstevel@tonic-gate3: 15287c478bd9Sstevel@tonic-gate flushw ! flush register windows, then 15297c478bd9Sstevel@tonic-gate ldn [%fp + STACK_BIAS + 14*CLONGSIZE], %g3 ! load initial fp 15307c478bd9Sstevel@tonic-gate ba 2b 15317c478bd9Sstevel@tonic-gate ldn [%fp + STACK_BIAS + 15*CLONGSIZE], %g4 ! and pc 15327c478bd9Sstevel@tonic-gate SET_SIZE(getpcstack_top) 15337c478bd9Sstevel@tonic-gate 15347c478bd9Sstevel@tonic-gate#endif /* lint */ 15357c478bd9Sstevel@tonic-gate 15367c478bd9Sstevel@tonic-gate#if defined(lint) || defined(__lint) 15377c478bd9Sstevel@tonic-gate 15387c478bd9Sstevel@tonic-gate/* ARGSUSED */ 15397c478bd9Sstevel@tonic-gatevoid 15407c478bd9Sstevel@tonic-gatesetwstate(u_int wstate) 15417c478bd9Sstevel@tonic-gate{} 15427c478bd9Sstevel@tonic-gate 15437c478bd9Sstevel@tonic-gate#else /* lint */ 15447c478bd9Sstevel@tonic-gate 15457c478bd9Sstevel@tonic-gate ENTRY_NP(setwstate) 15467c478bd9Sstevel@tonic-gate retl 15477c478bd9Sstevel@tonic-gate wrpr %g0, %o0, %wstate 15487c478bd9Sstevel@tonic-gate SET_SIZE(setwstate) 15497c478bd9Sstevel@tonic-gate 15507c478bd9Sstevel@tonic-gate#endif /* lint */ 15517c478bd9Sstevel@tonic-gate 15527c478bd9Sstevel@tonic-gate 15537c478bd9Sstevel@tonic-gate#if defined(lint) || defined(__lint) 15547c478bd9Sstevel@tonic-gate 15557c478bd9Sstevel@tonic-gateu_int 15567c478bd9Sstevel@tonic-gategetwstate(void) 15577c478bd9Sstevel@tonic-gate{ return(0); } 15587c478bd9Sstevel@tonic-gate 15597c478bd9Sstevel@tonic-gate#else /* lint */ 15607c478bd9Sstevel@tonic-gate 15617c478bd9Sstevel@tonic-gate ENTRY_NP(getwstate) 15627c478bd9Sstevel@tonic-gate retl 15637c478bd9Sstevel@tonic-gate rdpr %wstate, %o0 15647c478bd9Sstevel@tonic-gate SET_SIZE(getwstate) 15657c478bd9Sstevel@tonic-gate 15667c478bd9Sstevel@tonic-gate#endif /* lint */ 15677c478bd9Sstevel@tonic-gate 15687c478bd9Sstevel@tonic-gate 15697c478bd9Sstevel@tonic-gate/* 15707c478bd9Sstevel@tonic-gate * int panic_trigger(int *tp) 15717c478bd9Sstevel@tonic-gate * 15727c478bd9Sstevel@tonic-gate * A panic trigger is a word which is updated atomically and can only be set 15737c478bd9Sstevel@tonic-gate * once. We atomically store 0xFF into the high byte and load the old value. 15747c478bd9Sstevel@tonic-gate * If the byte was 0xFF, the trigger has already been activated and we fail. 15757c478bd9Sstevel@tonic-gate * If the previous value was 0 or not 0xFF, we succeed. This allows a 15767c478bd9Sstevel@tonic-gate * partially corrupt trigger to still trigger correctly. DTrace has its own 15777c478bd9Sstevel@tonic-gate * version of this function to allow it to panic correctly from probe context. 15787c478bd9Sstevel@tonic-gate */ 15797c478bd9Sstevel@tonic-gate#if defined(lint) 15807c478bd9Sstevel@tonic-gate 15817c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 15827c478bd9Sstevel@tonic-gateint panic_trigger(int *tp) { return (0); } 15837c478bd9Sstevel@tonic-gate 15847c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 15857c478bd9Sstevel@tonic-gateint dtrace_panic_trigger(int *tp) { return (0); } 15867c478bd9Sstevel@tonic-gate 15877c478bd9Sstevel@tonic-gate#else /* lint */ 15887c478bd9Sstevel@tonic-gate 15897c478bd9Sstevel@tonic-gate ENTRY_NP(panic_trigger) 15907c478bd9Sstevel@tonic-gate ldstub [%o0], %o0 ! store 0xFF, load byte into %o0 15917c478bd9Sstevel@tonic-gate cmp %o0, 0xFF ! compare %o0 to 0xFF 15927c478bd9Sstevel@tonic-gate set 1, %o1 ! %o1 = 1 15937c478bd9Sstevel@tonic-gate be,a 0f ! if (%o0 == 0xFF) goto 0f (else annul) 15947c478bd9Sstevel@tonic-gate set 0, %o1 ! delay - %o1 = 0 15957c478bd9Sstevel@tonic-gate0: retl 15967c478bd9Sstevel@tonic-gate mov %o1, %o0 ! return (%o1); 15977c478bd9Sstevel@tonic-gate SET_SIZE(panic_trigger) 15987c478bd9Sstevel@tonic-gate 15997c478bd9Sstevel@tonic-gate ENTRY_NP(dtrace_panic_trigger) 16007c478bd9Sstevel@tonic-gate ldstub [%o0], %o0 ! store 0xFF, load byte into %o0 16017c478bd9Sstevel@tonic-gate cmp %o0, 0xFF ! compare %o0 to 0xFF 16027c478bd9Sstevel@tonic-gate set 1, %o1 ! %o1 = 1 16037c478bd9Sstevel@tonic-gate be,a 0f ! if (%o0 == 0xFF) goto 0f (else annul) 16047c478bd9Sstevel@tonic-gate set 0, %o1 ! delay - %o1 = 0 16057c478bd9Sstevel@tonic-gate0: retl 16067c478bd9Sstevel@tonic-gate mov %o1, %o0 ! return (%o1); 16077c478bd9Sstevel@tonic-gate SET_SIZE(dtrace_panic_trigger) 16087c478bd9Sstevel@tonic-gate 16097c478bd9Sstevel@tonic-gate#endif /* lint */ 16107c478bd9Sstevel@tonic-gate 16117c478bd9Sstevel@tonic-gate/* 16127c478bd9Sstevel@tonic-gate * void vpanic(const char *format, va_list alist) 16137c478bd9Sstevel@tonic-gate * 16147c478bd9Sstevel@tonic-gate * The panic() and cmn_err() functions invoke vpanic() as a common entry point 16157c478bd9Sstevel@tonic-gate * into the panic code implemented in panicsys(). vpanic() is responsible 16167c478bd9Sstevel@tonic-gate * for passing through the format string and arguments, and constructing a 16177c478bd9Sstevel@tonic-gate * regs structure on the stack into which it saves the current register 16187c478bd9Sstevel@tonic-gate * values. If we are not dying due to a fatal trap, these registers will 16197c478bd9Sstevel@tonic-gate * then be preserved in panicbuf as the current processor state. Before 16207c478bd9Sstevel@tonic-gate * invoking panicsys(), vpanic() activates the first panic trigger (see 16217c478bd9Sstevel@tonic-gate * common/os/panic.c) and switches to the panic_stack if successful. Note that 16227c478bd9Sstevel@tonic-gate * DTrace takes a slightly different panic path if it must panic from probe 16237c478bd9Sstevel@tonic-gate * context. Instead of calling panic, it calls into dtrace_vpanic(), which 16247c478bd9Sstevel@tonic-gate * sets up the initial stack as vpanic does, calls dtrace_panic_trigger(), and 16257c478bd9Sstevel@tonic-gate * branches back into vpanic(). 16267c478bd9Sstevel@tonic-gate */ 16277c478bd9Sstevel@tonic-gate#if defined(lint) 16287c478bd9Sstevel@tonic-gate 16297c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 16307c478bd9Sstevel@tonic-gatevoid vpanic(const char *format, va_list alist) {} 16317c478bd9Sstevel@tonic-gate 16327c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 16337c478bd9Sstevel@tonic-gatevoid dtrace_vpanic(const char *format, va_list alist) {} 16347c478bd9Sstevel@tonic-gate 16357c478bd9Sstevel@tonic-gate#else /* lint */ 16367c478bd9Sstevel@tonic-gate 16377c478bd9Sstevel@tonic-gate ENTRY_NP(vpanic) 16387c478bd9Sstevel@tonic-gate 16397c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME + REGSIZE), %sp ! save and allocate regs 16407c478bd9Sstevel@tonic-gate 16417c478bd9Sstevel@tonic-gate ! 16427c478bd9Sstevel@tonic-gate ! The v9 struct regs has a 64-bit r_tstate field, which we use here 16437c478bd9Sstevel@tonic-gate ! to store the %ccr, %asi, %pstate, and %cwp as they would appear 16447c478bd9Sstevel@tonic-gate ! in %tstate if a trap occurred. We leave it up to the debugger to 16457c478bd9Sstevel@tonic-gate ! realize what happened and extract the register values. 16467c478bd9Sstevel@tonic-gate ! 16477c478bd9Sstevel@tonic-gate rd %ccr, %l0 ! %l0 = %ccr 16487c478bd9Sstevel@tonic-gate sllx %l0, TSTATE_CCR_SHIFT, %l0 ! %l0 <<= CCR_SHIFT 16497c478bd9Sstevel@tonic-gate rd %asi, %l1 ! %l1 = %asi 16507c478bd9Sstevel@tonic-gate sllx %l1, TSTATE_ASI_SHIFT, %l1 ! %l1 <<= ASI_SHIFT 16517c478bd9Sstevel@tonic-gate or %l0, %l1, %l0 ! %l0 |= %l1 16527c478bd9Sstevel@tonic-gate rdpr %pstate, %l1 ! %l1 = %pstate 16537c478bd9Sstevel@tonic-gate sllx %l1, TSTATE_PSTATE_SHIFT, %l1 ! %l1 <<= PSTATE_SHIFT 16547c478bd9Sstevel@tonic-gate or %l0, %l1, %l0 ! %l0 |= %l1 16557c478bd9Sstevel@tonic-gate rdpr %cwp, %l1 ! %l1 = %cwp 16567c478bd9Sstevel@tonic-gate sllx %l1, TSTATE_CWP_SHIFT, %l1 ! %l1 <<= CWP_SHIFT 16577c478bd9Sstevel@tonic-gate or %l0, %l1, %l0 ! %l0 |= %l1 16587c478bd9Sstevel@tonic-gate 16597c478bd9Sstevel@tonic-gate set vpanic, %l1 ! %l1 = %pc (vpanic) 16607c478bd9Sstevel@tonic-gate add %l1, 4, %l2 ! %l2 = %npc (vpanic+4) 16617c478bd9Sstevel@tonic-gate rd %y, %l3 ! %l3 = %y 16627c478bd9Sstevel@tonic-gate ! 16637c478bd9Sstevel@tonic-gate ! Flush register windows before panic_trigger() in order to avoid a 16647c478bd9Sstevel@tonic-gate ! problem that a dump hangs if flush_windows() causes another panic. 16657c478bd9Sstevel@tonic-gate ! 16667c478bd9Sstevel@tonic-gate call flush_windows 16677c478bd9Sstevel@tonic-gate nop 16687c478bd9Sstevel@tonic-gate 16697c478bd9Sstevel@tonic-gate sethi %hi(panic_quiesce), %o0 16707c478bd9Sstevel@tonic-gate call panic_trigger 16717c478bd9Sstevel@tonic-gate or %o0, %lo(panic_quiesce), %o0 ! if (!panic_trigger( 16727c478bd9Sstevel@tonic-gate 16737c478bd9Sstevel@tonic-gatevpanic_common: 16747c478bd9Sstevel@tonic-gate tst %o0 ! &panic_quiesce)) 16757c478bd9Sstevel@tonic-gate be 0f ! goto 0f; 16767c478bd9Sstevel@tonic-gate mov %o0, %l4 ! delay - %l4 = %o0 16777c478bd9Sstevel@tonic-gate 16787c478bd9Sstevel@tonic-gate ! 16797c478bd9Sstevel@tonic-gate ! If panic_trigger() was successful, we are the first to initiate a 16807c478bd9Sstevel@tonic-gate ! panic: switch to the panic_stack. 16817c478bd9Sstevel@tonic-gate ! 16827c478bd9Sstevel@tonic-gate set panic_stack, %o0 ! %o0 = panic_stack 16837c478bd9Sstevel@tonic-gate set PANICSTKSIZE, %o1 ! %o1 = size of stack 16847c478bd9Sstevel@tonic-gate add %o0, %o1, %o0 ! %o0 = top of stack 16857c478bd9Sstevel@tonic-gate 16867c478bd9Sstevel@tonic-gate sub %o0, SA(MINFRAME + REGSIZE) + STACK_BIAS, %sp 16877c478bd9Sstevel@tonic-gate 16887c478bd9Sstevel@tonic-gate ! 16897c478bd9Sstevel@tonic-gate ! Now that we've got everything set up, store each register to its 16907c478bd9Sstevel@tonic-gate ! designated location in the regs structure allocated on the stack. 16917c478bd9Sstevel@tonic-gate ! The register set we store is the equivalent of the registers at 16927c478bd9Sstevel@tonic-gate ! the time the %pc was pointing to vpanic, thus the %i's now contain 16937c478bd9Sstevel@tonic-gate ! what the %o's contained prior to the save instruction. 16947c478bd9Sstevel@tonic-gate ! 16957c478bd9Sstevel@tonic-gate0: stx %l0, [%sp + STACK_BIAS + SA(MINFRAME) + TSTATE_OFF] 16967c478bd9Sstevel@tonic-gate stx %g1, [%sp + STACK_BIAS + SA(MINFRAME) + G1_OFF] 16977c478bd9Sstevel@tonic-gate stx %g2, [%sp + STACK_BIAS + SA(MINFRAME) + G2_OFF] 16987c478bd9Sstevel@tonic-gate stx %g3, [%sp + STACK_BIAS + SA(MINFRAME) + G3_OFF] 16997c478bd9Sstevel@tonic-gate stx %g4, [%sp + STACK_BIAS + SA(MINFRAME) + G4_OFF] 17007c478bd9Sstevel@tonic-gate stx %g5, [%sp + STACK_BIAS + SA(MINFRAME) + G5_OFF] 17017c478bd9Sstevel@tonic-gate stx %g6, [%sp + STACK_BIAS + SA(MINFRAME) + G6_OFF] 17027c478bd9Sstevel@tonic-gate stx %g7, [%sp + STACK_BIAS + SA(MINFRAME) + G7_OFF] 17037c478bd9Sstevel@tonic-gate stx %i0, [%sp + STACK_BIAS + SA(MINFRAME) + O0_OFF] 17047c478bd9Sstevel@tonic-gate stx %i1, [%sp + STACK_BIAS + SA(MINFRAME) + O1_OFF] 17057c478bd9Sstevel@tonic-gate stx %i2, [%sp + STACK_BIAS + SA(MINFRAME) + O2_OFF] 17067c478bd9Sstevel@tonic-gate stx %i3, [%sp + STACK_BIAS + SA(MINFRAME) + O3_OFF] 17077c478bd9Sstevel@tonic-gate stx %i4, [%sp + STACK_BIAS + SA(MINFRAME) + O4_OFF] 17087c478bd9Sstevel@tonic-gate stx %i5, [%sp + STACK_BIAS + SA(MINFRAME) + O5_OFF] 17097c478bd9Sstevel@tonic-gate stx %i6, [%sp + STACK_BIAS + SA(MINFRAME) + O6_OFF] 17107c478bd9Sstevel@tonic-gate stx %i7, [%sp + STACK_BIAS + SA(MINFRAME) + O7_OFF] 17117c478bd9Sstevel@tonic-gate stn %l1, [%sp + STACK_BIAS + SA(MINFRAME) + PC_OFF] 17127c478bd9Sstevel@tonic-gate stn %l2, [%sp + STACK_BIAS + SA(MINFRAME) + NPC_OFF] 17137c478bd9Sstevel@tonic-gate st %l3, [%sp + STACK_BIAS + SA(MINFRAME) + Y_OFF] 17147c478bd9Sstevel@tonic-gate 17157c478bd9Sstevel@tonic-gate mov %l4, %o3 ! %o3 = on_panic_stack 17167c478bd9Sstevel@tonic-gate add %sp, STACK_BIAS + SA(MINFRAME), %o2 ! %o2 = ®s 17177c478bd9Sstevel@tonic-gate mov %i1, %o1 ! %o1 = alist 17187c478bd9Sstevel@tonic-gate call panicsys ! panicsys(); 17197c478bd9Sstevel@tonic-gate mov %i0, %o0 ! %o0 = format 17207c478bd9Sstevel@tonic-gate ret 17217c478bd9Sstevel@tonic-gate restore 17227c478bd9Sstevel@tonic-gate 17237c478bd9Sstevel@tonic-gate SET_SIZE(vpanic) 17247c478bd9Sstevel@tonic-gate 17257c478bd9Sstevel@tonic-gate ENTRY_NP(dtrace_vpanic) 17267c478bd9Sstevel@tonic-gate 17277c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME + REGSIZE), %sp ! save and allocate regs 17287c478bd9Sstevel@tonic-gate 17297c478bd9Sstevel@tonic-gate ! 17307c478bd9Sstevel@tonic-gate ! The v9 struct regs has a 64-bit r_tstate field, which we use here 17317c478bd9Sstevel@tonic-gate ! to store the %ccr, %asi, %pstate, and %cwp as they would appear 17327c478bd9Sstevel@tonic-gate ! in %tstate if a trap occurred. We leave it up to the debugger to 17337c478bd9Sstevel@tonic-gate ! realize what happened and extract the register values. 17347c478bd9Sstevel@tonic-gate ! 17357c478bd9Sstevel@tonic-gate rd %ccr, %l0 ! %l0 = %ccr 17367c478bd9Sstevel@tonic-gate sllx %l0, TSTATE_CCR_SHIFT, %l0 ! %l0 <<= CCR_SHIFT 17377c478bd9Sstevel@tonic-gate rd %asi, %l1 ! %l1 = %asi 17387c478bd9Sstevel@tonic-gate sllx %l1, TSTATE_ASI_SHIFT, %l1 ! %l1 <<= ASI_SHIFT 17397c478bd9Sstevel@tonic-gate or %l0, %l1, %l0 ! %l0 |= %l1 17407c478bd9Sstevel@tonic-gate rdpr %pstate, %l1 ! %l1 = %pstate 17417c478bd9Sstevel@tonic-gate sllx %l1, TSTATE_PSTATE_SHIFT, %l1 ! %l1 <<= PSTATE_SHIFT 17427c478bd9Sstevel@tonic-gate or %l0, %l1, %l0 ! %l0 |= %l1 17437c478bd9Sstevel@tonic-gate rdpr %cwp, %l1 ! %l1 = %cwp 17447c478bd9Sstevel@tonic-gate sllx %l1, TSTATE_CWP_SHIFT, %l1 ! %l1 <<= CWP_SHIFT 17457c478bd9Sstevel@tonic-gate or %l0, %l1, %l0 ! %l0 |= %l1 17467c478bd9Sstevel@tonic-gate 17477c478bd9Sstevel@tonic-gate set dtrace_vpanic, %l1 ! %l1 = %pc (vpanic) 17487c478bd9Sstevel@tonic-gate add %l1, 4, %l2 ! %l2 = %npc (vpanic+4) 17497c478bd9Sstevel@tonic-gate rd %y, %l3 ! %l3 = %y 17507c478bd9Sstevel@tonic-gate ! 17517c478bd9Sstevel@tonic-gate ! Flush register windows before panic_trigger() in order to avoid a 17527c478bd9Sstevel@tonic-gate ! problem that a dump hangs if flush_windows() causes another panic. 17537c478bd9Sstevel@tonic-gate ! 17547c478bd9Sstevel@tonic-gate call dtrace_flush_windows 17557c478bd9Sstevel@tonic-gate nop 17567c478bd9Sstevel@tonic-gate 17577c478bd9Sstevel@tonic-gate sethi %hi(panic_quiesce), %o0 17587c478bd9Sstevel@tonic-gate call dtrace_panic_trigger 17597c478bd9Sstevel@tonic-gate or %o0, %lo(panic_quiesce), %o0 ! if (!panic_trigger( 17607c478bd9Sstevel@tonic-gate 17617c478bd9Sstevel@tonic-gate ba,a vpanic_common 17627c478bd9Sstevel@tonic-gate SET_SIZE(dtrace_vpanic) 17637c478bd9Sstevel@tonic-gate 17647c478bd9Sstevel@tonic-gate#endif /* lint */ 1765bfb7f382Skalai 1766bfb7f382Skalai#if defined(lint) 1767bfb7f382Skalai 1768bfb7f382Skalai/*ARGSUSED*/ 1769bfb7f382Skalai 1770bfb7f382Skalaiuint_t 1771bfb7f382Skalaiget_subcc_ccr( uint64_t addrl, uint64_t addrr) 1772bfb7f382Skalai{ return (0); } 1773bfb7f382Skalai 1774bfb7f382Skalai#else /* lint */ 1775bfb7f382Skalai 1776bfb7f382Skalai ENTRY(get_subcc_ccr) 1777bfb7f382Skalai wr %g0, %ccr ! clear condition codes 1778bfb7f382Skalai subcc %o0, %o1, %g0 1779bfb7f382Skalai retl 1780bfb7f382Skalai rd %ccr, %o0 ! return condition codes 1781bfb7f382Skalai SET_SIZE(get_subcc_ccr) 1782bfb7f382Skalai 1783bfb7f382Skalai#endif /* lint */ 17844df4bd60Sbs21162 17854df4bd60Sbs21162#if defined(lint) || defined(__lint) 17864df4bd60Sbs21162 17874df4bd60Sbs21162ftrace_icookie_t 17884df4bd60Sbs21162ftrace_interrupt_disable(void) 17894df4bd60Sbs21162{ return (0); } 17904df4bd60Sbs21162 17914df4bd60Sbs21162#else /* lint */ 17924df4bd60Sbs21162 17934df4bd60Sbs21162 ENTRY_NP(ftrace_interrupt_disable) 17944df4bd60Sbs21162 rdpr %pstate, %o0 17954df4bd60Sbs21162 andn %o0, PSTATE_IE, %o1 17964df4bd60Sbs21162 retl 17974df4bd60Sbs21162 wrpr %g0, %o1, %pstate 17984df4bd60Sbs21162 SET_SIZE(ftrace_interrupt_disable) 17994df4bd60Sbs21162 18004df4bd60Sbs21162#endif /* lint */ 18014df4bd60Sbs21162 18024df4bd60Sbs21162#if defined(lint) || defined(__lint) 18034df4bd60Sbs21162 18044df4bd60Sbs21162/*ARGSUSED*/ 18054df4bd60Sbs21162void 18064df4bd60Sbs21162ftrace_interrupt_enable(ftrace_icookie_t cookie) 18074df4bd60Sbs21162{} 18084df4bd60Sbs21162 18094df4bd60Sbs21162#else 18104df4bd60Sbs21162 18114df4bd60Sbs21162 ENTRY_NP(ftrace_interrupt_enable) 18124df4bd60Sbs21162 retl 18134df4bd60Sbs21162 wrpr %g0, %o0, %pstate 18144df4bd60Sbs21162 SET_SIZE(ftrace_interrupt_enable) 18154df4bd60Sbs21162 18164df4bd60Sbs21162#endif /* lint*/ 1817