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