init.S 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * Copyright (C) 2012 - Virtual Open Systems and Columbia University
  3. * Author: Christoffer Dall <c.dall@virtualopensystems.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License, version 2, as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. */
  18. #include <linux/linkage.h>
  19. #include <asm/assembler.h>
  20. #include <asm/unified.h>
  21. #include <asm/asm-offsets.h>
  22. #include <asm/kvm_asm.h>
  23. #include <asm/kvm_arm.h>
  24. #include <asm/kvm_mmu.h>
  25. /********************************************************************
  26. * Hypervisor initialization
  27. * - should be called with:
  28. * r0 = top of Hyp stack (kernel VA)
  29. * r1 = pointer to hyp vectors
  30. * r2,r3 = Hypervisor pgd pointer
  31. *
  32. * The init scenario is:
  33. * - We jump in HYP with four parameters: boot HYP pgd, runtime HYP pgd,
  34. * runtime stack, runtime vectors
  35. * - Enable the MMU with the boot pgd
  36. * - Jump to a target into the trampoline page (remember, this is the same
  37. * physical page!)
  38. * - Now switch to the runtime pgd (same VA, and still the same physical
  39. * page!)
  40. * - Invalidate TLBs
  41. * - Set stack and vectors
  42. * - Profit! (or eret, if you only care about the code).
  43. *
  44. * As we only have four registers available to pass parameters (and we
  45. * need six), we split the init in two phases:
  46. * - Phase 1: r0 = 0, r1 = 0, r2,r3 contain the boot PGD.
  47. * Provides the basic HYP init, and enable the MMU.
  48. * - Phase 2: r0 = ToS, r1 = vectors, r2,r3 contain the runtime PGD.
  49. * Switches to the runtime PGD, set stack and vectors.
  50. */
  51. .text
  52. .pushsection .hyp.idmap.text,"ax"
  53. .align 5
  54. __kvm_hyp_init:
  55. .globl __kvm_hyp_init
  56. @ Hyp-mode exception vector
  57. W(b) .
  58. W(b) .
  59. W(b) .
  60. W(b) .
  61. W(b) .
  62. W(b) __do_hyp_init
  63. W(b) .
  64. W(b) .
  65. __do_hyp_init:
  66. cmp r0, #0 @ We have a SP?
  67. bne phase2 @ Yes, second stage init
  68. @ Set the HTTBR to point to the hypervisor PGD pointer passed
  69. mcrr p15, 4, rr_lo_hi(r2, r3), c2
  70. @ Set the HTCR and VTCR to the same shareability and cacheability
  71. @ settings as the non-secure TTBCR and with T0SZ == 0.
  72. mrc p15, 4, r0, c2, c0, 2 @ HTCR
  73. ldr r2, =HTCR_MASK
  74. bic r0, r0, r2
  75. mrc p15, 0, r1, c2, c0, 2 @ TTBCR
  76. and r1, r1, #(HTCR_MASK & ~TTBCR_T0SZ)
  77. orr r0, r0, r1
  78. mcr p15, 4, r0, c2, c0, 2 @ HTCR
  79. mrc p15, 4, r1, c2, c1, 2 @ VTCR
  80. ldr r2, =VTCR_MASK
  81. bic r1, r1, r2
  82. bic r0, r0, #(~VTCR_HTCR_SH) @ clear non-reusable HTCR bits
  83. orr r1, r0, r1
  84. orr r1, r1, #(KVM_VTCR_SL0 | KVM_VTCR_T0SZ | KVM_VTCR_S)
  85. mcr p15, 4, r1, c2, c1, 2 @ VTCR
  86. @ Use the same memory attributes for hyp. accesses as the kernel
  87. @ (copy MAIRx ro HMAIRx).
  88. mrc p15, 0, r0, c10, c2, 0
  89. mcr p15, 4, r0, c10, c2, 0
  90. mrc p15, 0, r0, c10, c2, 1
  91. mcr p15, 4, r0, c10, c2, 1
  92. @ Invalidate the stale TLBs from Bootloader
  93. mcr p15, 4, r0, c8, c7, 0 @ TLBIALLH
  94. dsb ish
  95. @ Set the HSCTLR to:
  96. @ - ARM/THUMB exceptions: Kernel config (Thumb-2 kernel)
  97. @ - Endianness: Kernel config
  98. @ - Fast Interrupt Features: Kernel config
  99. @ - Write permission implies XN: disabled
  100. @ - Instruction cache: enabled
  101. @ - Data/Unified cache: enabled
  102. @ - Memory alignment checks: enabled
  103. @ - MMU: enabled (this code must be run from an identity mapping)
  104. mrc p15, 4, r0, c1, c0, 0 @ HSCR
  105. ldr r2, =HSCTLR_MASK
  106. bic r0, r0, r2
  107. mrc p15, 0, r1, c1, c0, 0 @ SCTLR
  108. ldr r2, =(HSCTLR_EE | HSCTLR_FI | HSCTLR_I | HSCTLR_C)
  109. and r1, r1, r2
  110. ARM( ldr r2, =(HSCTLR_M | HSCTLR_A) )
  111. THUMB( ldr r2, =(HSCTLR_M | HSCTLR_A | HSCTLR_TE) )
  112. orr r1, r1, r2
  113. orr r0, r0, r1
  114. isb
  115. mcr p15, 4, r0, c1, c0, 0 @ HSCR
  116. @ End of init phase-1
  117. eret
  118. phase2:
  119. @ Set stack pointer
  120. mov sp, r0
  121. @ Set HVBAR to point to the HYP vectors
  122. mcr p15, 4, r1, c12, c0, 0 @ HVBAR
  123. @ Jump to the trampoline page
  124. ldr r0, =TRAMPOLINE_VA
  125. adr r1, target
  126. bfi r0, r1, #0, #PAGE_SHIFT
  127. ret r0
  128. target: @ We're now in the trampoline code, switch page tables
  129. mcrr p15, 4, rr_lo_hi(r2, r3), c2
  130. isb
  131. @ Invalidate the old TLBs
  132. mcr p15, 4, r0, c8, c7, 0 @ TLBIALLH
  133. dsb ish
  134. eret
  135. .ltorg
  136. .globl __kvm_hyp_init_end
  137. __kvm_hyp_init_end:
  138. .popsection