1*0Sstevel@tonic-gate/* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate/* 23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate#pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate#include <sys/asm_linkage.h> 30*0Sstevel@tonic-gate#include <sys/machparam.h> /* To get SYSBASE and PAGESIZE */ 31*0Sstevel@tonic-gate#include <sys/privregs.h> 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate#if !defined(lint) 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gate .seg ".text" 36*0Sstevel@tonic-gate .align 4 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate#define PSR_PIL_BIT 0x8 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate/* 41*0Sstevel@tonic-gate * Macro to raise processor priority level. 42*0Sstevel@tonic-gate * Avoid dropping processor priority if already at high level. 43*0Sstevel@tonic-gate * Also avoid going below CPU->cpu_base_spl, which could've just been set by 44*0Sstevel@tonic-gate * a higher-level interrupt thread that just blocked. 45*0Sstevel@tonic-gate * XXX4U: bring splr inline 46*0Sstevel@tonic-gate */ 47*0Sstevel@tonic-gate#define RAISE(level) \ 48*0Sstevel@tonic-gate b splr; \ 49*0Sstevel@tonic-gate mov ((level) << PSR_PIL_BIT), %o0 50*0Sstevel@tonic-gate/* 51*0Sstevel@tonic-gate * Macro to set the priority to a specified level. 52*0Sstevel@tonic-gate * Avoid dropping the priority below CPU->cpu_base_spl. 53*0Sstevel@tonic-gate * XXX4U: bring splx inline 54*0Sstevel@tonic-gate */ 55*0Sstevel@tonic-gate#define SETPRI(level) \ 56*0Sstevel@tonic-gate b splx; \ 57*0Sstevel@tonic-gate mov ((level) << PSR_PIL_BIT), %o0 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate#endif /* lint */ 60*0Sstevel@tonic-gate 61*0Sstevel@tonic-gate /* 62*0Sstevel@tonic-gate * Berkley 4.3 introduced symbolically named interrupt levels 63*0Sstevel@tonic-gate * as a way deal with priority in a machine independent fashion. 64*0Sstevel@tonic-gate * Numbered priorities are machine specific, and should be 65*0Sstevel@tonic-gate * discouraged where possible. 66*0Sstevel@tonic-gate * 67*0Sstevel@tonic-gate * Note, for the machine specific priorities there are 68*0Sstevel@tonic-gate * examples listed for devices that use a particular priority. 69*0Sstevel@tonic-gate * It should not be construed that all devices of that 70*0Sstevel@tonic-gate * type should be at that priority. It is currently were 71*0Sstevel@tonic-gate * the current devices fit into the priority scheme based 72*0Sstevel@tonic-gate * upon time criticalness. 73*0Sstevel@tonic-gate * 74*0Sstevel@tonic-gate * The underlying assumption of these assignments is that 75*0Sstevel@tonic-gate * SPARC9 IPL 10 is the highest level from which a device 76*0Sstevel@tonic-gate * routine can call wakeup. Devices that interrupt from higher 77*0Sstevel@tonic-gate * levels are restricted in what they can do. If they need 78*0Sstevel@tonic-gate * kernels services they should schedule a routine at a lower 79*0Sstevel@tonic-gate * level (via software interrupt) to do the required 80*0Sstevel@tonic-gate * processing. 81*0Sstevel@tonic-gate * 82*0Sstevel@tonic-gate * Examples of this higher usage: 83*0Sstevel@tonic-gate * Level Usage 84*0Sstevel@tonic-gate * 15 Asynchronous memory exceptions 85*0Sstevel@tonic-gate * 14 Profiling clock (and PROM uart polling clock) 86*0Sstevel@tonic-gate * 13 Audio device 87*0Sstevel@tonic-gate * 12 Serial ports 88*0Sstevel@tonic-gate * 11 Floppy controller 89*0Sstevel@tonic-gate * 90*0Sstevel@tonic-gate * The serial ports request lower level processing on level 6. 91*0Sstevel@tonic-gate * Audio and floppy request lower level processing on level 4. 92*0Sstevel@tonic-gate * 93*0Sstevel@tonic-gate * Also, almost all splN routines (where N is a number or a 94*0Sstevel@tonic-gate * mnemonic) will do a RAISE(), on the assumption that they are 95*0Sstevel@tonic-gate * never used to lower our priority. 96*0Sstevel@tonic-gate * The exceptions are: 97*0Sstevel@tonic-gate * spl8() Because you can't be above 15 to begin with! 98*0Sstevel@tonic-gate * splzs() Because this is used at boot time to lower our 99*0Sstevel@tonic-gate * priority, to allow the PROM to poll the uart. 100*0Sstevel@tonic-gate * spl0() Used to lower priority to 0. 101*0Sstevel@tonic-gate * splsoftclock() Used by hardclock to lower priority. 102*0Sstevel@tonic-gate */ 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate#if defined(lint) 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gateint splimp(void) { return (0); } 107*0Sstevel@tonic-gateint splnet(void) { return (0); } 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate#ifdef notdef 110*0Sstevel@tonic-gateint spl6(void) { return (0); } 111*0Sstevel@tonic-gateint spl5(void) { return (0); } 112*0Sstevel@tonic-gate#endif notdef 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate#else /* lint */ 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate /* locks out all interrupts, including memory errors */ 117*0Sstevel@tonic-gate ENTRY(spl8) 118*0Sstevel@tonic-gate SETPRI(15) 119*0Sstevel@tonic-gate SET_SIZE(spl8) 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gate /* just below the level that profiling runs */ 122*0Sstevel@tonic-gate ALTENTRY(splaudio) 123*0Sstevel@tonic-gate ENTRY(spl7) 124*0Sstevel@tonic-gate RAISE(13) 125*0Sstevel@tonic-gate SET_SIZE(spl7) 126*0Sstevel@tonic-gate SET_SIZE(splaudio) 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate /* sun specific - highest priority onboard serial i/o zs ports */ 129*0Sstevel@tonic-gate ALTENTRY(splzs) 130*0Sstevel@tonic-gate SETPRI(12) /* Can't be a RAISE, as it's used to lower us */ 131*0Sstevel@tonic-gate SET_SIZE(splzs) 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate /* 134*0Sstevel@tonic-gate * should lock out clocks and all interrupts, 135*0Sstevel@tonic-gate * as you can see, there are exceptions 136*0Sstevel@tonic-gate */ 137*0Sstevel@tonic-gate ALTENTRY(splhigh) 138*0Sstevel@tonic-gate ALTENTRY(splhi) 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate /* the standard clock interrupt priority */ 141*0Sstevel@tonic-gate ALTENTRY(splclock) 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate /* highest priority for any tty handling */ 144*0Sstevel@tonic-gate ALTENTRY(spltty) 145*0Sstevel@tonic-gate 146*0Sstevel@tonic-gate /* highest priority required for protection of buffered io system */ 147*0Sstevel@tonic-gate ALTENTRY(splbio) 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate /* machine specific */ 150*0Sstevel@tonic-gate ENTRY2(spl6,spl5) 151*0Sstevel@tonic-gate RAISE(10) 152*0Sstevel@tonic-gate SET_SIZE(splhigh) 153*0Sstevel@tonic-gate SET_SIZE(splhi) 154*0Sstevel@tonic-gate SET_SIZE(splclock) 155*0Sstevel@tonic-gate SET_SIZE(spltty) 156*0Sstevel@tonic-gate SET_SIZE(splbio) 157*0Sstevel@tonic-gate SET_SIZE(spl5) 158*0Sstevel@tonic-gate SET_SIZE(spl6) 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate /* 161*0Sstevel@tonic-gate * machine specific 162*0Sstevel@tonic-gate * for sun, some frame buffers must be at this priority 163*0Sstevel@tonic-gate */ 164*0Sstevel@tonic-gate ENTRY(spl4) 165*0Sstevel@tonic-gate RAISE(8) 166*0Sstevel@tonic-gate SET_SIZE(spl4) 167*0Sstevel@tonic-gate 168*0Sstevel@tonic-gate /* highest level that any network device will use */ 169*0Sstevel@tonic-gate ALTENTRY(splimp) 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate /* 172*0Sstevel@tonic-gate * machine specific 173*0Sstevel@tonic-gate * for sun, devices with limited buffering: tapes, ethernet 174*0Sstevel@tonic-gate */ 175*0Sstevel@tonic-gate ENTRY(spl3) 176*0Sstevel@tonic-gate RAISE(6) 177*0Sstevel@tonic-gate SET_SIZE(splimp) 178*0Sstevel@tonic-gate SET_SIZE(spl3) 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gate /* 181*0Sstevel@tonic-gate * machine specific - not as time critical as above 182*0Sstevel@tonic-gate * for sun, disks 183*0Sstevel@tonic-gate */ 184*0Sstevel@tonic-gate ENTRY(spl2) 185*0Sstevel@tonic-gate RAISE(4) 186*0Sstevel@tonic-gate SET_SIZE(spl2) 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate ENTRY(spl1) 189*0Sstevel@tonic-gate RAISE(2) 190*0Sstevel@tonic-gate SET_SIZE(spl1) 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate /* highest level that any protocol handler will run */ 193*0Sstevel@tonic-gate ENTRY(splnet) 194*0Sstevel@tonic-gate RAISE(1) 195*0Sstevel@tonic-gate SET_SIZE(splnet) 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gate /* softcall priority */ 198*0Sstevel@tonic-gate /* used by hardclock to LOWER priority */ 199*0Sstevel@tonic-gate ENTRY(splsoftclock) 200*0Sstevel@tonic-gate SETPRI(1) 201*0Sstevel@tonic-gate SET_SIZE(splsoftclock) 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate /* allow all interrupts */ 204*0Sstevel@tonic-gate ENTRY(spl0) 205*0Sstevel@tonic-gate SETPRI(0) 206*0Sstevel@tonic-gate SET_SIZE(spl0) 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate#endif /* lint */ 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate/* 211*0Sstevel@tonic-gate * splx - set PIL back to that indicated by the old %PSR passed as an argument, 212*0Sstevel@tonic-gate * or to the CPU's base priority, whichever is higher. 213*0Sstevel@tonic-gate * sys_rtt (in locore.s) relies on this not to use %g1 or %g2. 214*0Sstevel@tonic-gate */ 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate#if defined(lint) 217*0Sstevel@tonic-gate 218*0Sstevel@tonic-gate/* ARGSUSED */ 219*0Sstevel@tonic-gatevoid 220*0Sstevel@tonic-gatesplx(int level) 221*0Sstevel@tonic-gate{ 222*0Sstevel@tonic-gate} 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate#else /* lint */ 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate ENTRY(splx) 227*0Sstevel@tonic-gate rdpr %pil, %o1 ! get current pil 228*0Sstevel@tonic-gate wrpr %o0, %pil 229*0Sstevel@tonic-gate retl 230*0Sstevel@tonic-gate mov %o1, %o0 231*0Sstevel@tonic-gate SET_SIZE(splx) 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gate#endif /* level */ 234*0Sstevel@tonic-gate 235*0Sstevel@tonic-gate/* 236*0Sstevel@tonic-gate * splr() 237*0Sstevel@tonic-gate * 238*0Sstevel@tonic-gate * splr is like splx but will only raise the priority and never drop it 239*0Sstevel@tonic-gate * Be careful not to set priority lower than CPU->cpu_base_pri, 240*0Sstevel@tonic-gate * even though it seems we're raising the priority, it could be set higher 241*0Sstevel@tonic-gate * at any time by an interrupt routine, so we must block interrupts and 242*0Sstevel@tonic-gate * look at CPU->cpu_base_pri. 243*0Sstevel@tonic-gate * 244*0Sstevel@tonic-gate */ 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gate#if defined(lint) 247*0Sstevel@tonic-gate#ifdef notdef 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate/* ARGSUSED */ 250*0Sstevel@tonic-gateint 251*0Sstevel@tonic-gatesplr(int level) 252*0Sstevel@tonic-gate{ return (0); } 253*0Sstevel@tonic-gate 254*0Sstevel@tonic-gate#endif notdef 255*0Sstevel@tonic-gate#else /* lint */ 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gate/* 258*0Sstevel@tonic-gate * splr(psr_pri_field) 259*0Sstevel@tonic-gate * splr is like splx but will only raise the priority and never drop it 260*0Sstevel@tonic-gate */ 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gate ENTRY(splr) 263*0Sstevel@tonic-gate rdpr %pil, %o1 ! get current pil 264*0Sstevel@tonic-gate cmp %o0, %o1 265*0Sstevel@tonic-gate ble 1f 266*0Sstevel@tonic-gate nop 267*0Sstevel@tonic-gate wrpr %o0, %pil 268*0Sstevel@tonic-gate1: retl 269*0Sstevel@tonic-gate mov %o1, %o0 ! return the old pil 270*0Sstevel@tonic-gate SET_SIZE(splr) 271*0Sstevel@tonic-gate 272*0Sstevel@tonic-gate#endif /* lint */ 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gate/* 275*0Sstevel@tonic-gate * get_ticks() 276*0Sstevel@tonic-gate */ 277*0Sstevel@tonic-gate#if defined(lint) 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate/* ARGSUSED */ 280*0Sstevel@tonic-gateuint64_t 281*0Sstevel@tonic-gateget_ticks(void) 282*0Sstevel@tonic-gate{ return (0); } 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate#else /* lint */ 285*0Sstevel@tonic-gate 286*0Sstevel@tonic-gate ENTRY(get_ticks) 287*0Sstevel@tonic-gate rdpr %tick, %o0 288*0Sstevel@tonic-gate sllx %o0, 1, %o0 289*0Sstevel@tonic-gate retl 290*0Sstevel@tonic-gate srlx %o0, 1, %o0 ! shake off npt bit 291*0Sstevel@tonic-gate SET_SIZE(get_ticks) 292*0Sstevel@tonic-gate 293*0Sstevel@tonic-gate#endif /* lint */ 294