Home | History | Annotate | Line # | Download | only in include
psl.h revision 1.3
      1 /*	$NetBSD: psl.h,v 1.3 1998/07/28 04:44:52 eeh Exp $ */
      2 
      3 /*
      4  * Copyright (c) 1992, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * This software was developed by the Computer Systems Engineering group
      8  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
      9  * contributed to Berkeley.
     10  *
     11  * All advertising materials mentioning features or use of this software
     12  * must display the following acknowledgement:
     13  *	This product includes software developed by the University of
     14  *	California, Lawrence Berkeley Laboratory.
     15  *
     16  * Redistribution and use in source and binary forms, with or without
     17  * modification, are permitted provided that the following conditions
     18  * are met:
     19  * 1. Redistributions of source code must retain the above copyright
     20  *    notice, this list of conditions and the following disclaimer.
     21  * 2. Redistributions in binary form must reproduce the above copyright
     22  *    notice, this list of conditions and the following disclaimer in the
     23  *    documentation and/or other materials provided with the distribution.
     24  * 3. All advertising materials mentioning features or use of this software
     25  *    must display the following acknowledgement:
     26  *	This product includes software developed by the University of
     27  *	California, Berkeley and its contributors.
     28  * 4. Neither the name of the University nor the names of its contributors
     29  *    may be used to endorse or promote products derived from this software
     30  *    without specific prior written permission.
     31  *
     32  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     35  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     36  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     40  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     41  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     42  * SUCH DAMAGE.
     43  *
     44  *	@(#)psl.h	8.1 (Berkeley) 6/11/93
     45  */
     46 
     47 #ifndef PSR_IMPL
     48 
     49 /*
     50  * SPARC Process Status Register (in psl.h for hysterical raisins).
     51  * Of course, this register does not exist in v9, but we keep this stuff
     52  * in here in case we need it for compatibility w/v7 and v8.
     53  *
     54  * The picture in the Sun manuals looks like this:
     55  *	                                     1 1
     56  *	 31   28 27   24 23   20 19       14 3 2 11    8 7 6 5 4       0
     57  *	+-------+-------+-------+-----------+-+-+-------+-+-+-+---------+
     58  *	|  impl |  ver  |  icc  |  reserved |E|E|  pil  |S|P|E|   CWP   |
     59  *	|       |       |n z v c|           |C|F|       | |S|T|         |
     60  *	+-------+-------+-------+-----------+-+-+-------+-+-+-+---------+
     61  */
     62 
     63 #define	PSR_IMPL	0xf0000000	/* implementation */
     64 #define	PSR_VER		0x0f000000	/* version */
     65 #define	PSR_ICC		0x00f00000	/* integer condition codes */
     66 #define	PSR_N		0x00800000	/* negative */
     67 #define	PSR_Z		0x00400000	/* zero */
     68 #define	PSR_O		0x00200000	/* overflow */
     69 #define	PSR_C		0x00100000	/* carry */
     70 #define	PSR_EC		0x00002000	/* coprocessor enable */
     71 #define	PSR_EF		0x00001000	/* FP enable */
     72 #define	PSR_PIL		0x00000f00	/* interrupt level */
     73 #define	PSR_S		0x00000080	/* supervisor (kernel) mode */
     74 #define	PSR_PS		0x00000040	/* previous supervisor mode (traps) */
     75 #define	PSR_ET		0x00000020	/* trap enable */
     76 #define	PSR_CWP		0x0000001f	/* current window pointer */
     77 
     78 #define	PSR_BITS "\20\16EC\15EF\10S\7PS\6ET"
     79 
     80 /* Interesting spl()s */
     81 #define PIL_SCSI	3
     82 #define PIL_FDSOFT	4
     83 #define	PIL_AUSOFT	4
     84 #define PIL_BIO		5
     85 #define PIL_VIDEO	5
     86 #define	PIL_TTY		6
     87 #define	PIL_NET		6
     88 #define PIL_IMP		7
     89 #define	PIL_CLOCK	10
     90 #define PIL_FD		11
     91 #define PIL_SER		12
     92 #define PIL_AUD		13
     93 
     94 /*
     95  * SPARC V9 CCR register
     96  *
     97  */
     98 
     99 #define ICC_C	0x01
    100 #define ICC_V	0x02
    101 #define ICC_Z	0x04
    102 #define ICC_N	0x08
    103 #define XCC_SHIFT	4
    104 #define XCC_C	(ICC_C<<XCC_SHIFT)
    105 #define XCC_V	(ICC_V<<XCC_SHIFT)
    106 #define XCC_Z	(ICC_Z<<XCC_SHIFT)
    107 #define XCC_N	(ICC_N<<XCC_SHIFT)
    108 
    109 
    110 /*
    111  * SPARC V9 PSTATE register (what replaces the PSR in V9)
    112  *
    113  * Here's the layout:
    114  *
    115  *    11   10    9     8   7  6   5     4     3     2     1   0
    116  *  +------------------------------------------------------------+
    117  *  | IG | MG | CLE | TLE | MM | RED | PEF | AM | PRIV | IE | AG |
    118  *  +------------------------------------------------------------+
    119  */
    120 
    121 #define PSTATE_IG	0x800	/* enable spitfire interrupt globals */
    122 #define PSTATE_MG	0x400	/* enable spitfire MMU globals */
    123 #define PSTATE_CLE	0x200	/* current little endian */
    124 #define PSTATE_TLE	0x100	/* traps little endian */
    125 #define PSTATE_MM	0x0c0	/* memory model */
    126 #define PSTATE_MM_TSO	0x000	/* total store order */
    127 #define PSTATE_MM_PSO	0x040	/* partial store order */
    128 #define PSTATE_MM_RMO	0x080	/* Relaxed memory order */
    129 #define PSTATE_RED	0x020	/* RED state */
    130 #define PSTATE_PEF	0x010	/* enable floating point */
    131 #define PSTATE_AM	0x008	/* 32-bit address masking */
    132 #define PSTATE_PRIV	0x004	/* privileged mode */
    133 #define PSTATE_IE	0x002	/* interrupt enable */
    134 #define PSTATE_AG	0x001	/* enable alternate globals */
    135 
    136 #define	PSTATE_BITS "\20\14IG\13MG\12CLE\11TLE\10\7MM\6RED\5PEF\4AM\3PRIV\2IE\1AG"
    137 
    138 #define PSTATE_PROM	(PSTATE_MM_TSO|PSTATE_PRIV)
    139 #define PSTATE_NUCLEUS	(PSTATE_MM_TSO|PSTATE_AM|PSTATE_PRIV|PSTATE_AG)
    140 #define PSTATE_KERN	(PSTATE_MM_TSO|PSTATE_AM|PSTATE_PRIV)
    141 #define PSTATE_INTR	(PSTATE_KERN|PSTATE_IE)
    142 #ifdef DEBUG
    143 #define PSTATE_USER	(PSTATE_MM_TSO|PSTATE_AM|PSTATE_IE)	/* It's easier to debug */
    144 #else
    145 #define PSTATE_USER	(PSTATE_MM_RMO|PSTATE_AM|PSTATE_IE)
    146 #endif
    147 
    148 /*
    149  * SPARC V9 TSTATE register
    150  *
    151  *   39 32 31 24 23 18  17   8	7 5 4   0
    152  *  +-----+-----+-----+--------+---+-----+
    153  *  | CCR | ASI |  -  | PSTATE | - | CWP |
    154  *  +-----+-----+-----+--------+---+-----+
    155  *
    156  */
    157 
    158 #define TSTATE_CWP		0x01f
    159 #define TSTATE_PSTATE		0x6ff00
    160 #define TSTATE_PSTATE_SHIFT	8
    161 #define TSTATE_ASI		0xff000000LL
    162 #define TSTATE_ASI_SHIFT	24
    163 #define TSTATE_CCR		0xff00000000LL
    164 #define TSTATE_CCR_SHIFT	32
    165 
    166 #define PSRCC_TO_TSTATE(x)	(((int64_t)(x)&PSR_ICC)<<(TSTATE_CCR_SHIFT-19))
    167 #define TSTATECCR_TO_PSR(x)	(((x)&TSTATE_CCR)>>(TSTATE_CCR_SHIFT-19))
    168 
    169 /*
    170  * These are here to simplify life.
    171  */
    172 #define TSTATE_IG	(PSTATE_IG<<TSTATE_PSTATE_SHIFT)
    173 #define TSTATE_MG	(PSTATE_MG<<TSTATE_PSTATE_SHIFT)
    174 #define TSTATE_CLE	(PSTATE_CLE<<TSTATE_PSTATE_SHIFT)
    175 #define TSTATE_TLE	(PSTATE_TLE<<TSTATE_PSTATE_SHIFT)
    176 #define TSTATE_MM	(PSTATE_MM<<TSTATE_PSTATE_SHIFT)
    177 #define TSTATE_MM_TSO	(PSTATE_MM_TSO<<TSTATE_PSTATE_SHIFT)
    178 #define TSTATE_MM_PSO	(PSTATE_MM_PSO<<TSTATE_PSTATE_SHIFT)
    179 #define TSTATE_MM_RMO	(PSTATE_MM_RMO<<TSTATE_PSTATE_SHIFT)
    180 #define TSTATE_RED	(PSTATE_RED<<TSTATE_PSTATE_SHIFT)
    181 #define TSTATE_PEF	(PSTATE_PEF<<TSTATE_PSTATE_SHIFT)
    182 #define TSTATE_AM	(PSTATE_AM<<TSTATE_PSTATE_SHIFT)
    183 #define TSTATE_PRIV	(PSTATE_PRIV<<TSTATE_PSTATE_SHIFT)
    184 #define TSTATE_IE	(PSTATE_IE<<TSTATE_PSTATE_SHIFT)
    185 #define TSTATE_AG	(PSTATE_AG<<TSTATE_PSTATE_SHIFT)
    186 
    187 #define	TSTATE_BITS "\20\14IG\13MG\12CLE\11TLE\10\7MM\6RED\5PEF\4AM\3PRIV\2IE\1AG"
    188 
    189 #define TSTATE_KERN	((TSTATE_KERN)<<TSTATE_PSTATE_SHIFT)
    190 #define TSTATE_USER	((TSTATE_USER)<<TSTATE_PSTATE_SHIFT)
    191 /*
    192  * SPARC V9 VER version register.
    193  *
    194  *  63   48 47  32 31  24 23 16 15    8 7 5 4      0
    195  * +-------+------+------+-----+-------+---+--------+
    196  * | manuf | impl | mask |  -  | maxtl | - | maxwin |
    197  * +-------+------+------+-----+-------+---+--------+
    198  *
    199  */
    200 
    201 #define VER_MANUF	0xffff000000000000LL
    202 #define VER_MANUF_SHIFT	48
    203 #define VER_IMPL	0x0000ffff00000000LL
    204 #define VER_IMPL_SHIFT	32
    205 #define VER_MASK	0x00000000ff000000LL
    206 #define VER_MASK_SHIFT	24
    207 #define VER_MAXTL	0x000000000000ff00LL
    208 #define VER_MAXTL_SHIFT	8
    209 #define VER_MAXWIN	0x000000000000001fLL
    210 
    211 /*
    212  * Here are a few things to help us transition between user and kernel mode:
    213  */
    214 
    215 /* Memory models */
    216 #define KERN_MM		PSTATE_MM_TSO
    217 #define USER_MM		PSTATE_MM_RMO
    218 
    219 #define WSTATE_KERN	026
    220 #define WSTATE_USER	022
    221 
    222 #define CWP		0x01f
    223 
    224 /* 64-byte alignment -- this seems the best place to put this. */
    225 #define BLOCK_SIZE	64
    226 #define BLOCK_ALIGN	0x3f
    227 
    228 #if defined(_KERNEL) && !defined(_LOCORE)
    229 
    230 extern u_int64_t ver;	/* Copy of v9 version register.  We need to read this only once, in locore.s. */
    231 static __inline int getpstate __P((void));
    232 static __inline void setpstate __P((int));
    233 static __inline int getcwp __P((void));
    234 static __inline void setcwp __P((int));
    235 #ifndef SPLDEBUG
    236 static __inline void splx __P((int));
    237 #endif
    238 static __inline u_int64_t getver __P((void));
    239 
    240 /*
    241  * GCC pseudo-functions for manipulating privileged registers
    242  */
    243 static __inline int getpstate()
    244 {
    245 	int pstate;
    246 
    247 	__asm __volatile("rdpr %%pstate,%0" : "=r" (pstate));
    248 	return (pstate);
    249 }
    250 
    251 static __inline void setpstate(newpstate)
    252 	int newpstate;
    253 {
    254 	__asm __volatile("wrpr %0,0,%%pstate" : : "r" (newpstate));
    255 }
    256 
    257 static __inline int getcwp()
    258 {
    259 	int cwp;
    260 
    261 	__asm __volatile("rdpr %%cwp,%0" : "=r" (cwp));
    262 	return (cwp);
    263 }
    264 
    265 static __inline void setcwp(newcwp)
    266 	int newcwp;
    267 {
    268 	__asm __volatile("wrpr %0,0,%%cwp" : : "r" (newcwp));
    269 }
    270 
    271 static __inline u_int64_t getver()
    272 {
    273 	u_int64_t ver;
    274 
    275 	__asm __volatile("rdpr %%ver,%0" : "=r" (ver));
    276 	return (ver);
    277 }
    278 
    279 /*
    280  * GCC pseudo-functions for manipulating PIL
    281  */
    282 
    283 #ifdef SPLDEBUG
    284 void prom_printf __P((const char *fmt, ...));
    285 extern int printspl;
    286 #define SPLPRINT(x)	if(printspl) { int i=10000000; prom_printf x ; while(i--); }
    287 #define	SPL(name, newpil) \
    288 static __inline int name##X __P((const char*, int)); \
    289 static __inline int name##X(const char* file, int line) \
    290 { \
    291 	int oldpil; \
    292 	__asm __volatile("rdpr %%pil,%0" : "=r" (oldpil)); \
    293 	SPLPRINT(("{%s:%d %d=>%d}", file, line, oldpil, newpil)); \
    294 	__asm __volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil)); \
    295 	return (oldpil); \
    296 }
    297 /* A non-priority-decreasing version of SPL */
    298 #define	SPLHOLD(name, newpil) \
    299 static __inline int name##X __P((const char*, int)); \
    300 static __inline int name##X(const char* file, int line) \
    301 { \
    302 	int oldpil; \
    303 	__asm __volatile("rdpr %%pil,%0" : "=r" (oldpil)); \
    304 	if (newpil <= oldpil) \
    305 		return oldpil; \
    306 	SPLPRINT(("{%s:%d %d->!d}", file, line, oldpil, newpil)); \
    307 	__asm __volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil)); \
    308 	return (oldpil); \
    309 }
    310 
    311 #else
    312 #define SPLPRINT(x)
    313 #define	SPL(name, newpil) \
    314 static __inline int name __P((void)); \
    315 static __inline int name() \
    316 { \
    317 	int oldpil; \
    318 	__asm __volatile("rdpr %%pil,%0" : "=r" (oldpil)); \
    319 	__asm __volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil)); \
    320 	return (oldpil); \
    321 }
    322 /* A non-priority-decreasing version of SPL */
    323 #define	SPLHOLD(name, newpil) \
    324 static __inline int name __P((void)); \
    325 static __inline int name() \
    326 { \
    327 	int oldpil; \
    328 	__asm __volatile("rdpr %%pil,%0" : "=r" (oldpil)); \
    329 	if (newpil <= oldpil) \
    330 		return oldpil; \
    331 	__asm __volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil)); \
    332 	return (oldpil); \
    333 }
    334 #endif
    335 
    336 SPL(spl0, 0)
    337 
    338 SPLHOLD(splsoftint, 1)
    339 #define	splsoftclock	splsoftint
    340 #define	splsoftnet	splsoftint
    341 
    342 /* audio software interrupts are at software level 4 */
    343 SPLHOLD(splausoft, PIL_AUSOFT)
    344 
    345 /* floppy software interrupts are at software level 4 too */
    346 SPLHOLD(splfdsoft, PIL_FDSOFT)
    347 
    348 /* Block devices */
    349 SPLHOLD(splbio, PIL_BIO)
    350 
    351 /* network hardware interrupts are at level 6 */
    352 SPLHOLD(splnet, PIL_NET)
    353 
    354 /* tty input runs at software level 6 */
    355 SPLHOLD(spltty, PIL_TTY)
    356 
    357 /*
    358  * Memory allocation (must be as high as highest network, tty, or disk device)
    359  */
    360 SPLHOLD(splimp, PIL_IMP)
    361 SPLHOLD(splpmap, PIL_IMP)
    362 
    363 SPLHOLD(splclock, PIL_CLOCK)
    364 
    365 /* fd hardware interrupts are at level 11 */
    366 SPLHOLD(splfd, PIL_FD)
    367 
    368 /* zs hardware interrupts are at level 12 */
    369 SPLHOLD(splzs, PIL_SER)
    370 
    371 /* audio hardware interrupts are at level 13 */
    372 SPLHOLD(splaudio, PIL_AUD)
    373 
    374 /* second sparc timer interrupts at level 14 */
    375 SPLHOLD(splstatclock, 14)
    376 
    377 SPLHOLD(splhigh, 15)
    378 
    379 /* splx does not have a return value */
    380 #ifdef SPLDEBUG
    381 /* Keep gcc happy -- reduce warnings */
    382 #if 0
    383 static __inline void splx(newpil)
    384 	int newpil;
    385 {
    386 	int pil;
    387 
    388 	__asm __volatile("rdpr %%pil,%0" : "=r" (pil));
    389 	SPLPRINT(("{%d->%d}", pil, newpil)); \
    390 	__asm __volatile("wrpr %%g0,%0,%%pil" : : "rn" (newpil));
    391 }
    392 #endif
    393 
    394 #define	spl0()	spl0X(__FILE__, __LINE__)
    395 #define	splsoftint()	splsoftintX(__FILE__, __LINE__)
    396 #define	splausoft()	splausoftX(__FILE__, __LINE__)
    397 #define	splfdsoft()	splfdsoftX(__FILE__, __LINE__)
    398 #define	splbio()	splbioX(__FILE__, __LINE__)
    399 #define	splnet()	splnetX(__FILE__, __LINE__)
    400 #define	spltty()	splttyX(__FILE__, __LINE__)
    401 #define	splimp()	splimpX(__FILE__, __LINE__)
    402 #define	splpmap()	splpmapX(__FILE__, __LINE__)
    403 #define	splclock()	splclockX(__FILE__, __LINE__)
    404 #define	splfd()		splfdX(__FILE__, __LINE__)
    405 #define	splzs()		splzsX(__FILE__, __LINE__)
    406 #define	splaudio()	splaudioX(__FILE__, __LINE__)
    407 #define	splstatclock()	splstatclockX(__FILE__, __LINE__)
    408 #define	splhigh()	splhighX(__FILE__, __LINE__)
    409 #define splx(x)		splxX((x),__FILE__, __LINE__)
    410 
    411 static __inline void splxX __P((int, const char*, int));
    412 static __inline void splxX(newpil, file, line)
    413 	int newpil, line;
    414 	const char* file;
    415 #else
    416 static __inline void splx(newpil)
    417 	int newpil;
    418 #endif
    419 {
    420 	int pil;
    421 
    422 	__asm __volatile("rdpr %%pil,%0" : "=r" (pil));
    423 	SPLPRINT(("{%d->%d}", pil, newpil)); \
    424 	__asm __volatile("wrpr %%g0,%0,%%pil" : : "rn" (newpil));
    425 }
    426 #endif /* KERNEL && !_LOCORE */
    427 
    428 #endif /* PSR_IMPL */
    429