/* * Copyright (C) 2012,2013 - ARM Ltd * Author: Marc Zyngier * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include .text .pushsection .hyp.idmap.text, "ax" .align 11 ENTRY(__kvm_hyp_init) ventry __invalid // Synchronous EL2t ventry __invalid // IRQ EL2t ventry __invalid // FIQ EL2t ventry __invalid // Error EL2t ventry __invalid // Synchronous EL2h ventry __invalid // IRQ EL2h ventry __invalid // FIQ EL2h ventry __invalid // Error EL2h ventry __do_hyp_init // Synchronous 64-bit EL1 ventry __invalid // IRQ 64-bit EL1 ventry __invalid // FIQ 64-bit EL1 ventry __invalid // Error 64-bit EL1 ventry __invalid // Synchronous 32-bit EL1 ventry __invalid // IRQ 32-bit EL1 ventry __invalid // FIQ 32-bit EL1 ventry __invalid // Error 32-bit EL1 __invalid: b . /* * x0: HYP boot pgd * x1: HYP pgd * x2: HYP stack * x3: HYP vectors */ __do_hyp_init: msr ttbr0_el2, x0 mrs x4, tcr_el1 ldr x5, =TCR_EL2_MASK and x4, x4, x5 ldr x5, =TCR_EL2_FLAGS orr x4, x4, x5 msr tcr_el2, x4 ldr x4, =VTCR_EL2_FLAGS /* * Read the PARange bits from ID_AA64MMFR0_EL1 and set the PS bits in * VTCR_EL2. */ mrs x5, ID_AA64MMFR0_EL1 bfi x4, x5, #16, #3 msr vtcr_el2, x4 mrs x4, mair_el1 msr mair_el2, x4 isb /* Invalidate the stale TLBs from Bootloader */ tlbi alle2 dsb sy mrs x4, sctlr_el2 and x4, x4, #SCTLR_EL2_EE // preserve endianness of EL2 ldr x5, =SCTLR_EL2_FLAGS orr x4, x4, x5 msr sctlr_el2, x4 isb /* MMU is now enabled. Get ready for the trampoline dance */ ldr x4, =TRAMPOLINE_VA adr x5, target bfi x4, x5, #0, #PAGE_SHIFT br x4 target: /* We're now in the trampoline code, switch page tables */ msr ttbr0_el2, x1 isb /* Invalidate the old TLBs */ tlbi alle2 dsb sy /* Set the stack and new vectors */ kern_hyp_va x2 mov sp, x2 kern_hyp_va x3 msr vbar_el2, x3 /* Hello, World! */ eret ENDPROC(__kvm_hyp_init) .ltorg .popsection