linux/arch/arm/kvm/init.S
<<
>>
Prefs
   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
  19#include <linux/linkage.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/********************************************************************
  27 * Hypervisor initialization
  28 *   - should be called with:
  29 *       r0 = top of Hyp stack (kernel VA)
  30 *       r1 = pointer to hyp vectors
  31 *       r2,r3 = Hypervisor pgd pointer
  32 *
  33 * The init scenario is:
  34 * - We jump in HYP with four parameters: boot HYP pgd, runtime HYP pgd,
  35 *   runtime stack, runtime vectors
  36 * - Enable the MMU with the boot pgd
  37 * - Jump to a target into the trampoline page (remember, this is the same
  38 *   physical page!)
  39 * - Now switch to the runtime pgd (same VA, and still the same physical
  40 *   page!)
  41 * - Invalidate TLBs
  42 * - Set stack and vectors
  43 * - Profit! (or eret, if you only care about the code).
  44 *
  45 * As we only have four registers available to pass parameters (and we
  46 * need six), we split the init in two phases:
  47 * - Phase 1: r0 = 0, r1 = 0, r2,r3 contain the boot PGD.
  48 *   Provides the basic HYP init, and enable the MMU.
  49 * - Phase 2: r0 = ToS, r1 = vectors, r2,r3 contain the runtime PGD.
  50 *   Switches to the runtime PGD, set stack and vectors.
  51 */
  52
  53        .text
  54        .pushsection    .hyp.idmap.text,"ax"
  55        .align 5
  56__kvm_hyp_init:
  57        .globl __kvm_hyp_init
  58
  59        @ Hyp-mode exception vector
  60        W(b)    .
  61        W(b)    .
  62        W(b)    .
  63        W(b)    .
  64        W(b)    .
  65        W(b)    __do_hyp_init
  66        W(b)    .
  67        W(b)    .
  68
  69__do_hyp_init:
  70        cmp     r0, #0                  @ We have a SP?
  71        bne     phase2                  @ Yes, second stage init
  72
  73        @ Set the HTTBR to point to the hypervisor PGD pointer passed
  74        mcrr    p15, 4, r2, r3, c2
  75
  76        @ Set the HTCR and VTCR to the same shareability and cacheability
  77        @ settings as the non-secure TTBCR and with T0SZ == 0.
  78        mrc     p15, 4, r0, c2, c0, 2   @ HTCR
  79        ldr     r2, =HTCR_MASK
  80        bic     r0, r0, r2
  81        mrc     p15, 0, r1, c2, c0, 2   @ TTBCR
  82        and     r1, r1, #(HTCR_MASK & ~TTBCR_T0SZ)
  83        orr     r0, r0, r1
  84        mcr     p15, 4, r0, c2, c0, 2   @ HTCR
  85
  86        mrc     p15, 4, r1, c2, c1, 2   @ VTCR
  87        ldr     r2, =VTCR_MASK
  88        bic     r1, r1, r2
  89        bic     r0, r0, #(~VTCR_HTCR_SH)        @ clear non-reusable HTCR bits
  90        orr     r1, r0, r1
  91        orr     r1, r1, #(KVM_VTCR_SL0 | KVM_VTCR_T0SZ | KVM_VTCR_S)
  92        mcr     p15, 4, r1, c2, c1, 2   @ VTCR
  93
  94        @ Use the same memory attributes for hyp. accesses as the kernel
  95        @ (copy MAIRx ro HMAIRx).
  96        mrc     p15, 0, r0, c10, c2, 0
  97        mcr     p15, 4, r0, c10, c2, 0
  98        mrc     p15, 0, r0, c10, c2, 1
  99        mcr     p15, 4, r0, c10, c2, 1
 100
 101        @ Set the HSCTLR to:
 102        @  - ARM/THUMB exceptions: Kernel config (Thumb-2 kernel)
 103        @  - Endianness: Kernel config
 104        @  - Fast Interrupt Features: Kernel config
 105        @  - Write permission implies XN: disabled
 106        @  - Instruction cache: enabled
 107        @  - Data/Unified cache: enabled
 108        @  - Memory alignment checks: enabled
 109        @  - MMU: enabled (this code must be run from an identity mapping)
 110        mrc     p15, 4, r0, c1, c0, 0   @ HSCR
 111        ldr     r2, =HSCTLR_MASK
 112        bic     r0, r0, r2
 113        mrc     p15, 0, r1, c1, c0, 0   @ SCTLR
 114        ldr     r2, =(HSCTLR_EE | HSCTLR_FI | HSCTLR_I | HSCTLR_C)
 115        and     r1, r1, r2
 116 ARM(   ldr     r2, =(HSCTLR_M | HSCTLR_A)                      )
 117 THUMB( ldr     r2, =(HSCTLR_M | HSCTLR_A | HSCTLR_TE)          )
 118        orr     r1, r1, r2
 119        orr     r0, r0, r1
 120        isb
 121        mcr     p15, 4, r0, c1, c0, 0   @ HSCR
 122
 123        @ End of init phase-1
 124        eret
 125
 126phase2:
 127        @ Set stack pointer
 128        mov     sp, r0
 129
 130        @ Set HVBAR to point to the HYP vectors
 131        mcr     p15, 4, r1, c12, c0, 0  @ HVBAR
 132
 133        @ Jump to the trampoline page
 134        ldr     r0, =TRAMPOLINE_VA
 135        adr     r1, target
 136        bfi     r0, r1, #0, #PAGE_SHIFT
 137        mov     pc, r0
 138
 139target: @ We're now in the trampoline code, switch page tables
 140        mcrr    p15, 4, r2, r3, c2
 141        isb
 142
 143        @ Invalidate the old TLBs
 144        mcr     p15, 4, r0, c8, c7, 0   @ TLBIALLH
 145        dsb
 146
 147        eret
 148
 149        .ltorg
 150
 151        .globl __kvm_hyp_init_end
 152__kvm_hyp_init_end:
 153
 154        .popsection
 155