1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */ 21da177e4SLinus Torvalds/* 31da177e4SLinus Torvalds * EFI call stub. 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * Copyright (C) 1999-2001 Hewlett-Packard Co 61da177e4SLinus Torvalds * David Mosberger <davidm@hpl.hp.com> 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * This stub allows us to make EFI calls in physical mode with interrupts 91da177e4SLinus Torvalds * turned off. We need this because we can't call SetVirtualMap() until 10*5673a60bSChen Li * the kernel has booted far enough to allow allocation of struct vm_area_struct 111da177e4SLinus Torvalds * entries (which we would need to map stuff with memory attributes other 121da177e4SLinus Torvalds * than uncached or writeback...). Since the GetTime() service gets called 131da177e4SLinus Torvalds * earlier than that, we need to be able to make physical mode EFI calls from 141da177e4SLinus Torvalds * the kernel. 151da177e4SLinus Torvalds */ 161da177e4SLinus Torvalds 171da177e4SLinus Torvalds/* 181da177e4SLinus Torvalds * PSR settings as per SAL spec (Chapter 8 in the "IA-64 System 191da177e4SLinus Torvalds * Abstraction Layer Specification", revision 2.6e). Note that 201da177e4SLinus Torvalds * psr.dfl and psr.dfh MUST be cleared, despite what this manual says. 211da177e4SLinus Torvalds * Otherwise, SAL dies whenever it's trying to do an IA-32 BIOS call 221da177e4SLinus Torvalds * (the br.ia instruction fails unless psr.dfl and psr.dfh are 231da177e4SLinus Torvalds * cleared). Fortunately, SAL promises not to touch the floating 241da177e4SLinus Torvalds * point regs, so at least we don't have to save f2-f127. 251da177e4SLinus Torvalds */ 261da177e4SLinus Torvalds#define PSR_BITS_TO_CLEAR \ 271da177e4SLinus Torvalds (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT | \ 281da177e4SLinus Torvalds IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \ 291da177e4SLinus Torvalds IA64_PSR_DFL | IA64_PSR_DFH) 301da177e4SLinus Torvalds 311da177e4SLinus Torvalds#define PSR_BITS_TO_SET \ 321da177e4SLinus Torvalds (IA64_PSR_BN) 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds#include <asm/processor.h> 351da177e4SLinus Torvalds#include <asm/asmmacro.h> 361da177e4SLinus Torvalds 371da177e4SLinus Torvalds/* 381da177e4SLinus Torvalds * Inputs: 391da177e4SLinus Torvalds * in0 = address of function descriptor of EFI routine to call 401da177e4SLinus Torvalds * in1..in7 = arguments to routine 411da177e4SLinus Torvalds * 421da177e4SLinus Torvalds * Outputs: 431da177e4SLinus Torvalds * r8 = EFI_STATUS returned by called function 441da177e4SLinus Torvalds */ 451da177e4SLinus Torvalds 461da177e4SLinus TorvaldsGLOBAL_ENTRY(efi_call_phys) 471da177e4SLinus Torvalds .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) 481da177e4SLinus Torvalds alloc loc1=ar.pfs,8,7,7,0 491da177e4SLinus Torvalds ld8 r2=[in0],8 // load EFI function's entry point 501da177e4SLinus Torvalds mov loc0=rp 511da177e4SLinus Torvalds .body 521da177e4SLinus Torvalds ;; 531da177e4SLinus Torvalds mov loc2=gp // save global pointer 541da177e4SLinus Torvalds mov loc4=ar.rsc // save RSE configuration 551da177e4SLinus Torvalds mov ar.rsc=0 // put RSE in enforced lazy, LE mode 561da177e4SLinus Torvalds ;; 571da177e4SLinus Torvalds ld8 gp=[in0] // load EFI function's global pointer 581da177e4SLinus Torvalds movl r16=PSR_BITS_TO_CLEAR 591da177e4SLinus Torvalds mov loc3=psr // save processor status word 601da177e4SLinus Torvalds movl r17=PSR_BITS_TO_SET 611da177e4SLinus Torvalds ;; 621da177e4SLinus Torvalds or loc3=loc3,r17 631da177e4SLinus Torvalds mov b6=r2 641da177e4SLinus Torvalds ;; 651da177e4SLinus Torvalds andcm r16=loc3,r16 // get psr with IT, DT, and RT bits cleared 661da177e4SLinus Torvalds br.call.sptk.many rp=ia64_switch_mode_phys 671da177e4SLinus Torvalds.ret0: mov out4=in5 681da177e4SLinus Torvalds mov out0=in1 691da177e4SLinus Torvalds mov out1=in2 701da177e4SLinus Torvalds mov out2=in3 711da177e4SLinus Torvalds mov out3=in4 721da177e4SLinus Torvalds mov out5=in6 731da177e4SLinus Torvalds mov out6=in7 741da177e4SLinus Torvalds mov loc5=r19 751da177e4SLinus Torvalds mov loc6=r20 761da177e4SLinus Torvalds br.call.sptk.many rp=b6 // call the EFI function 771da177e4SLinus Torvalds.ret1: mov ar.rsc=0 // put RSE in enforced lazy, LE mode 781da177e4SLinus Torvalds mov r16=loc3 791da177e4SLinus Torvalds mov r19=loc5 801da177e4SLinus Torvalds mov r20=loc6 811da177e4SLinus Torvalds br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode 821da177e4SLinus Torvalds.ret2: mov ar.rsc=loc4 // restore RSE configuration 831da177e4SLinus Torvalds mov ar.pfs=loc1 841da177e4SLinus Torvalds mov rp=loc0 851da177e4SLinus Torvalds mov gp=loc2 861da177e4SLinus Torvalds br.ret.sptk.many rp 871da177e4SLinus TorvaldsEND(efi_call_phys) 88