Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / arch / arm64 / kvm / vgic-v2-switch.S
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 #include <linux/irqchip/arm-gic.h>
20
21 #include <asm/assembler.h>
22 #include <asm/memory.h>
23 #include <asm/asm-offsets.h>
24 #include <asm/kvm.h>
25 #include <asm/kvm_asm.h>
26 #include <asm/kvm_arm.h>
27 #include <asm/kvm_mmu.h>
28
29         .text
30         .pushsection    .hyp.text, "ax"
31
32 /*
33  * Save the VGIC CPU state into memory
34  * x0: Register pointing to VCPU struct
35  * Do not corrupt x1!!!
36  */
37 ENTRY(__save_vgic_v2_state)
38 __save_vgic_v2_state:
39         /* Get VGIC VCTRL base into x2 */
40         ldr     x2, [x0, #VCPU_KVM]
41         kern_hyp_va     x2
42         ldr     x2, [x2, #KVM_VGIC_VCTRL]
43         kern_hyp_va     x2
44         cbz     x2, 2f          // disabled
45
46         /* Compute the address of struct vgic_cpu */
47         add     x3, x0, #VCPU_VGIC_CPU
48
49         /* Save all interesting registers */
50         ldr     w4, [x2, #GICH_HCR]
51         ldr     w5, [x2, #GICH_VMCR]
52         ldr     w6, [x2, #GICH_MISR]
53         ldr     w7, [x2, #GICH_EISR0]
54         ldr     w8, [x2, #GICH_EISR1]
55         ldr     w9, [x2, #GICH_ELRSR0]
56         ldr     w10, [x2, #GICH_ELRSR1]
57         ldr     w11, [x2, #GICH_APR]
58 CPU_BE( rev     w4,  w4  )
59 CPU_BE( rev     w5,  w5  )
60 CPU_BE( rev     w6,  w6  )
61 CPU_BE( rev     w7,  w7  )
62 CPU_BE( rev     w8,  w8  )
63 CPU_BE( rev     w9,  w9  )
64 CPU_BE( rev     w10, w10 )
65 CPU_BE( rev     w11, w11 )
66
67         str     w4, [x3, #VGIC_V2_CPU_HCR]
68         str     w5, [x3, #VGIC_V2_CPU_VMCR]
69         str     w6, [x3, #VGIC_V2_CPU_MISR]
70 CPU_LE( str     w7, [x3, #VGIC_V2_CPU_EISR] )
71 CPU_LE( str     w8, [x3, #(VGIC_V2_CPU_EISR + 4)] )
72 CPU_LE( str     w9, [x3, #VGIC_V2_CPU_ELRSR] )
73 CPU_LE( str     w10, [x3, #(VGIC_V2_CPU_ELRSR + 4)] )
74 CPU_BE( str     w7, [x3, #(VGIC_V2_CPU_EISR + 4)] )
75 CPU_BE( str     w8, [x3, #VGIC_V2_CPU_EISR] )
76 CPU_BE( str     w9, [x3, #(VGIC_V2_CPU_ELRSR + 4)] )
77 CPU_BE( str     w10, [x3, #VGIC_V2_CPU_ELRSR] )
78         str     w11, [x3, #VGIC_V2_CPU_APR]
79
80         /* Clear GICH_HCR */
81         str     wzr, [x2, #GICH_HCR]
82
83         /* Save list registers */
84         add     x2, x2, #GICH_LR0
85         ldr     w4, [x3, #VGIC_CPU_NR_LR]
86         add     x3, x3, #VGIC_V2_CPU_LR
87 1:      ldr     w5, [x2], #4
88 CPU_BE( rev     w5, w5 )
89         str     w5, [x3], #4
90         sub     w4, w4, #1
91         cbnz    w4, 1b
92 2:
93         ret
94 ENDPROC(__save_vgic_v2_state)
95
96 /*
97  * Restore the VGIC CPU state from memory
98  * x0: Register pointing to VCPU struct
99  */
100 ENTRY(__restore_vgic_v2_state)
101 __restore_vgic_v2_state:
102         /* Get VGIC VCTRL base into x2 */
103         ldr     x2, [x0, #VCPU_KVM]
104         kern_hyp_va     x2
105         ldr     x2, [x2, #KVM_VGIC_VCTRL]
106         kern_hyp_va     x2
107         cbz     x2, 2f          // disabled
108
109         /* Compute the address of struct vgic_cpu */
110         add     x3, x0, #VCPU_VGIC_CPU
111
112         /* We only restore a minimal set of registers */
113         ldr     w4, [x3, #VGIC_V2_CPU_HCR]
114         ldr     w5, [x3, #VGIC_V2_CPU_VMCR]
115         ldr     w6, [x3, #VGIC_V2_CPU_APR]
116 CPU_BE( rev     w4, w4 )
117 CPU_BE( rev     w5, w5 )
118 CPU_BE( rev     w6, w6 )
119
120         str     w4, [x2, #GICH_HCR]
121         str     w5, [x2, #GICH_VMCR]
122         str     w6, [x2, #GICH_APR]
123
124         /* Restore list registers */
125         add     x2, x2, #GICH_LR0
126         ldr     w4, [x3, #VGIC_CPU_NR_LR]
127         add     x3, x3, #VGIC_V2_CPU_LR
128 1:      ldr     w5, [x3], #4
129 CPU_BE( rev     w5, w5 )
130         str     w5, [x2], #4
131         sub     w4, w4, #1
132         cbnz    w4, 1b
133 2:
134         ret
135 ENDPROC(__restore_vgic_v2_state)
136
137         .popsection