1/*
2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#pragma once
8
9/* These are the indices of the registers in the
10 * saved thread context. The values are determined
11 * by the order in which they're saved in the trap
12 * handler.
13 *
14 * BEWARE:
15 * You will have to adapt traps.S extensively if
16 * you change anything in this enum!
17 */
18
19/* This register layout is optimized for usage with
20 * the syscall and sysret instructions. Interrupts
21 * and sysenter have to do some juggling to make
22 * things work */
23enum _register {
24    // User registers that will be preserved during syscall
25    // Deliberately place the cap and badge registers early
26    // So that when popping on the fastpath we can just not
27    // pop these
28    RDI                     = 0,    /* 0x00 */
29    capRegister             = 0,
30    badgeRegister           = 0,
31    RSI                     = 1,    /* 0x08 */
32    msgInfoRegister         = 1,
33    RAX                     = 2,    /* 0x10 */
34    RBX                     = 3,    /* 0x18 */
35    RBP                     = 4,    /* 0x20 */
36    R12                     = 5,    /* 0x28 */
37#ifdef CONFIG_KERNEL_MCS
38    replyRegister           = 5,
39#endif
40    R13                     = 6,    /* 0x30 */
41#ifdef CONFIG_KERNEL_MCS
42    nbsendRecvDest          = 6,
43#endif
44    R14                     = 7,    /* 0x38 */
45    RDX                     = 8,    /* 0x40 */
46    // Group the message registers so they can be efficiently copied
47    R10                     = 9,    /* 0x48 */
48    R8                      = 10,   /* 0x50 */
49    R9                      = 11,   /* 0x58 */
50    R15                     = 12,   /* 0x60 */
51    FLAGS                   = 13,   /* 0x68 */
52    // Put the NextIP, which is a virtual register, here as we
53    // need to set this in the syscall path
54    NextIP                  = 14,   /* 0x70 */
55    // Same for the error code
56    Error                   = 15,   /* 0x78 */
57    /* Kernel stack points here on kernel entry */
58    RSP                     = 16,   /* 0x80 */
59    FaultIP                 = 17,   /* 0x88 */
60    // Now user Registers that get clobbered by syscall
61    R11                     = 18,   /* 0x90 */
62    RCX                     = 19,   /* 0x98 */
63    CS                      = 20,   /* 0xa0 */
64    SS                      = 21,   /* 0xa8 */
65    n_immContextRegisters   = 22,   /* 0xb0 */
66
67    // For locality put these here as well
68    FS_BASE                 = 22,   /* 0xb0 */
69    TLS_BASE                = FS_BASE,
70    GS_BASE                 = 23,   /* 0xb8 */
71
72    n_contextRegisters      = 24    /* 0xc0 */
73};
74
75typedef uint32_t register_t;
76
77enum messageSizes {
78    n_msgRegisters = seL4_FastMessageRegisters,
79    n_frameRegisters = 18,
80    n_gpRegisters = 2,
81    n_exceptionMessage = 3,
82    n_syscallMessage = 18,
83#ifdef CONFIG_KERNEL_MCS
84    n_timeoutMessage = 19,
85#endif
86};
87
88#define SYSCALL_MESSAGE \
89{    \
90    [seL4_UnknownSyscall_RAX] = RAX,\
91    [seL4_UnknownSyscall_RBX] = RBX,\
92    [seL4_UnknownSyscall_RCX] = RCX,\
93    [seL4_UnknownSyscall_RDX] = RDX,\
94    [seL4_UnknownSyscall_RSI] = RSI,\
95    [seL4_UnknownSyscall_RDI] = RDI,\
96    [seL4_UnknownSyscall_RBP] = RBP,\
97    [seL4_UnknownSyscall_R8]  = R8,\
98    [seL4_UnknownSyscall_R9]  = R9,\
99    [seL4_UnknownSyscall_R10] = R10,\
100    [seL4_UnknownSyscall_R11] = R11,\
101    [seL4_UnknownSyscall_R12] = R12,\
102    [seL4_UnknownSyscall_R13] = R13,\
103    [seL4_UnknownSyscall_R14] = R14,\
104    [seL4_UnknownSyscall_R15] = R15,\
105    [seL4_UnknownSyscall_FaultIP] = FaultIP,\
106    [seL4_UnknownSyscall_SP] = RSP,\
107    [seL4_UnknownSyscall_FLAGS] = FLAGS\
108}
109
110#define EXCEPTION_MESSAGE \
111{ \
112    [seL4_UserException_FaultIP] = FaultIP,\
113    [seL4_UserException_SP] = RSP,\
114    [seL4_UserException_FLAGS] = FLAGS\
115}
116
117#define TIMEOUT_REPLY_MESSAGE \
118{ \
119    [seL4_TimeoutReply_FaultIP] = FaultIP,\
120    [seL4_TimeoutReply_RSP] = RSP,\
121    [seL4_TimeoutReply_FLAGS] = FLAGS,\
122    [seL4_TimeoutReply_RAX] = RAX,\
123    [seL4_TimeoutReply_RBX] = RBX,\
124    [seL4_TimeoutReply_RCX] = RCX,\
125    [seL4_TimeoutReply_RDX] = RDX,\
126    [seL4_TimeoutReply_RSI] = RSI,\
127    [seL4_TimeoutReply_RDI] = RDI,\
128    [seL4_TimeoutReply_RBP] = RBP,\
129    [seL4_TimeoutReply_R8] = R8,\
130    [seL4_TimeoutReply_R9] = R9,\
131    [seL4_TimeoutReply_R10] = R10,\
132    [seL4_TimeoutReply_R11] = R11,\
133    [seL4_TimeoutReply_R12] = R12,\
134    [seL4_TimeoutReply_R13] = R13,\
135    [seL4_TimeoutReply_R14] = R14,\
136    [seL4_TimeoutReply_R15] = R15,\
137    [seL4_TimeoutReply_TLS_BASE] = TLS_BASE,\
138}
139
140extern const register_t msgRegisters[];
141extern const register_t frameRegisters[];
142extern const register_t gpRegisters[];
143
144#define FPU_PADDING word_t padding[1];
145
146