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 57bafd143Sjb145095 * Common Development and Distribution License (the "License"). 67bafd143Sjb145095 * 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/* 22b52a336eSPavel Tatashin * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate#if !defined(lint) 267c478bd9Sstevel@tonic-gate#include "assym.h" 277c478bd9Sstevel@tonic-gate#endif 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate/* 307c478bd9Sstevel@tonic-gate * General assembly language routines. 317c478bd9Sstevel@tonic-gate * It is the intent of this file to contain routines that are 327c478bd9Sstevel@tonic-gate * specific to cpu architecture. 337c478bd9Sstevel@tonic-gate */ 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate/* 367c478bd9Sstevel@tonic-gate * WARNING: If you add a fast trap handler which can be invoked by a 377c478bd9Sstevel@tonic-gate * non-privileged user, you may have to use the FAST_TRAP_DONE macro 387c478bd9Sstevel@tonic-gate * instead of "done" instruction to return back to the user mode. See 397c478bd9Sstevel@tonic-gate * comments for the "fast_trap_done" entry point for more information. 407c478bd9Sstevel@tonic-gate */ 417c478bd9Sstevel@tonic-gate#define FAST_TRAP_DONE \ 427c478bd9Sstevel@tonic-gate ba,a fast_trap_done 437c478bd9Sstevel@tonic-gate 44023e71deSHaik Aftandilian#include <sys/machclock.h> 457c478bd9Sstevel@tonic-gate#include <sys/clock.h> 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate#if defined(lint) 487c478bd9Sstevel@tonic-gate#include <sys/types.h> 497c478bd9Sstevel@tonic-gate#include <sys/scb.h> 507c478bd9Sstevel@tonic-gate#include <sys/systm.h> 517c478bd9Sstevel@tonic-gate#include <sys/regset.h> 527c478bd9Sstevel@tonic-gate#include <sys/sunddi.h> 537c478bd9Sstevel@tonic-gate#include <sys/lockstat.h> 547c478bd9Sstevel@tonic-gate#endif /* lint */ 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 587c478bd9Sstevel@tonic-gate#include <sys/privregs.h> 591e2e7a75Shuah#include <vm/hat_sfmmu.h> 607c478bd9Sstevel@tonic-gate#include <sys/machparam.h> /* To get SYSBASE and PAGESIZE */ 617c478bd9Sstevel@tonic-gate#include <sys/machthread.h> 627c478bd9Sstevel@tonic-gate#include <sys/clock.h> 637c478bd9Sstevel@tonic-gate#include <sys/intreg.h> 647c478bd9Sstevel@tonic-gate#include <sys/psr_compat.h> 657c478bd9Sstevel@tonic-gate#include <sys/isa_defs.h> 667c478bd9Sstevel@tonic-gate#include <sys/dditypes.h> 677c478bd9Sstevel@tonic-gate#include <sys/intr.h> 687c478bd9Sstevel@tonic-gate#include <sys/hypervisor_api.h> 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate#if !defined(lint) 717c478bd9Sstevel@tonic-gate#include "assym.h" 727c478bd9Sstevel@tonic-gate#endif 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate#define ICACHE_FLUSHSZ 0x20 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate#if defined(lint) 777c478bd9Sstevel@tonic-gate/* 787c478bd9Sstevel@tonic-gate * Softint generated when counter field of tick reg matches value field 797c478bd9Sstevel@tonic-gate * of tick_cmpr reg 807c478bd9Sstevel@tonic-gate */ 817c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 827c478bd9Sstevel@tonic-gatevoid 837c478bd9Sstevel@tonic-gatetickcmpr_set(uint64_t clock_cycles) 847c478bd9Sstevel@tonic-gate{} 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate#else /* lint */ 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate ENTRY_NP(tickcmpr_set) 897c478bd9Sstevel@tonic-gate ! get 64-bit clock_cycles interval 907c478bd9Sstevel@tonic-gate mov %o0, %o2 917c478bd9Sstevel@tonic-gate mov 8, %o3 ! A reasonable initial step size 927c478bd9Sstevel@tonic-gate1: 937c478bd9Sstevel@tonic-gate WR_TICKCMPR(%o2,%o4,%o5,__LINE__) ! Write to TICK_CMPR 947c478bd9Sstevel@tonic-gate 95023e71deSHaik Aftandilian GET_NATIVE_TIME(%o0,%o4,%o5,__LINE__) ! Read %tick to confirm the 96023e71deSHaik Aftandilian ! value we wrote was in the 97023e71deSHaik Aftandilian ! future. 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate cmp %o2, %o0 ! If the value we wrote was in the 1007c478bd9Sstevel@tonic-gate bg,pt %xcc, 2f ! future, then blow out of here. 1017c478bd9Sstevel@tonic-gate sllx %o3, 1, %o3 ! If not, then double our step size, 1027c478bd9Sstevel@tonic-gate ba,pt %xcc, 1b ! and take another lap. 1037c478bd9Sstevel@tonic-gate add %o0, %o3, %o2 ! 1047c478bd9Sstevel@tonic-gate2: 1057c478bd9Sstevel@tonic-gate retl 1067c478bd9Sstevel@tonic-gate nop 1077c478bd9Sstevel@tonic-gate SET_SIZE(tickcmpr_set) 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate#endif /* lint */ 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate#if defined(lint) 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gatevoid 1147c478bd9Sstevel@tonic-gatetickcmpr_disable(void) 1157c478bd9Sstevel@tonic-gate{} 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate#else 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate ENTRY_NP(tickcmpr_disable) 1207c478bd9Sstevel@tonic-gate mov 1, %g1 1217c478bd9Sstevel@tonic-gate sllx %g1, TICKINT_DIS_SHFT, %o0 1227c478bd9Sstevel@tonic-gate WR_TICKCMPR(%o0,%o4,%o5,__LINE__) ! Write to TICK_CMPR 1237c478bd9Sstevel@tonic-gate retl 1247c478bd9Sstevel@tonic-gate nop 1257c478bd9Sstevel@tonic-gate SET_SIZE(tickcmpr_disable) 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate#endif 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate#if defined(lint) 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate/* 13200a57bdfSHaik Aftandilian * tick_write_delta() is intended to increment %stick by the specified delta, 13300a57bdfSHaik Aftandilian * but %stick is only writeable in hyperprivileged mode and at present there 13400a57bdfSHaik Aftandilian * is no provision for this. tick_write_delta is called by the cylic subsystem 13500a57bdfSHaik Aftandilian * if a negative %stick delta is observed after cyclic processing is resumed 13600a57bdfSHaik Aftandilian * after an event such as an OS suspend/resume. On sun4v, the suspend/resume 13700a57bdfSHaik Aftandilian * routines should adjust the %stick offset preventing the cyclic subsystem 13800a57bdfSHaik Aftandilian * from detecting a negative delta. If a negative delta is detected, panic the 13900a57bdfSHaik Aftandilian * system. The negative delta could be caused by improper %stick 14000a57bdfSHaik Aftandilian * synchronization after a suspend/resume. 1417c478bd9Sstevel@tonic-gate */ 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 1447c478bd9Sstevel@tonic-gatevoid 1457c478bd9Sstevel@tonic-gatetick_write_delta(uint64_t delta) 1467c478bd9Sstevel@tonic-gate{} 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate#else /* lint */ 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate .seg ".text" 1517c478bd9Sstevel@tonic-gatetick_write_delta_panic: 15200a57bdfSHaik Aftandilian .asciz "tick_write_delta: not supported, delta: 0x%lx" 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate ENTRY_NP(tick_write_delta) 1557c478bd9Sstevel@tonic-gate sethi %hi(tick_write_delta_panic), %o1 1567c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME), %sp ! get a new window to preserve caller 15700a57bdfSHaik Aftandilian mov %i0, %o1 1587c478bd9Sstevel@tonic-gate call panic 1597c478bd9Sstevel@tonic-gate or %i1, %lo(tick_write_delta_panic), %o0 1607c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 1617c478bd9Sstevel@tonic-gate retl 1627c478bd9Sstevel@tonic-gate nop 1637c478bd9Sstevel@tonic-gate#endif 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate#if defined(lint) 1667c478bd9Sstevel@tonic-gate/* 1677c478bd9Sstevel@tonic-gate * return 1 if disabled 1687c478bd9Sstevel@tonic-gate */ 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gateint 1717c478bd9Sstevel@tonic-gatetickcmpr_disabled(void) 1727c478bd9Sstevel@tonic-gate{ return (0); } 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate#else /* lint */ 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate ENTRY_NP(tickcmpr_disabled) 177023e71deSHaik Aftandilian RD_TICKCMPR(%g1,%o0,%o1,__LINE__) 1787c478bd9Sstevel@tonic-gate retl 1797c478bd9Sstevel@tonic-gate srlx %g1, TICKINT_DIS_SHFT, %o0 1807c478bd9Sstevel@tonic-gate SET_SIZE(tickcmpr_disabled) 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate#endif /* lint */ 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate/* 1857c478bd9Sstevel@tonic-gate * Get current tick 1867c478bd9Sstevel@tonic-gate */ 1877c478bd9Sstevel@tonic-gate#if defined(lint) 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gateu_longlong_t 1907c478bd9Sstevel@tonic-gategettick(void) 1917c478bd9Sstevel@tonic-gate{ return (0); } 1927c478bd9Sstevel@tonic-gate 193b52a336eSPavel Tatashinu_longlong_t 194b52a336eSPavel Tatashinrandtick(void) 195b52a336eSPavel Tatashin{ return (0); } 196b52a336eSPavel Tatashin 1977c478bd9Sstevel@tonic-gate#else /* lint */ 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate ENTRY(gettick) 200b52a336eSPavel Tatashin ALTENTRY(randtick) 201023e71deSHaik Aftandilian GET_NATIVE_TIME(%o0,%o2,%o3,__LINE__) 2027c478bd9Sstevel@tonic-gate retl 2037c478bd9Sstevel@tonic-gate nop 204b52a336eSPavel Tatashin SET_SIZE(randtick) 2057c478bd9Sstevel@tonic-gate SET_SIZE(gettick) 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate#endif /* lint */ 2087c478bd9Sstevel@tonic-gate 209023e71deSHaik Aftandilian/* 210023e71deSHaik Aftandilian * Get current tick. For trapstat use only. 211023e71deSHaik Aftandilian */ 212023e71deSHaik Aftandilian#if defined (lint) 213023e71deSHaik Aftandilian 214023e71deSHaik Aftandilianhrtime_t 215023e71deSHaik Aftandilianrdtick() 216023e71deSHaik Aftandilian{ return (0); } 217023e71deSHaik Aftandilian 218023e71deSHaik Aftandilian#else 219023e71deSHaik Aftandilian ENTRY(rdtick) 220023e71deSHaik Aftandilian retl 221023e71deSHaik Aftandilian RD_TICK_PHYSICAL(%o0) 222023e71deSHaik Aftandilian SET_SIZE(rdtick) 223023e71deSHaik Aftandilian#endif /* lint */ 224023e71deSHaik Aftandilian 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate/* 2277c478bd9Sstevel@tonic-gate * Return the counter portion of the tick register. 2287c478bd9Sstevel@tonic-gate */ 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate#if defined(lint) 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gateuint64_t 2337c478bd9Sstevel@tonic-gategettick_counter(void) 2347c478bd9Sstevel@tonic-gate{ return(0); } 2357c478bd9Sstevel@tonic-gate 236023e71deSHaik Aftandilianuint64_t 237023e71deSHaik Aftandiliangettick_npt(void) 238023e71deSHaik Aftandilian{ return(0); } 239023e71deSHaik Aftandilian 240023e71deSHaik Aftandilianuint64_t 241023e71deSHaik Aftandiliangetstick_npt(void) 242023e71deSHaik Aftandilian{ return(0); } 243023e71deSHaik Aftandilian 2447c478bd9Sstevel@tonic-gate#else /* lint */ 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate ENTRY_NP(gettick_counter) 247023e71deSHaik Aftandilian RD_TICK(%o0,%o1,%o2,__LINE__) 2487c478bd9Sstevel@tonic-gate retl 249023e71deSHaik Aftandilian nop 2507c478bd9Sstevel@tonic-gate SET_SIZE(gettick_counter) 251023e71deSHaik Aftandilian 252023e71deSHaik Aftandilian ENTRY_NP(gettick_npt) 253023e71deSHaik Aftandilian RD_TICK_PHYSICAL(%o0) 254023e71deSHaik Aftandilian retl 255023e71deSHaik Aftandilian srlx %o0, 63, %o0 256023e71deSHaik Aftandilian SET_SIZE(gettick_npt) 257023e71deSHaik Aftandilian 258023e71deSHaik Aftandilian ENTRY_NP(getstick_npt) 259023e71deSHaik Aftandilian RD_STICK_PHYSICAL(%o0) 260023e71deSHaik Aftandilian retl 261023e71deSHaik Aftandilian srlx %o0, 63, %o0 262023e71deSHaik Aftandilian SET_SIZE(getstick_npt) 2637c478bd9Sstevel@tonic-gate#endif /* lint */ 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate/* 2667c478bd9Sstevel@tonic-gate * Provide a C callable interface to the trap that reads the hi-res timer. 2677c478bd9Sstevel@tonic-gate * Returns 64-bit nanosecond timestamp in %o0 and %o1. 2687c478bd9Sstevel@tonic-gate */ 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate#if defined(lint) 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gatehrtime_t 2737c478bd9Sstevel@tonic-gategethrtime(void) 2747c478bd9Sstevel@tonic-gate{ 2757c478bd9Sstevel@tonic-gate return ((hrtime_t)0); 2767c478bd9Sstevel@tonic-gate} 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gatehrtime_t 2797c478bd9Sstevel@tonic-gategethrtime_unscaled(void) 2807c478bd9Sstevel@tonic-gate{ 2817c478bd9Sstevel@tonic-gate return ((hrtime_t)0); 2827c478bd9Sstevel@tonic-gate} 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gatehrtime_t 2857c478bd9Sstevel@tonic-gategethrtime_max(void) 2867c478bd9Sstevel@tonic-gate{ 2877c478bd9Sstevel@tonic-gate return ((hrtime_t)0); 2887c478bd9Sstevel@tonic-gate} 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gatevoid 2917c478bd9Sstevel@tonic-gatescalehrtime(hrtime_t *hrt) 2927c478bd9Sstevel@tonic-gate{ 2937c478bd9Sstevel@tonic-gate *hrt = 0; 2947c478bd9Sstevel@tonic-gate} 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gatevoid 2977c478bd9Sstevel@tonic-gategethrestime(timespec_t *tp) 2987c478bd9Sstevel@tonic-gate{ 2997c478bd9Sstevel@tonic-gate tp->tv_sec = 0; 3007c478bd9Sstevel@tonic-gate tp->tv_nsec = 0; 3017c478bd9Sstevel@tonic-gate} 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gatetime_t 3047c478bd9Sstevel@tonic-gategethrestime_sec(void) 3057c478bd9Sstevel@tonic-gate{ 3067c478bd9Sstevel@tonic-gate return (0); 3077c478bd9Sstevel@tonic-gate} 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gatevoid 3107c478bd9Sstevel@tonic-gategethrestime_lasttick(timespec_t *tp) 3117c478bd9Sstevel@tonic-gate{ 3127c478bd9Sstevel@tonic-gate tp->tv_sec = 0; 3137c478bd9Sstevel@tonic-gate tp->tv_nsec = 0; 3147c478bd9Sstevel@tonic-gate} 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 3177c478bd9Sstevel@tonic-gatevoid 3187c478bd9Sstevel@tonic-gatehres_tick(void) 3197c478bd9Sstevel@tonic-gate{ 3207c478bd9Sstevel@tonic-gate} 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gatevoid 3237c478bd9Sstevel@tonic-gatepanic_hres_tick(void) 3247c478bd9Sstevel@tonic-gate{ 3257c478bd9Sstevel@tonic-gate} 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate#else /* lint */ 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate ENTRY_NP(gethrtime) 330023e71deSHaik Aftandilian GET_HRTIME(%g1,%o0,%o1,%o2,%o3,%o4,%o5,%g2,__LINE__) 3317c478bd9Sstevel@tonic-gate ! %g1 = hrtime 3327c478bd9Sstevel@tonic-gate retl 3337c478bd9Sstevel@tonic-gate mov %g1, %o0 3347c478bd9Sstevel@tonic-gate SET_SIZE(gethrtime) 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate ENTRY_NP(gethrtime_unscaled) 337023e71deSHaik Aftandilian GET_NATIVE_TIME(%g1,%o2,%o3,__LINE__) ! %g1 = native time 3387c478bd9Sstevel@tonic-gate retl 3397c478bd9Sstevel@tonic-gate mov %g1, %o0 3407c478bd9Sstevel@tonic-gate SET_SIZE(gethrtime_unscaled) 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate ENTRY_NP(gethrtime_waitfree) 3437c478bd9Sstevel@tonic-gate ALTENTRY(dtrace_gethrtime) 344023e71deSHaik Aftandilian GET_NATIVE_TIME(%g1,%o2,%o3,__LINE__) ! %g1 = native time 3457c478bd9Sstevel@tonic-gate NATIVE_TIME_TO_NSEC(%g1, %o2, %o3) 3467c478bd9Sstevel@tonic-gate retl 3477c478bd9Sstevel@tonic-gate mov %g1, %o0 3487c478bd9Sstevel@tonic-gate SET_SIZE(dtrace_gethrtime) 3497c478bd9Sstevel@tonic-gate SET_SIZE(gethrtime_waitfree) 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate ENTRY(gethrtime_max) 3527c478bd9Sstevel@tonic-gate NATIVE_TIME_MAX(%g1) 3537c478bd9Sstevel@tonic-gate NATIVE_TIME_TO_NSEC(%g1, %o0, %o1) 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate ! hrtime_t's are signed, max hrtime_t must be positive 3567c478bd9Sstevel@tonic-gate mov -1, %o2 3577c478bd9Sstevel@tonic-gate brlz,a %g1, 1f 3587c478bd9Sstevel@tonic-gate srlx %o2, 1, %g1 3597c478bd9Sstevel@tonic-gate1: 3607c478bd9Sstevel@tonic-gate retl 3617c478bd9Sstevel@tonic-gate mov %g1, %o0 3627c478bd9Sstevel@tonic-gate SET_SIZE(gethrtime_max) 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate ENTRY(scalehrtime) 3657c478bd9Sstevel@tonic-gate ldx [%o0], %o1 3667c478bd9Sstevel@tonic-gate NATIVE_TIME_TO_NSEC(%o1, %o2, %o3) 3677c478bd9Sstevel@tonic-gate retl 3687c478bd9Sstevel@tonic-gate stx %o1, [%o0] 3697c478bd9Sstevel@tonic-gate SET_SIZE(scalehrtime) 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate/* 3727c478bd9Sstevel@tonic-gate * Fast trap to return a timestamp, uses trap window, leaves traps 3737c478bd9Sstevel@tonic-gate * disabled. Returns a 64-bit nanosecond timestamp in %o0 and %o1. 3747c478bd9Sstevel@tonic-gate * 3757c478bd9Sstevel@tonic-gate * This is the handler for the ST_GETHRTIME trap. 3767c478bd9Sstevel@tonic-gate */ 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate ENTRY_NP(get_timestamp) 379023e71deSHaik Aftandilian GET_HRTIME(%g1,%g2,%g3,%g4,%g5,%o0,%o1,%o2,__LINE__) 380023e71deSHaik Aftandilian ! %g1 = hrtime 3817c478bd9Sstevel@tonic-gate srlx %g1, 32, %o0 ! %o0 = hi32(%g1) 3827c478bd9Sstevel@tonic-gate srl %g1, 0, %o1 ! %o1 = lo32(%g1) 3837c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 3847c478bd9Sstevel@tonic-gate SET_SIZE(get_timestamp) 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate/* 3877c478bd9Sstevel@tonic-gate * Macro to convert GET_HRESTIME() bits into a timestamp. 3887c478bd9Sstevel@tonic-gate * 3897c478bd9Sstevel@tonic-gate * We use two separate macros so that the platform-dependent GET_HRESTIME() 3907c478bd9Sstevel@tonic-gate * can be as small as possible; CONV_HRESTIME() implements the generic part. 3917c478bd9Sstevel@tonic-gate */ 3927c478bd9Sstevel@tonic-gate#define CONV_HRESTIME(hrestsec, hrestnsec, adj, nslt, nano) \ 3937c478bd9Sstevel@tonic-gate brz,pt adj, 3f; /* no adjustments, it's easy */ \ 3947c478bd9Sstevel@tonic-gate add hrestnsec, nslt, hrestnsec; /* hrest.tv_nsec += nslt */ \ 3957c478bd9Sstevel@tonic-gate brlz,pn adj, 2f; /* if hrestime_adj negative */ \ 396646e55b6Scth srlx nslt, ADJ_SHIFT, nslt; /* delay: nslt >>= 4 */ \ 3977c478bd9Sstevel@tonic-gate subcc adj, nslt, %g0; /* hrestime_adj - nslt/16 */ \ 3987c478bd9Sstevel@tonic-gate movg %xcc, nslt, adj; /* adj by min(adj, nslt/16) */ \ 3997c478bd9Sstevel@tonic-gate ba 3f; /* go convert to sec/nsec */ \ 4007c478bd9Sstevel@tonic-gate add hrestnsec, adj, hrestnsec; /* delay: apply adjustment */ \ 4017c478bd9Sstevel@tonic-gate2: addcc adj, nslt, %g0; /* hrestime_adj + nslt/16 */ \ 4027c478bd9Sstevel@tonic-gate bge,a,pt %xcc, 3f; /* is adj less negative? */ \ 4037c478bd9Sstevel@tonic-gate add hrestnsec, adj, hrestnsec; /* yes: hrest.nsec += adj */ \ 4047c478bd9Sstevel@tonic-gate sub hrestnsec, nslt, hrestnsec; /* no: hrest.nsec -= nslt/16 */ \ 4057c478bd9Sstevel@tonic-gate3: cmp hrestnsec, nano; /* more than a billion? */ \ 4067c478bd9Sstevel@tonic-gate bl,pt %xcc, 4f; /* if not, we're done */ \ 4077c478bd9Sstevel@tonic-gate nop; /* delay: do nothing :( */ \ 4087c478bd9Sstevel@tonic-gate add hrestsec, 1, hrestsec; /* hrest.tv_sec++; */ \ 4097c478bd9Sstevel@tonic-gate sub hrestnsec, nano, hrestnsec; /* hrest.tv_nsec -= NANOSEC; */ \ 410646e55b6Scth ba,a 3b; /* check >= billion again */ \ 4117c478bd9Sstevel@tonic-gate4: 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate ENTRY_NP(gethrestime) 414023e71deSHaik Aftandilian GET_HRESTIME(%o1,%o2,%o3,%o4,%o5,%g1,%g2,%g3,%g4,__LINE__) 4157c478bd9Sstevel@tonic-gate CONV_HRESTIME(%o1, %o2, %o3, %o4, %o5) 4167c478bd9Sstevel@tonic-gate stn %o1, [%o0] 4177c478bd9Sstevel@tonic-gate retl 4187c478bd9Sstevel@tonic-gate stn %o2, [%o0 + CLONGSIZE] 4197c478bd9Sstevel@tonic-gate SET_SIZE(gethrestime) 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate/* 4227c478bd9Sstevel@tonic-gate * Similar to gethrestime(), but gethrestime_sec() returns current hrestime 4237c478bd9Sstevel@tonic-gate * seconds. 4247c478bd9Sstevel@tonic-gate */ 4257c478bd9Sstevel@tonic-gate ENTRY_NP(gethrestime_sec) 426023e71deSHaik Aftandilian GET_HRESTIME(%o0,%o2,%o3,%o4,%o5,%g1,%g2,%g3,%g4,__LINE__) 4277c478bd9Sstevel@tonic-gate CONV_HRESTIME(%o0, %o2, %o3, %o4, %o5) 4287c478bd9Sstevel@tonic-gate retl ! %o0 current hrestime seconds 4297c478bd9Sstevel@tonic-gate nop 4307c478bd9Sstevel@tonic-gate SET_SIZE(gethrestime_sec) 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate/* 4337c478bd9Sstevel@tonic-gate * Returns the hrestime on the last tick. This is simpler than gethrestime() 4347c478bd9Sstevel@tonic-gate * and gethrestime_sec(): no conversion is required. gethrestime_lasttick() 4357c478bd9Sstevel@tonic-gate * follows the same locking algorithm as GET_HRESTIME and GET_HRTIME, 4367c478bd9Sstevel@tonic-gate * outlined in detail in clock.h. (Unlike GET_HRESTIME/GET_HRTIME, we don't 4377c478bd9Sstevel@tonic-gate * rely on load dependencies to effect the membar #LoadLoad, instead declaring 4387c478bd9Sstevel@tonic-gate * it explicitly.) 4397c478bd9Sstevel@tonic-gate */ 4407c478bd9Sstevel@tonic-gate ENTRY_NP(gethrestime_lasttick) 4417c478bd9Sstevel@tonic-gate sethi %hi(hres_lock), %o1 4427c478bd9Sstevel@tonic-gate0: 4437c478bd9Sstevel@tonic-gate lduw [%o1 + %lo(hres_lock)], %o2 ! Load lock value 4447c478bd9Sstevel@tonic-gate membar #LoadLoad ! Load of lock must complete 4457c478bd9Sstevel@tonic-gate andn %o2, 1, %o2 ! Mask off lowest bit 4467c478bd9Sstevel@tonic-gate ldn [%o1 + %lo(hrestime)], %g1 ! Seconds. 4477c478bd9Sstevel@tonic-gate add %o1, %lo(hrestime), %o4 4487c478bd9Sstevel@tonic-gate ldn [%o4 + CLONGSIZE], %g2 ! Nanoseconds. 4497c478bd9Sstevel@tonic-gate membar #LoadLoad ! All loads must complete 4507c478bd9Sstevel@tonic-gate lduw [%o1 + %lo(hres_lock)], %o3 ! Reload lock value 4517c478bd9Sstevel@tonic-gate cmp %o3, %o2 ! If lock is locked or has 4527c478bd9Sstevel@tonic-gate bne 0b ! changed, retry. 4537c478bd9Sstevel@tonic-gate stn %g1, [%o0] ! Delay: store seconds 4547c478bd9Sstevel@tonic-gate retl 4557c478bd9Sstevel@tonic-gate stn %g2, [%o0 + CLONGSIZE] ! Delay: store nanoseconds 4567c478bd9Sstevel@tonic-gate SET_SIZE(gethrestime_lasttick) 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate/* 4597c478bd9Sstevel@tonic-gate * Fast trap for gettimeofday(). Returns a timestruc_t in %o0 and %o1. 4607c478bd9Sstevel@tonic-gate * 4617c478bd9Sstevel@tonic-gate * This is the handler for the ST_GETHRESTIME trap. 4627c478bd9Sstevel@tonic-gate */ 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate ENTRY_NP(get_hrestime) 465023e71deSHaik Aftandilian GET_HRESTIME(%o0,%o1,%g1,%g2,%g3,%g4,%g5,%o2,%o3,__LINE__) 4667c478bd9Sstevel@tonic-gate CONV_HRESTIME(%o0, %o1, %g1, %g2, %g3) 4677c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 4687c478bd9Sstevel@tonic-gate SET_SIZE(get_hrestime) 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate/* 4717c478bd9Sstevel@tonic-gate * Fast trap to return lwp virtual time, uses trap window, leaves traps 4727c478bd9Sstevel@tonic-gate * disabled. Returns a 64-bit number in %o0:%o1, which is the number 4737c478bd9Sstevel@tonic-gate * of nanoseconds consumed. 4747c478bd9Sstevel@tonic-gate * 4757c478bd9Sstevel@tonic-gate * This is the handler for the ST_GETHRVTIME trap. 4767c478bd9Sstevel@tonic-gate * 4777c478bd9Sstevel@tonic-gate * Register usage: 4787c478bd9Sstevel@tonic-gate * %o0, %o1 = return lwp virtual time 4797c478bd9Sstevel@tonic-gate * %o2 = CPU/thread 4807c478bd9Sstevel@tonic-gate * %o3 = lwp 4817c478bd9Sstevel@tonic-gate * %g1 = scratch 4827c478bd9Sstevel@tonic-gate * %g5 = scratch 4837c478bd9Sstevel@tonic-gate */ 4847c478bd9Sstevel@tonic-gate ENTRY_NP(get_virtime) 485023e71deSHaik Aftandilian GET_NATIVE_TIME(%g5,%g1,%g2,__LINE__) ! %g5 = native time in ticks 4867c478bd9Sstevel@tonic-gate CPU_ADDR(%g2, %g3) ! CPU struct ptr to %g2 4877c478bd9Sstevel@tonic-gate ldn [%g2 + CPU_THREAD], %g2 ! thread pointer to %g2 4887c478bd9Sstevel@tonic-gate ldn [%g2 + T_LWP], %g3 ! lwp pointer to %g3 4897c478bd9Sstevel@tonic-gate 4907c478bd9Sstevel@tonic-gate /* 4917c478bd9Sstevel@tonic-gate * Subtract start time of current microstate from time 4927c478bd9Sstevel@tonic-gate * of day to get increment for lwp virtual time. 4937c478bd9Sstevel@tonic-gate */ 4947c478bd9Sstevel@tonic-gate ldx [%g3 + LWP_STATE_START], %g1 ! ms_state_start 4957c478bd9Sstevel@tonic-gate sub %g5, %g1, %g5 4967c478bd9Sstevel@tonic-gate 4977c478bd9Sstevel@tonic-gate /* 4987c478bd9Sstevel@tonic-gate * Add current value of ms_acct[LMS_USER] 4997c478bd9Sstevel@tonic-gate */ 5007c478bd9Sstevel@tonic-gate ldx [%g3 + LWP_ACCT_USER], %g1 ! ms_acct[LMS_USER] 5017c478bd9Sstevel@tonic-gate add %g5, %g1, %g5 5027c478bd9Sstevel@tonic-gate NATIVE_TIME_TO_NSEC(%g5, %g1, %o0) 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate srl %g5, 0, %o1 ! %o1 = lo32(%g5) 5057c478bd9Sstevel@tonic-gate srlx %g5, 32, %o0 ! %o0 = hi32(%g5) 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate FAST_TRAP_DONE 5087c478bd9Sstevel@tonic-gate SET_SIZE(get_virtime) 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate .seg ".text" 5137c478bd9Sstevel@tonic-gatehrtime_base_panic: 5147c478bd9Sstevel@tonic-gate .asciz "hrtime_base stepping back" 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate ENTRY_NP(hres_tick) 5187c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME), %sp ! get a new window 5197c478bd9Sstevel@tonic-gate 5207c478bd9Sstevel@tonic-gate sethi %hi(hrestime), %l4 5217c478bd9Sstevel@tonic-gate ldstub [%l4 + %lo(hres_lock + HRES_LOCK_OFFSET)], %l5 ! try locking 5227c478bd9Sstevel@tonic-gate7: tst %l5 5237c478bd9Sstevel@tonic-gate bz,pt %xcc, 8f ! if we got it, drive on 5247c478bd9Sstevel@tonic-gate ld [%l4 + %lo(nsec_scale)], %l5 ! delay: %l5 = scaling factor 5257c478bd9Sstevel@tonic-gate ldub [%l4 + %lo(hres_lock + HRES_LOCK_OFFSET)], %l5 5267c478bd9Sstevel@tonic-gate9: tst %l5 5277c478bd9Sstevel@tonic-gate bz,a,pn %xcc, 7b 5287c478bd9Sstevel@tonic-gate ldstub [%l4 + %lo(hres_lock + HRES_LOCK_OFFSET)], %l5 5297c478bd9Sstevel@tonic-gate ba,pt %xcc, 9b 5307c478bd9Sstevel@tonic-gate ldub [%l4 + %lo(hres_lock + HRES_LOCK_OFFSET)], %l5 5317c478bd9Sstevel@tonic-gate8: 5327c478bd9Sstevel@tonic-gate membar #StoreLoad|#StoreStore 5337c478bd9Sstevel@tonic-gate 5347c478bd9Sstevel@tonic-gate ! 5357c478bd9Sstevel@tonic-gate ! update hres_last_tick. %l5 has the scaling factor (nsec_scale). 5367c478bd9Sstevel@tonic-gate ! 5377c478bd9Sstevel@tonic-gate ldx [%l4 + %lo(hrtime_base)], %g1 ! load current hrtime_base 538023e71deSHaik Aftandilian GET_NATIVE_TIME(%l0,%l3,%l6,__LINE__) ! current native time 5397c478bd9Sstevel@tonic-gate stx %l0, [%l4 + %lo(hres_last_tick)]! prev = current 5407c478bd9Sstevel@tonic-gate ! convert native time to nsecs 5417c478bd9Sstevel@tonic-gate NATIVE_TIME_TO_NSEC_SCALE(%l0, %l5, %l2, NSEC_SHIFT) 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate sub %l0, %g1, %i1 ! get accurate nsec delta 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate ldx [%l4 + %lo(hrtime_base)], %l1 5467c478bd9Sstevel@tonic-gate cmp %l1, %l0 5477c478bd9Sstevel@tonic-gate bg,pn %xcc, 9f 5487c478bd9Sstevel@tonic-gate nop 5497c478bd9Sstevel@tonic-gate 5507c478bd9Sstevel@tonic-gate stx %l0, [%l4 + %lo(hrtime_base)] ! update hrtime_base 5517c478bd9Sstevel@tonic-gate 5527c478bd9Sstevel@tonic-gate ! 5537c478bd9Sstevel@tonic-gate ! apply adjustment, if any 5547c478bd9Sstevel@tonic-gate ! 5557c478bd9Sstevel@tonic-gate ldx [%l4 + %lo(hrestime_adj)], %l0 ! %l0 = hrestime_adj 5567c478bd9Sstevel@tonic-gate brz %l0, 2f 5577c478bd9Sstevel@tonic-gate ! hrestime_adj == 0 ? 5587c478bd9Sstevel@tonic-gate ! yes, skip adjustments 5597c478bd9Sstevel@tonic-gate clr %l5 ! delay: set adj to zero 5607c478bd9Sstevel@tonic-gate tst %l0 ! is hrestime_adj >= 0 ? 5617c478bd9Sstevel@tonic-gate bge,pt %xcc, 1f ! yes, go handle positive case 5627c478bd9Sstevel@tonic-gate srl %i1, ADJ_SHIFT, %l5 ! delay: %l5 = adj 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate addcc %l0, %l5, %g0 ! hrestime_adj < -adj ? 5657c478bd9Sstevel@tonic-gate bl,pt %xcc, 2f ! yes, use current adj 5667c478bd9Sstevel@tonic-gate neg %l5 ! delay: %l5 = -adj 5677c478bd9Sstevel@tonic-gate ba,pt %xcc, 2f 5687c478bd9Sstevel@tonic-gate mov %l0, %l5 ! no, so set adj = hrestime_adj 5697c478bd9Sstevel@tonic-gate1: 5707c478bd9Sstevel@tonic-gate subcc %l0, %l5, %g0 ! hrestime_adj < adj ? 5717c478bd9Sstevel@tonic-gate bl,a,pt %xcc, 2f ! yes, set adj = hrestime_adj 5727c478bd9Sstevel@tonic-gate mov %l0, %l5 ! delay: adj = hrestime_adj 5737c478bd9Sstevel@tonic-gate2: 5747c478bd9Sstevel@tonic-gate ldx [%l4 + %lo(timedelta)], %l0 ! %l0 = timedelta 5757c478bd9Sstevel@tonic-gate sub %l0, %l5, %l0 ! timedelta -= adj 5767c478bd9Sstevel@tonic-gate 5777c478bd9Sstevel@tonic-gate stx %l0, [%l4 + %lo(timedelta)] ! store new timedelta 5787c478bd9Sstevel@tonic-gate stx %l0, [%l4 + %lo(hrestime_adj)] ! hrestime_adj = timedelta 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate or %l4, %lo(hrestime), %l2 5817c478bd9Sstevel@tonic-gate ldn [%l2], %i2 ! %i2:%i3 = hrestime sec:nsec 5827c478bd9Sstevel@tonic-gate ldn [%l2 + CLONGSIZE], %i3 5837c478bd9Sstevel@tonic-gate add %i3, %l5, %i3 ! hrestime.nsec += adj 5847c478bd9Sstevel@tonic-gate add %i3, %i1, %i3 ! hrestime.nsec += nslt 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate set NANOSEC, %l5 ! %l5 = NANOSEC 5877c478bd9Sstevel@tonic-gate cmp %i3, %l5 5887c478bd9Sstevel@tonic-gate bl,pt %xcc, 5f ! if hrestime.tv_nsec < NANOSEC 5897c478bd9Sstevel@tonic-gate sethi %hi(one_sec), %i1 ! delay 5907c478bd9Sstevel@tonic-gate add %i2, 0x1, %i2 ! hrestime.tv_sec++ 5917c478bd9Sstevel@tonic-gate sub %i3, %l5, %i3 ! hrestime.tv_nsec - NANOSEC 5927c478bd9Sstevel@tonic-gate mov 0x1, %l5 5937c478bd9Sstevel@tonic-gate st %l5, [%i1 + %lo(one_sec)] 5947c478bd9Sstevel@tonic-gate5: 5957c478bd9Sstevel@tonic-gate stn %i2, [%l2] 5967c478bd9Sstevel@tonic-gate stn %i3, [%l2 + CLONGSIZE] ! store the new hrestime 5977c478bd9Sstevel@tonic-gate 5987c478bd9Sstevel@tonic-gate membar #StoreStore 5997c478bd9Sstevel@tonic-gate 6007c478bd9Sstevel@tonic-gate ld [%l4 + %lo(hres_lock)], %i1 6017c478bd9Sstevel@tonic-gate inc %i1 ! release lock 6027c478bd9Sstevel@tonic-gate st %i1, [%l4 + %lo(hres_lock)] ! clear hres_lock 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate ret 6057c478bd9Sstevel@tonic-gate restore 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate9: 6087c478bd9Sstevel@tonic-gate ! 6097c478bd9Sstevel@tonic-gate ! release hres_lock 6107c478bd9Sstevel@tonic-gate ! 6117c478bd9Sstevel@tonic-gate ld [%l4 + %lo(hres_lock)], %i1 6127c478bd9Sstevel@tonic-gate inc %i1 6137c478bd9Sstevel@tonic-gate st %i1, [%l4 + %lo(hres_lock)] 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate sethi %hi(hrtime_base_panic), %o0 6167c478bd9Sstevel@tonic-gate call panic 6177c478bd9Sstevel@tonic-gate or %o0, %lo(hrtime_base_panic), %o0 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate SET_SIZE(hres_tick) 6207c478bd9Sstevel@tonic-gate 6217c478bd9Sstevel@tonic-gate#endif /* lint */ 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate#if !defined(lint) && !defined(__lint) 6247c478bd9Sstevel@tonic-gate 6257c478bd9Sstevel@tonic-gate .seg ".text" 6267c478bd9Sstevel@tonic-gatekstat_q_panic_msg: 6277c478bd9Sstevel@tonic-gate .asciz "kstat_q_exit: qlen == 0" 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate ENTRY(kstat_q_panic) 6307c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME), %sp 6317c478bd9Sstevel@tonic-gate sethi %hi(kstat_q_panic_msg), %o0 6327c478bd9Sstevel@tonic-gate call panic 6337c478bd9Sstevel@tonic-gate or %o0, %lo(kstat_q_panic_msg), %o0 6347c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 6357c478bd9Sstevel@tonic-gate SET_SIZE(kstat_q_panic) 6367c478bd9Sstevel@tonic-gate 6377c478bd9Sstevel@tonic-gate#define BRZPN brz,pn 6387c478bd9Sstevel@tonic-gate#define BRZPT brz,pt 6397c478bd9Sstevel@tonic-gate 6407c478bd9Sstevel@tonic-gate#define KSTAT_Q_UPDATE(QOP, QBR, QZERO, QRETURN, QTYPE) \ 6417c478bd9Sstevel@tonic-gate ld [%o0 + QTYPE/**/CNT], %o1; /* %o1 = old qlen */ \ 6427c478bd9Sstevel@tonic-gate QOP %o1, 1, %o2; /* %o2 = new qlen */ \ 6437c478bd9Sstevel@tonic-gate QBR %o1, QZERO; /* done if qlen == 0 */ \ 6447c478bd9Sstevel@tonic-gate st %o2, [%o0 + QTYPE/**/CNT]; /* delay: save qlen */ \ 6457c478bd9Sstevel@tonic-gate ldx [%o0 + QTYPE/**/LASTUPDATE], %o3; \ 6467c478bd9Sstevel@tonic-gate ldx [%o0 + QTYPE/**/TIME], %o4; /* %o4 = old time */ \ 6477c478bd9Sstevel@tonic-gate ldx [%o0 + QTYPE/**/LENTIME], %o5; /* %o5 = old lentime */ \ 6487c478bd9Sstevel@tonic-gate sub %g1, %o3, %o2; /* %o2 = time delta */ \ 6497c478bd9Sstevel@tonic-gate mulx %o1, %o2, %o3; /* %o3 = cur lentime */ \ 6507c478bd9Sstevel@tonic-gate add %o4, %o2, %o4; /* %o4 = new time */ \ 6517c478bd9Sstevel@tonic-gate add %o5, %o3, %o5; /* %o5 = new lentime */ \ 6527c478bd9Sstevel@tonic-gate stx %o4, [%o0 + QTYPE/**/TIME]; /* save time */ \ 6537c478bd9Sstevel@tonic-gate stx %o5, [%o0 + QTYPE/**/LENTIME]; /* save lentime */ \ 6547c478bd9Sstevel@tonic-gateQRETURN; \ 6557c478bd9Sstevel@tonic-gate stx %g1, [%o0 + QTYPE/**/LASTUPDATE]; /* lastupdate = now */ 6567c478bd9Sstevel@tonic-gate 657*6e7bd672SToomas Soome#if !defined(DEBUG) 658*6e7bd672SToomas Soome/* 659*6e7bd672SToomas Soome * same as KSTAT_Q_UPDATE but without: 660*6e7bd672SToomas Soome * QBR %o1, QZERO; 661*6e7bd672SToomas Soome * to be used only with non-debug build. mimics ASSERT() behaviour. 662*6e7bd672SToomas Soome */ 663*6e7bd672SToomas Soome#define KSTAT_Q_UPDATE_ND(QOP, QRETURN, QTYPE) \ 664*6e7bd672SToomas Soome ld [%o0 + QTYPE/**/CNT], %o1; /* %o1 = old qlen */ \ 665*6e7bd672SToomas Soome QOP %o1, 1, %o2; /* %o2 = new qlen */ \ 666*6e7bd672SToomas Soome st %o2, [%o0 + QTYPE/**/CNT]; /* delay: save qlen */ \ 667*6e7bd672SToomas Soome ldx [%o0 + QTYPE/**/LASTUPDATE], %o3; \ 668*6e7bd672SToomas Soome ldx [%o0 + QTYPE/**/TIME], %o4; /* %o4 = old time */ \ 669*6e7bd672SToomas Soome ldx [%o0 + QTYPE/**/LENTIME], %o5; /* %o5 = old lentime */ \ 670*6e7bd672SToomas Soome sub %g1, %o3, %o2; /* %o2 = time delta */ \ 671*6e7bd672SToomas Soome mulx %o1, %o2, %o3; /* %o3 = cur lentime */ \ 672*6e7bd672SToomas Soome add %o4, %o2, %o4; /* %o4 = new time */ \ 673*6e7bd672SToomas Soome add %o5, %o3, %o5; /* %o5 = new lentime */ \ 674*6e7bd672SToomas Soome stx %o4, [%o0 + QTYPE/**/TIME]; /* save time */ \ 675*6e7bd672SToomas Soome stx %o5, [%o0 + QTYPE/**/LENTIME]; /* save lentime */ \ 676*6e7bd672SToomas SoomeQRETURN; \ 677*6e7bd672SToomas Soome stx %g1, [%o0 + QTYPE/**/LASTUPDATE]; /* lastupdate = now */ 678*6e7bd672SToomas Soome#endif 679*6e7bd672SToomas Soome 6807c478bd9Sstevel@tonic-gate .align 16 6817c478bd9Sstevel@tonic-gate ENTRY(kstat_waitq_enter) 682023e71deSHaik Aftandilian GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__) 6837c478bd9Sstevel@tonic-gate KSTAT_Q_UPDATE(add, BRZPT, 1f, 1:retl, KSTAT_IO_W) 6847c478bd9Sstevel@tonic-gate SET_SIZE(kstat_waitq_enter) 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate .align 16 6877c478bd9Sstevel@tonic-gate ENTRY(kstat_waitq_exit) 688023e71deSHaik Aftandilian GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__) 689*6e7bd672SToomas Soome#if defined(DEBUG) 6907c478bd9Sstevel@tonic-gate KSTAT_Q_UPDATE(sub, BRZPN, kstat_q_panic, retl, KSTAT_IO_W) 691*6e7bd672SToomas Soome#else 692*6e7bd672SToomas Soome KSTAT_Q_UPDATE_ND(sub, retl, KSTAT_IO_W) 693*6e7bd672SToomas Soome#endif 6947c478bd9Sstevel@tonic-gate SET_SIZE(kstat_waitq_exit) 6957c478bd9Sstevel@tonic-gate 6967c478bd9Sstevel@tonic-gate .align 16 6977c478bd9Sstevel@tonic-gate ENTRY(kstat_runq_enter) 698023e71deSHaik Aftandilian GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__) 6997c478bd9Sstevel@tonic-gate KSTAT_Q_UPDATE(add, BRZPT, 1f, 1:retl, KSTAT_IO_R) 7007c478bd9Sstevel@tonic-gate SET_SIZE(kstat_runq_enter) 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate .align 16 7037c478bd9Sstevel@tonic-gate ENTRY(kstat_runq_exit) 704023e71deSHaik Aftandilian GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__) 705*6e7bd672SToomas Soome#if defined(DEBUG) 7067c478bd9Sstevel@tonic-gate KSTAT_Q_UPDATE(sub, BRZPN, kstat_q_panic, retl, KSTAT_IO_R) 707*6e7bd672SToomas Soome#else 708*6e7bd672SToomas Soome KSTAT_Q_UPDATE_ND(sub, retl, KSTAT_IO_R) 709*6e7bd672SToomas Soome#endif 7107c478bd9Sstevel@tonic-gate SET_SIZE(kstat_runq_exit) 7117c478bd9Sstevel@tonic-gate 7127c478bd9Sstevel@tonic-gate .align 16 7137c478bd9Sstevel@tonic-gate ENTRY(kstat_waitq_to_runq) 714023e71deSHaik Aftandilian GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__) 715*6e7bd672SToomas Soome#if defined(DEBUG) 7167c478bd9Sstevel@tonic-gate KSTAT_Q_UPDATE(sub, BRZPN, kstat_q_panic, 1:, KSTAT_IO_W) 717*6e7bd672SToomas Soome#else 718*6e7bd672SToomas Soome KSTAT_Q_UPDATE_ND(sub, 1:, KSTAT_IO_W) 719*6e7bd672SToomas Soome#endif 7207c478bd9Sstevel@tonic-gate KSTAT_Q_UPDATE(add, BRZPT, 1f, 1:retl, KSTAT_IO_R) 7217c478bd9Sstevel@tonic-gate SET_SIZE(kstat_waitq_to_runq) 7227c478bd9Sstevel@tonic-gate 7237c478bd9Sstevel@tonic-gate .align 16 7247c478bd9Sstevel@tonic-gate ENTRY(kstat_runq_back_to_waitq) 725023e71deSHaik Aftandilian GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__) 726*6e7bd672SToomas Soome#if defined(DEBUG) 7277c478bd9Sstevel@tonic-gate KSTAT_Q_UPDATE(sub, BRZPN, kstat_q_panic, 1:, KSTAT_IO_R) 728*6e7bd672SToomas Soome#else 729*6e7bd672SToomas Soome KSTAT_Q_UPDATE_ND(sub, 1:, KSTAT_IO_R) 730*6e7bd672SToomas Soome#endif 7317c478bd9Sstevel@tonic-gate KSTAT_Q_UPDATE(add, BRZPT, 1f, 1:retl, KSTAT_IO_W) 7327c478bd9Sstevel@tonic-gate SET_SIZE(kstat_runq_back_to_waitq) 7337c478bd9Sstevel@tonic-gate 7347c478bd9Sstevel@tonic-gate#endif /* lint */ 7357c478bd9Sstevel@tonic-gate 7367c478bd9Sstevel@tonic-gate#ifdef lint 7377c478bd9Sstevel@tonic-gate 7387c478bd9Sstevel@tonic-gateint64_t timedelta; 7397c478bd9Sstevel@tonic-gatehrtime_t hres_last_tick; 740b5b48cc1Ssudheervolatile timestruc_t hrestime; 7417c478bd9Sstevel@tonic-gateint64_t hrestime_adj; 742b5b48cc1Ssudheervolatile int hres_lock; 7437c478bd9Sstevel@tonic-gateuint_t nsec_scale; 7447c478bd9Sstevel@tonic-gatehrtime_t hrtime_base; 7457c478bd9Sstevel@tonic-gateint traptrace_use_stick; 7467c478bd9Sstevel@tonic-gate 7477c478bd9Sstevel@tonic-gate#else 7487c478bd9Sstevel@tonic-gate /* 7497c478bd9Sstevel@tonic-gate * -- WARNING -- 7507c478bd9Sstevel@tonic-gate * 7517c478bd9Sstevel@tonic-gate * The following variables MUST be together on a 128-byte boundary. 7527c478bd9Sstevel@tonic-gate * In addition to the primary performance motivation (having them all 7537c478bd9Sstevel@tonic-gate * on the same cache line(s)), code here and in the GET*TIME() macros 7547c478bd9Sstevel@tonic-gate * assumes that they all have the same high 22 address bits (so 7557c478bd9Sstevel@tonic-gate * there's only one sethi). 7567c478bd9Sstevel@tonic-gate */ 7577c478bd9Sstevel@tonic-gate .seg ".data" 7587c478bd9Sstevel@tonic-gate .global timedelta, hres_last_tick, hrestime, hrestime_adj 7597c478bd9Sstevel@tonic-gate .global hres_lock, nsec_scale, hrtime_base, traptrace_use_stick 760023e71deSHaik Aftandilian .global nsec_shift, adj_shift, native_tick_offset, native_stick_offset 7617c478bd9Sstevel@tonic-gate 7627c478bd9Sstevel@tonic-gate /* XXX - above comment claims 128-bytes is necessary */ 7637c478bd9Sstevel@tonic-gate .align 64 7647c478bd9Sstevel@tonic-gatetimedelta: 7657c478bd9Sstevel@tonic-gate .word 0, 0 /* int64_t */ 7667c478bd9Sstevel@tonic-gatehres_last_tick: 7677c478bd9Sstevel@tonic-gate .word 0, 0 /* hrtime_t */ 7687c478bd9Sstevel@tonic-gatehrestime: 7697c478bd9Sstevel@tonic-gate .nword 0, 0 /* 2 longs */ 7707c478bd9Sstevel@tonic-gatehrestime_adj: 7717c478bd9Sstevel@tonic-gate .word 0, 0 /* int64_t */ 7727c478bd9Sstevel@tonic-gatehres_lock: 7737c478bd9Sstevel@tonic-gate .word 0 7747c478bd9Sstevel@tonic-gatensec_scale: 7757c478bd9Sstevel@tonic-gate .word 0 7767c478bd9Sstevel@tonic-gatehrtime_base: 7777c478bd9Sstevel@tonic-gate .word 0, 0 7787c478bd9Sstevel@tonic-gatetraptrace_use_stick: 7797c478bd9Sstevel@tonic-gate .word 0 7807c478bd9Sstevel@tonic-gatensec_shift: 7817c478bd9Sstevel@tonic-gate .word NSEC_SHIFT 7827c478bd9Sstevel@tonic-gateadj_shift: 7837c478bd9Sstevel@tonic-gate .word ADJ_SHIFT 784023e71deSHaik Aftandilian .align 8 785023e71deSHaik Aftandiliannative_tick_offset: 786023e71deSHaik Aftandilian .word 0, 0 787023e71deSHaik Aftandilian .align 8 788023e71deSHaik Aftandiliannative_stick_offset: 789023e71deSHaik Aftandilian .word 0, 0 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate#endif 7927c478bd9Sstevel@tonic-gate 7937c478bd9Sstevel@tonic-gate 7947c478bd9Sstevel@tonic-gate/* 7957c478bd9Sstevel@tonic-gate * drv_usecwait(clock_t n) [DDI/DKI - section 9F] 7967c478bd9Sstevel@tonic-gate * usec_delay(int n) [compatibility - should go one day] 7977c478bd9Sstevel@tonic-gate * Delay by spinning. 7987c478bd9Sstevel@tonic-gate * 7997c478bd9Sstevel@tonic-gate * delay for n microseconds. numbers <= 0 delay 1 usec 8007c478bd9Sstevel@tonic-gate * 8017c478bd9Sstevel@tonic-gate * With UltraSPARC-III the combination of supporting mixed-speed CPUs 8027c478bd9Sstevel@tonic-gate * and variable clock rate for power management requires that we 8037c478bd9Sstevel@tonic-gate * use %stick to implement this routine. 8047c478bd9Sstevel@tonic-gate */ 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate#if defined(lint) 8077c478bd9Sstevel@tonic-gate 8087c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 8097c478bd9Sstevel@tonic-gatevoid 8107c478bd9Sstevel@tonic-gatedrv_usecwait(clock_t n) 8117c478bd9Sstevel@tonic-gate{} 8127c478bd9Sstevel@tonic-gate 8137c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 8147c478bd9Sstevel@tonic-gatevoid 8157c478bd9Sstevel@tonic-gateusec_delay(int n) 8167c478bd9Sstevel@tonic-gate{} 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate#else /* lint */ 8197c478bd9Sstevel@tonic-gate 8207c478bd9Sstevel@tonic-gate ENTRY(drv_usecwait) 8217c478bd9Sstevel@tonic-gate ALTENTRY(usec_delay) 8227c478bd9Sstevel@tonic-gate brlez,a,pn %o0, 0f 8237c478bd9Sstevel@tonic-gate mov 1, %o0 8247c478bd9Sstevel@tonic-gate0: 8257c478bd9Sstevel@tonic-gate sethi %hi(sticks_per_usec), %o1 8267c478bd9Sstevel@tonic-gate lduw [%o1 + %lo(sticks_per_usec)], %o1 8277c478bd9Sstevel@tonic-gate mulx %o1, %o0, %o1 ! Scale usec to ticks 8287c478bd9Sstevel@tonic-gate inc %o1 ! We don't start on a tick edge 829023e71deSHaik Aftandilian GET_NATIVE_TIME(%o2,%o3,%o4,__LINE__) 8307c478bd9Sstevel@tonic-gate add %o1, %o2, %o1 8317c478bd9Sstevel@tonic-gate 8327c478bd9Sstevel@tonic-gate1: cmp %o1, %o2 833023e71deSHaik Aftandilian GET_NATIVE_TIME(%o2,%o3,%o4,__LINE__) 8347c478bd9Sstevel@tonic-gate bgeu,pt %xcc, 1b 8357c478bd9Sstevel@tonic-gate nop 8367c478bd9Sstevel@tonic-gate retl 8377c478bd9Sstevel@tonic-gate nop 8387c478bd9Sstevel@tonic-gate SET_SIZE(usec_delay) 8397c478bd9Sstevel@tonic-gate SET_SIZE(drv_usecwait) 8407c478bd9Sstevel@tonic-gate#endif /* lint */ 8417c478bd9Sstevel@tonic-gate 8427c478bd9Sstevel@tonic-gate#if defined(lint) 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate/* ARGSUSED */ 8457c478bd9Sstevel@tonic-gatevoid 8467c478bd9Sstevel@tonic-gatepil14_interrupt(int level) 8477c478bd9Sstevel@tonic-gate{} 8487c478bd9Sstevel@tonic-gate 8497c478bd9Sstevel@tonic-gate#else 8507c478bd9Sstevel@tonic-gate 8517c478bd9Sstevel@tonic-gate/* 8527c478bd9Sstevel@tonic-gate * Level-14 interrupt prologue. 8537c478bd9Sstevel@tonic-gate */ 8547c478bd9Sstevel@tonic-gate ENTRY_NP(pil14_interrupt) 8557c478bd9Sstevel@tonic-gate CPU_ADDR(%g1, %g2) 8567c478bd9Sstevel@tonic-gate rdpr %pil, %g6 ! %g6 = interrupted PIL 8577c478bd9Sstevel@tonic-gate stn %g6, [%g1 + CPU_PROFILE_PIL] ! record interrupted PIL 8587c478bd9Sstevel@tonic-gate rdpr %tstate, %g6 8597c478bd9Sstevel@tonic-gate rdpr %tpc, %g5 8607c478bd9Sstevel@tonic-gate btst TSTATE_PRIV, %g6 ! trap from supervisor mode? 8617c478bd9Sstevel@tonic-gate bnz,a,pt %xcc, 1f 8627c478bd9Sstevel@tonic-gate stn %g5, [%g1 + CPU_PROFILE_PC] ! if so, record kernel PC 8637c478bd9Sstevel@tonic-gate stn %g5, [%g1 + CPU_PROFILE_UPC] ! if not, record user PC 8647c478bd9Sstevel@tonic-gate ba pil_interrupt_common ! must be large-disp branch 8657c478bd9Sstevel@tonic-gate stn %g0, [%g1 + CPU_PROFILE_PC] ! zero kernel PC 8667c478bd9Sstevel@tonic-gate1: ba pil_interrupt_common ! must be large-disp branch 8677c478bd9Sstevel@tonic-gate stn %g0, [%g1 + CPU_PROFILE_UPC] ! zero user PC 8687c478bd9Sstevel@tonic-gate SET_SIZE(pil14_interrupt) 8697c478bd9Sstevel@tonic-gate 8707c478bd9Sstevel@tonic-gate ENTRY_NP(tick_rtt) 8717c478bd9Sstevel@tonic-gate ! 8727c478bd9Sstevel@tonic-gate ! Load TICK_COMPARE into %o5; if bit 63 is set, then TICK_COMPARE is 8737c478bd9Sstevel@tonic-gate ! disabled. If TICK_COMPARE is enabled, we know that we need to 8747c478bd9Sstevel@tonic-gate ! reenqueue the interrupt request structure. We'll then check TICKINT 8757c478bd9Sstevel@tonic-gate ! in SOFTINT; if it's set, then we know that we were in a TICK_COMPARE 8767c478bd9Sstevel@tonic-gate ! interrupt. In this case, TICK_COMPARE may have been rewritten 8777c478bd9Sstevel@tonic-gate ! recently; we'll compare %o5 to the current time to verify that it's 8787c478bd9Sstevel@tonic-gate ! in the future. 8797c478bd9Sstevel@tonic-gate ! 8807c478bd9Sstevel@tonic-gate ! Note that %o5 is live until after 1f. 8817c478bd9Sstevel@tonic-gate ! XXX - there is a subroutine call while %o5 is live! 8827c478bd9Sstevel@tonic-gate ! 883023e71deSHaik Aftandilian RD_TICKCMPR(%o5,%g1,%g2,__LINE__) 8847c478bd9Sstevel@tonic-gate srlx %o5, TICKINT_DIS_SHFT, %g1 8857c478bd9Sstevel@tonic-gate brnz,pt %g1, 2f 8867c478bd9Sstevel@tonic-gate nop 8877c478bd9Sstevel@tonic-gate 8887c478bd9Sstevel@tonic-gate rdpr %pstate, %g5 8897c478bd9Sstevel@tonic-gate andn %g5, PSTATE_IE, %g1 8907c478bd9Sstevel@tonic-gate wrpr %g0, %g1, %pstate ! Disable vec interrupts 8917c478bd9Sstevel@tonic-gate 8927c478bd9Sstevel@tonic-gate sethi %hi(cbe_level14_inum), %o1 893b0fc0e77Sgovinda ldx [%o1 + %lo(cbe_level14_inum)], %o1 8947c478bd9Sstevel@tonic-gate call intr_enqueue_req ! preserves %o5 and %g5 8957c478bd9Sstevel@tonic-gate mov PIL_14, %o0 8967c478bd9Sstevel@tonic-gate 8977c478bd9Sstevel@tonic-gate ! Check SOFTINT for TICKINT/STICKINT 8987c478bd9Sstevel@tonic-gate rd SOFTINT, %o4 8997c478bd9Sstevel@tonic-gate set (TICK_INT_MASK | STICK_INT_MASK), %o0 9007c478bd9Sstevel@tonic-gate andcc %o4, %o0, %g0 9017c478bd9Sstevel@tonic-gate bz,a,pn %icc, 2f 9027c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %pstate ! Enable vec interrupts 9037c478bd9Sstevel@tonic-gate 9047c478bd9Sstevel@tonic-gate ! clear TICKINT/STICKINT 9057c478bd9Sstevel@tonic-gate wr %o0, CLEAR_SOFTINT 9067c478bd9Sstevel@tonic-gate 9077c478bd9Sstevel@tonic-gate ! 9087c478bd9Sstevel@tonic-gate ! Now that we've cleared TICKINT, we can reread %tick and confirm 9097c478bd9Sstevel@tonic-gate ! that the value we programmed is still in the future. If it isn't, 9107c478bd9Sstevel@tonic-gate ! we need to reprogram TICK_COMPARE to fire as soon as possible. 9117c478bd9Sstevel@tonic-gate ! 912023e71deSHaik Aftandilian GET_NATIVE_TIME(%o0,%g1,%g2,__LINE__) ! %o0 = tick 9137c478bd9Sstevel@tonic-gate cmp %o5, %o0 ! In the future? 9147c478bd9Sstevel@tonic-gate bg,a,pt %xcc, 2f ! Yes, drive on. 9157c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %pstate ! delay: enable vec intr 9167c478bd9Sstevel@tonic-gate 9177c478bd9Sstevel@tonic-gate ! 9187c478bd9Sstevel@tonic-gate ! If we're here, then we have programmed TICK_COMPARE with a %tick 9197c478bd9Sstevel@tonic-gate ! which is in the past; we'll now load an initial step size, and loop 9207c478bd9Sstevel@tonic-gate ! until we've managed to program TICK_COMPARE to fire in the future. 9217c478bd9Sstevel@tonic-gate ! 9227c478bd9Sstevel@tonic-gate mov 8, %o4 ! 8 = arbitrary inital step 9237c478bd9Sstevel@tonic-gate1: add %o0, %o4, %o5 ! Add the step 9247c478bd9Sstevel@tonic-gate WR_TICKCMPR(%o5,%g1,%g2,__LINE__) ! Write to TICK_CMPR 925023e71deSHaik Aftandilian GET_NATIVE_TIME(%o0,%g1,%g2,__LINE__) ! %o0 = tick 9267c478bd9Sstevel@tonic-gate cmp %o5, %o0 ! In the future? 9277c478bd9Sstevel@tonic-gate bg,a,pt %xcc, 2f ! Yes, drive on. 9287c478bd9Sstevel@tonic-gate wrpr %g0, %g5, %pstate ! delay: enable vec intr 9297c478bd9Sstevel@tonic-gate ba 1b ! No, try again. 9307c478bd9Sstevel@tonic-gate sllx %o4, 1, %o4 ! delay: double step size 9317c478bd9Sstevel@tonic-gate 9327c478bd9Sstevel@tonic-gate2: ba current_thread_complete 9337c478bd9Sstevel@tonic-gate nop 9347c478bd9Sstevel@tonic-gate SET_SIZE(tick_rtt) 9357c478bd9Sstevel@tonic-gate 9367c478bd9Sstevel@tonic-gate#endif /* lint */ 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate#if defined(lint) 939b9e93c10SJonathan Haslam 940b9e93c10SJonathan Haslam/* ARGSUSED */ 941b9e93c10SJonathan Haslamvoid 942b9e93c10SJonathan Haslampil15_interrupt(int level) 943b9e93c10SJonathan Haslam{} 944b9e93c10SJonathan Haslam 945b9e93c10SJonathan Haslam#else /* lint */ 946b9e93c10SJonathan Haslam 947b9e93c10SJonathan Haslam/* 948b9e93c10SJonathan Haslam * Level-15 interrupt prologue. 949b9e93c10SJonathan Haslam */ 950b9e93c10SJonathan Haslam ENTRY_NP(pil15_interrupt) 951b9e93c10SJonathan Haslam CPU_ADDR(%g1, %g2) 952b9e93c10SJonathan Haslam rdpr %tstate, %g6 953b9e93c10SJonathan Haslam rdpr %tpc, %g5 954b9e93c10SJonathan Haslam btst TSTATE_PRIV, %g6 ! trap from supervisor mode? 955b9e93c10SJonathan Haslam bnz,a,pt %xcc, 1f 956b9e93c10SJonathan Haslam stn %g5, [%g1 + CPU_CPCPROFILE_PC] ! if so, record kernel PC 957b9e93c10SJonathan Haslam stn %g5, [%g1 + CPU_CPCPROFILE_UPC] ! if not, record user PC 958b9e93c10SJonathan Haslam ba pil15_epilogue ! must be large-disp branch 959b9e93c10SJonathan Haslam stn %g0, [%g1 + CPU_CPCPROFILE_PC] ! zero kernel PC 960b9e93c10SJonathan Haslam1: ba pil15_epilogue ! must be large-disp branch 961b9e93c10SJonathan Haslam stn %g0, [%g1 + CPU_CPCPROFILE_UPC] ! zero user PC 962b9e93c10SJonathan Haslam SET_SIZE(pil15_interrupt) 963b9e93c10SJonathan Haslam 964b9e93c10SJonathan Haslam#endif /* lint */ 965b9e93c10SJonathan Haslam 966b9e93c10SJonathan Haslam#if defined(lint) 9677c478bd9Sstevel@tonic-gate/* 9687c478bd9Sstevel@tonic-gate * Prefetch a page_t for write or read, this assumes a linear 9697c478bd9Sstevel@tonic-gate * scan of sequential page_t's. 9707c478bd9Sstevel@tonic-gate */ 9717c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 9727c478bd9Sstevel@tonic-gatevoid 9737c478bd9Sstevel@tonic-gateprefetch_page_w(void *pp) 9747c478bd9Sstevel@tonic-gate{} 9757c478bd9Sstevel@tonic-gate 9767c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 9777c478bd9Sstevel@tonic-gatevoid 9787c478bd9Sstevel@tonic-gateprefetch_page_r(void *pp) 9797c478bd9Sstevel@tonic-gate{} 9807c478bd9Sstevel@tonic-gate#else /* lint */ 9817c478bd9Sstevel@tonic-gate 9827c478bd9Sstevel@tonic-gate/* XXXQ These should be inline templates, not functions */ 9837c478bd9Sstevel@tonic-gate ENTRY(prefetch_page_w) 9847c478bd9Sstevel@tonic-gate retl 9857c478bd9Sstevel@tonic-gate nop 9867c478bd9Sstevel@tonic-gate SET_SIZE(prefetch_page_w) 9877c478bd9Sstevel@tonic-gate 9887c478bd9Sstevel@tonic-gate ENTRY(prefetch_page_r) 9897c478bd9Sstevel@tonic-gate retl 9907c478bd9Sstevel@tonic-gate nop 9917c478bd9Sstevel@tonic-gate SET_SIZE(prefetch_page_r) 9927c478bd9Sstevel@tonic-gate 9937c478bd9Sstevel@tonic-gate#endif /* lint */ 9947c478bd9Sstevel@tonic-gate 9957c478bd9Sstevel@tonic-gate#if defined(lint) 9967c478bd9Sstevel@tonic-gate/* 9977c478bd9Sstevel@tonic-gate * Prefetch struct smap for write. 9987c478bd9Sstevel@tonic-gate */ 9997c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10007c478bd9Sstevel@tonic-gatevoid 10017c478bd9Sstevel@tonic-gateprefetch_smap_w(void *smp) 10027c478bd9Sstevel@tonic-gate{} 10037c478bd9Sstevel@tonic-gate#else /* lint */ 10047c478bd9Sstevel@tonic-gate 10057c478bd9Sstevel@tonic-gate/* XXXQ These should be inline templates, not functions */ 10067c478bd9Sstevel@tonic-gate ENTRY(prefetch_smap_w) 10077c478bd9Sstevel@tonic-gate retl 10087c478bd9Sstevel@tonic-gate nop 10097c478bd9Sstevel@tonic-gate SET_SIZE(prefetch_smap_w) 10107c478bd9Sstevel@tonic-gate 10117c478bd9Sstevel@tonic-gate#endif /* lint */ 10127c478bd9Sstevel@tonic-gate 10137c478bd9Sstevel@tonic-gate/* 10147c478bd9Sstevel@tonic-gate * Generic sun4v MMU and Cache operations. 10157c478bd9Sstevel@tonic-gate */ 10167c478bd9Sstevel@tonic-gate 10177c478bd9Sstevel@tonic-gate#if defined(lint) 10187c478bd9Sstevel@tonic-gate 10197c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10207c478bd9Sstevel@tonic-gatevoid 10211e2e7a75Shuahvtag_flushpage(caddr_t vaddr, uint64_t sfmmup) 10227c478bd9Sstevel@tonic-gate{} 10237c478bd9Sstevel@tonic-gate 10247c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10257c478bd9Sstevel@tonic-gatevoid 10267c478bd9Sstevel@tonic-gatevtag_flushall(void) 10277c478bd9Sstevel@tonic-gate{} 10287c478bd9Sstevel@tonic-gate 10297c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10307c478bd9Sstevel@tonic-gatevoid 10317c478bd9Sstevel@tonic-gatevtag_unmap_perm_tl1(uint64_t vaddr, uint64_t ctxnum) 10327c478bd9Sstevel@tonic-gate{} 10337c478bd9Sstevel@tonic-gate 10347c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10357c478bd9Sstevel@tonic-gatevoid 10361e2e7a75Shuahvtag_flushpage_tl1(uint64_t vaddr, uint64_t sfmmup) 10377c478bd9Sstevel@tonic-gate{} 10387c478bd9Sstevel@tonic-gate 10397c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10407c478bd9Sstevel@tonic-gatevoid 10411e2e7a75Shuahvtag_flush_pgcnt_tl1(uint64_t vaddr, uint64_t sfmmup_pgcnt) 10427c478bd9Sstevel@tonic-gate{} 10437c478bd9Sstevel@tonic-gate 10447c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10457c478bd9Sstevel@tonic-gatevoid 10467c478bd9Sstevel@tonic-gatevtag_flushall_tl1(uint64_t dummy1, uint64_t dummy2) 10477c478bd9Sstevel@tonic-gate{} 10487c478bd9Sstevel@tonic-gate 10497c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10507c478bd9Sstevel@tonic-gatevoid 10517c478bd9Sstevel@tonic-gatevac_flushpage(pfn_t pfnum, int vcolor) 10527c478bd9Sstevel@tonic-gate{} 10537c478bd9Sstevel@tonic-gate 10547c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10557c478bd9Sstevel@tonic-gatevoid 10567c478bd9Sstevel@tonic-gatevac_flushpage_tl1(uint64_t pfnum, uint64_t vcolor) 10577c478bd9Sstevel@tonic-gate{} 10587c478bd9Sstevel@tonic-gate 10597c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 10607c478bd9Sstevel@tonic-gatevoid 10617c478bd9Sstevel@tonic-gateflush_instr_mem(caddr_t vaddr, size_t len) 10627c478bd9Sstevel@tonic-gate{} 10637c478bd9Sstevel@tonic-gate 10647c478bd9Sstevel@tonic-gate#else /* lint */ 10657c478bd9Sstevel@tonic-gate 10667c478bd9Sstevel@tonic-gate ENTRY_NP(vtag_flushpage) 10677c478bd9Sstevel@tonic-gate /* 10687c478bd9Sstevel@tonic-gate * flush page from the tlb 10697c478bd9Sstevel@tonic-gate * 10707c478bd9Sstevel@tonic-gate * %o0 = vaddr 10711e2e7a75Shuah * %o1 = sfmmup 10727c478bd9Sstevel@tonic-gate */ 10731e2e7a75Shuah SFMMU_CPU_CNUM(%o1, %g1, %g2) /* %g1 = sfmmu cnum on this CPU */ 10741e2e7a75Shuah 10751e2e7a75Shuah mov %g1, %o1 10767c478bd9Sstevel@tonic-gate mov MAP_ITLB | MAP_DTLB, %o2 10777c478bd9Sstevel@tonic-gate ta MMU_UNMAP_ADDR 10787c478bd9Sstevel@tonic-gate brz,pt %o0, 1f 10797c478bd9Sstevel@tonic-gate nop 10807c478bd9Sstevel@tonic-gate ba panic_bad_hcall 10817c478bd9Sstevel@tonic-gate mov MMU_UNMAP_ADDR, %o1 10827c478bd9Sstevel@tonic-gate1: 10837c478bd9Sstevel@tonic-gate retl 10847c478bd9Sstevel@tonic-gate nop 10857c478bd9Sstevel@tonic-gate SET_SIZE(vtag_flushpage) 10867c478bd9Sstevel@tonic-gate 10877c478bd9Sstevel@tonic-gate ENTRY_NP(vtag_flushall) 10887c478bd9Sstevel@tonic-gate mov %g0, %o0 ! XXX no cpu list yet 10897c478bd9Sstevel@tonic-gate mov %g0, %o1 ! XXX no cpu list yet 10907c478bd9Sstevel@tonic-gate mov MAP_ITLB | MAP_DTLB, %o2 10917c478bd9Sstevel@tonic-gate mov MMU_DEMAP_ALL, %o5 10927c478bd9Sstevel@tonic-gate ta FAST_TRAP 10937c478bd9Sstevel@tonic-gate brz,pt %o0, 1f 10947c478bd9Sstevel@tonic-gate nop 10957c478bd9Sstevel@tonic-gate ba panic_bad_hcall 10967c478bd9Sstevel@tonic-gate mov MMU_DEMAP_ALL, %o1 10977c478bd9Sstevel@tonic-gate1: 10987c478bd9Sstevel@tonic-gate retl 10997c478bd9Sstevel@tonic-gate nop 11007c478bd9Sstevel@tonic-gate SET_SIZE(vtag_flushall) 11017c478bd9Sstevel@tonic-gate 11027c478bd9Sstevel@tonic-gate ENTRY_NP(vtag_unmap_perm_tl1) 11037c478bd9Sstevel@tonic-gate /* 11047c478bd9Sstevel@tonic-gate * x-trap to unmap perm map entry 11057c478bd9Sstevel@tonic-gate * %g1 = vaddr 11061e2e7a75Shuah * %g2 = ctxnum (KCONTEXT only) 11077c478bd9Sstevel@tonic-gate */ 11087c478bd9Sstevel@tonic-gate mov %o0, %g3 11097c478bd9Sstevel@tonic-gate mov %o1, %g4 11107c478bd9Sstevel@tonic-gate mov %o2, %g5 11117c478bd9Sstevel@tonic-gate mov %o5, %g6 11127c478bd9Sstevel@tonic-gate mov %g1, %o0 11137c478bd9Sstevel@tonic-gate mov %g2, %o1 11147c478bd9Sstevel@tonic-gate mov MAP_ITLB | MAP_DTLB, %o2 11157c478bd9Sstevel@tonic-gate mov UNMAP_PERM_ADDR, %o5 11167c478bd9Sstevel@tonic-gate ta FAST_TRAP 11177c478bd9Sstevel@tonic-gate brz,pt %o0, 1f 11187c478bd9Sstevel@tonic-gate nop 11191ae08745Sheppo 11207c478bd9Sstevel@tonic-gate mov PTL1_BAD_HCALL, %g1 11211ae08745Sheppo 11221ae08745Sheppo cmp %o0, H_ENOMAP 11231ae08745Sheppo move %xcc, PTL1_BAD_HCALL_UNMAP_PERM_ENOMAP, %g1 11241ae08745Sheppo 11251ae08745Sheppo cmp %o0, H_EINVAL 11261ae08745Sheppo move %xcc, PTL1_BAD_HCALL_UNMAP_PERM_EINVAL, %g1 11271ae08745Sheppo 11281ae08745Sheppo ba,a ptl1_panic 11297c478bd9Sstevel@tonic-gate1: 11307c478bd9Sstevel@tonic-gate mov %g6, %o5 11317c478bd9Sstevel@tonic-gate mov %g5, %o2 11327c478bd9Sstevel@tonic-gate mov %g4, %o1 11337c478bd9Sstevel@tonic-gate mov %g3, %o0 11347c478bd9Sstevel@tonic-gate retry 11357c478bd9Sstevel@tonic-gate SET_SIZE(vtag_unmap_perm_tl1) 11367c478bd9Sstevel@tonic-gate 11377c478bd9Sstevel@tonic-gate ENTRY_NP(vtag_flushpage_tl1) 11387c478bd9Sstevel@tonic-gate /* 11397c478bd9Sstevel@tonic-gate * x-trap to flush page from tlb and tsb 11407c478bd9Sstevel@tonic-gate * 11417c478bd9Sstevel@tonic-gate * %g1 = vaddr, zero-extended on 32-bit kernel 11421e2e7a75Shuah * %g2 = sfmmup 11437c478bd9Sstevel@tonic-gate * 11447c478bd9Sstevel@tonic-gate * assumes TSBE_TAG = 0 11457c478bd9Sstevel@tonic-gate */ 11467c478bd9Sstevel@tonic-gate srln %g1, MMU_PAGESHIFT, %g1 11477c478bd9Sstevel@tonic-gate slln %g1, MMU_PAGESHIFT, %g1 /* g1 = vaddr */ 11487c478bd9Sstevel@tonic-gate mov %o0, %g3 11497c478bd9Sstevel@tonic-gate mov %o1, %g4 11507c478bd9Sstevel@tonic-gate mov %o2, %g5 11511e2e7a75Shuah mov %g1, %o0 /* vaddr */ 11521e2e7a75Shuah 11531e2e7a75Shuah SFMMU_CPU_CNUM(%g2, %o1, %g6) /* %o1 = sfmmu cnum on this CPU */ 11541e2e7a75Shuah 11557c478bd9Sstevel@tonic-gate mov MAP_ITLB | MAP_DTLB, %o2 11567c478bd9Sstevel@tonic-gate ta MMU_UNMAP_ADDR 11577c478bd9Sstevel@tonic-gate brz,pt %o0, 1f 11587c478bd9Sstevel@tonic-gate nop 11597c478bd9Sstevel@tonic-gate ba ptl1_panic 11607c478bd9Sstevel@tonic-gate mov PTL1_BAD_HCALL, %g1 11617c478bd9Sstevel@tonic-gate1: 11627c478bd9Sstevel@tonic-gate mov %g5, %o2 11637c478bd9Sstevel@tonic-gate mov %g4, %o1 11647c478bd9Sstevel@tonic-gate mov %g3, %o0 11657c478bd9Sstevel@tonic-gate membar #Sync 11667c478bd9Sstevel@tonic-gate retry 11677c478bd9Sstevel@tonic-gate SET_SIZE(vtag_flushpage_tl1) 11687c478bd9Sstevel@tonic-gate 11697c478bd9Sstevel@tonic-gate ENTRY_NP(vtag_flush_pgcnt_tl1) 11707c478bd9Sstevel@tonic-gate /* 11717c478bd9Sstevel@tonic-gate * x-trap to flush pgcnt MMU_PAGESIZE pages from tlb 11727c478bd9Sstevel@tonic-gate * 11737c478bd9Sstevel@tonic-gate * %g1 = vaddr, zero-extended on 32-bit kernel 11741e2e7a75Shuah * %g2 = <sfmmup58|pgcnt6>, (pgcnt - 1) is pass'ed in via pgcnt6 bits. 11757c478bd9Sstevel@tonic-gate * 11767c478bd9Sstevel@tonic-gate * NOTE: this handler relies on the fact that no 11777c478bd9Sstevel@tonic-gate * interrupts or traps can occur during the loop 11787c478bd9Sstevel@tonic-gate * issuing the TLB_DEMAP operations. It is assumed 11797c478bd9Sstevel@tonic-gate * that interrupts are disabled and this code is 11807c478bd9Sstevel@tonic-gate * fetching from the kernel locked text address. 11817c478bd9Sstevel@tonic-gate * 11827c478bd9Sstevel@tonic-gate * assumes TSBE_TAG = 0 11837c478bd9Sstevel@tonic-gate */ 11847c478bd9Sstevel@tonic-gate srln %g1, MMU_PAGESHIFT, %g1 11857c478bd9Sstevel@tonic-gate slln %g1, MMU_PAGESHIFT, %g1 /* g1 = vaddr */ 11867c478bd9Sstevel@tonic-gate mov %o0, %g3 11877c478bd9Sstevel@tonic-gate mov %o1, %g4 11887c478bd9Sstevel@tonic-gate mov %o2, %g5 11897c478bd9Sstevel@tonic-gate 11901e2e7a75Shuah and %g2, SFMMU_PGCNT_MASK, %g7 /* g7 = pgcnt - 1 */ 11911e2e7a75Shuah add %g7, 1, %g7 /* g7 = pgcnt */ 11927c478bd9Sstevel@tonic-gate 11931e2e7a75Shuah andn %g2, SFMMU_PGCNT_MASK, %o0 /* %o0 = sfmmup */ 11941e2e7a75Shuah 11951e2e7a75Shuah SFMMU_CPU_CNUM(%o0, %g2, %g6) /* %g2 = sfmmu cnum on this CPU */ 11961e2e7a75Shuah 11971e2e7a75Shuah set MMU_PAGESIZE, %g6 /* g6 = pgsize */ 11981e2e7a75Shuah 11997c478bd9Sstevel@tonic-gate1: 12001e2e7a75Shuah mov %g1, %o0 /* vaddr */ 12011e2e7a75Shuah mov %g2, %o1 /* cnum */ 12027c478bd9Sstevel@tonic-gate mov MAP_ITLB | MAP_DTLB, %o2 12037c478bd9Sstevel@tonic-gate ta MMU_UNMAP_ADDR 12047c478bd9Sstevel@tonic-gate brz,pt %o0, 2f 12057c478bd9Sstevel@tonic-gate nop 12067c478bd9Sstevel@tonic-gate ba ptl1_panic 12077c478bd9Sstevel@tonic-gate mov PTL1_BAD_HCALL, %g1 12087c478bd9Sstevel@tonic-gate2: 12097c478bd9Sstevel@tonic-gate deccc %g7 /* decr pgcnt */ 12107c478bd9Sstevel@tonic-gate bnz,pt %icc,1b 12117c478bd9Sstevel@tonic-gate add %g1, %g6, %g1 /* go to nextpage */ 12127c478bd9Sstevel@tonic-gate 12137c478bd9Sstevel@tonic-gate mov %g5, %o2 12147c478bd9Sstevel@tonic-gate mov %g4, %o1 12157c478bd9Sstevel@tonic-gate mov %g3, %o0 12167c478bd9Sstevel@tonic-gate membar #Sync 12177c478bd9Sstevel@tonic-gate retry 12187c478bd9Sstevel@tonic-gate SET_SIZE(vtag_flush_pgcnt_tl1) 12197c478bd9Sstevel@tonic-gate 12207c478bd9Sstevel@tonic-gate ! Not implemented on US1/US2 12217c478bd9Sstevel@tonic-gate ENTRY_NP(vtag_flushall_tl1) 12227c478bd9Sstevel@tonic-gate mov %o0, %g3 12237c478bd9Sstevel@tonic-gate mov %o1, %g4 12247c478bd9Sstevel@tonic-gate mov %o2, %g5 12257c478bd9Sstevel@tonic-gate mov %o3, %g6 ! XXXQ not used? 12267c478bd9Sstevel@tonic-gate mov %o5, %g7 12277c478bd9Sstevel@tonic-gate mov %g0, %o0 ! XXX no cpu list yet 12287c478bd9Sstevel@tonic-gate mov %g0, %o1 ! XXX no cpu list yet 12297c478bd9Sstevel@tonic-gate mov MAP_ITLB | MAP_DTLB, %o2 12307c478bd9Sstevel@tonic-gate mov MMU_DEMAP_ALL, %o5 12317c478bd9Sstevel@tonic-gate ta FAST_TRAP 12327c478bd9Sstevel@tonic-gate brz,pt %o0, 1f 12337c478bd9Sstevel@tonic-gate nop 12347c478bd9Sstevel@tonic-gate ba ptl1_panic 12357c478bd9Sstevel@tonic-gate mov PTL1_BAD_HCALL, %g1 12367c478bd9Sstevel@tonic-gate1: 12377c478bd9Sstevel@tonic-gate mov %g7, %o5 12387c478bd9Sstevel@tonic-gate mov %g6, %o3 ! XXXQ not used? 12397c478bd9Sstevel@tonic-gate mov %g5, %o2 12407c478bd9Sstevel@tonic-gate mov %g4, %o1 12417c478bd9Sstevel@tonic-gate mov %g3, %o0 12427c478bd9Sstevel@tonic-gate retry 12437c478bd9Sstevel@tonic-gate SET_SIZE(vtag_flushall_tl1) 12447c478bd9Sstevel@tonic-gate 12457c478bd9Sstevel@tonic-gate/* 12467c478bd9Sstevel@tonic-gate * flush_instr_mem: 12477c478bd9Sstevel@tonic-gate * Flush a portion of the I-$ starting at vaddr 12487c478bd9Sstevel@tonic-gate * %o0 vaddr 12497c478bd9Sstevel@tonic-gate * %o1 bytes to be flushed 12507c478bd9Sstevel@tonic-gate */ 12517c478bd9Sstevel@tonic-gate 12527c478bd9Sstevel@tonic-gate ENTRY(flush_instr_mem) 12537c478bd9Sstevel@tonic-gate membar #StoreStore ! Ensure the stores 12547c478bd9Sstevel@tonic-gate ! are globally visible 12557c478bd9Sstevel@tonic-gate1: 12567c478bd9Sstevel@tonic-gate flush %o0 12577c478bd9Sstevel@tonic-gate subcc %o1, ICACHE_FLUSHSZ, %o1 ! bytes = bytes-0x20 12587c478bd9Sstevel@tonic-gate bgu,pt %ncc, 1b 12597c478bd9Sstevel@tonic-gate add %o0, ICACHE_FLUSHSZ, %o0 ! vaddr = vaddr+0x20 12607c478bd9Sstevel@tonic-gate 12617c478bd9Sstevel@tonic-gate retl 12627c478bd9Sstevel@tonic-gate nop 12637c478bd9Sstevel@tonic-gate SET_SIZE(flush_instr_mem) 12647c478bd9Sstevel@tonic-gate 12657c478bd9Sstevel@tonic-gate#endif /* !lint */ 12667bafd143Sjb145095 12672f0fcb93SJason Beloro#if !defined(CUSTOM_FPZERO) 12682f0fcb93SJason Beloro 12697bafd143Sjb145095/* 12707bafd143Sjb145095 * fp_zero() - clear all fp data registers and the fsr 12717bafd143Sjb145095 */ 12727bafd143Sjb145095 12737bafd143Sjb145095#if defined(lint) || defined(__lint) 12747bafd143Sjb145095 12757bafd143Sjb145095void 12767bafd143Sjb145095fp_zero(void) 12777bafd143Sjb145095{} 12787bafd143Sjb145095 12797bafd143Sjb145095#else /* lint */ 12807bafd143Sjb145095 12817bafd143Sjb145095.global fp_zero_zero 12827bafd143Sjb145095.align 8 12837bafd143Sjb145095fp_zero_zero: 12847bafd143Sjb145095 .xword 0 12857bafd143Sjb145095 12867bafd143Sjb145095 ENTRY_NP(fp_zero) 12877bafd143Sjb145095 sethi %hi(fp_zero_zero), %o0 12882f0fcb93SJason Beloro ldx [%o0 + %lo(fp_zero_zero)], %fsr 12897bafd143Sjb145095 ldd [%o0 + %lo(fp_zero_zero)], %f0 12907bafd143Sjb145095 fmovd %f0, %f2 12917bafd143Sjb145095 fmovd %f0, %f4 12927bafd143Sjb145095 fmovd %f0, %f6 12937bafd143Sjb145095 fmovd %f0, %f8 12947bafd143Sjb145095 fmovd %f0, %f10 12957bafd143Sjb145095 fmovd %f0, %f12 12967bafd143Sjb145095 fmovd %f0, %f14 12977bafd143Sjb145095 fmovd %f0, %f16 12987bafd143Sjb145095 fmovd %f0, %f18 12997bafd143Sjb145095 fmovd %f0, %f20 13007bafd143Sjb145095 fmovd %f0, %f22 13017bafd143Sjb145095 fmovd %f0, %f24 13027bafd143Sjb145095 fmovd %f0, %f26 13037bafd143Sjb145095 fmovd %f0, %f28 13047bafd143Sjb145095 fmovd %f0, %f30 13057bafd143Sjb145095 fmovd %f0, %f32 13067bafd143Sjb145095 fmovd %f0, %f34 13077bafd143Sjb145095 fmovd %f0, %f36 13087bafd143Sjb145095 fmovd %f0, %f38 13097bafd143Sjb145095 fmovd %f0, %f40 13107bafd143Sjb145095 fmovd %f0, %f42 13117bafd143Sjb145095 fmovd %f0, %f44 13127bafd143Sjb145095 fmovd %f0, %f46 13137bafd143Sjb145095 fmovd %f0, %f48 13147bafd143Sjb145095 fmovd %f0, %f50 13157bafd143Sjb145095 fmovd %f0, %f52 13167bafd143Sjb145095 fmovd %f0, %f54 13177bafd143Sjb145095 fmovd %f0, %f56 13187bafd143Sjb145095 fmovd %f0, %f58 13197bafd143Sjb145095 fmovd %f0, %f60 13207bafd143Sjb145095 retl 13217bafd143Sjb145095 fmovd %f0, %f62 13227bafd143Sjb145095 SET_SIZE(fp_zero) 13237bafd143Sjb145095 13247bafd143Sjb145095#endif /* lint */ 13252f0fcb93SJason Beloro#endif /* CUSTOM_FPZERO */ 1326