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