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)65 static 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