1/**
2 * \file
3 * \brief Capability invocations specific to the monitors
4 */
5
6/*
7 * Copyright (c) 2007, 2008, 2009, 2010, 2012, 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, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#ifndef MONITOR_INVOCATIONS_ARCH_H
16#define MONITOR_INVOCATIONS_ARCH_H
17
18#include <barrelfish/syscall_arch.h>
19#include <barrelfish/caddr.h>
20#include <barrelfish/invocations_arch.h>
21#include <barrelfish_kpi/cpu.h>
22#include <barrelfish_kpi/syscall_overflows_arch.h>
23#include <barrelfish_kpi/syscalls.h>
24
25static inline errval_t
26invoke_monitor_remote_relations(capaddr_t root_cap, int root_bits,
27                                capaddr_t cap, int bits,
28                                uint8_t relations, uint8_t mask,
29                                uint8_t *ret_remote_relations)
30{
31    struct sysret r = cap_invoke6(cap_kernel, KernelCmd_Remote_relations,
32                                  root_cap, root_bits, cap, bits,
33                                  ((uint16_t)relations) | (((uint16_t)mask)<<8));
34    if (err_is_ok(r.error) && ret_remote_relations) {
35        *ret_remote_relations = r.value;
36    }
37    return r.error;
38}
39
40static inline errval_t
41invoke_monitor_cap_has_relations(capaddr_t caddr, uint8_t bits, uint8_t mask,
42                                 uint8_t *res)
43{
44    assert(res);
45    struct sysret ret = cap_invoke4(cap_kernel, KernelCmd_Cap_has_relations,
46                                    caddr, bits, mask);
47    if (err_is_ok(ret.error)) {
48        *res = ret.value;
49    }
50    return ret.error;
51}
52
53static inline errval_t
54invoke_monitor_identify_cap(capaddr_t cap, int bits, struct capability *out)
55{
56    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
57    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
58
59    return syscall5((invoke_bits << 16) | (KernelCmd_Identify_cap << 8)
60                    | SYSCALL_INVOKE, invoke_cptr, cap, bits,
61                    (uintptr_t)out).error;
62}
63
64static inline errval_t
65invoke_monitor_identify_domains_cap(capaddr_t root_cap, int root_bits,
66                                    capaddr_t cap, int bits,
67                                    struct capability *out)
68{
69    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
70    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
71
72    return syscall7((invoke_bits << 16) | (KernelCmd_Identify_domains_cap << 8)
73                    | SYSCALL_INVOKE, invoke_cptr, root_cap, root_bits,
74                    cap, bits, (uintptr_t)out).error;
75}
76
77static inline errval_t
78invoke_monitor_nullify_cap(capaddr_t cap, int bits)
79{
80    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
81    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
82
83    return syscall4((invoke_bits << 16) | (KernelCmd_Nullify_cap << 8)
84                    | SYSCALL_INVOKE, invoke_cptr, cap, bits).error;
85}
86
87static inline errval_t
88invoke_monitor_create_cap(uint64_t *raw, capaddr_t caddr, int bits,
89                          capaddr_t slot, coreid_t owner)
90{
91    assert(sizeof(struct capability) <= 3*sizeof(uint64_t));
92
93    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
94    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
95
96    return syscall7((invoke_bits << 16) | (KernelCmd_Create_cap << 8)
97                    | SYSCALL_INVOKE, invoke_cptr, caddr, bits, slot, owner,
98                    (uintptr_t)raw).error;
99}
100
101static inline errval_t
102invoke_monitor_register(struct capref ep)
103{
104    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
105    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
106
107    return syscall3((invoke_bits << 16) | (KernelCmd_Register << 8)
108                    | SYSCALL_INVOKE, invoke_cptr, get_cap_addr(ep)).error;
109}
110
111/**
112 * \brief Set up tracing in the kernel
113 *
114 */
115static inline errval_t
116invoke_trace_setup(struct capref cap)
117{
118    USER_PANIC("NYI");
119    return LIB_ERR_NOT_IMPLEMENTED;
120#if 0
121    struct idc_send_msg msg;
122    idc_msg_init(&msg);
123    idc_msg_encode_word(&msg, KernelCmd_Setup_trace);
124    idc_msg_encode_word(&msg, get_cap_addr(cap));
125    return cap_invoke(cap_kernel, &msg);
126#endif
127}
128
129static inline errval_t
130invoke_domain_id(struct capref cap, domainid_t domain_id)
131{
132    USER_PANIC("NYI");
133    return LIB_ERR_NOT_IMPLEMENTED;
134#if 0
135    struct idc_send_msg msg;
136    idc_msg_init(&msg);
137    idc_msg_encode_word(&msg, KernelCmd_Domain_Id);
138    idc_msg_encode_word(&msg, get_cap_addr(cap));
139    idc_msg_encode_word(&msg, domain_id);
140    return cap_invoke(cap_kernel, &msg);
141#endif
142}
143
144static inline errval_t
145invoke_monitor_ipi_register(struct capref ep, int chanid)
146{
147    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
148    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
149
150    return syscall4((invoke_bits << 16) | (KernelCmd_IPI_Register << 8)
151                    | SYSCALL_INVOKE, invoke_cptr,
152                    get_cap_addr(ep),
153                    chanid).error;
154}
155
156static inline errval_t
157invoke_monitor_ipi_delete(int chanid)
158{
159    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
160    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
161
162    return syscall3((invoke_bits << 16) | (KernelCmd_IPI_Delete << 8)
163                    | SYSCALL_INVOKE, invoke_cptr,
164                    chanid).error;
165}
166
167static inline errval_t
168invoke_monitor_get_arch_id(uintptr_t *arch_id)
169{
170    assert(arch_id != NULL);
171
172    struct sysret sysret = cap_invoke1(cap_kernel, KernelCmd_Get_arch_id);
173    if (sysret.error == SYS_ERR_OK) {
174        *arch_id = sysret.value;
175    }
176    return sysret.error;
177}
178
179static inline errval_t invoke_monitor_sync_timer(uint64_t synctime)
180{
181    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
182    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
183
184    return syscall4((invoke_bits << 16) | (KernelCmd_Sync_timer << 8)
185                    | SYSCALL_INVOKE, invoke_cptr, synctime >> 32,
186                    synctime & 0xffffffff).error;
187}
188
189static inline errval_t
190invoke_monitor_add_kcb(uintptr_t kcb_base)
191{
192    assert(kcb_base);
193    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
194    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
195
196    return syscall3((invoke_bits << 16) | (KernelCmd_Add_kcb << 8) | SYSCALL_INVOKE,
197                    invoke_cptr,
198                    kcb_base).error;
199}
200
201static inline errval_t
202invoke_monitor_remove_kcb(uintptr_t kcb_base)
203{
204    assert(kcb_base);
205
206    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
207    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
208
209    return syscall3((invoke_bits << 16) | (KernelCmd_Remove_kcb << 8) | SYSCALL_INVOKE,
210                    invoke_cptr,
211                    kcb_base).error;
212}
213
214static inline errval_t
215invoke_monitor_suspend_kcb_scheduler(bool suspend)
216{
217    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
218    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
219
220    return syscall3((invoke_bits << 16) | (KernelCmd_Suspend_kcb_sched << 8) | SYSCALL_INVOKE,
221                    invoke_cptr,
222                    suspend).error;
223}
224
225static inline errval_t
226invoke_monitor_remote_cap_retype(capaddr_t rootcap_addr, uint8_t rootcap_vbits,
227                                 capaddr_t src, enum objtype newtype,
228                                 int objbits, capaddr_t to, capaddr_t slot,
229                                 int bits)
230{
231    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
232    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
233
234    assert(newtype <= ObjType_Num);
235    assert(objbits <= 0xff);
236    assert(bits <= 0xff);
237
238    struct remote_retype_syscall_overflow rootcap_struct = {
239        .rootcap_addr = rootcap_addr,
240        .rootcap_vbits = rootcap_vbits,
241    };
242
243    // arguments 2-5 must match the deserialisation in
244    // kernel/arch/x86_32/handle_retype_common.
245    return syscall7((invoke_bits << 16) | (KernelCmd_Retype << 8) | SYSCALL_INVOKE,
246            invoke_cptr, (uintptr_t)&rootcap_struct, src,
247            (newtype << 16) | (objbits << 8) | bits, to, slot).error;
248}
249
250static inline errval_t
251invoke_monitor_copy_existing(uint64_t *raw, capaddr_t cn_addr, int cn_bits, cslot_t slot)
252{
253    // XXX: this is assumed in client code of this function!
254    assert(sizeof(struct capability) <= 3*sizeof(uint64_t));
255
256    return cap_invoke5(cap_kernel, KernelCmd_Copy_existing,
257                       cn_addr, cn_bits, slot, (uintptr_t)raw).error;
258}
259
260static inline errval_t
261invoke_monitor_get_cap_owner(capaddr_t root, int rbits, capaddr_t cap, int cbits, coreid_t *ret_owner)
262{
263    struct sysret sysret = cap_invoke5(cap_kernel, KernelCmd_Get_cap_owner,
264                                       root, rbits, cap, cbits);
265    if (err_is_ok(sysret.error)) {
266        *ret_owner = sysret.value;
267    }
268    return sysret.error;
269}
270
271static inline errval_t
272invoke_monitor_set_cap_owner(capaddr_t root, int rbits, capaddr_t cap, int cbits, coreid_t owner)
273{
274    return cap_invoke6(cap_kernel, KernelCmd_Set_cap_owner, root, rbits, cap, cbits, owner).error;
275}
276
277static inline errval_t
278invoke_monitor_lock_cap(capaddr_t root, int rbits, capaddr_t cap, int cbits)
279{
280    return cap_invoke5(cap_kernel, KernelCmd_Lock_cap, root, rbits, cap, cbits).error;
281}
282
283static inline errval_t
284invoke_monitor_unlock_cap(capaddr_t root, int rbits, capaddr_t cap, int cbits)
285{
286    return cap_invoke5(cap_kernel, KernelCmd_Unlock_cap, root, rbits, cap, cbits).error;
287}
288
289static inline errval_t
290invoke_monitor_delete_last(capaddr_t root, int rbits, capaddr_t cap, int cbits,
291                           capaddr_t retcn, int retcnbits, cslot_t retslot)
292{
293    assert(rbits <= 0xff);
294    assert(cbits <= 0xff);
295    assert(retcnbits <= 0xff);
296
297    return cap_invoke6(cap_kernel, KernelCmd_Delete_last, root, cap,
298                       retcn, retslot, ((cbits<<16)|(rbits<<8)|retcnbits)).error;
299}
300
301static inline errval_t
302invoke_monitor_delete_foreigns(capaddr_t cap, int bits)
303{
304    return cap_invoke3(cap_kernel, KernelCmd_Delete_foreigns, cap, bits).error;
305}
306
307static inline errval_t
308invoke_monitor_revoke_mark_target(capaddr_t root, int rbits,
309                                  capaddr_t cap, int cbits)
310{
311    return cap_invoke5(cap_kernel, KernelCmd_Revoke_mark_target,
312                       root, rbits, cap, cbits).error;
313}
314
315static inline errval_t
316invoke_monitor_revoke_mark_relations(uint64_t *raw_base)
317{
318    // XXX: this is assumed in client code of this function!
319    assert(sizeof(struct capability) <= 3*sizeof(uint64_t));
320    return cap_invoke2(cap_kernel, KernelCmd_Revoke_mark_relations,
321                       (uintptr_t)raw_base).error;
322}
323
324static inline errval_t
325invoke_monitor_delete_step(capaddr_t retcn, int retcnbits, cslot_t retslot)
326{
327    return cap_invoke4(cap_kernel, KernelCmd_Delete_step,
328                       retcn, retcnbits, retslot).error;
329}
330
331static inline errval_t
332invoke_monitor_clear_step(capaddr_t retcn, int retcnbits, cslot_t retslot)
333{
334    return cap_invoke4(cap_kernel, KernelCmd_Clear_step,
335                       retcn, retcnbits, retslot).error;
336}
337
338static inline errval_t
339invoke_monitor_has_descendants(uint64_t *raw, bool *res)
340{
341    // XXX: this is assumed in client code of this function!
342    assert(sizeof(struct capability) <= 3*sizeof(uint64_t));
343
344    struct sysret sysret;
345    sysret = cap_invoke2(cap_kernel, KernelCmd_Has_descendants,
346                         (uintptr_t)raw);
347    if (err_is_ok(sysret.error)) {
348        *res = sysret.value;
349    }
350    return sysret.error;
351}
352
353#endif
354