1 /* 2 * Copyright (c) 2014 Travis Geiselbrecht 3 * 4 * Use of this source code is governed by a MIT-style 5 * license that can be found in the LICENSE file or at 6 * https://opensource.org/licenses/MIT 7 */ 8 #pragma once 9 10 #include <stdbool.h> 11 #include <sys/types.h> 12 #include <lk/compiler.h> 13 14 __BEGIN_CDECLS 15 16 #define DSB __asm__ volatile("dsb sy" ::: "memory") 17 #define ISB __asm__ volatile("isb" ::: "memory") 18 19 #define STRINGIFY(x) #x 20 #define TOSTRING(x) STRINGIFY(x) 21 22 #define ARM64_READ_SYSREG(reg) \ 23 ({ \ 24 uint64_t _val; \ 25 __asm__ volatile("mrs %0," TOSTRING(reg) : "=r" (_val)); \ 26 _val; \ 27 }) 28 29 #define ARM64_WRITE_SYSREG(reg, val) \ 30 ({ \ 31 __asm__ volatile("msr " TOSTRING(reg) ", %0" :: "r" (val)); \ 32 ISB; \ 33 }) 34 35 void arm64_context_switch(vaddr_t *old_sp, vaddr_t new_sp); 36 37 /* exception handling */ 38 struct arm64_iframe_long { 39 uint64_t r[30]; 40 uint64_t lr; 41 uint64_t usp; 42 uint64_t elr; 43 uint64_t spsr; 44 }; 45 46 struct arm64_iframe_short { 47 uint64_t r[18]; 48 uint64_t lr; 49 uint64_t usp; 50 uint64_t elr; 51 uint64_t spsr; 52 }; 53 54 struct arm64_stackframe { 55 uint64_t fp; 56 uint64_t pc; 57 }; 58 59 struct thread; 60 extern void arm64_exception_base(void); 61 void arm64_el3_to_el1(void); 62 void arm64_fpu_exception(struct arm64_iframe_long *iframe); 63 void arm64_fpu_save_state(struct thread *thread); 64 arm64_fpu_pre_context_switch(struct thread * thread)65static inline void arm64_fpu_pre_context_switch(struct thread *thread) { 66 uint32_t cpacr = ARM64_READ_SYSREG(cpacr_el1); 67 if ((cpacr >> 20) & 3) { 68 arm64_fpu_save_state(thread); 69 cpacr &= ~(3 << 20); 70 ARM64_WRITE_SYSREG(cpacr_el1, cpacr); 71 } 72 } 73 74 /* overridable syscall handler */ 75 void arm64_syscall(struct arm64_iframe_long *iframe, bool is_64bit); 76 77 /* Local per-cpu cache flush routines. 78 * These routines clean or invalidate the cache from the point of view 79 * of a single cpu to the point of coherence. 80 */ 81 void arm64_local_invalidate_cache_all(void); 82 void arm64_local_clean_invalidate_cache_all(void); 83 void arm64_local_clean_cache_all(void); 84 85 __END_CDECLS 86 87