efi_stub_32.S 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * EFI call stub for IA32.
  4. *
  5. * This stub allows us to make EFI calls in physical mode with interrupts
  6. * turned off.
  7. */
  8. #include <linux/linkage.h>
  9. #include <linux/init.h>
  10. #include <asm/asm-offsets.h>
  11. #include <asm/page_types.h>
  12. __INIT
  13. SYM_FUNC_START(efi_call_svam)
  14. push %ebp
  15. movl %esp, %ebp
  16. push %ebx
  17. push 16(%esp)
  18. push 16(%esp)
  19. push %ecx
  20. push %edx
  21. movl %eax, %ebx // &systab_phys->runtime
  22. /*
  23. * Switch to the flat mapped alias of this routine, by jumping to the
  24. * address of label '1' after subtracting PAGE_OFFSET from it.
  25. */
  26. movl $1f, %edx
  27. subl $__PAGE_OFFSET, %edx
  28. jmp *%edx
  29. 1:
  30. /* disable paging */
  31. movl %cr0, %edx
  32. andl $0x7fffffff, %edx
  33. movl %edx, %cr0
  34. /* convert the stack pointer to a flat mapped address */
  35. subl $__PAGE_OFFSET, %esp
  36. /* call the EFI routine */
  37. movl (%eax), %eax
  38. call *EFI_svam(%eax)
  39. /* grab the virtually remapped EFI runtime services table pointer */
  40. movl (%ebx), %ecx
  41. movl 36(%esp), %edx // &efi.runtime
  42. movl %ecx, (%edx)
  43. /* re-enable paging */
  44. movl %cr0, %edx
  45. orl $0x80000000, %edx
  46. movl %edx, %cr0
  47. movl 16(%esp), %ebx
  48. leave
  49. RET
  50. SYM_FUNC_END(efi_call_svam)