efi_stub.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * EFI call stub.
  3.  *
  4.  * Copyright (C) 1999-2001 Hewlett-Packard Co
  5.  * David Mosberger <davidm@hpl.hp.com>
  6.  *
  7.  * This stub allows us to make EFI calls in physical mode with interrupts
  8.  * turned off.  We need this because we can't call SetVirtualMap() until
  9.  * the kernel has booted far enough to allow allocation of struct vma_struct
  10.  * entries (which we would need to map stuff with memory attributes other
  11.  * than uncached or writeback...).  Since the GetTime() service gets called
  12.  * earlier than that, we need to be able to make physical mode EFI calls from
  13.  * the kernel.
  14.  */
  15. /*
  16.  * PSR settings as per SAL spec (Chapter 8 in the "IA-64 System
  17.  * Abstraction Layer Specification", revision 2.6e).  Note that
  18.  * psr.dfl and psr.dfh MUST be cleared, despite what this manual says.
  19.  * Otherwise, SAL dies whenever it's trying to do an IA-32 BIOS call
  20.  * (the br.ia instruction fails unless psr.dfl and psr.dfh are
  21.  * cleared).  Fortunately, SAL promises not to touch the floating
  22.  * point regs, so at least we don't have to save f2-f127.
  23.  */
  24. #define PSR_BITS_TO_CLEAR
  25. (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT |
  26.  IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED |
  27.  IA64_PSR_DFL | IA64_PSR_DFH)
  28. #define PSR_BITS_TO_SET
  29. (IA64_PSR_BN)
  30. #include <asm/processor.h>
  31. #include <asm/asmmacro.h>
  32. /*
  33.  * Inputs:
  34.  * in0 = address of function descriptor of EFI routine to call
  35.  * in1..in7 = arguments to routine
  36.  *
  37.  * Outputs:
  38.  * r8 = EFI_STATUS returned by called function
  39.  */
  40. GLOBAL_ENTRY(efi_call_phys)
  41. .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
  42. alloc loc1=ar.pfs,8,5,7,0
  43. ld8 r2=[in0],8 // load EFI function's entry point
  44. mov loc0=rp
  45. .body
  46. ;;
  47. mov loc2=gp // save global pointer
  48. mov loc4=ar.rsc // save RSE configuration
  49. mov ar.rsc=0 // put RSE in enforced lazy, LE mode
  50. ;;
  51. ld8 gp=[in0] // load EFI function's global pointer
  52. mov out0=in1
  53. mov out1=in2
  54. movl r16=PSR_BITS_TO_CLEAR
  55. mov loc3=psr // save processor status word
  56. movl r17=PSR_BITS_TO_SET
  57. ;;
  58. mov out2=in3
  59. or loc3=loc3,r17
  60. mov b6=r2
  61. ;;
  62. andcm r16=loc3,r16 // get psr with IT, DT, and RT bits cleared
  63. mov out3=in4
  64. br.call.sptk.many rp=ia64_switch_mode
  65. .ret0: mov out4=in5
  66. mov out5=in6
  67. mov out6=in7
  68. br.call.sptk.many rp=b6 // call the EFI function
  69. .ret1: mov ar.rsc=0 // put RSE in enforced lazy, LE mode
  70. mov r16=loc3
  71. br.call.sptk.many rp=ia64_switch_mode // return to virtual mode
  72. .ret2: mov ar.rsc=loc4 // restore RSE configuration
  73. mov ar.pfs=loc1
  74. mov rp=loc0
  75. mov gp=loc2
  76. br.ret.sptk.many rp
  77. END(efi_call_phys)