1/* $NetBSD: alpha_cpu.h,v 1.56 2022/07/20 15:52:47 thorpej Exp $ */
2
3/*
4 * Copyright (c) 1996 Carnegie-Mellon University.
5 * All rights reserved.
6 *
7 * Author: Chris G. Demetriou
8 *
9 * Permission to use, copy, modify and distribute this software and
10 * its documentation is hereby granted, provided that both the copyright
11 * notice and this permission notice appear in all copies of the
12 * software, derivative works or modified versions, and any portions
13 * thereof, and that both notices appear in supporting documentation.
14 *
15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 *
19 * Carnegie Mellon requests users of this software to return to
20 *
21 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
22 *  School of Computer Science
23 *  Carnegie Mellon University
24 *  Pittsburgh PA 15213-3890
25 *
26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes.
28 */
29
30#ifndef __ALPHA_ALPHA_CPU_H__
31#define	__ALPHA_ALPHA_CPU_H__
32
33/*
34 * Alpha CPU + OSF/1 PALcode definitions for use by the kernel.
35 *
36 * Definitions for:
37 *
38 *	Process Control Block
39 *	Interrupt/Exception/Syscall Stack Frame
40 *	Processor Status Register
41 *	Machine Check Error Summary Register
42 *	Machine Check Logout Area
43 *	Per CPU state Management of Machine Check Handling
44 *	Virtual Memory Management
45 *	Kernel Entry Vectors
46 *	MMCSR Fault Type Codes
47 *	AESR Fault Code bits
48 *	Translation Buffer Invalidation
49 *
50 * and miscellaneous PALcode operations.
51 */
52
53
54/*
55 * Process Control Block definitions [OSF/1 PALcode Specific]
56 */
57
58struct alpha_pcb {
59	unsigned long	apcb_ksp;	/* kernel stack ptr */
60	unsigned long	apcb_usp;	/* user stack ptr */
61	unsigned long	apcb_ptbr;	/* page table base reg */
62	unsigned int	apcb_cpc;	/* charged process cycles */
63	unsigned int	apcb_asn;	/* address space number */
64	unsigned long	apcb_unique;	/* process unique value */
65#define	apcb_backup_ksp	apcb_unique	/* backup kernel stack ptr */
66	unsigned long	apcb_flags;	/* flags; see below */
67	unsigned long	apcb_decrsv0;	/* DEC reserved */
68	unsigned long	apcb_decrsv1;	/* DEC reserved */
69};
70
71#define	ALPHA_PCB_FLAGS_FEN	0x0000000000000001
72#define	ALPHA_PCB_FLAGS_PME	0x4000000000000000
73
74/*
75 * Interrupt/Exception/Syscall "Hardware" (really PALcode)
76 * Stack Frame definitions
77 *
78 * These are quadword offsets from the sp on kernel entry, i.e.
79 * to get to the value in question you access (sp + (offset * 8)).
80 *
81 * On syscall entry, A0-A2 aren't written to memory but space
82 * _is_ reserved for them.
83 */
84
85#define	ALPHA_HWFRAME_PS	0	/* processor status register */
86#define	ALPHA_HWFRAME_PC	1	/* program counter */
87#define	ALPHA_HWFRAME_GP	2	/* global pointer */
88#define	ALPHA_HWFRAME_A0	3	/* a0 */
89#define	ALPHA_HWFRAME_A1	4	/* a1 */
90#define	ALPHA_HWFRAME_A2	5	/* a2 */
91
92#define	ALPHA_HWFRAME_SIZE	6	/* 6 8-byte words */
93
94/*
95 * Processor Status Register [OSF/1 PALcode Specific]
96 *
97 * Includes user/kernel mode bit, interrupt priority levels, etc.
98 *
99 * Processor Status Summary
100 * ---------------------------------------------------------------------------
101 * PS<mode>	PS<IPL>		Mode		Use
102 * ---------------------------------------------------------------------------
103 * 1		0		User		User software
104 * 0		0		Kernel		System software
105 * 0		1		Kernel		System software
106 * 0		2		Kernel		System software
107 * 0		3		Kernel		Low priority device interrupts
108 * 0		4		Kernel		High priority device interrupts
109 * 0		5		Kernel		Clock, inter-proc interrupts
110 * 0		6		Kernel		Real-time device interrupts
111 * 0		6		Kernel		Correctable error reporting
112 * 0		7		Kernel		Machine checks
113 */
114
115#define	ALPHA_PSL_USERMODE	0x0008		/* set -> user mode */
116#define	ALPHA_PSL_IPL_MASK	0x0007		/* interrupt level mask */
117
118#define	ALPHA_PSL_IPL_0		0x0000		/* all interrupts enabled */
119#define	ALPHA_PSL_IPL_SOFT_LO	0x0001		/* low pri soft ints disabled */
120#define	ALPHA_PSL_IPL_SOFT_HI	0x0002		/* hi pri soft ints disabled */
121#define	ALPHA_PSL_IPL_IO_LO	0x0003		/* low pri dev ints disabled */
122#define	ALPHA_PSL_IPL_IO_HI	0x0004		/* hi pri dev ints disabled */
123#define	ALPHA_PSL_IPL_CLOCK	0x0005		/* clock ints disabled */
124#define	ALPHA_PSL_IPL_HIGH	0x0006		/* all but mchecks disabled */
125#define	ALPHA_PSL_IPL_MCHECK	0x0007		/* machine checks disabled */
126
127#define	ALPHA_PSL_MUST_BE_ZERO	0xfffffffffffffff0
128
129/* Convenience constants: what must be set/clear in user mode */
130#define	ALPHA_PSL_USERSET	ALPHA_PSL_USERMODE
131#define	ALPHA_PSL_USERCLR	(ALPHA_PSL_MUST_BE_ZERO | ALPHA_PSL_IPL_MASK)
132
133/*
134 * Interrupt Type Code Definitions [OSF/1 PALcode Specific]
135 */
136
137#define	ALPHA_INTR_XPROC	0	/* interprocessor interrupt */
138#define	ALPHA_INTR_CLOCK	1	/* clock interrupt */
139#define	ALPHA_INTR_ERROR	2	/* correctable error or mcheck */
140#define	ALPHA_INTR_DEVICE	3	/* device interrupt */
141#define	ALPHA_INTR_PERF		4	/* performance counter */
142#define	ALPHA_INTR_PASSIVE	5	/* passive release */
143
144/*
145 * Machine Check Error Summary Register definitions [OSF/1 PALcode Specific]
146 *
147 * The following bits are values as read.  On write, _PCE, _SCE, and
148 * _MIP are "write 1 to clear."
149 */
150
151#define	ALPHA_MCES_IMP							\
152    0xffffffff00000000	/* impl. dependent */
153#define	ALPHA_MCES_RSVD							\
154    0x00000000ffffffe0	/* reserved */
155#define	ALPHA_MCES_DSC							\
156    0x0000000000000010	/* disable system correctable error reporting */
157#define	ALPHA_MCES_DPC							\
158    0x0000000000000008	/* disable processor correctable error reporting */
159#define	ALPHA_MCES_PCE							\
160    0x0000000000000004	/* processor correctable error in progress */
161#define	ALPHA_MCES_SCE							\
162    0x0000000000000002	/* system correctable error in progress */
163#define	ALPHA_MCES_MIP							\
164    0x0000000000000001	/* machine check in progress */
165
166/*
167 * Machine Check Error Summary Register definitions [OSF/1 PALcode Specific]
168 *
169 * Note that these are *generic* OSF/1 PALcode specific defines. There are
170 * platform variations to these entities.
171 */
172
173struct alpha_logout_area {
174	unsigned int	la_frame_size;		/* frame size */
175	unsigned int	la_flags;		/* flags; see below */
176	unsigned int	la_cpu_offset;		/* offset to cpu area */
177	unsigned int	la_system_offset;	/* offset to system area */
178};
179
180#define	ALPHA_LOGOUT_FLAGS_RETRY	0x80000000	/* OK to continue */
181#define	ALPHA_LOGOUT_FLAGS_SE		0x40000000	/* second error */
182#define	ALPHA_LOGOUT_FLAGS_SBZ		0x3fffffff	/* should be zero */
183
184#define	ALPHA_LOGOUT_NOT_BUILT						\
185    (struct alpha_logout_area *)0xffffffffffffffff)
186
187#define	ALPHA_LOGOUT_PAL_AREA(lap)					\
188    (unsigned long *)((unsigned char *)(lap) + 16)
189#define	ALPHA_LOGOUT_PAL_SIZE(lap)					\
190    ((lap)->la_cpu_offset - 16)
191#define	ALPHA_LOGOUT_CPU_AREA(lap)					\
192    (unsigned long *)((unsigned char *)(lap) + (lap)->la_cpu_offset)
193#define	ALPHA_LOGOUT_CPU_SIZE(lap)					\
194    ((lap)->la_system_offset - (lap)->la_cpu_offset)
195#define	ALPHA_LOGOUT_SYSTEM_AREA(lap)					\
196    (unsigned long *)((unsigned char *)(lap) + (lap)->la_system_offset)
197#define	ALPHA_LOGOUT_SYSTEM_SIZE(lap)					\
198    ((lap)->la_frame_size - (lap)->la_system_offset)
199
200/* types of machine checks */
201#define	ALPHA_SYS_ERROR		0x620	/* System correctable error	*/
202#define	ALPHA_PROC_ERROR	0x630	/* Processor correctable error	*/
203#define	ALPHA_SYS_MCHECK	0x660	/* System machine check		*/
204#define	ALPHA_PROC_MCHECK	0x670	/* Processor machine check	*/
205#define	ALPHA_ENV_MCHECK	0x680	/* Environmental error		*/
206
207/*
208 * Virtual Memory Management definitions [OSF/1 PALcode Specific]
209 *
210 * Includes user and kernel space addresses and information,
211 * page table entry definitions, etc.
212 *
213 * NOTE THAT THESE DEFINITIONS MAY CHANGE IN FUTURE ALPHA CPUS!
214 */
215
216#define	ALPHA_PGSHIFT		13
217#define	ALPHA_PGBYTES		(1 << ALPHA_PGSHIFT)
218
219#define	ALPHA_USEG_BASE		0			/* virtual */
220#define	ALPHA_USEG_END		0x000003ffffffffff
221
222#define	ALPHA_K0SEG_BASE	0xfffffc0000000000	/* direct-mapped */
223#define	ALPHA_K0SEG_END		0xfffffdffffffffff
224#define	ALPHA_K1SEG_BASE	0xfffffe0000000000	/* virtual */
225#define	ALPHA_K1SEG_END		0xffffffffffffffff
226
227#define ALPHA_K0SEG_TO_PHYS(x)	((x) & ~ALPHA_K0SEG_BASE)
228#define ALPHA_PHYS_TO_K0SEG(x)	((x) | ALPHA_K0SEG_BASE)
229
230#define	ALPHA_PTE_VALID			0x0001
231
232#define	ALPHA_PTE_FAULT_ON_READ		0x0002
233#define	ALPHA_PTE_FAULT_ON_WRITE	0x0004
234#define	ALPHA_PTE_FAULT_ON_EXECUTE	0x0008
235
236#define	ALPHA_PTE_ASM			0x0010		/* addr. space match */
237#define	ALPHA_PTE_GRANULARITY		0x0060		/* granularity hint */
238
239#define	ALPHA_PTE_PROT			0xff00
240#define	ALPHA_PTE_KR			0x0100
241#define	ALPHA_PTE_UR			0x0200
242#define	ALPHA_PTE_KW			0x1000
243#define	ALPHA_PTE_UW			0x2000
244
245#define	ALPHA_PTE_WRITE			(ALPHA_PTE_KW | ALPHA_PTE_UW)
246
247#define	ALPHA_PTE_SOFTWARE		0x00000000ffff0000
248#define	ALPHA_PTE_PALCODE		(~ALPHA_PTE_SOFTWARE) /* shorthand */
249
250#define	ALPHA_PTE_PFN			0xffffffff00000000
251
252#define	ALPHA_PTE_TO_PFN(pte)		((pte) >> 32)
253#define	ALPHA_PTE_FROM_PFN(pfn)		((pfn) << 32)
254
255typedef unsigned long alpha_pt_entry_t;
256
257/*
258 * Kernel Entry Vectors.  [OSF/1 PALcode Specific]
259 */
260
261#define	ALPHA_KENTRY_INT	0
262#define	ALPHA_KENTRY_ARITH	1
263#define	ALPHA_KENTRY_MM		2
264#define	ALPHA_KENTRY_IF		3
265#define	ALPHA_KENTRY_UNA	4
266#define	ALPHA_KENTRY_SYS	5
267
268/*
269 * Arithmetic Exception Summary Register.  [OSF/1 PALcode Specific]
270 */
271
272#define	ALPHA_AESR_SWC		__BIT(0)	/* software completion */
273#define	ALPHA_AESR_INV		__BIT(1)	/* invalid operation */
274#define	ALPHA_AESR_DZE		__BIT(2)	/* division by zero */
275#define	ALPHA_AESR_OVF		__BIT(3)	/* overflow */
276#define	ALPHA_AESR_UNF		__BIT(4)	/* underflow */
277#define	ALPHA_AESR_INE		__BIT(5)	/* inexact result */
278#define	ALPHA_AESR_IOV		__BIT(6)	/* integer overflow */
279
280/*
281 * MMCSR Fault Type Codes.  [OSF/1 PALcode Specific]
282 */
283
284#define	ALPHA_MMCSR_INVALTRANS	0
285#define	ALPHA_MMCSR_ACCESS	1
286#define	ALPHA_MMCSR_FOR		2
287#define	ALPHA_MMCSR_FOE		3
288#define	ALPHA_MMCSR_FOW		4
289
290/*
291 * Instruction Fault Type Codes.  [OSF/1 PALcode Specific]
292 */
293
294#define	ALPHA_IF_CODE_BPT	0
295#define	ALPHA_IF_CODE_BUGCHK	1
296#define	ALPHA_IF_CODE_GENTRAP	2
297#define	ALPHA_IF_CODE_FEN	3
298#define	ALPHA_IF_CODE_OPDEC	4
299
300#ifdef _KERNEL
301
302/*
303 * Translation Buffer Invalidation definitions [OSF/1 PALcode Specific]
304 */
305
306#define	ALPHA_TBIA()	alpha_pal_tbi(-2, 0)		/* all TB entries */
307#define	ALPHA_TBIAP()	alpha_pal_tbi(-1, 0)		/* all per-process */
308#define	ALPHA_TBISI(va)	alpha_pal_tbi(1, (va))		/* ITB entry for va */
309#define	ALPHA_TBISD(va)	alpha_pal_tbi(2, (va))		/* DTB entry for va */
310#define	ALPHA_TBIS(va)	alpha_pal_tbi(3, (va))		/* all for va */
311
312#endif /* _KERNEL */
313
314/*
315 * Bits used in the amask instruction [EV56 and later]
316 */
317
318#define	ALPHA_AMASK_BWX		0x0001		/* byte/word extension */
319#define	ALPHA_AMASK_FIX		0x0002		/* floating point conv. ext. */
320#define	ALPHA_AMASK_CIX		0x0004		/* count extension */
321#define	ALPHA_AMASK_MVI		0x0100		/* multimedia extension */
322#define	ALPHA_AMASK_PAT		0x0200		/* precise arith. traps */
323#define	ALPHA_AMASK_PMI		0x1000		/* prefetch w/ modify intent */
324
325#define	ALPHA_AMASK_ALL		(ALPHA_AMASK_BWX|ALPHA_AMASK_FIX|	\
326				 ALPHA_AMASK_CIX|ALPHA_AMASK_MVI|	\
327				 ALPHA_AMASK_PAT|ALPHA_AMASK_PMI)
328
329#define	ALPHA_AMASK_BITS						\
330    "\20\15PMI\12PAT\11MVI\3CIX\2FIX\1BWX"
331
332/*
333 * Chip family IDs returned by implver instruction
334 */
335
336#define	ALPHA_IMPLVER_EV4	0		/* LCA/EV4/EV45 */
337#define	ALPHA_IMPLVER_EV5	1		/* EV5/EV56/PCA56 */
338#define	ALPHA_IMPLVER_EV6	2		/* EV6 */
339#define	ALPHA_IMPLVER_EV7	3		/* EV7/EV79 */
340
341#ifdef _KERNEL
342
343/*
344 * Maximum processor ID we allow from `whami', and related constants.
345 *
346 * XXX This is not really processor or PALcode specific, but this is
347 * a convenient place to put these definitions.
348 *
349 * XXX This is clipped at 63 so that we can use `long's for proc bitmasks.
350 */
351
352#define	ALPHA_WHAMI_MAXID	63
353#define	ALPHA_MAXPROCS		(ALPHA_WHAMI_MAXID + 1)
354
355/*
356 * Misc. support routines.
357 */
358const char	*alpha_dsr_sysname(void);
359
360/*
361 * Stubs for Alpha instructions normally inaccessible from C.
362 */
363unsigned long	alpha_amask(unsigned long);
364unsigned long	alpha_implver(void);
365
366#endif /* _KERNEL */
367
368/* XXX Expose the insn wrappers to userspace, for now. */
369
370static __inline unsigned long
371alpha_rpcc(void)
372{
373	unsigned long v0;
374
375	__asm volatile("rpcc %0" : "=r" (v0));
376	return (v0);
377}
378
379#define	alpha_mb()	__asm volatile("mb" : : : "memory")
380#define	alpha_wmb()	__asm volatile("wmb" : : : "memory")
381
382#if defined(_KERNEL) || defined(_STANDALONE)
383
384/*
385 * Stubs for OSF/1 PALcode operations.
386 */
387#include <machine/pal.h>
388
389void		alpha_pal_cflush(unsigned long);
390void		alpha_pal_halt(void) __attribute__((__noreturn__));
391unsigned long	_alpha_pal_swpipl(unsigned long);	/* for profiling */
392void		alpha_pal_wrent(void *, unsigned long);
393void		alpha_pal_wrvptptr(unsigned long);
394unsigned long	alpha_pal_wtint(unsigned long);
395
396#define	alpha_pal_draina() __asm volatile("call_pal %0 # PAL_draina"	\
397				: : "i" (PAL_draina) : "memory")
398
399#define	alpha_pal_imb()	__asm volatile("call_pal %0 # PAL_imb"	\
400				: : "i" (PAL_imb) : "memory")
401
402static __inline unsigned long
403alpha_pal_rdmces(void)
404{
405	register unsigned long v0 __asm("$0");
406
407	__asm volatile("call_pal %1 # PAL_OSF1_rdmces"
408		: "=r" (v0)
409		: "i" (PAL_OSF1_rdmces)
410		/* clobbers t0, t8..t11 */
411		: "$1", "$22", "$23", "$24", "$25");
412
413	return (v0);
414}
415
416static __inline unsigned long
417alpha_pal_rdps(void)
418{
419	register unsigned long v0 __asm("$0");
420
421	__asm volatile("call_pal %1 # PAL_OSF1_rdps"
422		: "=r" (v0)
423		: "i" (PAL_OSF1_rdps)
424		/* clobbers t0, t8..t11 */
425		: "$1", "$22", "$23", "$24", "$25");
426
427	return (v0);
428}
429
430static __inline unsigned long
431alpha_pal_rdunique(void)
432{
433	register unsigned long v0 __asm("$0");
434
435	__asm volatile("call_pal %1 # PAL_rdunique"
436		: "=r" (v0)
437		: "i" (PAL_rdunique));
438
439	return (v0);
440}
441
442static __inline unsigned long
443alpha_pal_rdusp(void)
444{
445	register unsigned long v0 __asm("$0");
446
447	__asm volatile("call_pal %1 # PAL_OSF1_rdusp"
448		: "=r" (v0)
449		: "i" (PAL_OSF1_rdusp)
450		/* clobbers t0, t8..t11 */
451		: "$1", "$22", "$23", "$24", "$25");
452
453	return (v0);
454}
455
456static __inline __always_inline unsigned long
457alpha_pal_rdval(void)
458{
459	register unsigned long v0 __asm("$0");
460
461	__asm volatile("call_pal %1 # PAL_OSF1_rdval"
462		: "=r" (v0)
463		: "i" (PAL_OSF1_rdval)
464		/* clobbers t0, t8..t11 */
465		: "$1", "$22", "$23", "$24", "$25");
466
467	return (v0);
468}
469
470static __inline unsigned long
471alpha_pal_swpctx(unsigned long ctx)
472{
473	register unsigned long a0 __asm("$16") = ctx;
474	register unsigned long v0 __asm("$0");
475
476	__asm volatile("call_pal %2 # PAL_OSF1_swpctx"
477		: "=r" (a0), "=r" (v0)
478		: "i" (PAL_OSF1_swpctx), "0" (a0)
479		/* clobbers t0, t8..t11, a0 (above) */
480		: "$1", "$22", "$23", "$24", "$25", "memory");
481
482	return (v0);
483}
484
485static __inline unsigned long
486alpha_pal_swpipl(unsigned long ipl)
487{
488	register unsigned long a0 __asm("$16") = ipl;
489	register unsigned long v0 __asm("$0");
490
491	__asm volatile("call_pal %2 # PAL_OSF1_swpipl"
492		: "=r" (a0), "=r" (v0)
493		: "i" (PAL_OSF1_swpipl), "0" (a0)
494		/* clobbers t0, t8..t11, a0 (above) */
495		: "$1", "$22", "$23", "$24", "$25", "memory");
496
497	return (v0);
498}
499
500static __inline void
501alpha_pal_tbi(unsigned long op, vaddr_t va)
502{
503	register unsigned long a0 __asm("$16") = op;
504	register unsigned long a1 __asm("$17") = va;
505
506	__asm volatile("call_pal %2 # PAL_OSF1_tbi"
507		: "=r" (a0), "=r" (a1)
508		: "i" (PAL_OSF1_tbi), "0" (a0), "1" (a1)
509		/* clobbers t0, t8..t11, a0 (above), a1 (above) */
510		: "$1", "$22", "$23", "$24", "$25");
511}
512
513static __inline unsigned long
514alpha_pal_whami(void)
515{
516	register unsigned long v0 __asm("$0");
517
518	__asm volatile("call_pal %1 # PAL_OSF1_whami"
519		: "=r" (v0)
520		: "i" (PAL_OSF1_whami)
521		/* clobbers t0, t8..t11 */
522		: "$1", "$22", "$23", "$24", "$25");
523
524	return (v0);
525}
526
527static __inline void
528alpha_pal_wrfen(unsigned long onoff)
529{
530	register unsigned long a0 __asm("$16") = onoff;
531
532	__asm volatile("call_pal %1 # PAL_OSF1_wrfen"
533		: "=r" (a0)
534		: "i" (PAL_OSF1_wrfen), "0" (a0)
535		/* clobbers t0, t8..t11, a0 (above) */
536		: "$1", "$22", "$23", "$24", "$25");
537}
538
539static __inline void
540alpha_pal_wripir(unsigned long cpu_id)
541{
542	register unsigned long a0 __asm("$16") = cpu_id;
543
544	__asm volatile("call_pal %1 # PAL_ipir"
545		: "=r" (a0)
546		: "i" (PAL_ipir), "0" (a0)
547		/* clobbers t0, t8..t11, a0 (above) */
548		: "$1", "$22", "$23", "$24", "$25");
549}
550
551static __inline void
552alpha_pal_wrunique(unsigned long unique)
553{
554	register unsigned long a0 __asm("$16") = unique;
555
556	__asm volatile("call_pal %1 # PAL_wrunique"
557		: "=r" (a0)
558		: "i" (PAL_wrunique), "0" (a0));
559}
560
561static __inline void
562alpha_pal_wrusp(unsigned long usp)
563{
564	register unsigned long a0 __asm("$16") = usp;
565
566	__asm volatile("call_pal %1 # PAL_OSF1_wrusp"
567		: "=r" (a0)
568		: "i" (PAL_OSF1_wrusp), "0" (a0)
569		/* clobbers t0, t8..t11, a0 (above) */
570		: "$1", "$22", "$23", "$24", "$25");
571}
572
573static __inline void
574alpha_pal_wrmces(unsigned long mces)
575{
576	register unsigned long a0 __asm("$16") = mces;
577
578	__asm volatile("call_pal %1 # PAL_OSF1_wrmces"
579		: "=r" (a0)
580		: "i" (PAL_OSF1_wrmces), "0" (a0)
581		/* clobbers t0, t8..t11 */
582		: "$1", "$22", "$23", "$24", "$25");
583}
584
585static __inline void
586alpha_pal_wrval(unsigned long val)
587{
588	register unsigned long a0 __asm("$16") = val;
589
590	__asm volatile("call_pal %1 # PAL_OSF1_wrval"
591		: "=r" (a0)
592		: "i" (PAL_OSF1_wrval), "0" (a0)
593		/* clobbers t0, t8..t11, a0 (above) */
594		: "$1", "$22", "$23", "$24", "$25");
595}
596
597#endif /* _KERNEL */
598
599#endif /* __ALPHA_ALPHA_CPU_H__ */
600