1 #ifndef __ARM_CURRENT_H__
2 #define __ARM_CURRENT_H__
3
4 #include <xen/page-size.h>
5 #include <xen/percpu.h>
6
7 #include <asm/processor.h>
8 #include <asm/sysregs.h>
9
10 /* Tell whether the guest vCPU enabled Workaround 2 (i.e variant 4) */
11 #define CPUINFO_WORKAROUND_2_FLAG_SHIFT 0
12 #define CPUINFO_WORKAROUND_2_FLAG (_AC(1, U) << CPUINFO_WORKAROUND_2_FLAG_SHIFT)
13
14 #ifndef __ASSEMBLY__
15
16 struct vcpu;
17
18 /* Which VCPU is "current" on this PCPU. */
19 DECLARE_PER_CPU(struct vcpu *, curr_vcpu);
20
21 #define current (this_cpu(curr_vcpu))
22 #define set_current(vcpu) do { current = (vcpu); } while (0)
23 #define get_cpu_current(cpu) (per_cpu(curr_vcpu, cpu))
24
25 /* Per-VCPU state that lives at the top of the stack */
26 struct cpu_info {
27 struct cpu_user_regs guest_cpu_user_regs;
28 unsigned long elr;
29 uint32_t flags;
30 };
31
get_cpu_info(void)32 static inline struct cpu_info *get_cpu_info(void)
33 {
34 #ifdef __clang__
35 unsigned long sp;
36
37 asm ("mov %0, sp" : "=r" (sp));
38 #else
39 register unsigned long sp asm ("sp");
40 #endif
41
42 return (struct cpu_info *)((sp & ~(STACK_SIZE - 1)) +
43 STACK_SIZE - sizeof(struct cpu_info));
44 }
45
46 #define guest_cpu_user_regs() (&get_cpu_info()->guest_cpu_user_regs)
47
48 #define switch_stack_and_jump(stack, fn) do { \
49 asm volatile ("mov sp,%0; b " STR(fn) : : "r" (stack), "X" (fn) : "memory" ); \
50 unreachable(); \
51 } while ( false )
52
53 #define reset_stack_and_jump(fn) switch_stack_and_jump(get_cpu_info(), fn)
54
55 DECLARE_PER_CPU(unsigned int, cpu_id);
56
57 #define smp_processor_id() this_cpu(cpu_id)
58 #define set_processor_id(id) \
59 do { \
60 WRITE_SYSREG(__per_cpu_offset[(id)], TPIDR_EL2); \
61 this_cpu(cpu_id) = (id); \
62 } while ( 0 )
63
64 #define get_per_cpu_offset() READ_SYSREG(TPIDR_EL2)
65
66 #endif
67
68 #endif /* __ARM_CURRENT_H__ */
69 /*
70 * Local variables:
71 * mode: C
72 * c-file-style: "BSD"
73 * c-basic-offset: 4
74 * indent-tabs-mode: nil
75 * End:
76 */
77