1/* 2 * Copyright 2014, General Dynamics C4 Systems 3 * 4 * This software may be distributed and modified according to the terms of 5 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 6 * See "LICENSE_GPLv2.txt" for details. 7 * 8 * @TAG(GD_GPL) 9 */ 10 11#include <config.h> 12 13#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT 14 15#include <machine/assembler.h> 16#include <mode/api/constants.h> 17 18/*** Hypervisor coprocessor registers ***/ 19#define HVBAR(reg) p15, 4, reg, c12, c0, 0 20#define HCR(reg) p15, 4, reg, c1 , c1, 0 21#define HSCTLR(reg) p15, 4, reg, c1 , c0, 0 22#define HACTLR(reg) p15, 4, reg, c1 , c0, 1 23#define HDCR(reg) p15, 4, reg, c1 , c1, 1 24#define HCPTR(reg) p15, 4, reg, c1 , c1, 2 25#define HSTR(reg) p15, 4, reg, c1 , c1, 3 26#define HACR(reg) p15, 4, reg, c1 , c1, 7 27#define HTCR(reg) p15, 4, reg, c2 , c0, 2 28#define HADFSR(reg) p15, 4, reg, c5 , c1, 0 29#define HAIFSR(reg) p15, 4, reg, c5 , c1, 1 30#define HSR(reg) p15, 4, reg, c5 , c2, 0 31#define HDFAR(reg) p15, 4, reg, c6 , c0, 0 32#define HIFAR(reg) p15, 4, reg, c6 , c0, 2 33#define HPFAR(reg) p15, 4, reg, c6 , c0, 4 34#define HMAIR0(reg) p15, 4, reg, c10, c2, 0 35#define HMAIR1(reg) p15, 4, reg, c10, c2, 1 36#define HAMAIR0(reg) p15, 4, reg, c10, c3, 0 37#define HAMAIR1(reg) p15, 4, reg, c10, c3, 1 38#define HTPIDR(reg) p15, 4, reg, c13, c0, 2 39#define HTTBR(rh,rl) p15, 4, rl, rh, c2 40 41/*** VMM coprocessor registers ***/ 42#define VTCR(reg) p15, 4, reg, c2 , c1, 2 43#define VTTBR(rh,rl) p15, 6, rl, rh, c2 44 45 46#define DTLBIALL(reg) p15, 0, reg, c8, c6, 0 47#define TLBIALL(reg) p15, 0, reg, c8, c7, 0 48#define DTLBIASID(reg) p15, 0, reg, c8, c6, 2 49#define TLBIASID(reg) p15, 0, reg, c8, c7, 2 50 51/*** Hyp mode TLB maintenance ***/ 52/* Invalidate entire Hyp unified TLB Inner Shareable */ 53#define TLBIALLHIS() p15, 4, r0, c8, c7, 0 54/* Invalidate Hyp unified TLB entry by MVA Inner Shareable MVA */ 55#define TLBIMVAHIS(mva) p15, 4, mva, c8, c7, 0 56/* Invalidate entire Non-secure Non-Hyp unified TLB Inner Shareable */ 57#define TLBIALLNSNHIS() p15, 4, r0, c8, c7, 0 58/* Invalidate entire Hyp unified TLB */ 59#define TLBIALLH() p15, 4, r0, c8, c7, 0 60/* Invalidate Hyp unified TLB entry by MVA */ 61#define TLBIMVAH(mva) p15, 4, mva, c8, c7, 0 62/* Invalidate entire Non-secure Non-Hyp unified TLB */ 63#define TLBIALLNSNH() p15, 4, r0, c8, c7, 0 64 65.code 32 66.section .vectors, "ax" 67BEGIN_FUNC(arm_vector_table) 68 ldr pc, =arm_hyp_reset_exception 69 ldr pc, =arm_hyp_undefined_inst_exception 70 ldr pc, =arm_hyp_syscall 71 ldr pc, =arm_hyp_prefetch_abort_exception 72 ldr pc, =arm_hyp_data_abort_exception 73 ldr pc, =arm_hyp_trap 74 ldr pc, =arm_hyp_irq_exception 75 ldr pc, =arm_hyp_fiq_exception 76END_FUNC(arm_vector_table) 77 78.ltorg 79 80.section .vectors.text, "ax" 81 82#include <arch/api/syscall.h> 83#include <arch/machine/hardware.h> 84 85#include <arch/machine/registerset.h> 86 87#define HSREC_SHIFT 26 88#define HSREC_MASK (0x3f << HSREC_SHIFT) 89#define HSREC_UNKNOWN 0x00 90#define HSREC_WFI 0x01 91#define HSREC_SVC 0x11 92#define HSREC_HVC 0x12 93#define HSREC_SMC 0x13 94#define HSREC_PREFETCH_ABORT 0x20 95#define HSREC_DATA_ABORT 0x24 96#define HSRIL32 (1 << 25) 97 98.macro EX_ENTRY 99 /* Create some scratch space */ 100 push {lr} 101 /* Store ELR */ 102 mrs lr, elr_hyp 103 str lr, [sp, #4] 104 /* Store SPSR */ 105 mrs lr, spsr_hyp 106 str lr, [sp, #8] 107 /* Store SP_usr */ 108 mrs lr, sp_usr 109 push {lr} 110.endm 111 112/* Prepare to enter the kernel */ 113.macro PUSH_STACK 114 /* store FaultInstruction */ 115 str lr, [sp, #(PT_FaultInstruction - PT_SP)] 116 /* Stack all user registers */ 117 push {r0-r12} 118 /* Load the kernel's real stack pointer */ 119 /* the hyp mode uses HTPIDR */ 120 mrc p15, 4, sp, c13, c0, 2 121.endm 122 123/******************************** 124 *** Traps taken to HYP mode *** 125 ********************************/ 126 127BEGIN_FUNC(arm_hyp_trap) 128 EX_ENTRY 129 130 /* ARM_ARM B3.13.6 */ 131 mrc HSR(lr) 132 and lr, lr, #(HSREC_MASK) 133 cmp lr, #(HSREC_SVC << HSREC_SHIFT) 134 beq arm_syscall 135 cmp lr, #(HSREC_HVC << HSREC_SHIFT) 136 beq arm_syscall 137 cmp lr, #(HSREC_PREFETCH_ABORT << HSREC_SHIFT) 138 beq arm_prefetch_abort 139 cmp lr, #(HSREC_DATA_ABORT << HSREC_SHIFT) 140 beq arm_data_abort 141 cmp lr, #(HSREC_UNKNOWN << HSREC_SHIFT) 142 beq arm_undefined_inst 143 144 /** Everything else is assumed to be a VCPU trap **/ 145 mrs lr, elr_hyp 146 PUSH_STACK 147 mrc HSR(r0) 148 b c_handle_vcpu_fault 149END_FUNC(arm_hyp_trap) 150 151 152BEGIN_FUNC(arm_undefined_inst) 153 mrs lr, elr_hyp 154 PUSH_STACK 155 b c_handle_undefined_instruction 156END_FUNC(arm_undefined_inst) 157 158BEGIN_FUNC(arm_prefetch_abort) 159 mrs lr, elr_hyp 160 PUSH_STACK 161 b c_handle_instruction_fault 162END_FUNC(arm_prefetch_abort) 163 164BEGIN_FUNC(arm_data_abort) 165 mrs lr, elr_hyp 166 PUSH_STACK 167 b c_handle_data_fault 168END_FUNC(arm_data_abort) 169 170BEGIN_FUNC(arm_syscall) 171 mrs lr, elr_hyp 172 sub lr, lr, #4 173 PUSH_STACK 174 /* r0: cptr, r1: msgInfo, r2: syscallNo */ 175 mov r2, r7 176 b c_handle_syscall 177END_FUNC(arm_syscall) 178 179/********************************* 180 *** Traps taken from HYP mode *** 181 *********************************/ 182 183BEGIN_FUNC(arm_hyp_prefetch_abort_exception) 184#ifdef DEBUG 185 mrc p15, 4, sp, c13, c0, 2 186 mrs r0, elr_hyp 187 blx kernelPrefetchAbort 188#endif 189 mrc HSR(r9) /* Get Hype Syndrome Register. */ 190 mrc HIFAR(r10) /* Get fault address register. */ 1911: b 1b 192END_FUNC(arm_hyp_prefetch_abort_exception) 193 194BEGIN_FUNC(arm_hyp_data_abort_exception) 195#ifdef DEBUG 196 mrc p15, 4, sp, c13, c0, 2 197 mrs r0, elr_hyp 198 blx kernelDataAbort 199#endif 200 mrc HSR(r9) /* Get Hype Syndrome Register. */ 201 mrc HDFAR(r10) /* Get fault address register. */ 2021: b 1b 203END_FUNC(arm_hyp_data_abort_exception) 204 205BEGIN_FUNC(arm_hyp_undefined_inst_exception) 206#ifdef DEBUG 207 mrc p15, 4, sp, c13, c0, 2 208 mrs r0, elr_hyp 209 blx kernelUndefinedInstruction 210#endif 211 mrc HSR(r9) /* Get Hype Syndrome Register. */ 212 mrc HIFAR(r10) /* Get fault address register. */ 2131: b 1b 214END_FUNC(arm_hyp_undefined_inst_exception) 215 216BEGIN_FUNC(arm_hyp_syscall) 217 b arm_hyp_undefined_inst_exception 218END_FUNC(arm_hyp_syscall) 219 220/************************ 221 *** Other exceptions *** 222 ************************/ 223 224BEGIN_FUNC(arm_hyp_irq_exception) 225 EX_ENTRY 226 mrs lr, elr_hyp 227 PUSH_STACK 228 b c_handle_interrupt 229END_FUNC(arm_hyp_irq_exception) 230 231BEGIN_FUNC(arm_hyp_reset_exception) 232 blx halt 233END_FUNC(arm_hyp_reset_exception) 234 235BEGIN_FUNC(arm_hyp_fiq_exception) 236 blx halt 237END_FUNC(arm_hyp_fiq_exception) 238 239#endif /* CONFIG_ARM_HYP */ 240