1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
8 * See "LICENSE_GPLv2.txt" for details.
9 *
10 * @TAG(DATA61_GPL)
11 */
12
13#ifndef __ARCH_MODE_MACHINE_REGISTERSET_H_
14#define __ARCH_MODE_MACHINE_REGISTERSET_H_
15
16/* These are the indices of the registers in the
17 * saved thread context. The values are determined
18 * by the order in which they're saved in the trap
19 * handler.
20 *
21 * BEWARE:
22 * You will have to adapt traps.S extensively if
23 * you change anything in this enum!
24 */
25
26/* This register layout is optimized for usage with
27 * the syscall and sysret instructions. Interrupts
28 * and sysenter have to do some juggling to make
29 * things work */
30enum _register {
31    // User registers that will be preserved during syscall
32    // Deliberately place the cap and badge registers early
33    // So that when popping on the fastpath we can just not
34    // pop these
35    RDI                     = 0,    /* 0x00 */
36    capRegister             = 0,
37    badgeRegister           = 0,
38    RSI                     = 1,    /* 0x08 */
39    msgInfoRegister         = 1,
40    RAX                     = 2,    /* 0x10 */
41    RBX                     = 3,    /* 0x18 */
42    RBP                     = 4,    /* 0x20 */
43    R12                     = 5,    /* 0x28 */
44    R13                     = 6,    /* 0x30 */
45    R14                     = 7,    /* 0x38 */
46    RDX                     = 8,    /* 0x40 */
47    // Group the message registers so they can be efficiently copied
48    R10                     = 9,    /* 0x48 */
49    R8                      = 10,   /* 0x50 */
50    R9                      = 11,   /* 0x58 */
51    R15                     = 12,   /* 0x60 */
52    FLAGS                   = 13,   /* 0x68 */
53    // Put the NextIP, which is a virtual register, here as we
54    // need to set this in the syscall path
55    NextIP                  = 14,   /* 0x70 */
56    // Same for the error code
57    Error                   = 15,   /* 0x78 */
58    RSP                     = 16,   /* 0x80 */
59    // For locality put these here as well
60    TLS_BASE                = 17,   /* 0x88 */
61    FaultIP                 = 18,   /* 0x90 */
62    // Now user Registers that get clobbered by syscall
63    R11                     = 19,   /* 0x98 */
64    RCX                     = 20,   /* 0xa0 */
65    CS                      = 21,   /* 0xa8 */
66    SS                      = 22,   /* 0xb0 */
67
68    n_contextRegisters      = 23    /* 0xb8 */
69};
70
71typedef uint32_t register_t;
72
73enum messageSizes {
74    n_msgRegisters = seL4_FastMessageRegisters,
75    n_frameRegisters = 18,
76    n_gpRegisters = 1,
77    n_exceptionMessage = 3,
78    n_syscallMessage = 18
79};
80
81#define SYSCALL_MESSAGE \
82{    \
83    [seL4_UnknownSyscall_RAX] = RAX,\
84    [seL4_UnknownSyscall_RBX] = RBX,\
85    [seL4_UnknownSyscall_RCX] = RCX,\
86    [seL4_UnknownSyscall_RDX] = RDX,\
87    [seL4_UnknownSyscall_RSI] = RSI,\
88    [seL4_UnknownSyscall_RDI] = RDI,\
89    [seL4_UnknownSyscall_RBP] = RBP,\
90    [seL4_UnknownSyscall_R8]  = R8,\
91    [seL4_UnknownSyscall_R9]  = R9,\
92    [seL4_UnknownSyscall_R10] = R10,\
93    [seL4_UnknownSyscall_R11] = R11,\
94    [seL4_UnknownSyscall_R12] = R12,\
95    [seL4_UnknownSyscall_R13] = R13,\
96    [seL4_UnknownSyscall_R14] = R14,\
97    [seL4_UnknownSyscall_R15] = R15,\
98    [seL4_UnknownSyscall_FaultIP] = FaultIP,\
99    [seL4_UnknownSyscall_SP] = RSP,\
100    [seL4_UnknownSyscall_FLAGS] = FLAGS\
101}
102
103#define EXCEPTION_MESSAGE \
104{ \
105    [seL4_UserException_FaultIP] = FaultIP,\
106    [seL4_UserException_SP] = RSP,\
107    [seL4_UserException_FLAGS] = FLAGS\
108}
109
110extern const register_t msgRegisters[];
111extern const register_t frameRegisters[];
112extern const register_t gpRegisters[];
113
114#define FPU_PADDING word_t padding[1];
115
116#endif /* __ARCH_MODE_MACHINE_REGISTERSET_H_ */
117