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 82            /* 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
65union 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 r9; // r9 is the platform register, and holds the GOT base.
71        uint32_t r10, r11, r12;
72        uint32_t stack;
73        uint32_t link;
74        uint32_t pc;
75        uint32_t fpscr;
76        uint64_t d0, d1, d2, d3, d4, d5, d6, d7;
77        uint64_t d8, d9, d10, d11, d12, d13, d14, d15;
78        uint64_t d16, d17, d18, d19, d20, d21, d22, d23;
79        uint64_t d24, d25, d26, d27, d28, d29, d30, d31;
80    } named;
81    struct registers_arm_syscall_args {
82        uint32_t cpsr;
83        uint32_t arg0, arg1, arg2, arg3;
84        uint32_t arg4, arg5, arg6, arg7, arg8;
85        uint32_t arg9;
86        uint32_t arg10;
87        uint32_t fp;
88        uint32_t arg11;
89        uint32_t stack;
90        uint32_t link;
91        uint32_t pc;
92    } syscall_args;
93    uint32_t regs[sizeof(struct registers_arm_named) / sizeof(uint32_t)];
94};
95
96STATIC_ASSERT_SIZEOF(union registers_arm, (17 + 64 + 1) * 4);
97
98///< Opaque handle for the register state
99typedef union registers_arm arch_registers_state_t;
100
101static inline void
102registers_set_entry(arch_registers_state_t *regs, lvaddr_t entry)
103{
104    regs->named.pc = (uint32_t)entry;
105}
106
107static inline void
108registers_set_param(arch_registers_state_t *regs, uint32_t param)
109{
110    regs->named.r0 = param;
111}
112
113static inline void
114registers_get_param(arch_registers_state_t *regs, uintptr_t *param)
115{
116    *param = regs->named.r0;
117}
118
119static inline uint32_t
120registers_get_ip(arch_registers_state_t *regs)
121{
122    return regs->named.pc;
123}
124
125static inline uint32_t
126registers_get_sp(arch_registers_state_t *regs)
127{
128    return regs->named.stack;
129}
130
131#endif // __ASSEMBLER__
132
133#endif // ARCH_ARM_BARRELFISH_KPI_REGISTERS_H
134