linux/arch/arm64/kvm/hyp-init.S
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2012,2013 - ARM Ltd
   3 * Author: Marc Zyngier <marc.zyngier@arm.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, see <http://www.gnu.org/licenses/>.
  16 */
  17
  18#include <linux/linkage.h>
  19
  20#include <asm/assembler.h>
  21#include <asm/kvm_arm.h>
  22#include <asm/kvm_mmu.h>
  23
  24        .text
  25        .pushsection    .hyp.idmap.text, "ax"
  26
  27        .align  11
  28
  29ENTRY(__kvm_hyp_init)
  30        ventry  __invalid               // Synchronous EL2t
  31        ventry  __invalid               // IRQ EL2t
  32        ventry  __invalid               // FIQ EL2t
  33        ventry  __invalid               // Error EL2t
  34
  35        ventry  __invalid               // Synchronous EL2h
  36        ventry  __invalid               // IRQ EL2h
  37        ventry  __invalid               // FIQ EL2h
  38        ventry  __invalid               // Error EL2h
  39
  40        ventry  __do_hyp_init           // Synchronous 64-bit EL1
  41        ventry  __invalid               // IRQ 64-bit EL1
  42        ventry  __invalid               // FIQ 64-bit EL1
  43        ventry  __invalid               // Error 64-bit EL1
  44
  45        ventry  __invalid               // Synchronous 32-bit EL1
  46        ventry  __invalid               // IRQ 32-bit EL1
  47        ventry  __invalid               // FIQ 32-bit EL1
  48        ventry  __invalid               // Error 32-bit EL1
  49
  50__invalid:
  51        b       .
  52
  53        /*
  54         * x0: HYP boot pgd
  55         * x1: HYP pgd
  56         * x2: HYP stack
  57         * x3: HYP vectors
  58         */
  59__do_hyp_init:
  60
  61        msr     ttbr0_el2, x0
  62
  63        mrs     x4, tcr_el1
  64        ldr     x5, =TCR_EL2_MASK
  65        and     x4, x4, x5
  66        ldr     x5, =TCR_EL2_FLAGS
  67        orr     x4, x4, x5
  68        msr     tcr_el2, x4
  69
  70        ldr     x4, =VTCR_EL2_FLAGS
  71        msr     vtcr_el2, x4
  72
  73        mrs     x4, mair_el1
  74        msr     mair_el2, x4
  75        isb
  76
  77        mrs     x4, sctlr_el2
  78        and     x4, x4, #SCTLR_EL2_EE   // preserve endianness of EL2
  79        ldr     x5, =SCTLR_EL2_FLAGS
  80        orr     x4, x4, x5
  81        msr     sctlr_el2, x4
  82        isb
  83
  84        /* MMU is now enabled. Get ready for the trampoline dance */
  85        ldr     x4, =TRAMPOLINE_VA
  86        adr     x5, target
  87        bfi     x4, x5, #0, #PAGE_SHIFT
  88        br      x4
  89
  90target: /* We're now in the trampoline code, switch page tables */
  91        msr     ttbr0_el2, x1
  92        isb
  93
  94        /* Invalidate the old TLBs */
  95        tlbi    alle2
  96        dsb     sy
  97
  98        /* Set the stack and new vectors */
  99        kern_hyp_va     x2
 100        mov     sp, x2
 101        kern_hyp_va     x3
 102        msr     vbar_el2, x3
 103
 104        /* Hello, World! */
 105        eret
 106ENDPROC(__kvm_hyp_init)
 107
 108        .ltorg
 109
 110        .popsection
 111