aboutsummaryrefslogtreecommitdiff
path: root/common/arm/arm_builtins.h
blob: ae03bff5ba1f32ab03f7813282dc29c6b94f27d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#ifndef _ARM_BUILTINS_H
#define _ARM_BUILTINS_H

#include <stdint.h>

#define CPTR_TFP    (1 << 10)
#define CPTR_TCPAC  (1 << 31)
#define SCTLR_nTWI  (1 << 16)
#define SCTLR_nTWE  (1 << 18)
#define SCR_WFI     (1 << 12)
#define SCR_WFE     (1 << 13)

#define __get_exception_return(_addr) \
    asm volatile("mov r0, r0\n")

#define __get_exception_address(_addr) \
    asm volatile("mov r0, r0\n")

extern uintptr_t read_scr();
extern void write_scr(uintptr_t);
extern uintptr_t read_sder();
extern void write_sder(uintptr_t);
extern uintptr_t read_cptr();
extern void write_cptr(uintptr_t);
extern uintptr_t read_cpacr();
extern void write_cpacr(uintptr_t);
extern uintptr_t read_cpacr();
extern void write_cpacr(uintptr_t);
extern uintptr_t read_sctlr();
extern void write_sctlr(uintptr_t);
extern uintptr_t read_mvbar();
extern void write_mvbar(uintptr_t);
extern uintptr_t read_nsacr();
extern void write_nsacr(uintptr_t);
extern uintptr_t read_dfar();
extern void write_dfsr(uintptr_t);
extern uintptr_t read_dfsr();
extern void write_dfar(uintptr_t);
extern uintptr_t read_ifar();
extern void write_ifar(uintptr_t);
extern uintptr_t read_ifsr();
extern void write_ifsr(uintptr_t);
extern void __set_exception_return(uintptr_t);
extern void __exception_return(uintptr_t, uint32_t);

#define READ_SCR() read_scr()
#define WRITE_SCR(_val) write_scr(_val)
#define READ_SDER() read_sder()
#define WRITE_SDER(_val) write_sder(_val)
#define READ_CPACR() read_cpacr()
#define WRITE_CPACR(_val) write_cpacr(_val)
#define READ_MVBAR() read_mvbar()
#define WRITE_MVBAR(_val) write_mvbar(_val)
#define READ_NSACR() read_nsacr()
#define WRITE_NSACR(_val) write_nsacr(_val)

#if REMOVE_OR_INTEGRATE
#define __cps(_r0) asm volatile ("cps %[r0]\n":: [r0] "X" (_r0))

#define __mrs(_r0, _reg) asm volatile ("mrs %[r0], "#_reg"\n" : [r0] "=r" (_r0))
#define __msr(_reg, _r0) asm volatile ("msr "#_reg", %[r0]\n" :: [r0] "r" (_r0))

#define __srsdb_svc(_mode) asm volatile ("srsdb sp!, #0x13\n")

#define __pop(_r0) \
    asm volatile ("pop {%[r0]}\n" : [r0] "=r" (_r0))

#define __mrc(_cp, _opc1, _r0, _crm, _crn, _opc2)                           \
    asm volatile (                                                          \
        "mrc p"#_cp", "#_opc1", %[r0], c"#_crm", c"#_crn", "#_opc2"\n"      \
        : [r0] "=r" (_r0)                                                   \
    )

#define __mcr(_cp, _opc1, _r0, _crm, _crn, _opc2)                           \
    asm volatile (                                                          \
        "mcr p"#_cp", "#_opc1", %[r0], c"#_crm", c"#_crn", "#_opc2"\n"      \
        : : [r0] "r" (_r0)                                                  \
    )

#define _READCP(_reg, _cp, _opc1, _crm, _crn, _opc2)    \
    static inline uint32_t _read_##_reg() {             \
        volatile int _r0 = -1;                          \
        __mrc(_cp, _opc1, _r0, _crm, _crn, _opc2);      \
        return _r0;                                     \
    }

#define _WRITECP(_reg, _cp, _opc1, _crm, _crn, _opc2)       \
    static inline uint32_t  _write_##_reg(uint32_t _r0) {   \
        __mcr(_cp, _opc1, _r0, _crm, _crn, _opc2);          \
        return 0;                                           \
    }

#define _RWCP(_reg, _cp, _opc1, _crm, _crn, _opc2)  \
    _READCP(_reg, _cp, _opc1, _crm, _crn, _opc2)    \
    _WRITECP(_reg, _cp, _opc1, _crm, _crn, _opc2)

_RWCP(scr, 15, 0, 1, 1, 0)           /* _read/write_scr */
_RWCP(sder, 15, 0, 1, 1, 1)          /* _read/write_sder */
_RWCP(nsacr, 15, 0, 1, 1, 2)         /* _read/write_nsacr */
_RWCP(mvbar, 15, 0, 12, 0, 1)        /* _read/write_mvbar */

/* Banked read/write CP register definitions */
_RWCP(csselr, 15, 2, 0, 0, 0)        /* _read/write_csselr */
_RWCP(sctlr, 15, 0, 1, 0, 0)         /* _read/write_sctlr */
_RWCP(actlr, 15, 0, 1, 0, 1)         /* _read/write_actlr */
_RWCP(ttbr0, 15, 0, 2, 0, 0)         /* _read/write_ttbr0 */
_RWCP(ttbr1, 15, 0, 2, 0, 1)         /* _read/write_ttbr1 */
_RWCP(ttbcr, 15, 0, 2, 0, 2)         /* _read/write_ttbcr */
_RWCP(dacr, 15, 0, 3, 0, 0)          /* _read/write_dacr */
_RWCP(dfsr, 15, 0, 5, 0, 0)          /* _read/write_dfsr */
_RWCP(ifsr, 15, 0, 5, 0, 1)          /* _read/write_ifsr */
_RWCP(dfar, 15, 0, 6, 0, 0)          /* _read/write_dfar */
_RWCP(ifar, 15, 0, 6, 0, 2)          /* _read/write_ifar */
_RWCP(par, 15, 0, 7, 4, 0)           /* _read/write_par */
_RWCP(prrr, 15, 0, 10, 2, 0)         /* _read/write_prrr */
_RWCP(nmrr, 15, 0, 10, 2, 1)         /* _read/write_nmrr */
_RWCP(vbar, 15, 0, 12, 0, 0)         /* _read/write_vbar */
_RWCP(fcseidr, 15, 0, 13, 0, 0)      /* _read/write_fcseidr */
_RWCP(contextidr, 15, 0, 13, 0, 1)   /* _read/write_contextidr*/
_RWCP(tpidrurw, 15, 0, 13, 0, 2)     /* _read/write_tpidrurw */
_RWCP(tpidruro, 15, 0, 13, 0, 3)     /* _read/write_tpidruro */
_RWCP(tpidrprw, 15, 0, 13, 0, 4)     /* _read/write_tpidrprw */

static inline uint32_t _read_cpsr() {
    uint32_t r0 = 0;
    __mrs(r0, cpsr);
    return r0;
}

static inline void _write_cpsr(uint32_t val) {
    __msr(cpsr_fsxc, val);
}
#endif
#endif