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/*! \file dispatcher.h
14    @brief Common shared dispatcher definitions and helper functions.
15
16    Shared helper functions and constant definitions for dispatchers, which every dispatcher should
17    most likely needs and should include to reduce code duplication.
18*/
19
20#ifndef _REFOS_PROCESS_SERVER_DISPATCHER_DISPATCHER_COMMON_H_
21#define _REFOS_PROCESS_SERVER_DISPATCHER_DISPATCHER_COMMON_H_
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <stdint.h>
26#include <stdbool.h>
27#include <sel4/sel4.h>
28
29#include "../common.h"
30#include "../state.h"
31#include "../badge.h"
32#include "../system/process/pid.h"
33#include "../system/process/process.h"
34#include "../system/memserv/ringbuffer.h"
35#include "../system/memserv/dataspace.h"
36
37 /*! @file
38     @brief Common Process server dispatcher helper functions. */
39
40#define DISPATCH_SUCCESS 0
41#define DISPATCH_PASS -1
42#define DISPATCH_ERROR -2
43
44#define SET_ERRNO_PTR(e, ev) if (e) {(*e) = (ev);}
45
46extern seL4_MessageInfo_t _dispatcherEmptyReply;
47
48/*! @brief Notify an async endpoint with a message. (non-blocking)
49    @param endpoint The endpoint to notify through.
50 */
51static inline void
52dispatcher_notify(seL4_CPtr endpoint)
53{
54    seL4_MessageInfo_t notifyTag = seL4_MessageInfo_new(PROCSERV_NOTIFY_TAG, 0, 0, 0);
55    seL4_Send(endpoint, notifyTag);
56}
57
58/*! @brief Checks whether a badge is an PID badge.
59    @param badge The badge to check.
60    @return true if the badge is an PID badge, false otherwise.
61 */
62static inline bool
63dispatcher_badge_PID(seL4_Word badge)
64{
65    return (badge >= PID_BADGE_BASE && badge < PID_BADGE_END);
66}
67
68/*! @brief Checks whether a badge is a client liveliness badge.
69    @param badge The badge to check.
70    @return true if the badge is a liveliness badge, false otherwise.
71 */
72static inline bool
73dispatcher_badge_liveness(seL4_Word badge)
74{
75    return (badge >= PID_LIVENESS_BADGE_BASE && badge < PID_LIVENESS_BADGE_END);
76}
77
78/*! @brief Checks whether a given badge is a ram dataspace.
79    @param badge The badge to check.
80    @return true if the given badge is a valid ram dataspace ID, false otherwise.
81 */
82static inline bool
83dispatcher_badge_dspace(seL4_Word badge)
84{
85    return (badge >= RAM_DATASPACE_BADGE_BASE && badge < RAM_DATASPACE_BADGE_END);
86}
87
88/*! @brief Checks whether a given badge is a window.
89    @param badge The badge to check.
90    @return true if the given badge is a valid windowID, false otherwise.
91 */
92static inline bool
93dispatcher_badge_window(seL4_Word badge)
94{
95    return (badge >= W_BADGE_BASE && badge < W_BADGE_END);
96}
97
98/*! @brief Helper function to check for an interface.
99
100    Most of the other check_dispatcher_*_interface functions use call this helper function, that
101    does most of the real work. It generates a usable userptr containing the client_t structure of
102    the calling process. If the calling syscall label enum is outside of given range,  DISPATCH_PASS
103    is returned.
104
105    @param m The recieved message structure.
106    @param userptr Output userptr containing corresponding client, to be passed into generated
107                   interface dispatcher function.
108    @param labelMin The minimum syscall label to accept.
109    @param labelMax The maximum syscall label to accept.
110*/
111int check_dispatch_interface(struct procserv_msg *m, void **userptr, int labelMin, int labelMax);
112
113/*! @brief Helper function to check recieved caps and unwrapped mask.
114    @param m The recieved message.
115    @param unwrappedMask The expected capability unwrap mask.
116    @param numExtraCaps The expected nubmer of recieved capabilities.
117    @return true if the recieved message capabilities match the unwrapped mask and number, false
118            if there is a mismatck and the recieved caps are invalid.
119*/
120bool check_dispatch_caps(struct procserv_msg *m, seL4_Word unwrappedMask, int numExtraCaps);
121
122/*! @brief Helper function to copy out a given capability. Used by dispatchers to quickly copy out
123           a recieved capability.
124    @param c The capability to copy out.
125    @return A copy of the given capability if success, 0 otherwise. (Ownership transferred.)
126*/
127seL4_CPtr dispatcher_copyout_cptr(seL4_CPtr c);
128
129/*! @brief Helper function to release a copied-out capability and free its cslot.
130    @param c The copied out capability to release (Takes ownership).
131*/
132void dispatcher_release_copyout_cptr(seL4_CPtr c);
133
134/*! @brief Reads the contents of the given process's param buffer.
135    @param pcb The PCB of the process to read parameter buffer from.
136    @param readLen The length in bytes to read from the parambuffer.
137    @return A static temporary buffer with contents of parameter buffer. (No ownership)
138*/
139char* dispatcher_read_param(struct proc_pcb *pcb, uint32_t readLen);
140
141#endif /* _REFOS_PROCESS_SERVER_DISPATCHER_DISPATCHER_COMMON_H_ */