1/*
2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <autoconf.h>
10#include <sel4/functions.h>
11#include <sel4/types.h>
12
13#ifdef CONFIG_KERNEL_MCS
14#define MCS_PARAM_DECL(r)    register seL4_Word reply_reg asm(r) = reply;
15#define MCS_PARAM    , "r"(reply_reg)
16#else
17#define MCS_PARAM_DECL(r)
18#define MCS_PARAM
19#endif
20
21
22static inline void x64_sys_send(seL4_Word sys, seL4_Word dest, seL4_Word info, seL4_Word msg0, seL4_Word msg1,
23                                seL4_Word msg2, seL4_Word msg3)
24{
25    register seL4_Word mr0 asm("r10") = msg0;
26    register seL4_Word mr1 asm("r8") = msg1;
27    register seL4_Word mr2 asm("r9") = msg2;
28    register seL4_Word mr3 asm("r15") = msg3;
29
30    asm volatile(
31        "movq   %%rsp, %%rcx        \n"
32        "leaq   1f, %%rdx           \n"
33        "1:                         \n"
34        "sysenter                   \n"
35        :
36        : "a"(sys),
37        "D"(dest),
38        "S"(info),
39        "r"(mr0),
40        "r"(mr1),
41        "r"(mr2),
42        "r"(mr3)
43        : "%rcx", "%rdx"
44    );
45}
46
47#ifndef CONFIG_KERNEL_MCS
48static inline void x64_sys_reply(seL4_Word sys, seL4_Word info, seL4_Word msg0, seL4_Word msg1, seL4_Word msg2,
49                                 seL4_Word msg3)
50{
51    register seL4_Word mr0 asm("r10") = msg0;
52    register seL4_Word mr1 asm("r8") = msg1;
53    register seL4_Word mr2 asm("r9") = msg2;
54    register seL4_Word mr3 asm("r15") = msg3;
55
56    asm volatile(
57        "movq   %%rsp, %%rcx        \n"
58        "leaq   1f, %%rdx           \n"
59        "1:                         \n"
60        "sysenter                   \n"
61        :
62        : "a"(sys),
63        "S"(info),
64        "r"(mr0),
65        "r"(mr1),
66        "r"(mr2),
67        "r"(mr3)
68        : "%rdx", "%rcx"
69    );
70}
71#endif
72
73static inline void x64_sys_send_null(seL4_Word sys, seL4_Word dest, seL4_Word info)
74{
75    asm volatile(
76        "movq   %%rsp, %%rcx        \n"
77        "leaq   1f, %%rdx           \n"
78        "1:                         \n"
79        "sysenter                   \n"
80        :
81        : "a"(sys),
82        "D"(dest),
83        "S"(info)
84        : "%rcx", "%rdx"
85    );
86}
87
88static inline void x64_sys_recv(seL4_Word sys, seL4_Word src, seL4_Word *out_badge, seL4_Word *out_info,
89                                seL4_Word *out_mr0, seL4_Word *out_mr1, seL4_Word *out_mr2, seL4_Word *out_mr3, LIBSEL4_UNUSED seL4_Word reply)
90{
91    register seL4_Word mr0 asm("r10");
92    register seL4_Word mr1 asm("r8");
93    register seL4_Word mr2 asm("r9");
94    register seL4_Word mr3 asm("r15");
95    MCS_PARAM_DECL("r12");
96
97    asm volatile(
98        "movq   %%rsp, %%rcx    \n"
99        "leaq   1f, %%rdx       \n"
100        "1:                     \n"
101        "sysenter               \n"
102        : "=D"(*out_badge),
103        "=S"(*out_info),
104        "=r"(mr0),
105        "=r"(mr1),
106        "=r"(mr2),
107        "=r"(mr3)
108        : "a"(sys),
109        "D"(src),
110        MCS_PARAM
111        : "%rcx", "%rdx", "memory"
112    );
113
114    *out_mr0 = mr0;
115    *out_mr1 = mr1;
116    *out_mr2 = mr2;
117    *out_mr3 = mr3;
118}
119
120static inline void x64_sys_send_recv(seL4_Word sys, seL4_Word dest, seL4_Word *out_dest, seL4_Word info,
121                                     seL4_Word *out_info, seL4_Word *in_out_mr0, seL4_Word *in_out_mr1, seL4_Word *in_out_mr2, seL4_Word *in_out_mr3,
122                                     LIBSEL4_UNUSED seL4_Word reply)
123{
124    register seL4_Word mr0 asm("r10") = *in_out_mr0;
125    register seL4_Word mr1 asm("r8") = *in_out_mr1;
126    register seL4_Word mr2 asm("r9") = *in_out_mr2;
127    register seL4_Word mr3 asm("r15") = *in_out_mr3;
128    MCS_PARAM_DECL("r12");
129
130    asm volatile(
131        "movq   %%rsp, %%rcx    \n"
132        "leaq   1f, %%rdx       \n"
133        "1:                     \n"
134        "sysenter               \n"
135        : "=S"(*out_info),
136        "=r"(mr0),
137        "=r"(mr1),
138        "=r"(mr2),
139        "=r"(mr3),
140        "=D"(*out_dest)
141        : "a"(sys),
142        "D"(dest),
143        "S"(info),
144        "r"(mr0),
145        "r"(mr1),
146        "r"(mr2),
147        "r"(mr3),
148        MCS_PARAM
149        : "%rcx", "%rdx", "memory"
150    );
151
152    *in_out_mr0 = mr0;
153    *in_out_mr1 = mr1;
154    *in_out_mr2 = mr2;
155    *in_out_mr3 = mr3;
156}
157
158#ifdef CONFIG_KERNEL_MCS
159static inline void x64_sys_nbsend_recv(seL4_Word sys, seL4_Word dest, seL4_Word src, seL4_Word *out_dest,
160                                       seL4_Word info, seL4_Word *out_info, seL4_Word *in_out_mr0, seL4_Word *in_out_mr1, seL4_Word *in_out_mr2,
161                                       seL4_Word *in_out_mr3, seL4_Word reply)
162{
163    register seL4_Word mr0 asm("r10") = *in_out_mr0;
164    register seL4_Word mr1 asm("r8") = *in_out_mr1;
165    register seL4_Word mr2 asm("r9") = *in_out_mr2;
166    register seL4_Word mr3 asm("r15") = *in_out_mr3;
167    register seL4_Word reply_reg asm("r12") = reply;
168    register seL4_Word dest_reg asm("r13") = dest;
169
170    asm volatile(
171        "movq   %%rsp, %%rcx    \n"
172        "leaq   1f, %%rdx       \n"
173        "1:                     \n"
174        "sysenter               \n"
175        : "=S"(*out_info),
176        "=r"(mr0),
177        "=r"(mr1),
178        "=D"(*out_dest)
179        : "a"(sys),
180        "D"(src),
181        "S"(info),
182        "r"(mr0),
183        "r"(mr1),
184        "r"(reply_reg),
185        "r"(dest_reg)
186        : "%rcx", "%rdx", "memory"
187    );
188
189    *in_out_mr0 = mr0;
190    *in_out_mr1 = mr1;
191    *in_out_mr2 = mr2;
192    *in_out_mr3 = mr3;
193}
194#endif
195
196static inline void x64_sys_null(seL4_Word sys)
197{
198    asm volatile(
199        "movq   %%rsp, %%rcx    \n"
200        "leaq   1f, %%rdx       \n"
201        "1:                     \n"
202        "sysenter               \n"
203        :
204        : "a"(sys)
205        : "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "memory"
206    );
207}
208
209