• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 
13 #pragma once
14 
15 #include <chcore/type.h>
16 #include <chcore/defs.h>
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 /* Starts from 1 because the uninitialized value is 0 */
23 enum system_server_identifier {
24     FS_MANAGER = 1,
25     NET_MANAGER,
26     PROC_MANAGER,
27 };
28 
29 /*
30  * ipc_struct is created in **ipc_register_client** and
31  * thus only used at client side.
32  */
33 typedef struct ipc_struct {
34     /* Connection_cap: used to call a server */
35     cap_t conn_cap;
36     /* Shared memory: used to create ipc_msg (client -> server) */
37     unsigned long shared_buf;
38     unsigned long shared_buf_len;
39 
40     /* A spin lock: used to coordinate the access to shared memory */
41     volatile int lock;
42     enum system_server_identifier server_id;
43 } ipc_struct_t;
44 
45 extern cap_t fsm_server_cap;
46 extern cap_t lwip_server_cap;
47 extern cap_t procmgr_server_cap;
48 extern int init_process_in_lwip;
49 extern int init_lwip_lock;
50 
51 /* ipc_struct for invoking system servers.
52  * fsm_ipc_struct and lwip_ipc_struct are two addresses.
53  * They can be used like **const** pointers.
54  *
55  * If a system server is related to the scalability (multi-threads) of
56  * applications, we should use the following way to make the connection with it
57  * as per-thread.
58  *
59  * For other system servers (e.g., process manager), it is OK to let multiple
60  * threads share a same connection.
61  */
62 ipc_struct_t *__fsm_ipc_struct_location(void);
63 ipc_struct_t *__net_ipc_struct_location(void);
64 ipc_struct_t *__procmgr_ipc_struct_location(void);
65 #define fsm_ipc_struct     (__fsm_ipc_struct_location())
66 #define lwip_ipc_struct    (__net_ipc_struct_location())
67 #define procmgr_ipc_struct (__procmgr_ipc_struct_location())
68 
69 /* ipc_msg is located at ipc_struct->shared_buf. */
70 typedef struct ipc_msg {
71     unsigned int data_len;
72     /*
73      * cap_slot_number represents the number of caps of the ipc_msg.
74      * This is useful for both sending IPC and returning from IPC.
75      * When calling ipc_return, cap_slot_number will be set 0 automatically,
76      * indicating that no cap will be sent.
77      * If you want to send caps when returning from IPC,
78      * use ipc_return_with_cap.
79      */
80     unsigned int cap_slot_number;
81     unsigned int data_offset;
82     unsigned int cap_slots_offset;
83 
84     /* icb: ipc control block (not needed by the kernel) */
85     ipc_struct_t *icb;
86 
87 #if __SIZEOF_POINTER__ == 4
88     /* ipc_msg should be alligned to 8 bytes */
89     void *padding;
90 #endif
91 } ipc_msg_t;
92 
93 #define IPC_SHM_AVAILABLE (IPC_PER_SHM_SIZE - sizeof(ipc_msg_t))
94 
95 /*
96  * server_handler is an IPC routine (can have two arguments):
97  * first is ipc_msg and second is client_badge.
98  */
99 typedef void (*server_handler)();
100 typedef void (*server_destructor)(badge_t);
101 
102 /* Registeration interfaces */
103 ipc_struct_t *ipc_register_client(cap_t server_thread_cap);
104 
105 void *register_cb(void *ipc_handler);
106 void *register_cb_single(void *ipc_handler);
107 
108 #define DEFAULT_CLIENT_REGISTER_HANDLER register_cb
109 #define DEFAULT_DESTRUCTOR              NULL
110 
111 int ipc_register_server(server_handler server_handler,
112                         void *(*client_register_handler)(void *));
113 int ipc_register_server_with_destructor(server_handler server_handler,
114                                         void *(*client_register_handler)(void *),
115                                         server_destructor server_destructor);
116 
117 /* IPC message operating interfaces */
118 ipc_msg_t *ipc_create_msg(ipc_struct_t *icb, unsigned int data_len);
119 ipc_msg_t *ipc_create_msg_with_cap(ipc_struct_t *icb, unsigned int data_len,
120                                    unsigned int cap_slot_number);
121 char *ipc_get_msg_data(ipc_msg_t *ipc_msg);
122 cap_t ipc_get_msg_cap(ipc_msg_t *ipc_msg, unsigned int cap_id);
123 int ipc_set_msg_data(ipc_msg_t *ipc_msg, void *data, unsigned int offset,
124                      unsigned int len);
125 int ipc_set_msg_cap(ipc_msg_t *ipc_msg, unsigned int cap_slot_index, cap_t cap);
126 int ipc_destroy_msg(ipc_msg_t *ipc_msg);
127 
128 /* IPC issue/finish interfaces */
129 long ipc_call(ipc_struct_t *icb, ipc_msg_t *ipc_msg);
130 _Noreturn void ipc_return(ipc_msg_t *ipc_msg, long ret);
131 _Noreturn void ipc_return_with_cap(ipc_msg_t *ipc_msg, long ret);
132 int ipc_client_close_connection(ipc_struct_t *ipc_struct);
133 
134 int simple_ipc_forward(ipc_struct_t *ipc_struct, void *data, int len);
135 
136 /*
137  * Magic number for coordination between client and server:
138  * the client should wait until the server has reigsterd the service.
139  */
140 #define NONE_INFO ((void *)(-1UL))
141 
142 #ifdef __cplusplus
143 }
144 #endif
145