1 #ifndef __ASM_ARM_ARM32_PROCESSOR_H
2 #define __ASM_ARM_ARM32_PROCESSOR_H
3 
4 #include <asm/cpregs.h>
5 
6 #define ACTLR_CAXX_SMP      (1<<6)
7 
8 #ifndef __ASSEMBLY__
9 /* On stack VCPU state */
10 struct cpu_user_regs
11 {
12     uint32_t r0;
13     uint32_t r1;
14     uint32_t r2;
15     uint32_t r3;
16     uint32_t r4;
17     uint32_t r5;
18     uint32_t r6;
19     uint32_t r7;
20     uint32_t r8;
21     uint32_t r9;
22     uint32_t r10;
23     union {
24         uint32_t r11;
25         uint32_t fp;
26     };
27     uint32_t r12;
28 
29     uint32_t sp; /* r13 - SP: Valid for Hyp. frames only, o/w banked (see below) */
30 
31     /* r14 - LR: is the same physical register as LR_usr */
32     union {
33         uint32_t lr; /* r14 - LR: Valid for Hyp. Same physical register as lr_usr. */
34 
35         uint32_t lr_usr;
36     };
37 
38     union {  /* Return IP, pc32 is used to allow code to be common with 64-bit */
39         uint32_t pc, pc32;
40     };
41     uint32_t cpsr; /* Return mode */
42     uint32_t hsr;  /* Exception Syndrome */
43 
44     /* Outer guest frame only from here on... */
45 
46     uint32_t sp_usr; /* LR_usr is the same register as LR, see above */
47 
48     uint32_t sp_irq, lr_irq;
49     uint32_t sp_svc, lr_svc;
50     uint32_t sp_abt, lr_abt;
51     uint32_t sp_und, lr_und;
52 
53     uint32_t r8_fiq, r9_fiq, r10_fiq, r11_fiq, r12_fiq;
54     uint32_t sp_fiq, lr_fiq;
55 
56     uint32_t spsr_svc, spsr_abt, spsr_und, spsr_irq, spsr_fiq;
57 
58     uint32_t pad1; /* Doubleword-align the user half of the frame */
59 };
60 
61 #endif
62 
63 /* Layout as used in assembly, with src/dest registers mixed in */
64 #define __CP32(r, coproc, opc1, crn, crm, opc2) coproc, opc1, r, crn, crm, opc2
65 #define __CP64(r1, r2, coproc, opc, crm) coproc, opc, r1, r2, crm
66 #define CP32(r, name...) __CP32(r, name)
67 #define CP64(r, name...) __CP64(r, name)
68 
69 /* Stringified for inline assembly */
70 #define LOAD_CP32(r, name...)  "mrc " __stringify(CP32(%r, name)) ";"
71 #define STORE_CP32(r, name...) "mcr " __stringify(CP32(%r, name)) ";"
72 #define LOAD_CP64(r, name...)  "mrrc " __stringify(CP64(%r, %H##r, name)) ";"
73 #define STORE_CP64(r, name...) "mcrr " __stringify(CP64(%r, %H##r, name)) ";"
74 
75 /* Issue a CP operation which takes no argument,
76  * uses r0 as a placeholder register. */
77 #define CMD_CP32(name...)      "mcr " __stringify(CP32(r0, name)) ";"
78 
79 #ifndef __ASSEMBLY__
80 
81 /* C wrappers */
82 #define READ_CP32(name...) ({                                   \
83     register uint32_t _r;                                       \
84     asm volatile(LOAD_CP32(0, name) : "=r" (_r));               \
85     _r; })
86 
87 #define WRITE_CP32(v, name...) do {                             \
88     register uint32_t _r = (v);                                 \
89     asm volatile(STORE_CP32(0, name) : : "r" (_r));             \
90 } while (0)
91 
92 #define READ_CP64(name...) ({                                   \
93     register uint64_t _r;                                       \
94     asm volatile(LOAD_CP64(0, name) : "=r" (_r));               \
95     _r; })
96 
97 #define WRITE_CP64(v, name...) do {                             \
98     register uint64_t _r = (v);                                 \
99     asm volatile(STORE_CP64(0, name) : : "r" (_r));             \
100 } while (0)
101 
102 /*
103  * C wrappers for accessing system registers.
104  *
105  * Registers come in 3 types:
106  * - those which are always 32-bit regardless of AArch32 vs AArch64
107  *   (use {READ,WRITE}_SYSREG32).
108  * - those which are always 64-bit regardless of AArch32 vs AArch64
109  *   (use {READ,WRITE}_SYSREG64).
110  * - those which vary between AArch32 and AArch64 (use {READ,WRITE}_SYSREG).
111  */
112 #define READ_SYSREG32(R...)     READ_CP32(R)
113 #define WRITE_SYSREG32(V, R...) WRITE_CP32(V, R)
114 
115 #define READ_SYSREG64(R...)     READ_CP64(R)
116 #define WRITE_SYSREG64(V, R...) WRITE_CP64(V, R)
117 
118 #define READ_SYSREG(R...)       READ_SYSREG32(R)
119 #define WRITE_SYSREG(V, R...)   WRITE_SYSREG32(V, R)
120 
121 #endif /* __ASSEMBLY__ */
122 
123 #endif /* __ASM_ARM_ARM32_PROCESSOR_H */
124 /*
125  * Local variables:
126  * mode: C
127  * c-file-style: "BSD"
128  * c-basic-offset: 4
129  * indent-tabs-mode: nil
130  * End:
131  */
132