10Sstevel@tonic-gate/* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51614Sjb145095 * Common Development and Distribution License (the "License"). 61614Sjb145095 * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate/* 22*12908SPavel.Tatashin@Sun.COM * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 230Sstevel@tonic-gate */ 240Sstevel@tonic-gate 250Sstevel@tonic-gate#if !defined(lint) 260Sstevel@tonic-gate#include "assym.h" 270Sstevel@tonic-gate#endif 280Sstevel@tonic-gate 290Sstevel@tonic-gate/* 300Sstevel@tonic-gate * General assembly language routines. 310Sstevel@tonic-gate * It is the intent of this file to contain routines that are 320Sstevel@tonic-gate * specific to cpu architecture. 330Sstevel@tonic-gate */ 340Sstevel@tonic-gate 350Sstevel@tonic-gate/* 360Sstevel@tonic-gate * WARNING: If you add a fast trap handler which can be invoked by a 370Sstevel@tonic-gate * non-privileged user, you may have to use the FAST_TRAP_DONE macro 380Sstevel@tonic-gate * instead of "done" instruction to return back to the user mode. See 390Sstevel@tonic-gate * comments for the "fast_trap_done" entry point for more information. 400Sstevel@tonic-gate */ 410Sstevel@tonic-gate#define FAST_TRAP_DONE \ 420Sstevel@tonic-gate ba,a fast_trap_done 430Sstevel@tonic-gate 4411172SHaik.Aftandilian@Sun.COM#include <sys/machclock.h> 450Sstevel@tonic-gate#include <sys/clock.h> 460Sstevel@tonic-gate 470Sstevel@tonic-gate#if defined(lint) 480Sstevel@tonic-gate#include <sys/types.h> 490Sstevel@tonic-gate#include <sys/scb.h> 500Sstevel@tonic-gate#include <sys/systm.h> 510Sstevel@tonic-gate#include <sys/regset.h> 520Sstevel@tonic-gate#include <sys/sunddi.h> 530Sstevel@tonic-gate#include <sys/lockstat.h> 540Sstevel@tonic-gate#endif /* lint */ 550Sstevel@tonic-gate 560Sstevel@tonic-gate 570Sstevel@tonic-gate#include <sys/asm_linkage.h> 580Sstevel@tonic-gate#include <sys/privregs.h> 592241Shuah#include <vm/hat_sfmmu.h> 600Sstevel@tonic-gate#include <sys/machparam.h> /* To get SYSBASE and PAGESIZE */ 610Sstevel@tonic-gate#include <sys/machthread.h> 620Sstevel@tonic-gate#include <sys/clock.h> 630Sstevel@tonic-gate#include <sys/intreg.h> 640Sstevel@tonic-gate#include <sys/psr_compat.h> 650Sstevel@tonic-gate#include <sys/isa_defs.h> 660Sstevel@tonic-gate#include <sys/dditypes.h> 670Sstevel@tonic-gate#include <sys/intr.h> 680Sstevel@tonic-gate#include <sys/hypervisor_api.h> 690Sstevel@tonic-gate 700Sstevel@tonic-gate#if !defined(lint) 710Sstevel@tonic-gate#include "assym.h" 720Sstevel@tonic-gate#endif 730Sstevel@tonic-gate 740Sstevel@tonic-gate#define ICACHE_FLUSHSZ 0x20 750Sstevel@tonic-gate 760Sstevel@tonic-gate#if defined(lint) 770Sstevel@tonic-gate/* 780Sstevel@tonic-gate * Softint generated when counter field of tick reg matches value field 790Sstevel@tonic-gate * of tick_cmpr reg 800Sstevel@tonic-gate */ 810Sstevel@tonic-gate/*ARGSUSED*/ 820Sstevel@tonic-gatevoid 830Sstevel@tonic-gatetickcmpr_set(uint64_t clock_cycles) 840Sstevel@tonic-gate{} 850Sstevel@tonic-gate 860Sstevel@tonic-gate#else /* lint */ 870Sstevel@tonic-gate 880Sstevel@tonic-gate ENTRY_NP(tickcmpr_set) 890Sstevel@tonic-gate ! get 64-bit clock_cycles interval 900Sstevel@tonic-gate mov %o0, %o2 910Sstevel@tonic-gate mov 8, %o3 ! A reasonable initial step size 920Sstevel@tonic-gate1: 930Sstevel@tonic-gate WR_TICKCMPR(%o2,%o4,%o5,__LINE__) ! Write to TICK_CMPR 940Sstevel@tonic-gate 9511172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%o0,%o4,%o5,__LINE__) ! Read %tick to confirm the 9611172SHaik.Aftandilian@Sun.COM ! value we wrote was in the 9711172SHaik.Aftandilian@Sun.COM ! future. 980Sstevel@tonic-gate 990Sstevel@tonic-gate cmp %o2, %o0 ! If the value we wrote was in the 1000Sstevel@tonic-gate bg,pt %xcc, 2f ! future, then blow out of here. 1012241Shuah sllx %o3, 1, %o3 ! If not, then double our step size, 1020Sstevel@tonic-gate ba,pt %xcc, 1b ! and take another lap. 1032241Shuah add %o0, %o3, %o2 ! 1040Sstevel@tonic-gate2: 1050Sstevel@tonic-gate retl 1062241Shuah nop 1070Sstevel@tonic-gate SET_SIZE(tickcmpr_set) 1080Sstevel@tonic-gate 1090Sstevel@tonic-gate#endif /* lint */ 1100Sstevel@tonic-gate 1110Sstevel@tonic-gate#if defined(lint) 1120Sstevel@tonic-gate 1130Sstevel@tonic-gatevoid 1140Sstevel@tonic-gatetickcmpr_disable(void) 1150Sstevel@tonic-gate{} 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate#else 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate ENTRY_NP(tickcmpr_disable) 1200Sstevel@tonic-gate mov 1, %g1 1210Sstevel@tonic-gate sllx %g1, TICKINT_DIS_SHFT, %o0 1220Sstevel@tonic-gate WR_TICKCMPR(%o0,%o4,%o5,__LINE__) ! Write to TICK_CMPR 1230Sstevel@tonic-gate retl 1242241Shuah nop 1250Sstevel@tonic-gate SET_SIZE(tickcmpr_disable) 1260Sstevel@tonic-gate 1270Sstevel@tonic-gate#endif 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate#if defined(lint) 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate/* 13212015SHaik.Aftandilian@Sun.COM * tick_write_delta() is intended to increment %stick by the specified delta, 13312015SHaik.Aftandilian@Sun.COM * but %stick is only writeable in hyperprivileged mode and at present there 13412015SHaik.Aftandilian@Sun.COM * is no provision for this. tick_write_delta is called by the cylic subsystem 13512015SHaik.Aftandilian@Sun.COM * if a negative %stick delta is observed after cyclic processing is resumed 13612015SHaik.Aftandilian@Sun.COM * after an event such as an OS suspend/resume. On sun4v, the suspend/resume 13712015SHaik.Aftandilian@Sun.COM * routines should adjust the %stick offset preventing the cyclic subsystem 13812015SHaik.Aftandilian@Sun.COM * from detecting a negative delta. If a negative delta is detected, panic the 13912015SHaik.Aftandilian@Sun.COM * system. The negative delta could be caused by improper %stick 14012015SHaik.Aftandilian@Sun.COM * synchronization after a suspend/resume. 1410Sstevel@tonic-gate */ 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate/*ARGSUSED*/ 1440Sstevel@tonic-gatevoid 1450Sstevel@tonic-gatetick_write_delta(uint64_t delta) 1460Sstevel@tonic-gate{} 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate#else /* lint */ 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate .seg ".text" 1510Sstevel@tonic-gatetick_write_delta_panic: 15212015SHaik.Aftandilian@Sun.COM .asciz "tick_write_delta: not supported, delta: 0x%lx" 1530Sstevel@tonic-gate 1540Sstevel@tonic-gate ENTRY_NP(tick_write_delta) 1550Sstevel@tonic-gate sethi %hi(tick_write_delta_panic), %o1 1560Sstevel@tonic-gate save %sp, -SA(MINFRAME), %sp ! get a new window to preserve caller 15712015SHaik.Aftandilian@Sun.COM mov %i0, %o1 1580Sstevel@tonic-gate call panic 1592241Shuah or %i1, %lo(tick_write_delta_panic), %o0 1600Sstevel@tonic-gate /*NOTREACHED*/ 1610Sstevel@tonic-gate retl 1622241Shuah nop 1630Sstevel@tonic-gate#endif 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate#if defined(lint) 1660Sstevel@tonic-gate/* 1670Sstevel@tonic-gate * return 1 if disabled 1680Sstevel@tonic-gate */ 1690Sstevel@tonic-gate 1700Sstevel@tonic-gateint 1710Sstevel@tonic-gatetickcmpr_disabled(void) 1720Sstevel@tonic-gate{ return (0); } 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate#else /* lint */ 1750Sstevel@tonic-gate 1760Sstevel@tonic-gate ENTRY_NP(tickcmpr_disabled) 17711172SHaik.Aftandilian@Sun.COM RD_TICKCMPR(%g1,%o0,%o1,__LINE__) 1780Sstevel@tonic-gate retl 1792241Shuah srlx %g1, TICKINT_DIS_SHFT, %o0 1800Sstevel@tonic-gate SET_SIZE(tickcmpr_disabled) 1810Sstevel@tonic-gate 1820Sstevel@tonic-gate#endif /* lint */ 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate/* 1850Sstevel@tonic-gate * Get current tick 1860Sstevel@tonic-gate */ 1870Sstevel@tonic-gate#if defined(lint) 1880Sstevel@tonic-gate 1890Sstevel@tonic-gateu_longlong_t 1900Sstevel@tonic-gategettick(void) 1910Sstevel@tonic-gate{ return (0); } 1920Sstevel@tonic-gate 193*12908SPavel.Tatashin@Sun.COMu_longlong_t 194*12908SPavel.Tatashin@Sun.COMrandtick(void) 195*12908SPavel.Tatashin@Sun.COM{ return (0); } 196*12908SPavel.Tatashin@Sun.COM 1970Sstevel@tonic-gate#else /* lint */ 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate ENTRY(gettick) 200*12908SPavel.Tatashin@Sun.COM ALTENTRY(randtick) 20111172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%o0,%o2,%o3,__LINE__) 2020Sstevel@tonic-gate retl 2032241Shuah nop 204*12908SPavel.Tatashin@Sun.COM SET_SIZE(randtick) 2050Sstevel@tonic-gate SET_SIZE(gettick) 2060Sstevel@tonic-gate 2070Sstevel@tonic-gate#endif /* lint */ 2080Sstevel@tonic-gate 20911172SHaik.Aftandilian@Sun.COM/* 21011172SHaik.Aftandilian@Sun.COM * Get current tick. For trapstat use only. 21111172SHaik.Aftandilian@Sun.COM */ 21211172SHaik.Aftandilian@Sun.COM#if defined (lint) 21311172SHaik.Aftandilian@Sun.COM 21411172SHaik.Aftandilian@Sun.COMhrtime_t 21511172SHaik.Aftandilian@Sun.COMrdtick() 21611172SHaik.Aftandilian@Sun.COM{ return (0); } 21711172SHaik.Aftandilian@Sun.COM 21811172SHaik.Aftandilian@Sun.COM#else 21911172SHaik.Aftandilian@Sun.COM ENTRY(rdtick) 22011172SHaik.Aftandilian@Sun.COM retl 22111172SHaik.Aftandilian@Sun.COM RD_TICK_PHYSICAL(%o0) 22211172SHaik.Aftandilian@Sun.COM SET_SIZE(rdtick) 22311172SHaik.Aftandilian@Sun.COM#endif /* lint */ 22411172SHaik.Aftandilian@Sun.COM 2250Sstevel@tonic-gate 2260Sstevel@tonic-gate/* 2270Sstevel@tonic-gate * Return the counter portion of the tick register. 2280Sstevel@tonic-gate */ 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate#if defined(lint) 2310Sstevel@tonic-gate 2320Sstevel@tonic-gateuint64_t 2330Sstevel@tonic-gategettick_counter(void) 2340Sstevel@tonic-gate{ return(0); } 2350Sstevel@tonic-gate 23611172SHaik.Aftandilian@Sun.COMuint64_t 23711172SHaik.Aftandilian@Sun.COMgettick_npt(void) 23811172SHaik.Aftandilian@Sun.COM{ return(0); } 23911172SHaik.Aftandilian@Sun.COM 24011172SHaik.Aftandilian@Sun.COMuint64_t 24111172SHaik.Aftandilian@Sun.COMgetstick_npt(void) 24211172SHaik.Aftandilian@Sun.COM{ return(0); } 24311172SHaik.Aftandilian@Sun.COM 2440Sstevel@tonic-gate#else /* lint */ 2450Sstevel@tonic-gate 2460Sstevel@tonic-gate ENTRY_NP(gettick_counter) 24711172SHaik.Aftandilian@Sun.COM RD_TICK(%o0,%o1,%o2,__LINE__) 24811172SHaik.Aftandilian@Sun.COM retl 24911172SHaik.Aftandilian@Sun.COM nop 25011172SHaik.Aftandilian@Sun.COM SET_SIZE(gettick_counter) 25111172SHaik.Aftandilian@Sun.COM 25211172SHaik.Aftandilian@Sun.COM ENTRY_NP(gettick_npt) 25311172SHaik.Aftandilian@Sun.COM RD_TICK_PHYSICAL(%o0) 2540Sstevel@tonic-gate retl 25511172SHaik.Aftandilian@Sun.COM srlx %o0, 63, %o0 25611172SHaik.Aftandilian@Sun.COM SET_SIZE(gettick_npt) 25711172SHaik.Aftandilian@Sun.COM 25811172SHaik.Aftandilian@Sun.COM ENTRY_NP(getstick_npt) 25911172SHaik.Aftandilian@Sun.COM RD_STICK_PHYSICAL(%o0) 26011172SHaik.Aftandilian@Sun.COM retl 26111172SHaik.Aftandilian@Sun.COM srlx %o0, 63, %o0 26211172SHaik.Aftandilian@Sun.COM SET_SIZE(getstick_npt) 2630Sstevel@tonic-gate#endif /* lint */ 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate/* 2660Sstevel@tonic-gate * Provide a C callable interface to the trap that reads the hi-res timer. 2670Sstevel@tonic-gate * Returns 64-bit nanosecond timestamp in %o0 and %o1. 2680Sstevel@tonic-gate */ 2690Sstevel@tonic-gate 2700Sstevel@tonic-gate#if defined(lint) 2710Sstevel@tonic-gate 2720Sstevel@tonic-gatehrtime_t 2730Sstevel@tonic-gategethrtime(void) 2740Sstevel@tonic-gate{ 2750Sstevel@tonic-gate return ((hrtime_t)0); 2760Sstevel@tonic-gate} 2770Sstevel@tonic-gate 2780Sstevel@tonic-gatehrtime_t 2790Sstevel@tonic-gategethrtime_unscaled(void) 2800Sstevel@tonic-gate{ 2810Sstevel@tonic-gate return ((hrtime_t)0); 2820Sstevel@tonic-gate} 2830Sstevel@tonic-gate 2840Sstevel@tonic-gatehrtime_t 2850Sstevel@tonic-gategethrtime_max(void) 2860Sstevel@tonic-gate{ 2870Sstevel@tonic-gate return ((hrtime_t)0); 2880Sstevel@tonic-gate} 2890Sstevel@tonic-gate 2900Sstevel@tonic-gatevoid 2910Sstevel@tonic-gatescalehrtime(hrtime_t *hrt) 2920Sstevel@tonic-gate{ 2930Sstevel@tonic-gate *hrt = 0; 2940Sstevel@tonic-gate} 2950Sstevel@tonic-gate 2960Sstevel@tonic-gatevoid 2970Sstevel@tonic-gategethrestime(timespec_t *tp) 2980Sstevel@tonic-gate{ 2990Sstevel@tonic-gate tp->tv_sec = 0; 3000Sstevel@tonic-gate tp->tv_nsec = 0; 3010Sstevel@tonic-gate} 3020Sstevel@tonic-gate 3030Sstevel@tonic-gatetime_t 3040Sstevel@tonic-gategethrestime_sec(void) 3050Sstevel@tonic-gate{ 3060Sstevel@tonic-gate return (0); 3070Sstevel@tonic-gate} 3080Sstevel@tonic-gate 3090Sstevel@tonic-gatevoid 3100Sstevel@tonic-gategethrestime_lasttick(timespec_t *tp) 3110Sstevel@tonic-gate{ 3120Sstevel@tonic-gate tp->tv_sec = 0; 3130Sstevel@tonic-gate tp->tv_nsec = 0; 3140Sstevel@tonic-gate} 3150Sstevel@tonic-gate 3160Sstevel@tonic-gate/*ARGSUSED*/ 3170Sstevel@tonic-gatevoid 3180Sstevel@tonic-gatehres_tick(void) 3190Sstevel@tonic-gate{ 3200Sstevel@tonic-gate} 3210Sstevel@tonic-gate 3220Sstevel@tonic-gatevoid 3230Sstevel@tonic-gatepanic_hres_tick(void) 3240Sstevel@tonic-gate{ 3250Sstevel@tonic-gate} 3260Sstevel@tonic-gate 3270Sstevel@tonic-gate#else /* lint */ 3280Sstevel@tonic-gate 3290Sstevel@tonic-gate ENTRY_NP(gethrtime) 33011172SHaik.Aftandilian@Sun.COM GET_HRTIME(%g1,%o0,%o1,%o2,%o3,%o4,%o5,%g2,__LINE__) 3310Sstevel@tonic-gate ! %g1 = hrtime 3320Sstevel@tonic-gate retl 3332241Shuah mov %g1, %o0 3340Sstevel@tonic-gate SET_SIZE(gethrtime) 3350Sstevel@tonic-gate 3360Sstevel@tonic-gate ENTRY_NP(gethrtime_unscaled) 33711172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%g1,%o2,%o3,__LINE__) ! %g1 = native time 3380Sstevel@tonic-gate retl 3392241Shuah mov %g1, %o0 3400Sstevel@tonic-gate SET_SIZE(gethrtime_unscaled) 3410Sstevel@tonic-gate 3420Sstevel@tonic-gate ENTRY_NP(gethrtime_waitfree) 3430Sstevel@tonic-gate ALTENTRY(dtrace_gethrtime) 34411172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%g1,%o2,%o3,__LINE__) ! %g1 = native time 3450Sstevel@tonic-gate NATIVE_TIME_TO_NSEC(%g1, %o2, %o3) 3460Sstevel@tonic-gate retl 3472241Shuah mov %g1, %o0 3480Sstevel@tonic-gate SET_SIZE(dtrace_gethrtime) 3490Sstevel@tonic-gate SET_SIZE(gethrtime_waitfree) 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate ENTRY(gethrtime_max) 3520Sstevel@tonic-gate NATIVE_TIME_MAX(%g1) 3530Sstevel@tonic-gate NATIVE_TIME_TO_NSEC(%g1, %o0, %o1) 3540Sstevel@tonic-gate 3550Sstevel@tonic-gate ! hrtime_t's are signed, max hrtime_t must be positive 3560Sstevel@tonic-gate mov -1, %o2 3570Sstevel@tonic-gate brlz,a %g1, 1f 3582241Shuah srlx %o2, 1, %g1 3590Sstevel@tonic-gate1: 3600Sstevel@tonic-gate retl 3612241Shuah mov %g1, %o0 3620Sstevel@tonic-gate SET_SIZE(gethrtime_max) 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate ENTRY(scalehrtime) 3650Sstevel@tonic-gate ldx [%o0], %o1 3660Sstevel@tonic-gate NATIVE_TIME_TO_NSEC(%o1, %o2, %o3) 3670Sstevel@tonic-gate retl 3682241Shuah stx %o1, [%o0] 3690Sstevel@tonic-gate SET_SIZE(scalehrtime) 3700Sstevel@tonic-gate 3710Sstevel@tonic-gate/* 3720Sstevel@tonic-gate * Fast trap to return a timestamp, uses trap window, leaves traps 3730Sstevel@tonic-gate * disabled. Returns a 64-bit nanosecond timestamp in %o0 and %o1. 3740Sstevel@tonic-gate * 3750Sstevel@tonic-gate * This is the handler for the ST_GETHRTIME trap. 3760Sstevel@tonic-gate */ 3770Sstevel@tonic-gate 3780Sstevel@tonic-gate ENTRY_NP(get_timestamp) 37911172SHaik.Aftandilian@Sun.COM GET_HRTIME(%g1,%g2,%g3,%g4,%g5,%o0,%o1,%o2,__LINE__) 38011172SHaik.Aftandilian@Sun.COM ! %g1 = hrtime 3810Sstevel@tonic-gate srlx %g1, 32, %o0 ! %o0 = hi32(%g1) 3820Sstevel@tonic-gate srl %g1, 0, %o1 ! %o1 = lo32(%g1) 3830Sstevel@tonic-gate FAST_TRAP_DONE 3840Sstevel@tonic-gate SET_SIZE(get_timestamp) 3850Sstevel@tonic-gate 3860Sstevel@tonic-gate/* 3870Sstevel@tonic-gate * Macro to convert GET_HRESTIME() bits into a timestamp. 3880Sstevel@tonic-gate * 3890Sstevel@tonic-gate * We use two separate macros so that the platform-dependent GET_HRESTIME() 3900Sstevel@tonic-gate * can be as small as possible; CONV_HRESTIME() implements the generic part. 3910Sstevel@tonic-gate */ 3920Sstevel@tonic-gate#define CONV_HRESTIME(hrestsec, hrestnsec, adj, nslt, nano) \ 3930Sstevel@tonic-gate brz,pt adj, 3f; /* no adjustments, it's easy */ \ 3940Sstevel@tonic-gate add hrestnsec, nslt, hrestnsec; /* hrest.tv_nsec += nslt */ \ 3950Sstevel@tonic-gate brlz,pn adj, 2f; /* if hrestime_adj negative */ \ 3962399Scth srlx nslt, ADJ_SHIFT, nslt; /* delay: nslt >>= 4 */ \ 3970Sstevel@tonic-gate subcc adj, nslt, %g0; /* hrestime_adj - nslt/16 */ \ 3980Sstevel@tonic-gate movg %xcc, nslt, adj; /* adj by min(adj, nslt/16) */ \ 3990Sstevel@tonic-gate ba 3f; /* go convert to sec/nsec */ \ 4002241Shuah add hrestnsec, adj, hrestnsec; /* delay: apply adjustment */ \ 4010Sstevel@tonic-gate2: addcc adj, nslt, %g0; /* hrestime_adj + nslt/16 */ \ 4020Sstevel@tonic-gate bge,a,pt %xcc, 3f; /* is adj less negative? */ \ 4032241Shuah add hrestnsec, adj, hrestnsec; /* yes: hrest.nsec += adj */ \ 4040Sstevel@tonic-gate sub hrestnsec, nslt, hrestnsec; /* no: hrest.nsec -= nslt/16 */ \ 4050Sstevel@tonic-gate3: cmp hrestnsec, nano; /* more than a billion? */ \ 4060Sstevel@tonic-gate bl,pt %xcc, 4f; /* if not, we're done */ \ 4072241Shuah nop; /* delay: do nothing :( */ \ 4080Sstevel@tonic-gate add hrestsec, 1, hrestsec; /* hrest.tv_sec++; */ \ 4090Sstevel@tonic-gate sub hrestnsec, nano, hrestnsec; /* hrest.tv_nsec -= NANOSEC; */ \ 4102399Scth ba,a 3b; /* check >= billion again */ \ 4110Sstevel@tonic-gate4: 4120Sstevel@tonic-gate 4130Sstevel@tonic-gate ENTRY_NP(gethrestime) 41411172SHaik.Aftandilian@Sun.COM GET_HRESTIME(%o1,%o2,%o3,%o4,%o5,%g1,%g2,%g3,%g4,__LINE__) 4150Sstevel@tonic-gate CONV_HRESTIME(%o1, %o2, %o3, %o4, %o5) 4160Sstevel@tonic-gate stn %o1, [%o0] 4170Sstevel@tonic-gate retl 4182241Shuah stn %o2, [%o0 + CLONGSIZE] 4190Sstevel@tonic-gate SET_SIZE(gethrestime) 4200Sstevel@tonic-gate 4210Sstevel@tonic-gate/* 4220Sstevel@tonic-gate * Similar to gethrestime(), but gethrestime_sec() returns current hrestime 4230Sstevel@tonic-gate * seconds. 4240Sstevel@tonic-gate */ 4250Sstevel@tonic-gate ENTRY_NP(gethrestime_sec) 42611172SHaik.Aftandilian@Sun.COM GET_HRESTIME(%o0,%o2,%o3,%o4,%o5,%g1,%g2,%g3,%g4,__LINE__) 4270Sstevel@tonic-gate CONV_HRESTIME(%o0, %o2, %o3, %o4, %o5) 4280Sstevel@tonic-gate retl ! %o0 current hrestime seconds 4292241Shuah nop 4300Sstevel@tonic-gate SET_SIZE(gethrestime_sec) 4310Sstevel@tonic-gate 4320Sstevel@tonic-gate/* 4330Sstevel@tonic-gate * Returns the hrestime on the last tick. This is simpler than gethrestime() 4340Sstevel@tonic-gate * and gethrestime_sec(): no conversion is required. gethrestime_lasttick() 4350Sstevel@tonic-gate * follows the same locking algorithm as GET_HRESTIME and GET_HRTIME, 4360Sstevel@tonic-gate * outlined in detail in clock.h. (Unlike GET_HRESTIME/GET_HRTIME, we don't 4370Sstevel@tonic-gate * rely on load dependencies to effect the membar #LoadLoad, instead declaring 4380Sstevel@tonic-gate * it explicitly.) 4390Sstevel@tonic-gate */ 4400Sstevel@tonic-gate ENTRY_NP(gethrestime_lasttick) 4410Sstevel@tonic-gate sethi %hi(hres_lock), %o1 4420Sstevel@tonic-gate0: 4430Sstevel@tonic-gate lduw [%o1 + %lo(hres_lock)], %o2 ! Load lock value 4440Sstevel@tonic-gate membar #LoadLoad ! Load of lock must complete 4450Sstevel@tonic-gate andn %o2, 1, %o2 ! Mask off lowest bit 4460Sstevel@tonic-gate ldn [%o1 + %lo(hrestime)], %g1 ! Seconds. 4470Sstevel@tonic-gate add %o1, %lo(hrestime), %o4 4480Sstevel@tonic-gate ldn [%o4 + CLONGSIZE], %g2 ! Nanoseconds. 4490Sstevel@tonic-gate membar #LoadLoad ! All loads must complete 4500Sstevel@tonic-gate lduw [%o1 + %lo(hres_lock)], %o3 ! Reload lock value 4510Sstevel@tonic-gate cmp %o3, %o2 ! If lock is locked or has 4520Sstevel@tonic-gate bne 0b ! changed, retry. 4532241Shuah stn %g1, [%o0] ! Delay: store seconds 4540Sstevel@tonic-gate retl 4552241Shuah stn %g2, [%o0 + CLONGSIZE] ! Delay: store nanoseconds 4560Sstevel@tonic-gate SET_SIZE(gethrestime_lasttick) 4570Sstevel@tonic-gate 4580Sstevel@tonic-gate/* 4590Sstevel@tonic-gate * Fast trap for gettimeofday(). Returns a timestruc_t in %o0 and %o1. 4600Sstevel@tonic-gate * 4610Sstevel@tonic-gate * This is the handler for the ST_GETHRESTIME trap. 4620Sstevel@tonic-gate */ 4630Sstevel@tonic-gate 4640Sstevel@tonic-gate ENTRY_NP(get_hrestime) 46511172SHaik.Aftandilian@Sun.COM GET_HRESTIME(%o0,%o1,%g1,%g2,%g3,%g4,%g5,%o2,%o3,__LINE__) 4660Sstevel@tonic-gate CONV_HRESTIME(%o0, %o1, %g1, %g2, %g3) 4670Sstevel@tonic-gate FAST_TRAP_DONE 4680Sstevel@tonic-gate SET_SIZE(get_hrestime) 4690Sstevel@tonic-gate 4700Sstevel@tonic-gate/* 4710Sstevel@tonic-gate * Fast trap to return lwp virtual time, uses trap window, leaves traps 4720Sstevel@tonic-gate * disabled. Returns a 64-bit number in %o0:%o1, which is the number 4730Sstevel@tonic-gate * of nanoseconds consumed. 4740Sstevel@tonic-gate * 4750Sstevel@tonic-gate * This is the handler for the ST_GETHRVTIME trap. 4760Sstevel@tonic-gate * 4770Sstevel@tonic-gate * Register usage: 4780Sstevel@tonic-gate * %o0, %o1 = return lwp virtual time 4790Sstevel@tonic-gate * %o2 = CPU/thread 4800Sstevel@tonic-gate * %o3 = lwp 4810Sstevel@tonic-gate * %g1 = scratch 4820Sstevel@tonic-gate * %g5 = scratch 4830Sstevel@tonic-gate */ 4840Sstevel@tonic-gate ENTRY_NP(get_virtime) 48511172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%g5,%g1,%g2,__LINE__) ! %g5 = native time in ticks 4860Sstevel@tonic-gate CPU_ADDR(%g2, %g3) ! CPU struct ptr to %g2 4870Sstevel@tonic-gate ldn [%g2 + CPU_THREAD], %g2 ! thread pointer to %g2 4880Sstevel@tonic-gate ldn [%g2 + T_LWP], %g3 ! lwp pointer to %g3 4890Sstevel@tonic-gate 4900Sstevel@tonic-gate /* 4910Sstevel@tonic-gate * Subtract start time of current microstate from time 4920Sstevel@tonic-gate * of day to get increment for lwp virtual time. 4930Sstevel@tonic-gate */ 4940Sstevel@tonic-gate ldx [%g3 + LWP_STATE_START], %g1 ! ms_state_start 4950Sstevel@tonic-gate sub %g5, %g1, %g5 4960Sstevel@tonic-gate 4970Sstevel@tonic-gate /* 4980Sstevel@tonic-gate * Add current value of ms_acct[LMS_USER] 4990Sstevel@tonic-gate */ 5000Sstevel@tonic-gate ldx [%g3 + LWP_ACCT_USER], %g1 ! ms_acct[LMS_USER] 5010Sstevel@tonic-gate add %g5, %g1, %g5 5020Sstevel@tonic-gate NATIVE_TIME_TO_NSEC(%g5, %g1, %o0) 5030Sstevel@tonic-gate 5040Sstevel@tonic-gate srl %g5, 0, %o1 ! %o1 = lo32(%g5) 5050Sstevel@tonic-gate srlx %g5, 32, %o0 ! %o0 = hi32(%g5) 5060Sstevel@tonic-gate 5070Sstevel@tonic-gate FAST_TRAP_DONE 5080Sstevel@tonic-gate SET_SIZE(get_virtime) 5090Sstevel@tonic-gate 5100Sstevel@tonic-gate 5110Sstevel@tonic-gate 5120Sstevel@tonic-gate .seg ".text" 5130Sstevel@tonic-gatehrtime_base_panic: 5140Sstevel@tonic-gate .asciz "hrtime_base stepping back" 5150Sstevel@tonic-gate 5160Sstevel@tonic-gate 5170Sstevel@tonic-gate ENTRY_NP(hres_tick) 5180Sstevel@tonic-gate save %sp, -SA(MINFRAME), %sp ! get a new window 5190Sstevel@tonic-gate 5200Sstevel@tonic-gate sethi %hi(hrestime), %l4 5210Sstevel@tonic-gate ldstub [%l4 + %lo(hres_lock + HRES_LOCK_OFFSET)], %l5 ! try locking 5220Sstevel@tonic-gate7: tst %l5 5230Sstevel@tonic-gate bz,pt %xcc, 8f ! if we got it, drive on 5242241Shuah ld [%l4 + %lo(nsec_scale)], %l5 ! delay: %l5 = scaling factor 5250Sstevel@tonic-gate ldub [%l4 + %lo(hres_lock + HRES_LOCK_OFFSET)], %l5 5260Sstevel@tonic-gate9: tst %l5 5270Sstevel@tonic-gate bz,a,pn %xcc, 7b 5282241Shuah ldstub [%l4 + %lo(hres_lock + HRES_LOCK_OFFSET)], %l5 5290Sstevel@tonic-gate ba,pt %xcc, 9b 5302241Shuah ldub [%l4 + %lo(hres_lock + HRES_LOCK_OFFSET)], %l5 5310Sstevel@tonic-gate8: 5320Sstevel@tonic-gate membar #StoreLoad|#StoreStore 5330Sstevel@tonic-gate 5340Sstevel@tonic-gate ! 5350Sstevel@tonic-gate ! update hres_last_tick. %l5 has the scaling factor (nsec_scale). 5360Sstevel@tonic-gate ! 5370Sstevel@tonic-gate ldx [%l4 + %lo(hrtime_base)], %g1 ! load current hrtime_base 53811172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%l0,%l3,%l6,__LINE__) ! current native time 5390Sstevel@tonic-gate stx %l0, [%l4 + %lo(hres_last_tick)]! prev = current 5400Sstevel@tonic-gate ! convert native time to nsecs 5410Sstevel@tonic-gate NATIVE_TIME_TO_NSEC_SCALE(%l0, %l5, %l2, NSEC_SHIFT) 5420Sstevel@tonic-gate 5430Sstevel@tonic-gate sub %l0, %g1, %i1 ! get accurate nsec delta 5440Sstevel@tonic-gate 5450Sstevel@tonic-gate ldx [%l4 + %lo(hrtime_base)], %l1 5460Sstevel@tonic-gate cmp %l1, %l0 5470Sstevel@tonic-gate bg,pn %xcc, 9f 5482241Shuah nop 5490Sstevel@tonic-gate 5500Sstevel@tonic-gate stx %l0, [%l4 + %lo(hrtime_base)] ! update hrtime_base 5510Sstevel@tonic-gate 5520Sstevel@tonic-gate ! 5530Sstevel@tonic-gate ! apply adjustment, if any 5540Sstevel@tonic-gate ! 5550Sstevel@tonic-gate ldx [%l4 + %lo(hrestime_adj)], %l0 ! %l0 = hrestime_adj 5560Sstevel@tonic-gate brz %l0, 2f 5570Sstevel@tonic-gate ! hrestime_adj == 0 ? 5580Sstevel@tonic-gate ! yes, skip adjustments 5592241Shuah clr %l5 ! delay: set adj to zero 5600Sstevel@tonic-gate tst %l0 ! is hrestime_adj >= 0 ? 5610Sstevel@tonic-gate bge,pt %xcc, 1f ! yes, go handle positive case 5622241Shuah srl %i1, ADJ_SHIFT, %l5 ! delay: %l5 = adj 5630Sstevel@tonic-gate 5640Sstevel@tonic-gate addcc %l0, %l5, %g0 ! hrestime_adj < -adj ? 5650Sstevel@tonic-gate bl,pt %xcc, 2f ! yes, use current adj 5662241Shuah neg %l5 ! delay: %l5 = -adj 5670Sstevel@tonic-gate ba,pt %xcc, 2f 5682241Shuah mov %l0, %l5 ! no, so set adj = hrestime_adj 5690Sstevel@tonic-gate1: 5700Sstevel@tonic-gate subcc %l0, %l5, %g0 ! hrestime_adj < adj ? 5710Sstevel@tonic-gate bl,a,pt %xcc, 2f ! yes, set adj = hrestime_adj 5722241Shuah mov %l0, %l5 ! delay: adj = hrestime_adj 5730Sstevel@tonic-gate2: 5740Sstevel@tonic-gate ldx [%l4 + %lo(timedelta)], %l0 ! %l0 = timedelta 5750Sstevel@tonic-gate sub %l0, %l5, %l0 ! timedelta -= adj 5760Sstevel@tonic-gate 5770Sstevel@tonic-gate stx %l0, [%l4 + %lo(timedelta)] ! store new timedelta 5780Sstevel@tonic-gate stx %l0, [%l4 + %lo(hrestime_adj)] ! hrestime_adj = timedelta 5790Sstevel@tonic-gate 5800Sstevel@tonic-gate or %l4, %lo(hrestime), %l2 5810Sstevel@tonic-gate ldn [%l2], %i2 ! %i2:%i3 = hrestime sec:nsec 5820Sstevel@tonic-gate ldn [%l2 + CLONGSIZE], %i3 5830Sstevel@tonic-gate add %i3, %l5, %i3 ! hrestime.nsec += adj 5840Sstevel@tonic-gate add %i3, %i1, %i3 ! hrestime.nsec += nslt 5850Sstevel@tonic-gate 5860Sstevel@tonic-gate set NANOSEC, %l5 ! %l5 = NANOSEC 5870Sstevel@tonic-gate cmp %i3, %l5 5880Sstevel@tonic-gate bl,pt %xcc, 5f ! if hrestime.tv_nsec < NANOSEC 5892241Shuah sethi %hi(one_sec), %i1 ! delay 5900Sstevel@tonic-gate add %i2, 0x1, %i2 ! hrestime.tv_sec++ 5910Sstevel@tonic-gate sub %i3, %l5, %i3 ! hrestime.tv_nsec - NANOSEC 5920Sstevel@tonic-gate mov 0x1, %l5 5930Sstevel@tonic-gate st %l5, [%i1 + %lo(one_sec)] 5940Sstevel@tonic-gate5: 5950Sstevel@tonic-gate stn %i2, [%l2] 5960Sstevel@tonic-gate stn %i3, [%l2 + CLONGSIZE] ! store the new hrestime 5970Sstevel@tonic-gate 5980Sstevel@tonic-gate membar #StoreStore 5990Sstevel@tonic-gate 6000Sstevel@tonic-gate ld [%l4 + %lo(hres_lock)], %i1 6010Sstevel@tonic-gate inc %i1 ! release lock 6020Sstevel@tonic-gate st %i1, [%l4 + %lo(hres_lock)] ! clear hres_lock 6030Sstevel@tonic-gate 6040Sstevel@tonic-gate ret 6050Sstevel@tonic-gate restore 6060Sstevel@tonic-gate 6070Sstevel@tonic-gate9: 6080Sstevel@tonic-gate ! 6090Sstevel@tonic-gate ! release hres_lock 6100Sstevel@tonic-gate ! 6110Sstevel@tonic-gate ld [%l4 + %lo(hres_lock)], %i1 6120Sstevel@tonic-gate inc %i1 6130Sstevel@tonic-gate st %i1, [%l4 + %lo(hres_lock)] 6140Sstevel@tonic-gate 6150Sstevel@tonic-gate sethi %hi(hrtime_base_panic), %o0 6160Sstevel@tonic-gate call panic 6172241Shuah or %o0, %lo(hrtime_base_panic), %o0 6180Sstevel@tonic-gate 6190Sstevel@tonic-gate SET_SIZE(hres_tick) 6200Sstevel@tonic-gate 6210Sstevel@tonic-gate#endif /* lint */ 6220Sstevel@tonic-gate 6230Sstevel@tonic-gate#if !defined(lint) && !defined(__lint) 6240Sstevel@tonic-gate 6250Sstevel@tonic-gate .seg ".text" 6260Sstevel@tonic-gatekstat_q_panic_msg: 6270Sstevel@tonic-gate .asciz "kstat_q_exit: qlen == 0" 6280Sstevel@tonic-gate 6290Sstevel@tonic-gate ENTRY(kstat_q_panic) 6300Sstevel@tonic-gate save %sp, -SA(MINFRAME), %sp 6310Sstevel@tonic-gate sethi %hi(kstat_q_panic_msg), %o0 6320Sstevel@tonic-gate call panic 6332241Shuah or %o0, %lo(kstat_q_panic_msg), %o0 6340Sstevel@tonic-gate /*NOTREACHED*/ 6350Sstevel@tonic-gate SET_SIZE(kstat_q_panic) 6360Sstevel@tonic-gate 6370Sstevel@tonic-gate#define BRZPN brz,pn 6380Sstevel@tonic-gate#define BRZPT brz,pt 6390Sstevel@tonic-gate 6400Sstevel@tonic-gate#define KSTAT_Q_UPDATE(QOP, QBR, QZERO, QRETURN, QTYPE) \ 6410Sstevel@tonic-gate ld [%o0 + QTYPE/**/CNT], %o1; /* %o1 = old qlen */ \ 6420Sstevel@tonic-gate QOP %o1, 1, %o2; /* %o2 = new qlen */ \ 6430Sstevel@tonic-gate QBR %o1, QZERO; /* done if qlen == 0 */ \ 6440Sstevel@tonic-gate st %o2, [%o0 + QTYPE/**/CNT]; /* delay: save qlen */ \ 6450Sstevel@tonic-gate ldx [%o0 + QTYPE/**/LASTUPDATE], %o3; \ 6460Sstevel@tonic-gate ldx [%o0 + QTYPE/**/TIME], %o4; /* %o4 = old time */ \ 6470Sstevel@tonic-gate ldx [%o0 + QTYPE/**/LENTIME], %o5; /* %o5 = old lentime */ \ 6480Sstevel@tonic-gate sub %g1, %o3, %o2; /* %o2 = time delta */ \ 6490Sstevel@tonic-gate mulx %o1, %o2, %o3; /* %o3 = cur lentime */ \ 6500Sstevel@tonic-gate add %o4, %o2, %o4; /* %o4 = new time */ \ 6510Sstevel@tonic-gate add %o5, %o3, %o5; /* %o5 = new lentime */ \ 6520Sstevel@tonic-gate stx %o4, [%o0 + QTYPE/**/TIME]; /* save time */ \ 6530Sstevel@tonic-gate stx %o5, [%o0 + QTYPE/**/LENTIME]; /* save lentime */ \ 6540Sstevel@tonic-gateQRETURN; \ 6550Sstevel@tonic-gate stx %g1, [%o0 + QTYPE/**/LASTUPDATE]; /* lastupdate = now */ 6560Sstevel@tonic-gate 6570Sstevel@tonic-gate .align 16 6580Sstevel@tonic-gate ENTRY(kstat_waitq_enter) 65911172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__) 6600Sstevel@tonic-gate KSTAT_Q_UPDATE(add, BRZPT, 1f, 1:retl, KSTAT_IO_W) 6610Sstevel@tonic-gate SET_SIZE(kstat_waitq_enter) 6620Sstevel@tonic-gate 6630Sstevel@tonic-gate .align 16 6640Sstevel@tonic-gate ENTRY(kstat_waitq_exit) 66511172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__) 6660Sstevel@tonic-gate KSTAT_Q_UPDATE(sub, BRZPN, kstat_q_panic, retl, KSTAT_IO_W) 6670Sstevel@tonic-gate SET_SIZE(kstat_waitq_exit) 6680Sstevel@tonic-gate 6690Sstevel@tonic-gate .align 16 6700Sstevel@tonic-gate ENTRY(kstat_runq_enter) 67111172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__) 6720Sstevel@tonic-gate KSTAT_Q_UPDATE(add, BRZPT, 1f, 1:retl, KSTAT_IO_R) 6730Sstevel@tonic-gate SET_SIZE(kstat_runq_enter) 6740Sstevel@tonic-gate 6750Sstevel@tonic-gate .align 16 6760Sstevel@tonic-gate ENTRY(kstat_runq_exit) 67711172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__) 6780Sstevel@tonic-gate KSTAT_Q_UPDATE(sub, BRZPN, kstat_q_panic, retl, KSTAT_IO_R) 6790Sstevel@tonic-gate SET_SIZE(kstat_runq_exit) 6800Sstevel@tonic-gate 6810Sstevel@tonic-gate .align 16 6820Sstevel@tonic-gate ENTRY(kstat_waitq_to_runq) 68311172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__) 6840Sstevel@tonic-gate KSTAT_Q_UPDATE(sub, BRZPN, kstat_q_panic, 1:, KSTAT_IO_W) 6850Sstevel@tonic-gate KSTAT_Q_UPDATE(add, BRZPT, 1f, 1:retl, KSTAT_IO_R) 6860Sstevel@tonic-gate SET_SIZE(kstat_waitq_to_runq) 6870Sstevel@tonic-gate 6880Sstevel@tonic-gate .align 16 6890Sstevel@tonic-gate ENTRY(kstat_runq_back_to_waitq) 69011172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__) 6910Sstevel@tonic-gate KSTAT_Q_UPDATE(sub, BRZPN, kstat_q_panic, 1:, KSTAT_IO_R) 6920Sstevel@tonic-gate KSTAT_Q_UPDATE(add, BRZPT, 1f, 1:retl, KSTAT_IO_W) 6930Sstevel@tonic-gate SET_SIZE(kstat_runq_back_to_waitq) 6940Sstevel@tonic-gate 6950Sstevel@tonic-gate#endif /* lint */ 6960Sstevel@tonic-gate 6970Sstevel@tonic-gate#ifdef lint 6980Sstevel@tonic-gate 6990Sstevel@tonic-gateint64_t timedelta; 7000Sstevel@tonic-gatehrtime_t hres_last_tick; 7014551Ssudheervolatile timestruc_t hrestime; 7020Sstevel@tonic-gateint64_t hrestime_adj; 7034551Ssudheervolatile int hres_lock; 7040Sstevel@tonic-gateuint_t nsec_scale; 7050Sstevel@tonic-gatehrtime_t hrtime_base; 7060Sstevel@tonic-gateint traptrace_use_stick; 7070Sstevel@tonic-gate 7080Sstevel@tonic-gate#else 7090Sstevel@tonic-gate /* 7100Sstevel@tonic-gate * -- WARNING -- 7110Sstevel@tonic-gate * 7120Sstevel@tonic-gate * The following variables MUST be together on a 128-byte boundary. 7130Sstevel@tonic-gate * In addition to the primary performance motivation (having them all 7140Sstevel@tonic-gate * on the same cache line(s)), code here and in the GET*TIME() macros 7150Sstevel@tonic-gate * assumes that they all have the same high 22 address bits (so 7160Sstevel@tonic-gate * there's only one sethi). 7170Sstevel@tonic-gate */ 7180Sstevel@tonic-gate .seg ".data" 7190Sstevel@tonic-gate .global timedelta, hres_last_tick, hrestime, hrestime_adj 7200Sstevel@tonic-gate .global hres_lock, nsec_scale, hrtime_base, traptrace_use_stick 72111172SHaik.Aftandilian@Sun.COM .global nsec_shift, adj_shift, native_tick_offset, native_stick_offset 7220Sstevel@tonic-gate 7230Sstevel@tonic-gate /* XXX - above comment claims 128-bytes is necessary */ 7240Sstevel@tonic-gate .align 64 7250Sstevel@tonic-gatetimedelta: 7260Sstevel@tonic-gate .word 0, 0 /* int64_t */ 7270Sstevel@tonic-gatehres_last_tick: 7280Sstevel@tonic-gate .word 0, 0 /* hrtime_t */ 7290Sstevel@tonic-gatehrestime: 7300Sstevel@tonic-gate .nword 0, 0 /* 2 longs */ 7310Sstevel@tonic-gatehrestime_adj: 7320Sstevel@tonic-gate .word 0, 0 /* int64_t */ 7330Sstevel@tonic-gatehres_lock: 7340Sstevel@tonic-gate .word 0 7350Sstevel@tonic-gatensec_scale: 7360Sstevel@tonic-gate .word 0 7370Sstevel@tonic-gatehrtime_base: 7380Sstevel@tonic-gate .word 0, 0 7390Sstevel@tonic-gatetraptrace_use_stick: 7400Sstevel@tonic-gate .word 0 7410Sstevel@tonic-gatensec_shift: 7420Sstevel@tonic-gate .word NSEC_SHIFT 7430Sstevel@tonic-gateadj_shift: 7440Sstevel@tonic-gate .word ADJ_SHIFT 74511172SHaik.Aftandilian@Sun.COM .align 8 74611172SHaik.Aftandilian@Sun.COMnative_tick_offset: 74711172SHaik.Aftandilian@Sun.COM .word 0, 0 74811172SHaik.Aftandilian@Sun.COM .align 8 74911172SHaik.Aftandilian@Sun.COMnative_stick_offset: 75011172SHaik.Aftandilian@Sun.COM .word 0, 0 7510Sstevel@tonic-gate 7520Sstevel@tonic-gate#endif 7530Sstevel@tonic-gate 7540Sstevel@tonic-gate 7550Sstevel@tonic-gate/* 7560Sstevel@tonic-gate * drv_usecwait(clock_t n) [DDI/DKI - section 9F] 7570Sstevel@tonic-gate * usec_delay(int n) [compatibility - should go one day] 7580Sstevel@tonic-gate * Delay by spinning. 7590Sstevel@tonic-gate * 7600Sstevel@tonic-gate * delay for n microseconds. numbers <= 0 delay 1 usec 7610Sstevel@tonic-gate * 7620Sstevel@tonic-gate * With UltraSPARC-III the combination of supporting mixed-speed CPUs 7630Sstevel@tonic-gate * and variable clock rate for power management requires that we 7640Sstevel@tonic-gate * use %stick to implement this routine. 7650Sstevel@tonic-gate */ 7660Sstevel@tonic-gate 7670Sstevel@tonic-gate#if defined(lint) 7680Sstevel@tonic-gate 7690Sstevel@tonic-gate/*ARGSUSED*/ 7700Sstevel@tonic-gatevoid 7710Sstevel@tonic-gatedrv_usecwait(clock_t n) 7720Sstevel@tonic-gate{} 7730Sstevel@tonic-gate 7740Sstevel@tonic-gate/*ARGSUSED*/ 7750Sstevel@tonic-gatevoid 7760Sstevel@tonic-gateusec_delay(int n) 7770Sstevel@tonic-gate{} 7780Sstevel@tonic-gate 7790Sstevel@tonic-gate#else /* lint */ 7800Sstevel@tonic-gate 7810Sstevel@tonic-gate ENTRY(drv_usecwait) 7820Sstevel@tonic-gate ALTENTRY(usec_delay) 7830Sstevel@tonic-gate brlez,a,pn %o0, 0f 7842241Shuah mov 1, %o0 7850Sstevel@tonic-gate0: 7860Sstevel@tonic-gate sethi %hi(sticks_per_usec), %o1 7870Sstevel@tonic-gate lduw [%o1 + %lo(sticks_per_usec)], %o1 7880Sstevel@tonic-gate mulx %o1, %o0, %o1 ! Scale usec to ticks 7890Sstevel@tonic-gate inc %o1 ! We don't start on a tick edge 79011172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%o2,%o3,%o4,__LINE__) 7910Sstevel@tonic-gate add %o1, %o2, %o1 7920Sstevel@tonic-gate 7930Sstevel@tonic-gate1: cmp %o1, %o2 79411172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%o2,%o3,%o4,__LINE__) 7950Sstevel@tonic-gate bgeu,pt %xcc, 1b 7962241Shuah nop 7970Sstevel@tonic-gate retl 7982241Shuah nop 7990Sstevel@tonic-gate SET_SIZE(usec_delay) 8000Sstevel@tonic-gate SET_SIZE(drv_usecwait) 8010Sstevel@tonic-gate#endif /* lint */ 8020Sstevel@tonic-gate 8030Sstevel@tonic-gate#if defined(lint) 8040Sstevel@tonic-gate 8050Sstevel@tonic-gate/* ARGSUSED */ 8060Sstevel@tonic-gatevoid 8070Sstevel@tonic-gatepil14_interrupt(int level) 8080Sstevel@tonic-gate{} 8090Sstevel@tonic-gate 8100Sstevel@tonic-gate#else 8110Sstevel@tonic-gate 8120Sstevel@tonic-gate/* 8130Sstevel@tonic-gate * Level-14 interrupt prologue. 8140Sstevel@tonic-gate */ 8150Sstevel@tonic-gate ENTRY_NP(pil14_interrupt) 8160Sstevel@tonic-gate CPU_ADDR(%g1, %g2) 8170Sstevel@tonic-gate rdpr %pil, %g6 ! %g6 = interrupted PIL 8180Sstevel@tonic-gate stn %g6, [%g1 + CPU_PROFILE_PIL] ! record interrupted PIL 8190Sstevel@tonic-gate rdpr %tstate, %g6 8200Sstevel@tonic-gate rdpr %tpc, %g5 8210Sstevel@tonic-gate btst TSTATE_PRIV, %g6 ! trap from supervisor mode? 8220Sstevel@tonic-gate bnz,a,pt %xcc, 1f 8232241Shuah stn %g5, [%g1 + CPU_PROFILE_PC] ! if so, record kernel PC 8240Sstevel@tonic-gate stn %g5, [%g1 + CPU_PROFILE_UPC] ! if not, record user PC 8250Sstevel@tonic-gate ba pil_interrupt_common ! must be large-disp branch 8262241Shuah stn %g0, [%g1 + CPU_PROFILE_PC] ! zero kernel PC 8270Sstevel@tonic-gate1: ba pil_interrupt_common ! must be large-disp branch 8282241Shuah stn %g0, [%g1 + CPU_PROFILE_UPC] ! zero user PC 8290Sstevel@tonic-gate SET_SIZE(pil14_interrupt) 8300Sstevel@tonic-gate 8310Sstevel@tonic-gate ENTRY_NP(tick_rtt) 8320Sstevel@tonic-gate ! 8330Sstevel@tonic-gate ! Load TICK_COMPARE into %o5; if bit 63 is set, then TICK_COMPARE is 8340Sstevel@tonic-gate ! disabled. If TICK_COMPARE is enabled, we know that we need to 8350Sstevel@tonic-gate ! reenqueue the interrupt request structure. We'll then check TICKINT 8360Sstevel@tonic-gate ! in SOFTINT; if it's set, then we know that we were in a TICK_COMPARE 8370Sstevel@tonic-gate ! interrupt. In this case, TICK_COMPARE may have been rewritten 8380Sstevel@tonic-gate ! recently; we'll compare %o5 to the current time to verify that it's 8390Sstevel@tonic-gate ! in the future. 8400Sstevel@tonic-gate ! 8410Sstevel@tonic-gate ! Note that %o5 is live until after 1f. 8420Sstevel@tonic-gate ! XXX - there is a subroutine call while %o5 is live! 8430Sstevel@tonic-gate ! 84411172SHaik.Aftandilian@Sun.COM RD_TICKCMPR(%o5,%g1,%g2,__LINE__) 8450Sstevel@tonic-gate srlx %o5, TICKINT_DIS_SHFT, %g1 8460Sstevel@tonic-gate brnz,pt %g1, 2f 8472241Shuah nop 8480Sstevel@tonic-gate 8490Sstevel@tonic-gate rdpr %pstate, %g5 8500Sstevel@tonic-gate andn %g5, PSTATE_IE, %g1 8510Sstevel@tonic-gate wrpr %g0, %g1, %pstate ! Disable vec interrupts 8520Sstevel@tonic-gate 8530Sstevel@tonic-gate sethi %hi(cbe_level14_inum), %o1 8542973Sgovinda ldx [%o1 + %lo(cbe_level14_inum)], %o1 8550Sstevel@tonic-gate call intr_enqueue_req ! preserves %o5 and %g5 8562241Shuah mov PIL_14, %o0 8570Sstevel@tonic-gate 8580Sstevel@tonic-gate ! Check SOFTINT for TICKINT/STICKINT 8590Sstevel@tonic-gate rd SOFTINT, %o4 8600Sstevel@tonic-gate set (TICK_INT_MASK | STICK_INT_MASK), %o0 8610Sstevel@tonic-gate andcc %o4, %o0, %g0 8620Sstevel@tonic-gate bz,a,pn %icc, 2f 8632241Shuah wrpr %g0, %g5, %pstate ! Enable vec interrupts 8640Sstevel@tonic-gate 8650Sstevel@tonic-gate ! clear TICKINT/STICKINT 8660Sstevel@tonic-gate wr %o0, CLEAR_SOFTINT 8670Sstevel@tonic-gate 8680Sstevel@tonic-gate ! 8690Sstevel@tonic-gate ! Now that we've cleared TICKINT, we can reread %tick and confirm 8700Sstevel@tonic-gate ! that the value we programmed is still in the future. If it isn't, 8710Sstevel@tonic-gate ! we need to reprogram TICK_COMPARE to fire as soon as possible. 8720Sstevel@tonic-gate ! 87311172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%o0,%g1,%g2,__LINE__) ! %o0 = tick 8740Sstevel@tonic-gate cmp %o5, %o0 ! In the future? 8750Sstevel@tonic-gate bg,a,pt %xcc, 2f ! Yes, drive on. 8762241Shuah wrpr %g0, %g5, %pstate ! delay: enable vec intr 8770Sstevel@tonic-gate 8780Sstevel@tonic-gate ! 8790Sstevel@tonic-gate ! If we're here, then we have programmed TICK_COMPARE with a %tick 8800Sstevel@tonic-gate ! which is in the past; we'll now load an initial step size, and loop 8810Sstevel@tonic-gate ! until we've managed to program TICK_COMPARE to fire in the future. 8820Sstevel@tonic-gate ! 8830Sstevel@tonic-gate mov 8, %o4 ! 8 = arbitrary inital step 8840Sstevel@tonic-gate1: add %o0, %o4, %o5 ! Add the step 8850Sstevel@tonic-gate WR_TICKCMPR(%o5,%g1,%g2,__LINE__) ! Write to TICK_CMPR 88611172SHaik.Aftandilian@Sun.COM GET_NATIVE_TIME(%o0,%g1,%g2,__LINE__) ! %o0 = tick 8870Sstevel@tonic-gate cmp %o5, %o0 ! In the future? 8880Sstevel@tonic-gate bg,a,pt %xcc, 2f ! Yes, drive on. 8892241Shuah wrpr %g0, %g5, %pstate ! delay: enable vec intr 8900Sstevel@tonic-gate ba 1b ! No, try again. 8912241Shuah sllx %o4, 1, %o4 ! delay: double step size 8920Sstevel@tonic-gate 8930Sstevel@tonic-gate2: ba current_thread_complete 8942241Shuah nop 8950Sstevel@tonic-gate SET_SIZE(tick_rtt) 8960Sstevel@tonic-gate 8970Sstevel@tonic-gate#endif /* lint */ 8980Sstevel@tonic-gate 8990Sstevel@tonic-gate#if defined(lint) 9008803SJonathan.Haslam@Sun.COM 9018803SJonathan.Haslam@Sun.COM/* ARGSUSED */ 9028803SJonathan.Haslam@Sun.COMvoid 9038803SJonathan.Haslam@Sun.COMpil15_interrupt(int level) 9048803SJonathan.Haslam@Sun.COM{} 9058803SJonathan.Haslam@Sun.COM 9068803SJonathan.Haslam@Sun.COM#else /* lint */ 9078803SJonathan.Haslam@Sun.COM 9088803SJonathan.Haslam@Sun.COM/* 9098803SJonathan.Haslam@Sun.COM * Level-15 interrupt prologue. 9108803SJonathan.Haslam@Sun.COM */ 9118803SJonathan.Haslam@Sun.COM ENTRY_NP(pil15_interrupt) 9128803SJonathan.Haslam@Sun.COM CPU_ADDR(%g1, %g2) 9138803SJonathan.Haslam@Sun.COM rdpr %tstate, %g6 9148803SJonathan.Haslam@Sun.COM rdpr %tpc, %g5 9158803SJonathan.Haslam@Sun.COM btst TSTATE_PRIV, %g6 ! trap from supervisor mode? 9168803SJonathan.Haslam@Sun.COM bnz,a,pt %xcc, 1f 9178803SJonathan.Haslam@Sun.COM stn %g5, [%g1 + CPU_CPCPROFILE_PC] ! if so, record kernel PC 9188803SJonathan.Haslam@Sun.COM stn %g5, [%g1 + CPU_CPCPROFILE_UPC] ! if not, record user PC 9198803SJonathan.Haslam@Sun.COM ba pil15_epilogue ! must be large-disp branch 9208803SJonathan.Haslam@Sun.COM stn %g0, [%g1 + CPU_CPCPROFILE_PC] ! zero kernel PC 9218803SJonathan.Haslam@Sun.COM1: ba pil15_epilogue ! must be large-disp branch 9228803SJonathan.Haslam@Sun.COM stn %g0, [%g1 + CPU_CPCPROFILE_UPC] ! zero user PC 9238803SJonathan.Haslam@Sun.COM SET_SIZE(pil15_interrupt) 9248803SJonathan.Haslam@Sun.COM 9258803SJonathan.Haslam@Sun.COM#endif /* lint */ 9268803SJonathan.Haslam@Sun.COM 9278803SJonathan.Haslam@Sun.COM#if defined(lint) 9280Sstevel@tonic-gate/* 9290Sstevel@tonic-gate * Prefetch a page_t for write or read, this assumes a linear 9300Sstevel@tonic-gate * scan of sequential page_t's. 9310Sstevel@tonic-gate */ 9320Sstevel@tonic-gate/*ARGSUSED*/ 9330Sstevel@tonic-gatevoid 9340Sstevel@tonic-gateprefetch_page_w(void *pp) 9350Sstevel@tonic-gate{} 9360Sstevel@tonic-gate 9370Sstevel@tonic-gate/*ARGSUSED*/ 9380Sstevel@tonic-gatevoid 9390Sstevel@tonic-gateprefetch_page_r(void *pp) 9400Sstevel@tonic-gate{} 9410Sstevel@tonic-gate#else /* lint */ 9420Sstevel@tonic-gate 9430Sstevel@tonic-gate/* XXXQ These should be inline templates, not functions */ 9440Sstevel@tonic-gate ENTRY(prefetch_page_w) 9450Sstevel@tonic-gate retl 9462241Shuah nop 9470Sstevel@tonic-gate SET_SIZE(prefetch_page_w) 9480Sstevel@tonic-gate 9490Sstevel@tonic-gate ENTRY(prefetch_page_r) 9500Sstevel@tonic-gate retl 9512241Shuah nop 9520Sstevel@tonic-gate SET_SIZE(prefetch_page_r) 9530Sstevel@tonic-gate 9540Sstevel@tonic-gate#endif /* lint */ 9550Sstevel@tonic-gate 9560Sstevel@tonic-gate#if defined(lint) 9570Sstevel@tonic-gate/* 9580Sstevel@tonic-gate * Prefetch struct smap for write. 9590Sstevel@tonic-gate */ 9600Sstevel@tonic-gate/*ARGSUSED*/ 9610Sstevel@tonic-gatevoid 9620Sstevel@tonic-gateprefetch_smap_w(void *smp) 9630Sstevel@tonic-gate{} 9640Sstevel@tonic-gate#else /* lint */ 9650Sstevel@tonic-gate 9660Sstevel@tonic-gate/* XXXQ These should be inline templates, not functions */ 9670Sstevel@tonic-gate ENTRY(prefetch_smap_w) 9680Sstevel@tonic-gate retl 9692241Shuah nop 9700Sstevel@tonic-gate SET_SIZE(prefetch_smap_w) 9710Sstevel@tonic-gate 9720Sstevel@tonic-gate#endif /* lint */ 9730Sstevel@tonic-gate 9740Sstevel@tonic-gate/* 9750Sstevel@tonic-gate * Generic sun4v MMU and Cache operations. 9760Sstevel@tonic-gate */ 9770Sstevel@tonic-gate 9780Sstevel@tonic-gate#if defined(lint) 9790Sstevel@tonic-gate 9800Sstevel@tonic-gate/*ARGSUSED*/ 9810Sstevel@tonic-gatevoid 9822241Shuahvtag_flushpage(caddr_t vaddr, uint64_t sfmmup) 9830Sstevel@tonic-gate{} 9840Sstevel@tonic-gate 9850Sstevel@tonic-gate/*ARGSUSED*/ 9860Sstevel@tonic-gatevoid 9870Sstevel@tonic-gatevtag_flushall(void) 9880Sstevel@tonic-gate{} 9890Sstevel@tonic-gate 9900Sstevel@tonic-gate/*ARGSUSED*/ 9910Sstevel@tonic-gatevoid 9920Sstevel@tonic-gatevtag_unmap_perm_tl1(uint64_t vaddr, uint64_t ctxnum) 9930Sstevel@tonic-gate{} 9940Sstevel@tonic-gate 9950Sstevel@tonic-gate/*ARGSUSED*/ 9960Sstevel@tonic-gatevoid 9972241Shuahvtag_flushpage_tl1(uint64_t vaddr, uint64_t sfmmup) 9980Sstevel@tonic-gate{} 9990Sstevel@tonic-gate 10000Sstevel@tonic-gate/*ARGSUSED*/ 10010Sstevel@tonic-gatevoid 10022241Shuahvtag_flush_pgcnt_tl1(uint64_t vaddr, uint64_t sfmmup_pgcnt) 10030Sstevel@tonic-gate{} 10040Sstevel@tonic-gate 10050Sstevel@tonic-gate/*ARGSUSED*/ 10060Sstevel@tonic-gatevoid 10070Sstevel@tonic-gatevtag_flushall_tl1(uint64_t dummy1, uint64_t dummy2) 10080Sstevel@tonic-gate{} 10090Sstevel@tonic-gate 10100Sstevel@tonic-gate/*ARGSUSED*/ 10110Sstevel@tonic-gatevoid 10120Sstevel@tonic-gatevac_flushpage(pfn_t pfnum, int vcolor) 10130Sstevel@tonic-gate{} 10140Sstevel@tonic-gate 10150Sstevel@tonic-gate/*ARGSUSED*/ 10160Sstevel@tonic-gatevoid 10170Sstevel@tonic-gatevac_flushpage_tl1(uint64_t pfnum, uint64_t vcolor) 10180Sstevel@tonic-gate{} 10190Sstevel@tonic-gate 10200Sstevel@tonic-gate/*ARGSUSED*/ 10210Sstevel@tonic-gatevoid 10220Sstevel@tonic-gateflush_instr_mem(caddr_t vaddr, size_t len) 10230Sstevel@tonic-gate{} 10240Sstevel@tonic-gate 10250Sstevel@tonic-gate#else /* lint */ 10260Sstevel@tonic-gate 10270Sstevel@tonic-gate ENTRY_NP(vtag_flushpage) 10280Sstevel@tonic-gate /* 10290Sstevel@tonic-gate * flush page from the tlb 10300Sstevel@tonic-gate * 10310Sstevel@tonic-gate * %o0 = vaddr 10322241Shuah * %o1 = sfmmup 10330Sstevel@tonic-gate */ 10342241Shuah SFMMU_CPU_CNUM(%o1, %g1, %g2) /* %g1 = sfmmu cnum on this CPU */ 10352241Shuah 10362241Shuah mov %g1, %o1 10370Sstevel@tonic-gate mov MAP_ITLB | MAP_DTLB, %o2 10380Sstevel@tonic-gate ta MMU_UNMAP_ADDR 10390Sstevel@tonic-gate brz,pt %o0, 1f 10402241Shuah nop 10410Sstevel@tonic-gate ba panic_bad_hcall 10422241Shuah mov MMU_UNMAP_ADDR, %o1 10430Sstevel@tonic-gate1: 10440Sstevel@tonic-gate retl 10452241Shuah nop 10460Sstevel@tonic-gate SET_SIZE(vtag_flushpage) 10470Sstevel@tonic-gate 10480Sstevel@tonic-gate ENTRY_NP(vtag_flushall) 10490Sstevel@tonic-gate mov %g0, %o0 ! XXX no cpu list yet 10500Sstevel@tonic-gate mov %g0, %o1 ! XXX no cpu list yet 10510Sstevel@tonic-gate mov MAP_ITLB | MAP_DTLB, %o2 10520Sstevel@tonic-gate mov MMU_DEMAP_ALL, %o5 10530Sstevel@tonic-gate ta FAST_TRAP 10540Sstevel@tonic-gate brz,pt %o0, 1f 10552241Shuah nop 10560Sstevel@tonic-gate ba panic_bad_hcall 10572241Shuah mov MMU_DEMAP_ALL, %o1 10580Sstevel@tonic-gate1: 10590Sstevel@tonic-gate retl 10602241Shuah nop 10610Sstevel@tonic-gate SET_SIZE(vtag_flushall) 10620Sstevel@tonic-gate 10630Sstevel@tonic-gate ENTRY_NP(vtag_unmap_perm_tl1) 10640Sstevel@tonic-gate /* 10650Sstevel@tonic-gate * x-trap to unmap perm map entry 10660Sstevel@tonic-gate * %g1 = vaddr 10672241Shuah * %g2 = ctxnum (KCONTEXT only) 10680Sstevel@tonic-gate */ 10690Sstevel@tonic-gate mov %o0, %g3 10700Sstevel@tonic-gate mov %o1, %g4 10710Sstevel@tonic-gate mov %o2, %g5 10720Sstevel@tonic-gate mov %o5, %g6 10730Sstevel@tonic-gate mov %g1, %o0 10740Sstevel@tonic-gate mov %g2, %o1 10750Sstevel@tonic-gate mov MAP_ITLB | MAP_DTLB, %o2 10760Sstevel@tonic-gate mov UNMAP_PERM_ADDR, %o5 10770Sstevel@tonic-gate ta FAST_TRAP 10780Sstevel@tonic-gate brz,pt %o0, 1f 10790Sstevel@tonic-gate nop 10801991Sheppo 10810Sstevel@tonic-gate mov PTL1_BAD_HCALL, %g1 10821991Sheppo 10831991Sheppo cmp %o0, H_ENOMAP 10841991Sheppo move %xcc, PTL1_BAD_HCALL_UNMAP_PERM_ENOMAP, %g1 10851991Sheppo 10861991Sheppo cmp %o0, H_EINVAL 10871991Sheppo move %xcc, PTL1_BAD_HCALL_UNMAP_PERM_EINVAL, %g1 10881991Sheppo 10891991Sheppo ba,a ptl1_panic 10900Sstevel@tonic-gate1: 10910Sstevel@tonic-gate mov %g6, %o5 10920Sstevel@tonic-gate mov %g5, %o2 10930Sstevel@tonic-gate mov %g4, %o1 10940Sstevel@tonic-gate mov %g3, %o0 10950Sstevel@tonic-gate retry 10960Sstevel@tonic-gate SET_SIZE(vtag_unmap_perm_tl1) 10970Sstevel@tonic-gate 10980Sstevel@tonic-gate ENTRY_NP(vtag_flushpage_tl1) 10990Sstevel@tonic-gate /* 11000Sstevel@tonic-gate * x-trap to flush page from tlb and tsb 11010Sstevel@tonic-gate * 11020Sstevel@tonic-gate * %g1 = vaddr, zero-extended on 32-bit kernel 11032241Shuah * %g2 = sfmmup 11040Sstevel@tonic-gate * 11050Sstevel@tonic-gate * assumes TSBE_TAG = 0 11060Sstevel@tonic-gate */ 11070Sstevel@tonic-gate srln %g1, MMU_PAGESHIFT, %g1 11080Sstevel@tonic-gate slln %g1, MMU_PAGESHIFT, %g1 /* g1 = vaddr */ 11090Sstevel@tonic-gate mov %o0, %g3 11100Sstevel@tonic-gate mov %o1, %g4 11110Sstevel@tonic-gate mov %o2, %g5 11122241Shuah mov %g1, %o0 /* vaddr */ 11132241Shuah 11142241Shuah SFMMU_CPU_CNUM(%g2, %o1, %g6) /* %o1 = sfmmu cnum on this CPU */ 11152241Shuah 11160Sstevel@tonic-gate mov MAP_ITLB | MAP_DTLB, %o2 11170Sstevel@tonic-gate ta MMU_UNMAP_ADDR 11180Sstevel@tonic-gate brz,pt %o0, 1f 11190Sstevel@tonic-gate nop 11202241Shuah ba ptl1_panic 11210Sstevel@tonic-gate mov PTL1_BAD_HCALL, %g1 11220Sstevel@tonic-gate1: 11230Sstevel@tonic-gate mov %g5, %o2 11240Sstevel@tonic-gate mov %g4, %o1 11250Sstevel@tonic-gate mov %g3, %o0 11260Sstevel@tonic-gate membar #Sync 11270Sstevel@tonic-gate retry 11280Sstevel@tonic-gate SET_SIZE(vtag_flushpage_tl1) 11290Sstevel@tonic-gate 11300Sstevel@tonic-gate ENTRY_NP(vtag_flush_pgcnt_tl1) 11310Sstevel@tonic-gate /* 11320Sstevel@tonic-gate * x-trap to flush pgcnt MMU_PAGESIZE pages from tlb 11330Sstevel@tonic-gate * 11340Sstevel@tonic-gate * %g1 = vaddr, zero-extended on 32-bit kernel 11352241Shuah * %g2 = <sfmmup58|pgcnt6>, (pgcnt - 1) is pass'ed in via pgcnt6 bits. 11360Sstevel@tonic-gate * 11370Sstevel@tonic-gate * NOTE: this handler relies on the fact that no 11380Sstevel@tonic-gate * interrupts or traps can occur during the loop 11390Sstevel@tonic-gate * issuing the TLB_DEMAP operations. It is assumed 11400Sstevel@tonic-gate * that interrupts are disabled and this code is 11410Sstevel@tonic-gate * fetching from the kernel locked text address. 11420Sstevel@tonic-gate * 11430Sstevel@tonic-gate * assumes TSBE_TAG = 0 11440Sstevel@tonic-gate */ 11450Sstevel@tonic-gate srln %g1, MMU_PAGESHIFT, %g1 11460Sstevel@tonic-gate slln %g1, MMU_PAGESHIFT, %g1 /* g1 = vaddr */ 11470Sstevel@tonic-gate mov %o0, %g3 11480Sstevel@tonic-gate mov %o1, %g4 11490Sstevel@tonic-gate mov %o2, %g5 11500Sstevel@tonic-gate 11512241Shuah and %g2, SFMMU_PGCNT_MASK, %g7 /* g7 = pgcnt - 1 */ 11522241Shuah add %g7, 1, %g7 /* g7 = pgcnt */ 11532241Shuah 11542241Shuah andn %g2, SFMMU_PGCNT_MASK, %o0 /* %o0 = sfmmup */ 11550Sstevel@tonic-gate 11562241Shuah SFMMU_CPU_CNUM(%o0, %g2, %g6) /* %g2 = sfmmu cnum on this CPU */ 11572241Shuah 11582241Shuah set MMU_PAGESIZE, %g6 /* g6 = pgsize */ 11592241Shuah 11602241Shuah1: 11612241Shuah mov %g1, %o0 /* vaddr */ 11622241Shuah mov %g2, %o1 /* cnum */ 11630Sstevel@tonic-gate mov MAP_ITLB | MAP_DTLB, %o2 11640Sstevel@tonic-gate ta MMU_UNMAP_ADDR 11650Sstevel@tonic-gate brz,pt %o0, 2f 11662241Shuah nop 11670Sstevel@tonic-gate ba ptl1_panic 11682241Shuah mov PTL1_BAD_HCALL, %g1 11690Sstevel@tonic-gate2: 11700Sstevel@tonic-gate deccc %g7 /* decr pgcnt */ 11710Sstevel@tonic-gate bnz,pt %icc,1b 11722241Shuah add %g1, %g6, %g1 /* go to nextpage */ 11730Sstevel@tonic-gate 11740Sstevel@tonic-gate mov %g5, %o2 11750Sstevel@tonic-gate mov %g4, %o1 11760Sstevel@tonic-gate mov %g3, %o0 11770Sstevel@tonic-gate membar #Sync 11780Sstevel@tonic-gate retry 11790Sstevel@tonic-gate SET_SIZE(vtag_flush_pgcnt_tl1) 11800Sstevel@tonic-gate 11810Sstevel@tonic-gate ! Not implemented on US1/US2 11820Sstevel@tonic-gate ENTRY_NP(vtag_flushall_tl1) 11830Sstevel@tonic-gate mov %o0, %g3 11840Sstevel@tonic-gate mov %o1, %g4 11850Sstevel@tonic-gate mov %o2, %g5 11860Sstevel@tonic-gate mov %o3, %g6 ! XXXQ not used? 11870Sstevel@tonic-gate mov %o5, %g7 11880Sstevel@tonic-gate mov %g0, %o0 ! XXX no cpu list yet 11890Sstevel@tonic-gate mov %g0, %o1 ! XXX no cpu list yet 11900Sstevel@tonic-gate mov MAP_ITLB | MAP_DTLB, %o2 11910Sstevel@tonic-gate mov MMU_DEMAP_ALL, %o5 11920Sstevel@tonic-gate ta FAST_TRAP 11930Sstevel@tonic-gate brz,pt %o0, 1f 11942241Shuah nop 11950Sstevel@tonic-gate ba ptl1_panic 11962241Shuah mov PTL1_BAD_HCALL, %g1 11970Sstevel@tonic-gate1: 11980Sstevel@tonic-gate mov %g7, %o5 11990Sstevel@tonic-gate mov %g6, %o3 ! XXXQ not used? 12000Sstevel@tonic-gate mov %g5, %o2 12010Sstevel@tonic-gate mov %g4, %o1 12020Sstevel@tonic-gate mov %g3, %o0 12030Sstevel@tonic-gate retry 12040Sstevel@tonic-gate SET_SIZE(vtag_flushall_tl1) 12050Sstevel@tonic-gate 12060Sstevel@tonic-gate/* 12070Sstevel@tonic-gate * flush_instr_mem: 12080Sstevel@tonic-gate * Flush a portion of the I-$ starting at vaddr 12090Sstevel@tonic-gate * %o0 vaddr 12100Sstevel@tonic-gate * %o1 bytes to be flushed 12110Sstevel@tonic-gate */ 12120Sstevel@tonic-gate 12130Sstevel@tonic-gate ENTRY(flush_instr_mem) 12140Sstevel@tonic-gate membar #StoreStore ! Ensure the stores 12150Sstevel@tonic-gate ! are globally visible 12160Sstevel@tonic-gate1: 12170Sstevel@tonic-gate flush %o0 12180Sstevel@tonic-gate subcc %o1, ICACHE_FLUSHSZ, %o1 ! bytes = bytes-0x20 12190Sstevel@tonic-gate bgu,pt %ncc, 1b 12202241Shuah add %o0, ICACHE_FLUSHSZ, %o0 ! vaddr = vaddr+0x20 12210Sstevel@tonic-gate 12220Sstevel@tonic-gate retl 12232241Shuah nop 12240Sstevel@tonic-gate SET_SIZE(flush_instr_mem) 12250Sstevel@tonic-gate 12260Sstevel@tonic-gate#endif /* !lint */ 12271614Sjb145095 12287718SJason.Beloro@Sun.COM#if !defined(CUSTOM_FPZERO) 12297718SJason.Beloro@Sun.COM 12301614Sjb145095/* 12311614Sjb145095 * fp_zero() - clear all fp data registers and the fsr 12321614Sjb145095 */ 12331614Sjb145095 12341614Sjb145095#if defined(lint) || defined(__lint) 12351614Sjb145095 12361614Sjb145095void 12371614Sjb145095fp_zero(void) 12381614Sjb145095{} 12391614Sjb145095 12401614Sjb145095#else /* lint */ 12411614Sjb145095 12421614Sjb145095.global fp_zero_zero 12431614Sjb145095.align 8 12441614Sjb145095fp_zero_zero: 12451614Sjb145095 .xword 0 12461614Sjb145095 12471614Sjb145095 ENTRY_NP(fp_zero) 12481614Sjb145095 sethi %hi(fp_zero_zero), %o0 12497718SJason.Beloro@Sun.COM ldx [%o0 + %lo(fp_zero_zero)], %fsr 12501614Sjb145095 ldd [%o0 + %lo(fp_zero_zero)], %f0 12511614Sjb145095 fmovd %f0, %f2 12521614Sjb145095 fmovd %f0, %f4 12531614Sjb145095 fmovd %f0, %f6 12541614Sjb145095 fmovd %f0, %f8 12551614Sjb145095 fmovd %f0, %f10 12561614Sjb145095 fmovd %f0, %f12 12571614Sjb145095 fmovd %f0, %f14 12581614Sjb145095 fmovd %f0, %f16 12591614Sjb145095 fmovd %f0, %f18 12601614Sjb145095 fmovd %f0, %f20 12611614Sjb145095 fmovd %f0, %f22 12621614Sjb145095 fmovd %f0, %f24 12631614Sjb145095 fmovd %f0, %f26 12641614Sjb145095 fmovd %f0, %f28 12651614Sjb145095 fmovd %f0, %f30 12661614Sjb145095 fmovd %f0, %f32 12671614Sjb145095 fmovd %f0, %f34 12681614Sjb145095 fmovd %f0, %f36 12691614Sjb145095 fmovd %f0, %f38 12701614Sjb145095 fmovd %f0, %f40 12711614Sjb145095 fmovd %f0, %f42 12721614Sjb145095 fmovd %f0, %f44 12731614Sjb145095 fmovd %f0, %f46 12741614Sjb145095 fmovd %f0, %f48 12751614Sjb145095 fmovd %f0, %f50 12761614Sjb145095 fmovd %f0, %f52 12771614Sjb145095 fmovd %f0, %f54 12781614Sjb145095 fmovd %f0, %f56 12791614Sjb145095 fmovd %f0, %f58 12801614Sjb145095 fmovd %f0, %f60 12811614Sjb145095 retl 12821614Sjb145095 fmovd %f0, %f62 12831614Sjb145095 SET_SIZE(fp_zero) 12841614Sjb145095 12851614Sjb145095#endif /* lint */ 12867718SJason.Beloro@Sun.COM#endif /* CUSTOM_FPZERO */ 1287