d6213fa347e0be8153d318947c5d3cd76a56c672
[barrelfish] / include / arch / arm / barrelfish_kpi / registers_arch.h
1 /**
2  * \file
3  * \brief architecture-specific registers code
4  */
5
6 /*
7  * Copyright (c) 2010, ETH Zurich.
8  * All rights reserved.
9  *
10  * This file is distributed under the terms in the attached LICENSE file.
11  * If you do not find this file, copies can be found by writing to:
12  * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13  */
14
15 #ifndef ARCH_ARM_BARRELFISH_KPI_REGISTERS_H
16 #define ARCH_ARM_BARRELFISH_KPI_REGISTERS_H
17
18 #ifndef __ASSEMBLER__
19 #include<stddef.h> // for offsetof
20 #include <barrelfish/curdispatcher_arch.h> // XXX For curdispatcher()
21 #include <barrelfish_kpi/types.h> // for lvaddr_t
22 #endif
23
24 //
25 // Offsets of saved registers in save area.
26 //
27 #define CPSR_REG  0
28 #define R0_REG    1
29 #define R1_REG    2
30 #define R2_REG    3
31 #define R3_REG    4
32 #define R4_REG    5
33 #define R5_REG    6
34 #define R6_REG    7
35 #define R7_REG    8
36 #define R8_REG    9
37 #define R9_REG   10
38 #define R10_REG  11
39 #define R11_REG  12
40 #define R12_REG  13
41 #define SP_REG   14
42 #define LR_REG   15
43 #define PC_REG   16
44
45 #define NUM_REGS 17            /* cpsr, r0-r15 */
46 #define NUM_FPU_REGS 0
47 #define ARCH_NUMREGS NUM_REGS
48
49 #define RIP_REG  PC_REG        /* r15 = pc == rip.x86_64 */
50 #define RSP_REG  SP_REG        /* r13 = sp == rsp.x86_64 */
51
52 /// Register used in system calls to encode function and arg count
53 #define SYSCALL_REG       0
54
55 //
56 // Helpers for pasting system reserved register names
57 //
58 #define REG_OFFSET_CONCAT(x)    x ## _REG
59 #define REG_OFFSET(name)        REG_OFFSET_CONCAT(name)
60
61 #define REG_NAME(ord)
62
63 #ifndef __ASSEMBLER__
64
65 union registers_arm {
66     struct registers_arm_named {
67         uint32_t cpsr;
68         uint32_t r0, r1, r2, r3;
69         uint32_t r4, r5, r6, r7, r8;
70         uint32_t rtls;  // r9 is thread local storage
71         uint32_t r10;   // r10 is for global offset table base.
72         uint32_t r11, r12;
73         uint32_t stack;
74         uint32_t link;
75         uint32_t pc;
76     } named;
77     struct registers_arm_syscall_args {
78         uint32_t cpsr;
79         uint32_t arg0, arg1, arg2, arg3;
80         uint32_t arg4, arg5, arg6, arg7, arg8;
81         uint32_t arg9;
82         uint32_t arg10;
83         uint32_t fp;
84         uint32_t arg11;
85         uint32_t stack;
86         uint32_t link;
87         uint32_t pc;
88     } syscall_args;
89     uint32_t regs[sizeof(struct registers_arm_named) / sizeof(uint32_t)];
90 };
91
92 STATIC_ASSERT_SIZEOF(union registers_arm, 17 * 4);
93
94 STATIC_ASSERT((REG_OFFSET(THREAD_REGISTER) * sizeof(uint32_t)) == offsetof(struct registers_arm_named, rtls), "Thread register conflict");
95
96
97 ///< Opaque handle for the register state
98 typedef union registers_arm arch_registers_state_t;
99
100 ///< Opaque handle for the FPU register state
101 typedef void *arch_registers_fpu_state_t;
102
103 static inline void
104 registers_set_entry(arch_registers_state_t *regs, lvaddr_t entry)
105 {
106     regs->named.pc = (uint32_t)entry;
107 }
108
109 static inline void
110 registers_set_param(arch_registers_state_t *regs, uint32_t param)
111 {
112     regs->named.r0 = param;
113 }
114
115 static inline void
116 registers_get_param(arch_registers_state_t *regs, uint32_t *param)
117 {
118     *param = regs->named.r0;
119 }
120
121 static inline uint32_t
122 registers_get_ip(arch_registers_state_t *regs)
123 {
124     return regs->named.pc;
125 }
126
127 static inline uint32_t
128 registers_get_sp(arch_registers_state_t *regs)
129 {
130     return regs->named.stack;
131 }
132
133 #endif // __ASSEMBLER__
134
135 #endif // ARCH_ARM_BARRELFISH_KPI_REGISTERS_H