patch-2.4.0-test2 linux/arch/ia64/kernel/pal.S

Next file: linux/arch/ia64/kernel/palinfo.c
Previous file: linux/arch/ia64/kernel/minstate.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test1/linux/arch/ia64/kernel/pal.S linux/arch/ia64/kernel/pal.S
@@ -4,9 +4,16 @@
  *
  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999 David Mosberger <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2000 David Mosberger <davidm@hpl.hp.com>
+ * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com>
+ *
+ * 05/22/2000 eranian Added support for stacked register calls
+ * 05/24/2000 eranian Added support for physical mode static calls
  */
 
+#include <asm/asmmacro.h>
+#include <asm/processor.h>
+
 	.text
 	.psr abi64
 	.psr lsb
@@ -24,29 +31,23 @@
  *
  * in0		Address of the PAL entry point (text address, NOT a function descriptor).
  */
-	.align 16
-	.global ia64_pal_handler_init
-	.proc ia64_pal_handler_init
-ia64_pal_handler_init:
+GLOBAL_ENTRY(ia64_pal_handler_init)
 	alloc r3=ar.pfs,1,0,0,0
 	movl r2=pal_entry_point
 	;;
 	st8 [r2]=in0
 	br.ret.sptk.few rp
-	
-	.endp ia64_pal_handler_init	
+END(ia64_pal_handler_init)
 
 /*
  * Default PAL call handler.  This needs to be coded in assembly because it uses
  * the static calling convention, i.e., the RSE may not be used and calls are
  * done via "br.cond" (not "br.call").
  */
-	.align 16
-	.global ia64_pal_default_handler
-	.proc ia64_pal_default_handler
-ia64_pal_default_handler:
+GLOBAL_ENTRY(ia64_pal_default_handler)
 	mov r8=-1
 	br.cond.sptk.few rp
+END(ia64_pal_default_handler)
 
 /*
  * Make a PAL call using the static calling convention.
@@ -56,64 +57,139 @@
  * in2 - in4   Remaning PAL arguments
  *
  */
+GLOBAL_ENTRY(ia64_pal_call_static)
+	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6))
+	alloc loc1 = ar.pfs,6,90,0,0
+	movl loc2 = pal_entry_point
+1:	{
+	  mov r28 = in0
+	  mov r29 = in1
+	  mov r8 = ip
+	}
+	;;
+	ld8 loc2 = [loc2]		// loc2 <- entry point
+	mov r30 = in2
+	mov r31 = in3
+	;;
+	mov loc3 = psr
+	mov loc0 = rp
+	UNW(.body)
+	adds r8 = .ret0-1b,r8
+	;; 
+	rsm psr.i
+	mov b7 = loc2
+	mov rp = r8
+	;; 
+	br.cond.sptk.few b7
+.ret0:	mov psr.l = loc3
+	mov ar.pfs = loc1
+	mov rp = loc0
+	;;
+	srlz.d				// seralize restoration of psr.l
+	br.ret.sptk.few	b0
+END(ia64_pal_call_static)
 
-#ifdef __GCC_MULTIREG_RETVALS__
-# define arg0	in0
-# define arg1	in1
-# define arg2	in2
-# define arg3	in3
-# define arg4	in4
-#else
-# define arg0	in1
-# define arg1	in2
-# define arg2	in3
-# define arg3	in4
-# define arg4	in5
-#endif
+/*
+ * Make a PAL call using the stacked registers calling convention.
+ *
+ * Inputs:
+ * 	in0         Index of PAL service
+ * 	in2 - in3   Remaning PAL arguments
+ */
+GLOBAL_ENTRY(ia64_pal_call_stacked)
+	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5))
+	alloc loc1 = ar.pfs,5,4,87,0
+	movl loc2 = pal_entry_point
+
+	mov r28  = in0			// Index MUST be copied to r28
+	mov out0 = in0			// AND in0 of PAL function
+	mov loc0 = rp
+	UNW(.body)
+	;;
+	ld8 loc2 = [loc2]		// loc2 <- entry point
+	mov out1 = in1
+	mov out2 = in2
+	mov out3 = in3
+	mov loc3 = psr
+	;;
+	rsm psr.i
+	mov b7 = loc2
+	;; 
+	br.call.sptk.many rp=b7		// now make the call
+.ret2:
+	mov psr.l  = loc3
+	mov ar.pfs = loc1
+	mov rp = loc0
+	;;
+	srlz.d				// serialize restoration of psr.l
+	br.ret.sptk.few	b0
+END(ia64_pal_call_stacked)
 
-	.text
-	.psr abi64
-	.psr lsb
-	.lsb
+/*
+ * Make a physical mode PAL call using the static registers calling convention.
+ *
+ * Inputs:
+ * 	in0         Index of PAL service
+ * 	in2 - in3   Remaning PAL arguments
+ *
+ * PSR_DB, PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel.
+ * So we don't need to clear them.
+ */
+#define PAL_PSR_BITS_TO_CLEAR						\
+	(IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT |		\
+	 IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED |	\
+	 IA64_PSR_DFL | IA64_PSR_DFH)
+
+#define PAL_PSR_BITS_TO_SET						\
+	(IA64_PSR_BN)
 
-	.align 16
-	.global	ia64_pal_call_static
-	.proc ia64_pal_call_static
-ia64_pal_call_static:
-	alloc	loc0 = ar.pfs,6,90,0,0
-	movl	loc2 = pal_entry_point
+
+GLOBAL_ENTRY(ia64_pal_call_phys_static)
+	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6))
+	alloc loc1 = ar.pfs,6,90,0,0
+	movl loc2 = pal_entry_point
 1:	{
-	  mov	r28 = arg0
-	  mov	r29 = arg1
-	  mov	r8 = ip
+	  mov r28  = in0		// copy procedure index
+	  mov r8   = ip			// save ip to compute branch
+	  mov loc0 = rp			// save rp
 	}
+	UNW(.body)
 	;;
-	ld8	loc2 = [loc2]		// loc2 <- entry point
-	mov	r30 = arg2
-	mov	r31 = arg3
-	;;
-	mov	loc3 = psr
-	mov	loc1 = rp
-	adds	r8 = .ret0-1b,r8
-	;; 
-	rsm	psr.i
-	mov	b7 = loc2
-	mov	rp = r8
+	ld8 loc2 = [loc2]		// loc2 <- entry point
+	mov r29  = in1			// first argument
+	mov r30  = in2			// copy arg2
+	mov r31  = in3			// copy arg3
+	;;
+	mov loc3 = psr			// save psr
+	adds r8   = .ret4-1b,r8		// calculate return address for call
 	;; 
+	mov loc4=ar.rsc			// save RSE configuration
+	dep.z loc2=loc2,0,61		// convert pal entry point to physical
+	dep.z r8=r8,0,61		// convert rp to physical
+	;;
+	mov b7 = loc2			// install target to branch reg
+	mov ar.rsc=r0			// put RSE in enforced lazy, LE mode
+	movl r16=PAL_PSR_BITS_TO_CLEAR
+	movl r17=PAL_PSR_BITS_TO_SET
+	;;
+	or loc3=loc3,r17		// add in psr the bits to set
+	;;
+	andcm r16=loc3,r16		// removes bits to clear from psr
+	br.call.sptk.few rp=ia64_switch_mode
+.ret3:
+	mov rp = r8			// install return address (physical)
 	br.cond.sptk.few b7
-.ret0:	mov	psr.l = loc3
-#ifndef __GCC_MULTIREG_RETVALS__
-	st8	[in0] = r8, 8
-	;;
-	st8	[in0] = r9, 8 
-	;;
-	st8	[in0] = r10, 8
-	;;
-	st8	[in0] = r11, 8
-#endif
-	mov	ar.pfs = loc0
-	mov	rp = loc1
+.ret4:
+	mov ar.rsc=r0			// put RSE in enforced lazy, LE mode
+	mov r16=loc3			// r16= original psr
+	br.call.sptk.few rp=ia64_switch_mode // return to virtual mode
+
+.ret5:	mov psr.l = loc3		// restore init PSR
+
+	mov ar.pfs = loc1
+	mov rp = loc0
 	;;
+	mov ar.rsc=loc4			// restore RSE configuration
 	srlz.d				// seralize restoration of psr.l
 	br.ret.sptk.few	b0
-	.endp ia64_pal_call_static
+END(ia64_pal_call_phys_static)

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)