1// Copyright 2017 The Fuchsia Authors 2// 3// Use of this source code is governed by a MIT-style 4// license that can be found in the LICENSE file or at 5// https://opensource.org/licenses/MIT 6 7#include "constants_priv.h" 8 9.set CPACR_EL1_FPEN_NO_TRAP, (3 << 20) 10 11// See ARM ARM Table D1.10.2 for more details. 12.set CURRENT_EL_EL0_BASE, 0x000 13.set CURRENT_EL_ELx_BASE, 0x200 14.set LOWER_EL_ARCH64_BASE, 0x400 15.set LOWER_EL_ARCH32_BASE, 0x600 16.set SYNC_EXC_OFFSET, 0x000 17.set IRQ_EXC_OFFSET, 0x080 18.set FIQ_EXC_OFFSET, 0x100 19.set SERROR_EXC_OFFSET, 0x180 20 21.set SPSR_M_BIT_ARCH32, 0x010 22 23// Define new function 'name'. 24// Local label '1:' used by other macros to compute offsets. 25.macro FUNCTION name 26 .global \name 27 .type \name, STT_FUNC 28 \name: 29 1: 30.endm 31 32// Adjusts current text location to position at a specific exception handler. 33.macro exception_vector base offset 34 2: 35 .skip (\base + \offset) - (2b - 1b) 36.endm 37 38// test_complete Signals test completion by writing value (0-255) to 39// EXIT_TEST_ADDR. EXIT_TEST_ADDR is monitored by the test routine for 40// access - indicating test completion. 41.macro test_complete value=0 arch=aarch64 42 .if \value > 255 || \value < 0 43 .err 44 .endif 45 46 .ifeqs "\arch", "aarch64" 47 mov x0, EXIT_TEST_ADDR 48 .if \value == 0 49 str xzr, [x0] 50 .else 51 mov x1, \value 52 str x1, [x0] 53 .endif 54 .else 55 .ifeqs "\arch", "aarch32" 56 .word 0xE3A01000 + \value // aarch32: movw r1, \value 57 .word 0xE30F0000 // aarch32: movw r0, [lower]EXIT_TEST_ADDR 58 .word 0xE34000FF // aarch32: movw r0, [upper]EXIT_TEST_ADDR 59 .word 0xE5801000 // aarch32: str r0, [r1] 60 .else 61 .error "Unsupported architecture" 62 .endif 63 .endif 64.endm 65 66// Drop exception level from EL1 to EL0 and, if requested, switch execution 67// state. 68.macro drop_to_el0 arch=aarch64 69 .ifeqs "\arch", "aarch32" 70 mov x0, SPSR_M_BIT_ARCH32 // for aarch32, set PSTATE to AARCH32 71 msr spsr_el1, x0 // and clear everything else upon eret. 72 .else 73 .ifnes "\arch", "aarch64" // accept default architecture, do nothing. 74 .error "Unsupported architecture" 75 .endif 76 .endif 77 78 ldr w0, 2f // resume execution at label '2' ahead 79 msr elr_el1, x0 // store exception link register 80 eret // resume at el0 using specified arch. 81 2: 82 .word 2b - 1b + 4 83.endm 84 85.text 86 87// Test vcpu_resume. 88FUNCTION vcpu_resume_start 89 test_complete 90FUNCTION vcpu_resume_end 91 92// Test vcpu_interrupt. 93FUNCTION vcpu_interrupt_start 94 msr daifclr, #2 95 b . 96 97 exception_vector CURRENT_EL_ELx_BASE, IRQ_EXC_OFFSET 98 test_complete 99FUNCTION vcpu_interrupt_end 100 101// Test wfi instruction handling. 102FUNCTION vcpu_wfi_start 103 wfi 104 test_complete 105FUNCTION vcpu_wfi_end 106 107// Test wfi instruction handling. 108// Execution of WFI at EL0 on AARCH32 is propagated to EL1 / AARCH64. 109FUNCTION vcpu_aarch32_wfi_start 110 drop_to_el0 aarch32 111 .word 0xE320F003 // aarch32: wfi 112 test_complete 1 aarch32 // Fail, if instruction was executed 113 // without raising exception. 114 115 exception_vector LOWER_EL_ARCH32_BASE, SYNC_EXC_OFFSET 116 test_complete 117FUNCTION vcpu_aarch32_wfi_end 118 119// Test floating-point instruction handling with trapping between levels. 120FUNCTION vcpu_fp_start 121 drop_to_el0 122 123 // Access vector registers. 124 mov w0, 0xff 125 dup v0.16b, w0 126 test_complete 127 128 // Handle EL1 floating-point trap. 129 // This is interpreted as a Lower exception level (coming from EL0) 130 // captured by AARCH64. See ARM ARM Table D1.10.2 for more details. 131 exception_vector LOWER_EL_ARCH64_BASE, SYNC_EXC_OFFSET 132 mov x0, CPACR_EL1_FPEN_NO_TRAP 133 msr cpacr_el1, x0 134 eret 135FUNCTION vcpu_fp_end 136 137// Test wfi instruction handling. 138FUNCTION vcpu_aarch32_fp_start 139 drop_to_el0 aarch32 140 // Load double precision register d0 from address 0. 141 // This should trigger floating point exception. 142 .word 0xE3A00000 // aarch32: mov r0, 0 143 .word 0xED900B00 // aarch32: vldr d0, [r0] 144 test_complete 0 aarch32 145 146 exception_vector LOWER_EL_ARCH32_BASE, SYNC_EXC_OFFSET 147 mov x0, CPACR_EL1_FPEN_NO_TRAP 148 msr cpacr_el1, x0 149 eret 150FUNCTION vcpu_aarch32_fp_end 151 152// Test vcpu_read_state and vcpu_write_state. 153FUNCTION vcpu_read_write_state_start 154 add x1, x1, #1 155 add x2, x2, #2 156 add x3, x3, #3 157 add x4, x4, #4 158 add x5, x5, #5 159 add x6, x6, #6 160 add x7, x7, #7 161 add x8, x8, #8 162 add x9, x9, #9 163 add x10, x10, #10 164 add x11, x11, #11 165 add x12, x12, #12 166 add x13, x13, #13 167 add x14, x14, #14 168 add x15, x15, #15 169 add x16, x16, #16 170 add x17, x17, #17 171 add x18, x18, #18 172 add x19, x19, #19 173 add x20, x20, #20 174 add x21, x21, #21 175 add x22, x22, #22 176 add x23, x23, #23 177 add x24, x24, #24 178 add x25, x25, #25 179 add x26, x26, #26 180 add x27, x27, #27 181 add x28, x28, #28 182 add x29, x29, #29 183 add x30, x30, #30 184 185 add sp, sp, #64 186 cmp sp, #128 // Set ZC bits of CPSR. 187 188 test_complete 189FUNCTION vcpu_read_write_state_end 190 191// Test guest_set_trap using a memory-based trap. 192FUNCTION guest_set_trap_start 193 mov x0, TRAP_ADDR 194 str xzr, [x0] 195 test_complete 196FUNCTION guest_set_trap_end 197