/* SPDX-License-Identifier: GPL-2.0 */
/*
 * PAL Firmware support
 * IA-64 Processor Programmers Reference Vol 2
 *
 * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
 * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
 * Copyright (C) 1999-2001, 2003 Hewlett-Packard Co
 *	David Mosberger <davidm@hpl.hp.com>
 *	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 <linux/export.h>
#include <asm/asmmacro.h>
#include <asm/processor.h>

	.data
pal_entry_point:
	data8 ia64_pal_default_handler
	.text

/*
 * Set the PAL entry point address.  This could be written in C code, but we
 * do it here to keep it all in one module (besides, it's so trivial that it's
 * not a big deal).
 *
 * in0		Address of the PAL entry point (text address, NOT a function
 *		descriptor).
 */
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.many rp
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").
 */
GLOBAL_ENTRY(ia64_pal_default_handler)
	mov r8=-1
	br.cond.sptk.many rp
END(ia64_pal_default_handler)

/*
 * Make a PAL call using the static calling convention.
 *
 * in0         Index of PAL service
 * in1 - in3   Remaining PAL arguments
 */
GLOBAL_ENTRY(ia64_pal_call_static)
	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
	alloc loc1 = ar.pfs,4,5,0,0
	movl loc2 = pal_entry_point
1:	{
	  mov r28 = in0
	  mov r29 = in1
	  mov r8 = ip
	}
	;;
	ld8 loc2 = [loc2]		// loc2 <- entry point
	adds r8 = 1f-1b,r8
	mov loc4=ar.rsc			// save RSE configuration
	;;
	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
	mov loc3 = psr
	mov loc0 = rp
	.body
	mov r30 = in2

	mov r31 = in3
	mov b7 = loc2

	rsm psr.i
	;;
	mov rp = r8
	br.cond.sptk.many b7
1:	mov psr.l = loc3
	mov ar.rsc = loc4		// restore RSE configuration
	mov ar.pfs = loc1
	mov rp = loc0
	;;
	srlz.d				// serialize restoration of psr.l
	br.ret.sptk.many b0
END(ia64_pal_call_static)
EXPORT_SYMBOL(ia64_pal_call_static)

/*
 * Make a PAL call using the stacked registers calling convention.
 *
 * Inputs:
 *	in0         Index of PAL service
 *	in2 - in3   Remaining PAL arguments
 */
GLOBAL_ENTRY(ia64_pal_call_stacked)
	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
	alloc loc1 = ar.pfs,4,4,4,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
	.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
.ret0:	mov psr.l  = loc3
	mov ar.pfs = loc1
	mov rp = loc0
	;;
	srlz.d				// serialize restoration of psr.l
	br.ret.sptk.many b0
END(ia64_pal_call_stacked)
EXPORT_SYMBOL(ia64_pal_call_stacked)

/*
 * Make a physical mode PAL call using the static registers calling convention.
 *
 * Inputs:
 *	in0         Index of PAL service
 *	in2 - in3   Remaining PAL arguments
 *
 * 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_DB | 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)


GLOBAL_ENTRY(ia64_pal_call_phys_static)
	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
	alloc loc1 = ar.pfs,4,7,0,0
	movl loc2 = pal_entry_point
1:	{
	  mov r28  = in0		// copy procedure index
	  mov r8   = ip			// save ip to compute branch
	  mov loc0 = rp			// save rp
	}
	.body
	;;
	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  = 1f-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
	tpa r8=r8			// convert rp to physical
	;;
	mov b7 = loc2			// install target to branch reg
	mov ar.rsc=0			// 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.many rp=ia64_switch_mode_phys
	mov rp = r8			// install return address (physical)
	mov loc5 = r19
	mov loc6 = r20
	br.cond.sptk.many b7
1:
	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
	mov r16=loc3			// r16= original psr
	mov r19=loc5
	mov r20=loc6
	br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
	mov psr.l = loc3		// restore init PSR

	mov ar.pfs = loc1
	mov rp = loc0
	;;
	mov ar.rsc=loc4			// restore RSE configuration
	srlz.d				// serialize restoration of psr.l
	br.ret.sptk.many b0
END(ia64_pal_call_phys_static)
EXPORT_SYMBOL(ia64_pal_call_phys_static)

/*
 * Make a PAL call using the stacked registers in physical mode.
 *
 * Inputs:
 *	in0         Index of PAL service
 *	in2 - in3   Remaining PAL arguments
 */
GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
	alloc	loc1 = ar.pfs,5,7,4,0
	movl	loc2 = pal_entry_point
1:	{
	  mov r28  = in0		// copy procedure index
	  mov loc0 = rp			// save rp
	}
	.body
	;;
	ld8 loc2 = [loc2]		// loc2 <- entry point
	mov loc3 = psr			// save psr
	;;
	mov loc4=ar.rsc			// save RSE configuration
	dep.z loc2=loc2,0,61		// convert pal entry point to physical
	;;
	mov ar.rsc=0			// 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
	mov b7 = loc2			// install target to branch reg
	;;
	andcm r16=loc3,r16		// removes bits to clear from psr
	br.call.sptk.many rp=ia64_switch_mode_phys

	mov out0 = in0			// first argument
	mov out1 = in1			// copy arg2
	mov out2 = in2			// copy arg3
	mov out3 = in3			// copy arg3
	mov loc5 = r19
	mov loc6 = r20

	br.call.sptk.many rp=b7		// now make the call

	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
	mov r16=loc3			// r16= original psr
	mov r19=loc5
	mov r20=loc6
	br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode

	mov psr.l  = loc3		// restore init PSR
	mov ar.pfs = loc1
	mov rp = loc0
	;;
	mov ar.rsc=loc4			// restore RSE configuration
	srlz.d				// serialize restoration of psr.l
	br.ret.sptk.many b0
END(ia64_pal_call_phys_stacked)
EXPORT_SYMBOL(ia64_pal_call_phys_stacked)

/*
 * Save scratch fp scratch regs which aren't saved in pt_regs already
 * (fp10-fp15).
 *
 * NOTE: We need to do this since firmware (SAL and PAL) may use any of the
 * scratch regs fp-low partition.
 *
 * Inputs:
 *      in0	Address of stack storage for fp regs
 */
GLOBAL_ENTRY(ia64_save_scratch_fpregs)
	alloc r3=ar.pfs,1,0,0,0
	add r2=16,in0
	;;
	stf.spill [in0] = f10,32
	stf.spill [r2]  = f11,32
	;;
	stf.spill [in0] = f12,32
	stf.spill [r2]  = f13,32
	;;
	stf.spill [in0] = f14,32
	stf.spill [r2]  = f15,32
	br.ret.sptk.many rp
END(ia64_save_scratch_fpregs)
EXPORT_SYMBOL(ia64_save_scratch_fpregs)

/*
 * Load scratch fp scratch regs (fp10-fp15)
 *
 * Inputs:
 *      in0	Address of stack storage for fp regs
 */
GLOBAL_ENTRY(ia64_load_scratch_fpregs)
	alloc r3=ar.pfs,1,0,0,0
	add r2=16,in0
	;;
	ldf.fill  f10 = [in0],32
	ldf.fill  f11 = [r2],32
	;;
	ldf.fill  f12 = [in0],32
	ldf.fill  f13 = [r2],32
	;;
	ldf.fill  f14 = [in0],32
	ldf.fill  f15 = [r2],32
	br.ret.sptk.many rp
END(ia64_load_scratch_fpregs)
EXPORT_SYMBOL(ia64_load_scratch_fpregs)
