]> rtime.felk.cvut.cz Git - jailhouse.git/blob - hypervisor/arch/arm/include/asm/percpu.h
arm: Use asm-defines.h for struct per_cpu members
[jailhouse.git] / hypervisor / arch / arm / include / asm / percpu.h
1 /*
2  * Jailhouse, a Linux-based partitioning hypervisor
3  *
4  * Copyright (c) Siemens AG, 2013
5  *
6  * Authors:
7  *  Jan Kiszka <jan.kiszka@siemens.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.  See
10  * the COPYING file in the top-level directory.
11  */
12
13 #ifndef _JAILHOUSE_ASM_PERCPU_H
14 #define _JAILHOUSE_ASM_PERCPU_H
15
16 #include <jailhouse/types.h>
17 #include <asm/paging.h>
18
19 #define NUM_ENTRY_REGS                  13
20
21 #ifndef __ASSEMBLY__
22
23 #include <jailhouse/cell.h>
24 #include <asm/psci.h>
25 #include <asm/spinlock.h>
26 #include <asm/sysregs.h>
27
28 /* Round up sizeof(struct per_cpu) to the next power of two. */
29 #define PERCPU_SIZE_SHIFT \
30         (BITS_PER_LONG - __builtin_clzl(sizeof(struct per_cpu) - 1))
31
32 struct pending_irq;
33
34 struct per_cpu {
35         u8 stack[PAGE_SIZE];
36         unsigned long linux_sp;
37         unsigned long linux_ret;
38         unsigned long linux_flags;
39         unsigned long linux_reg[NUM_ENTRY_REGS];
40
41         unsigned int cpu_id;
42         unsigned int virt_id;
43
44         /* Other CPUs can insert sgis into the pending array */
45         spinlock_t gic_lock;
46         struct pending_irq *pending_irqs;
47         struct pending_irq *first_pending;
48         /* Only GICv3: redistributor base */
49         void *gicr_base;
50
51         struct cell *cell;
52
53         u32 stats[JAILHOUSE_NUM_CPU_STATS];
54
55         bool initialized;
56
57         /* The mbox will be accessed with a ldrd, which requires alignment */
58         __attribute__((aligned(8))) struct psci_mbox psci_mbox;
59         struct psci_mbox guest_mbox;
60
61         bool flush_vcpu_caches;
62         int shutdown_state;
63         bool shutdown;
64         bool failed;
65 } __attribute__((aligned(PAGE_SIZE)));
66
67 static inline struct per_cpu *this_cpu_data(void)
68 {
69         struct per_cpu *cpu_data;
70
71         arm_read_sysreg(TPIDR_EL2, cpu_data);
72         return cpu_data;
73 }
74
75 #define DEFINE_PER_CPU_ACCESSOR(field)                                  \
76 static inline typeof(((struct per_cpu *)0)->field) this_##field(void)   \
77 {                                                                       \
78         return this_cpu_data()->field;                                  \
79 }
80
81 DEFINE_PER_CPU_ACCESSOR(cpu_id)
82 DEFINE_PER_CPU_ACCESSOR(cell)
83
84 static inline struct per_cpu *per_cpu(unsigned int cpu)
85 {
86         extern u8 __page_pool[];
87
88         return (struct per_cpu *)(__page_pool + (cpu << PERCPU_SIZE_SHIFT));
89 }
90
91 static inline struct registers *guest_regs(struct per_cpu *cpu_data)
92 {
93         /* Assumes that the trap handler is entered with an empty stack */
94         return (struct registers *)(cpu_data->stack + sizeof(cpu_data->stack)
95                         - sizeof(struct registers));
96 }
97
98 static inline unsigned int arm_cpu_phys2virt(unsigned int cpu_id)
99 {
100         return per_cpu(cpu_id)->virt_id;
101 }
102
103 unsigned int arm_cpu_virt2phys(struct cell *cell, unsigned int virt_id);
104 #endif /* !__ASSEMBLY__ */
105
106 #endif /* !_JAILHOUSE_ASM_PERCPU_H */