^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * PAL Firmware support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * IA-64 Processor Programmers Reference Vol 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 1999-2001, 2003 Hewlett-Packard Co
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * David Mosberger <davidm@hpl.hp.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Stephane Eranian <eranian@hpl.hp.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * 05/22/2000 eranian Added support for stacked register calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * 05/24/2000 eranian Added support for physical mode static calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/asmmacro.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) .data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) pal_entry_point:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) data8 ia64_pal_default_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Set the PAL entry point address. This could be written in C code, but we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * do it here to keep it all in one module (besides, it's so trivial that it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * not a big deal).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * in0 Address of the PAL entry point (text address, NOT a function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * descriptor).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) GLOBAL_ENTRY(ia64_pal_handler_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) alloc r3=ar.pfs,1,0,0,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) movl r2=pal_entry_point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) st8 [r2]=in0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) br.ret.sptk.many rp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) END(ia64_pal_handler_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * Default PAL call handler. This needs to be coded in assembly because it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * uses the static calling convention, i.e., the RSE may not be used and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * calls are done via "br.cond" (not "br.call").
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) GLOBAL_ENTRY(ia64_pal_default_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) mov r8=-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) br.cond.sptk.many rp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) END(ia64_pal_default_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Make a PAL call using the static calling convention.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * in0 Index of PAL service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * in1 - in3 Remaining PAL arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) GLOBAL_ENTRY(ia64_pal_call_static)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) alloc loc1 = ar.pfs,4,5,0,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) movl loc2 = pal_entry_point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 1: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) mov r28 = in0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) mov r29 = in1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) mov r8 = ip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) ld8 loc2 = [loc2] // loc2 <- entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) adds r8 = 1f-1b,r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) mov loc4=ar.rsc // save RSE configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) mov ar.rsc=0 // put RSE in enforced lazy, LE mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) mov loc3 = psr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) mov loc0 = rp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .body
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) mov r30 = in2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) mov r31 = in3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) mov b7 = loc2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) rsm psr.i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) mov rp = r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) br.cond.sptk.many b7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) 1: mov psr.l = loc3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) mov ar.rsc = loc4 // restore RSE configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) mov ar.pfs = loc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) mov rp = loc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) srlz.d // seralize restoration of psr.l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) br.ret.sptk.many b0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) END(ia64_pal_call_static)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) EXPORT_SYMBOL(ia64_pal_call_static)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * Make a PAL call using the stacked registers calling convention.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * Inputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * in0 Index of PAL service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * in2 - in3 Remaining PAL arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) GLOBAL_ENTRY(ia64_pal_call_stacked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) alloc loc1 = ar.pfs,4,4,4,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) movl loc2 = pal_entry_point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) mov r28 = in0 // Index MUST be copied to r28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) mov out0 = in0 // AND in0 of PAL function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) mov loc0 = rp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .body
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ld8 loc2 = [loc2] // loc2 <- entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) mov out1 = in1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) mov out2 = in2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) mov out3 = in3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) mov loc3 = psr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) rsm psr.i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) mov b7 = loc2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) br.call.sptk.many rp=b7 // now make the call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .ret0: mov psr.l = loc3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) mov ar.pfs = loc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) mov rp = loc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) srlz.d // serialize restoration of psr.l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) br.ret.sptk.many b0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) END(ia64_pal_call_stacked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) EXPORT_SYMBOL(ia64_pal_call_stacked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * Make a physical mode PAL call using the static registers calling convention.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Inputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * in0 Index of PAL service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * in2 - in3 Remaining PAL arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * So we don't need to clear them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define PAL_PSR_BITS_TO_CLEAR \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_DB | IA64_PSR_RT |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) IA64_PSR_DFL | IA64_PSR_DFH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define PAL_PSR_BITS_TO_SET \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) (IA64_PSR_BN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) GLOBAL_ENTRY(ia64_pal_call_phys_static)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) alloc loc1 = ar.pfs,4,7,0,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) movl loc2 = pal_entry_point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 1: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) mov r28 = in0 // copy procedure index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) mov r8 = ip // save ip to compute branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) mov loc0 = rp // save rp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .body
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ld8 loc2 = [loc2] // loc2 <- entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) mov r29 = in1 // first argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) mov r30 = in2 // copy arg2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) mov r31 = in3 // copy arg3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) mov loc3 = psr // save psr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) adds r8 = 1f-1b,r8 // calculate return address for call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) mov loc4=ar.rsc // save RSE configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) dep.z loc2=loc2,0,61 // convert pal entry point to physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) tpa r8=r8 // convert rp to physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) mov b7 = loc2 // install target to branch reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) mov ar.rsc=0 // put RSE in enforced lazy, LE mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) movl r16=PAL_PSR_BITS_TO_CLEAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) movl r17=PAL_PSR_BITS_TO_SET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) or loc3=loc3,r17 // add in psr the bits to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) andcm r16=loc3,r16 // removes bits to clear from psr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) br.call.sptk.many rp=ia64_switch_mode_phys
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) mov rp = r8 // install return address (physical)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) mov loc5 = r19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) mov loc6 = r20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) br.cond.sptk.many b7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) mov ar.rsc=0 // put RSE in enforced lazy, LE mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) mov r16=loc3 // r16= original psr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) mov r19=loc5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) mov r20=loc6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) mov psr.l = loc3 // restore init PSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) mov ar.pfs = loc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) mov rp = loc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) mov ar.rsc=loc4 // restore RSE configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) srlz.d // seralize restoration of psr.l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) br.ret.sptk.many b0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) END(ia64_pal_call_phys_static)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) EXPORT_SYMBOL(ia64_pal_call_phys_static)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * Make a PAL call using the stacked registers in physical mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * Inputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * in0 Index of PAL service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * in2 - in3 Remaining PAL arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) alloc loc1 = ar.pfs,5,7,4,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) movl loc2 = pal_entry_point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 1: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) mov r28 = in0 // copy procedure index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) mov loc0 = rp // save rp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .body
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ld8 loc2 = [loc2] // loc2 <- entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) mov loc3 = psr // save psr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) mov loc4=ar.rsc // save RSE configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) dep.z loc2=loc2,0,61 // convert pal entry point to physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) mov ar.rsc=0 // put RSE in enforced lazy, LE mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) movl r16=PAL_PSR_BITS_TO_CLEAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) movl r17=PAL_PSR_BITS_TO_SET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) or loc3=loc3,r17 // add in psr the bits to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) mov b7 = loc2 // install target to branch reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) andcm r16=loc3,r16 // removes bits to clear from psr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) br.call.sptk.many rp=ia64_switch_mode_phys
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) mov out0 = in0 // first argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) mov out1 = in1 // copy arg2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) mov out2 = in2 // copy arg3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) mov out3 = in3 // copy arg3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) mov loc5 = r19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) mov loc6 = r20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) br.call.sptk.many rp=b7 // now make the call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) mov ar.rsc=0 // put RSE in enforced lazy, LE mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) mov r16=loc3 // r16= original psr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) mov r19=loc5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) mov r20=loc6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) mov psr.l = loc3 // restore init PSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) mov ar.pfs = loc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) mov rp = loc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) mov ar.rsc=loc4 // restore RSE configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) srlz.d // seralize restoration of psr.l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) br.ret.sptk.many b0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) END(ia64_pal_call_phys_stacked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) EXPORT_SYMBOL(ia64_pal_call_phys_stacked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * Save scratch fp scratch regs which aren't saved in pt_regs already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * (fp10-fp15).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * NOTE: We need to do this since firmware (SAL and PAL) may use any of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * scratch regs fp-low partition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * Inputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * in0 Address of stack storage for fp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) GLOBAL_ENTRY(ia64_save_scratch_fpregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) alloc r3=ar.pfs,1,0,0,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) add r2=16,in0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) stf.spill [in0] = f10,32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) stf.spill [r2] = f11,32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) stf.spill [in0] = f12,32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) stf.spill [r2] = f13,32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) stf.spill [in0] = f14,32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) stf.spill [r2] = f15,32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) br.ret.sptk.many rp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) END(ia64_save_scratch_fpregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) EXPORT_SYMBOL(ia64_save_scratch_fpregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * Load scratch fp scratch regs (fp10-fp15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * Inputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * in0 Address of stack storage for fp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) GLOBAL_ENTRY(ia64_load_scratch_fpregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) alloc r3=ar.pfs,1,0,0,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) add r2=16,in0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ldf.fill f10 = [in0],32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ldf.fill f11 = [r2],32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) ldf.fill f12 = [in0],32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) ldf.fill f13 = [r2],32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ldf.fill f14 = [in0],32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ldf.fill f15 = [r2],32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) br.ret.sptk.many rp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) END(ia64_load_scratch_fpregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) EXPORT_SYMBOL(ia64_load_scratch_fpregs)