efi-entry.S 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. * EFI entry point.
  3. *
  4. * Copyright (C) 2013, 2014 Red Hat, Inc.
  5. * Author: Mark Salter <msalter@redhat.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. *
  11. */
  12. #include <linux/linkage.h>
  13. #include <linux/init.h>
  14. #include <asm/assembler.h>
  15. #define EFI_LOAD_ERROR 0x8000000000000001
  16. __INIT
  17. /*
  18. * We arrive here from the EFI boot manager with:
  19. *
  20. * * CPU in little-endian mode
  21. * * MMU on with identity-mapped RAM
  22. * * Icache and Dcache on
  23. *
  24. * We will most likely be running from some place other than where
  25. * we want to be. The kernel image wants to be placed at TEXT_OFFSET
  26. * from start of RAM.
  27. */
  28. ENTRY(efi_stub_entry)
  29. /*
  30. * Create a stack frame to save FP/LR with extra space
  31. * for image_addr variable passed to efi_entry().
  32. */
  33. stp x29, x30, [sp, #-32]!
  34. /*
  35. * Call efi_entry to do the real work.
  36. * x0 and x1 are already set up by firmware. Current runtime
  37. * address of image is calculated and passed via *image_addr.
  38. *
  39. * unsigned long efi_entry(void *handle,
  40. * efi_system_table_t *sys_table,
  41. * unsigned long *image_addr) ;
  42. */
  43. adrp x8, _text
  44. add x8, x8, #:lo12:_text
  45. add x2, sp, 16
  46. str x8, [x2]
  47. bl efi_entry
  48. cmn x0, #1
  49. b.eq efi_load_fail
  50. /*
  51. * efi_entry() will have copied the kernel image if necessary and we
  52. * return here with device tree address in x0 and the kernel entry
  53. * point stored at *image_addr. Save those values in registers which
  54. * are callee preserved.
  55. */
  56. mov x20, x0 // DTB address
  57. ldr x0, [sp, #16] // relocated _text address
  58. ldr x21, =stext_offset
  59. add x21, x0, x21
  60. /*
  61. * Calculate size of the kernel Image (same for original and copy).
  62. */
  63. adrp x1, _text
  64. add x1, x1, #:lo12:_text
  65. adrp x2, _edata
  66. add x2, x2, #:lo12:_edata
  67. sub x1, x2, x1
  68. /*
  69. * Flush the copied Image to the PoC, and ensure it is not shadowed by
  70. * stale icache entries from before relocation.
  71. */
  72. bl __flush_dcache_area
  73. ic ialluis
  74. /*
  75. * Ensure that the rest of this function (in the original Image) is
  76. * visible when the caches are disabled. The I-cache can't have stale
  77. * entries for the VA range of the current image, so no maintenance is
  78. * necessary.
  79. */
  80. adr x0, efi_stub_entry
  81. adr x1, efi_stub_entry_end
  82. sub x1, x1, x0
  83. bl __flush_dcache_area
  84. /* Turn off Dcache and MMU */
  85. mrs x0, CurrentEL
  86. cmp x0, #CurrentEL_EL2
  87. b.ne 1f
  88. mrs x0, sctlr_el2
  89. bic x0, x0, #1 << 0 // clear SCTLR.M
  90. bic x0, x0, #1 << 2 // clear SCTLR.C
  91. msr sctlr_el2, x0
  92. isb
  93. b 2f
  94. 1:
  95. mrs x0, sctlr_el1
  96. bic x0, x0, #1 << 0 // clear SCTLR.M
  97. bic x0, x0, #1 << 2 // clear SCTLR.C
  98. msr sctlr_el1, x0
  99. isb
  100. 2:
  101. /* Jump to kernel entry point */
  102. mov x0, x20
  103. mov x1, xzr
  104. mov x2, xzr
  105. mov x3, xzr
  106. br x21
  107. efi_load_fail:
  108. mov x0, #EFI_LOAD_ERROR
  109. ldp x29, x30, [sp], #32
  110. ret
  111. efi_stub_entry_end:
  112. ENDPROC(efi_stub_entry)