1251877Speter/*
2251877Speter * Copyright 2016, Data61
3251877Speter * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4251877Speter * ABN 41 687 119 230.
5251877Speter *
6251877Speter * This software may be distributed and modified according to the terms of
7251877Speter * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8251877Speter * See "LICENSE_BSD2.txt" for details.
9251877Speter *
10251877Speter * @TAG(D61_BSD)
11251877Speter */
12251877Speter
13251877Speter#ifndef _SERVER_COMMON_HELPER_LIBRARY_H_
14251877Speter#define _SERVER_COMMON_HELPER_LIBRARY_H_
15251877Speter
16251877Speter#include <stdio.h>
17251877Speter#include <stdlib.h>
18251877Speter#include <stdint.h>
19251877Speter#include <stdbool.h>
20251877Speter#include <sel4/sel4.h>
21251877Speter#include <refos/refos.h>
22251877Speter#include <refos-util/dprintf.h>
23251877Speter#include <refos-util/serv_connect.h>
24251877Speter#include <refos-rpc/data_client.h>
25251877Speter#include <refos-rpc/data_client_helper.h>
26251877Speter#include <refos-rpc/proc_common.h>
27251877Speter
28251877Speter/*! @file
29251877Speter    @brief Server common shared helper functions.
30251877Speter
31251877Speter    This module implements helper functions to help reduce the work required to get a RefOS server
32251877Speter    up and running. It handles the most common setup cases for servers, especially dataspace
33251877Speter    servers, including endpoint creation, registration, and so forth.
34251877Speter*/
35251877Speter
36251877Speter#ifndef CONFIG_REFOS_DEBUG
37251877Speter    #define printf(x,...)
38251877Speter#endif /* CONFIG_REFOS_DEBUG */
39251877Speter
40251877Speter#define SRV_UNBADGED 0
41251877Speter#define SRV_DEFAULT_MAX_CLIENTS PROCSERV_MAX_PROCESSES
42251877Speter#define SRV_DEFAULT_NOTIFICATION_BUFFER_SIZE 0x8000
43251877Speter#define SRV_DEFAULT_PARAM_BUFFER_SIZE 0x2000
44251877Speter#define SRV_MAGIC 0x261A2055
45251877Speter
46251877Speter#ifndef SET_ERRNO_PTR
47251877Speter    #define SET_ERRNO_PTR(e, ev) if (e) {(*e) = (ev);}
48251877Speter#endif
49251877Speter
50251877Speter/*! @brief Common server dispatcher message structure.
51251877Speter
52251877Speter    Simple structure containing the seL4 message and seL4 badge recieved from the IPC.
53251877Speter*/
54251877Spetertypedef struct srv_msg {
55251877Speter    seL4_MessageInfo_t message;
56251877Speter    seL4_Word badge;
57251877Speter} srv_msg_t;
58251877Speter
59251877Speter
60251877Speter/*! @brief Enum to keep track of the common server dispatching return values. */
61251877Speterenum srv_dispatch_return_code_enum {
62251877Speter    DISPATCH_ERROR = -2,     /*!< A dispatch error has occured. Should not happen. */
63251877Speter    DISPATCH_PASS,           /*!< Wrong dispatcher. Pass onto another one. */
64251877Speter    DISPATCH_SUCCESS         /*!< This is the correct dispatcher, or correctly dispatched. */
65251877Speter};
66251877Speter
67251877Speter/*! @brief Common server state configuration.
68251877Speter
69251877Speter    This structure stores the server's configuration, including things like name to register under,
70251877Speter    badge layouts, number of max clients, and so forth. Servers wishing to use this library should
71251877Speter    fill this config structure with their configuration parameters then pass this into
72251877Speter    srv_common_init().
73251877Speter*/
74251877Spetertypedef struct srv_common_config {
75251877Speter    /*! @brief Maximum number of clients in the client table. Set to 0 to disable. */
76251877Speter    int maxClients;
77251877Speter    uint32_t clientBadgeBase; /*!< @brief Client badge number base. */
78251877Speter    uint32_t clientMagic; /*!< @brief Client structure magic number identifier. */
79251877Speter
80251877Speter    /*! @brief Size of death / fault notification buffer. Set to 0 to disable. */
81251877Speter    int notificationBufferSize;
82251877Speter    /*! @brief Size of procserv parameter buffer. Set to 0 to disable. */
83251877Speter    int paramBufferSize;
84251877Speter
85251877Speter    /*! @brief Server name, used for debug printing. */
86251877Speter    char* serverName;
87251877Speter    /*! @brief Server registration mountpoint. NULL to disable registration. */
88251877Speter    char* mountPointPath;
89251877Speter    /*! @brief Server registration parent nameserver, to register under. */
90251877Speter    seL4_CPtr nameServEP;
91251877Speter
92251877Speter    /*! @brief Fault / death async notification badge number. */
93251877Speter    uint32_t faultDeathNotifyBadge;
94251877Speter} srv_common_config_t;
95251877Speter
96251877Speterstruct srv_common;
97251877Spetertypedef struct srv_common srv_common_t;
98251877Speter
99251877Speter/*! @brief Common server state structure. */
100251877Speterstruct srv_common {
101251877Speter    uint32_t magic;
102251877Speter    srv_common_config_t config;
103251877Speter
104251877Speter    /* Endpoints and badges. */
105251877Speter    seL4_CPtr anonEP;
106251877Speter    seL4_CPtr notifyAsyncEP;
107251877Speter    seL4_CPtr notifyClientFaultDeathAsyncEP;
108251877Speter
109251877Speter    /* Mapped shared buffers. */
110251877Speter    data_mapping_t notifyBuffer;
111251877Speter    size_t notifyBufferStart;
112251877Speter    data_mapping_t procServParamBuffer;
113251877Speter
114251877Speter    /* Client table structure. */
115251877Speter    struct srv_client_table clientTable;
116251877Speter
117251877Speter    /* Default client table handlers. These should provide a simple default implementation for
118251877Speter       the serv interface defined in the generated <refos-rpc/serv_server.h>. */
119251877Speter
120251877Speter    struct srv_client* (*ctable_connect_direct_handler) (srv_common_t *srv, srv_msg_t *m,
121251877Speter            seL4_CPtr liveness, int* _errno);
122251877Speter
123251877Speter    refos_err_t (*ctable_set_param_buffer_handler) (srv_common_t *srv, struct srv_client *c,
124251877Speter            srv_msg_t *m, seL4_CPtr parambufferDataspace, uint32_t parambufferSize);
125251877Speter
126251877Speter    void (*ctable_disconnect_direct_handler) (srv_common_t *srv, struct srv_client *c);
127251877Speter};
128251877Speter
129251877Speter/*! @brief Notification handler callback type. */
130251877Spetertypedef int (*srv_notify_handler_callback_fn_t)(struct proc_notification *notification);
131251877Speter
132251877Speter/*! @brief Notification handler callbacks structure. */
133251877Spetertypedef struct srv_common_notify_handler_callbacks {
134251877Speter    srv_notify_handler_callback_fn_t handle_server_fault;
135251877Speter    srv_notify_handler_callback_fn_t handle_server_content_init;
136    srv_notify_handler_callback_fn_t handle_server_death_notification;
137} srv_common_notify_handler_callbacks_t;
138
139/*! @brief Initialise server common state.
140    @param s The common server state structure to initialise.
141    @param config The  structure containing info on server configuration.
142    @return ESUCCESS on success, refos_err_t error otherwise.
143*/
144int srv_common_init(srv_common_t *s, srv_common_config_t config);
145
146/*! @brief Helper function to mint a badged server endpoint cap.
147    @param badge The badge ID to mint.
148    @param ep The endpoint to mint from.
149    @return The minted capability (Ownership transferred).
150*/
151seL4_CPtr srv_mint(int badge, seL4_CPtr ep);
152
153/*! @brief Helper function to check recieved caps and unwrapped mask.
154    @param m The recieved message.
155    @param unwrappedMask The expected capability unwrap mask.
156    @param numExtraCaps The expected nubmer of recieved capabilities.
157    @return true if the recieved message capabilities match the unwrapped mask and number, false
158            if there is a mismatck and the recieved caps are invalid.
159*/
160bool srv_check_dispatch_caps(srv_msg_t *m, seL4_Word unwrappedMask, int numExtraCaps);
161
162/*! @brief Server notification dispatcher helper.
163
164    The goal of this helper function is to remove the common shared ringbuffer notification reading
165    and handling routines used by servers wishing to recieve async notifications. When a message
166    is read from the given server state's notification buffer, then the corresponding callback
167    handler function pointer is called.
168
169    @param srv The server common state structure. (No ownership)
170    @param callbacks Struct containing callbacks, one for each possible type of notification.
171                     If the given server does not handle a certain type of notification, simply
172                     set the corresponding callback as NULL.
173    @return ESUCCESS on success, refos_err_t error otherwise.
174*/
175int srv_dispatch_notification(srv_common_t *srv, srv_common_notify_handler_callbacks_t callbacks);
176
177#endif /* _SERVER_COMMON_HELPER_LIBRARY_H_ */