1/*
2 * Copyright 2016, 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 BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(D61_BSD)
11 */
12
13#ifndef _RPC_INTERFACE_PROC_CLIENT_HELPER_H_
14#define _RPC_INTERFACE_PROC_CLIENT_HELPER_H_
15
16#include <refos-rpc/rpc.h>
17#include <refos/refos.h>
18#include <refos/error.h>
19#include <refos-rpc/proc_client.h>
20#include <refos-util/cspace.h>
21
22/*! @file
23    @brief Helper functions for the process server interface.
24
25    This file contains a simple layer of helper functions that make using the procserv interface
26    much easier, but are too complex to have been generated by the stub generator.
27*/
28
29/* Should mirror definitions in window.h. */
30#define PROC_WINDOW_PERMISSION_WRITE 0x1
31#define PROC_WINDOW_PERMISSION_READ 0x2
32#define PROC_WINDOW_PERMISSION_READWRITE \
33        (PROC_WINDOW_PERMISSION_WRITE | PROC_WINDOW_PERMISSION_READ)
34#define PROC_WINDOW_FLAGS_UNCACHED 0x1
35
36seL4_CPtr rpc_copyout_cptr(seL4_CPtr v);
37
38/*! @brief Create a new sync endpoint. Helper function for proc_new_endpoint_internal().
39    @return Recieved cap if success, 0 otherwise.
40*/
41static inline seL4_CPtr
42proc_new_endpoint(void) {
43    refos_err_t errnoRetVal = EINVALID;
44    seL4_CPtr tcap = proc_new_endpoint_internal(&errnoRetVal);
45    if (errnoRetVal != ESUCCESS || tcap == 0) {
46        REFOS_SET_ERRNO(errnoRetVal);
47        return 0;
48    }
49    REFOS_SET_ERRNO(ESUCCESS);
50    return tcap;
51}
52
53/*! @brief Delete a created endpoint. */
54static inline void
55proc_del_endpoint(seL4_CPtr ep) {
56    seL4_CNode_Delete(REFOS_CSPACE, ep, REFOS_CSPACE_DEPTH);
57    csfree(ep);
58}
59
60/*! @brief Create a new sync endpoint. Helper function for proc_new_async_endpoint_internal().
61    @return Recieved cap if success, 0 otherwise.
62*/
63static inline seL4_CPtr
64proc_new_async_endpoint(void) {
65    refos_err_t errnoRetVal = EINVALID;
66    seL4_CPtr tcap = proc_new_async_endpoint_internal(&errnoRetVal);
67    if (errnoRetVal != ESUCCESS || tcap == 0) {
68        REFOS_SET_ERRNO(errnoRetVal);
69        return 0;
70    }
71    REFOS_SET_ERRNO(ESUCCESS);
72    return tcap;
73}
74
75/*! @brief Delete a created async endpoint. */
76static inline void
77proc_del_async_endpoint(seL4_CPtr ep) {
78    seL4_CNode_Delete(REFOS_CSPACE, ep, REFOS_CSPACE_DEPTH);
79    csfree(ep);
80}
81
82/*! @brief Create a new sync endpoint, and then mints a badged async endpoint from it, before
83           discarding the capability to the original.
84    @param badge The badge to mint endpoint with.
85    @return Minted cap if success, 0 otherwise.
86*/
87static inline seL4_CPtr
88proc_new_async_endpoint_badged(int badge) {
89    seL4_CPtr tcap = proc_new_async_endpoint();
90    if (!tcap) {
91        return 0;
92    }
93    seL4_CPtr bgcap = csalloc();
94    if (!bgcap) {
95        proc_del_async_endpoint(tcap);
96        REFOS_SET_ERRNO(ENOMEM);
97        return 0;
98    }
99    /* Mint the badged cap. */
100    int error = seL4_CNode_Mint (
101        REFOS_CSPACE, bgcap, REFOS_CDEPTH,
102        REFOS_CSPACE, tcap, REFOS_CDEPTH,
103        seL4_AllRights, seL4_CapData_Badge_new(badge)
104    );
105    if (error != seL4_NoError) {
106        proc_del_async_endpoint(tcap);
107        REFOS_SET_ERRNO(EINVALID);
108        return 0;
109    }
110    proc_del_async_endpoint(tcap);
111    REFOS_SET_ERRNO(ESUCCESS);
112    return bgcap;
113}
114
115/*! @brief Create a new memory window segment (with extra parameters). Helper function for
116           proc_create_mem_window_internal().
117    @param vaddr The window base address in the calling client's VSpace.
118    @param size The size of the mem window.
119    @param permission The read / write permission bitmask.
120    @param flags The flags bitmask (cached / uncached).
121    @return Capability to created window if success, 0 otherwise (errno will be set).
122*/
123static inline seL4_CPtr
124proc_create_mem_window_ext(uint32_t vaddr, uint32_t size, uint32_t permission, uint32_t flags)
125{
126    refos_err_t errnoRetVal = EINVALID;
127    seL4_CPtr tcap = proc_create_mem_window_internal(vaddr, size, permission, flags, &errnoRetVal);
128    if (errnoRetVal != ESUCCESS || tcap == 0) {
129        REFOS_SET_ERRNO(errnoRetVal);
130        return 0;
131    }
132    REFOS_SET_ERRNO(ESUCCESS);
133    return tcap;
134}
135
136/*! @brief Create a new memory window segment. Helper function for
137           proc_create_mem_window_internal(). Permission is set to PROC_WINDOW_PERMISSION_READWRITE,
138           and flags 0x0.
139    @param vaddr The window base address in the calling client's VSpace.
140    @param size The size of the mem window.
141    @return Capability to created window if success, 0 otherwise (errno will be set).
142*/
143static inline seL4_CPtr
144proc_create_mem_window(uint32_t vaddr, uint32_t size)
145{
146    return proc_create_mem_window_ext(vaddr, size, PROC_WINDOW_PERMISSION_READWRITE, 0x0);
147}
148
149/*! @brief Clones a new thread for process. Helper function for proc_clone_internal().
150    @param func The entry point function of the new thread.
151    @param childStack The stack vaddr of the new thread.
152    @param flags Unused, must be 0.
153    @param arg Unused, must be 0.
154    @return threadID if success, negative if error occured (errno will be set).
155*/
156static inline int
157proc_clone(int (*func)(void *), void *childStack, int flags, void *arg)
158{
159    (void) flags;
160    refos_err_t errnoRetVal = EINVALID;
161    int threadID = proc_clone_internal((seL4_Word) func, (seL4_Word) childStack, flags,
162            (seL4_Word) arg, &errnoRetVal);
163    REFOS_SET_ERRNO(errnoRetVal);
164    return threadID;
165}
166
167#endif /* _RPC_INTERFACE_PROC_CLIENT_HELPER_H_ */
168