xref: /onnv-gate/usr/src/psm/stand/boot/sparc/common/sparcv9_subr.s (revision 0:68f95e015346)
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