Changeset 2d5a54f3 in mainline
- Timestamp:
- 2006-03-16T00:25:50Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2fb49101
- Parents:
- c23502d
- Files:
-
- 1 added
- 1 deleted
- 7 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
Makefile
rc23502d r2d5a54f3 136 136 generic/src/smp/ipi.c \ 137 137 generic/src/ipc/ipc.c \ 138 generic/src/ipc/ ns.c138 generic/src/ipc/sysipc.c 139 139 140 140 ## Test sources -
generic/include/errno.h
rc23502d r2d5a54f3 34 34 #define ENOENT -1 /* No such entry */ 35 35 #define ENOMEM -2 /* Not enough memory */ 36 #define ELIMIT -3 /* Limit exceeded */ 37 #define EREFUSED -4 /* Connection refused */ 36 38 37 39 #endif -
generic/include/ipc/ipc.h
rc23502d r2d5a54f3 69 69 #define PHONE_NS 0 70 70 71 /* System-specific methods - only through special syscalls 72 * These methods have special behaviour 73 */ 74 #define IPC_M_IAMCONNECTING 0 75 /** Protocol for CONNECT - TO - ME 76 * 77 * Calling process asks the callee to create a callback connection, 78 * so that it can start initiating new messages. 79 * 80 * The protocol for negotiating is as follows: 81 * - sys_connecttome - sends a message IPC_M_CONNECTTOME 82 * - sys_wait_for_call - upon receipt tries to allocate new phone 83 * - if it fails, responds with ELIMIT 84 * - passes call to userspace. If userspace 85 * responds with error, phone is deallocated and 86 * error is sent back to caller. Otherwise 87 * the call is accepted and the response is sent back. 88 * - the allocated phoneid is passed to userspace as 89 * ARG3 of the call. 90 * - the caller obtains taskid of the called thread 91 */ 92 #define IPC_M_CONNECTTOME 1 93 #define IPC_M_CONNECTMETO 2 94 95 96 /* Well-known methods */ 97 #define IPC_M_FIRST_USER 512 98 #define IPC_M_PING 512 99 /* User methods */ 100 #define FIRST_USER_METHOD 1024 101 71 102 #ifdef KERNEL 72 103 … … 77 108 #define IPC_MAX_PHONES 16 78 109 79 80 110 typedef struct answerbox answerbox_t; 111 typedef __native ipc_data_t[IPC_CALL_LEN]; 81 112 82 113 typedef struct { … … 85 116 int flags; 86 117 task_t *sender; 87 __native data[IPC_CALL_LEN];118 ipc_data_t data; 88 119 } call_t; 89 120 90 121 struct answerbox { 91 122 SPINLOCK_DECLARE(lock); 123 124 task_t *task; 92 125 93 126 mutex_t mutex; -
generic/include/ipc/sysipc.h
rc23502d r2d5a54f3 27 27 */ 28 28 29 #ifndef __ NS_H_30 #define __ NS_H_29 #ifndef __SYSIPC_H__ 30 #define __SYSIPC_H__ 31 31 32 /* NameService methods */ 33 34 /** Ping name service */ 35 #define NS_PING 1 36 37 38 #ifdef KERNEL 39 40 #include <ipc/ipc.h> 41 42 extern void ns_start(void); 32 __native sys_ipc_call_sync_fast(__native phoneid, __native method, 33 __native arg1, __native *data); 34 __native sys_ipc_call_sync(__native phoneid, __native *question, 35 __native *reply); 36 __native sys_ipc_call_async_fast(__native phoneid, __native method, 37 __native arg1, __native arg2); 38 __native sys_ipc_call_async(__native phoneid, __native *data); 39 __native sys_ipc_answer_fast(__native callid, __native retval, 40 __native arg1, __native arg2); 41 __native sys_ipc_answer(__native callid, __native *data); 42 __native sys_ipc_connect_to_me(__native phoneid, __native arg1, 43 __native arg2, task_id_t *taskid); 44 __native sys_ipc_wait_for_call(ipc_data_t *calldata, task_id_t *taskid, 45 __native flags); 43 46 44 47 #endif 45 46 #endif -
generic/include/syscall/syscall.h
rc23502d r2d5a54f3 41 41 SYS_IPC_ANSWER, 42 42 SYS_IPC_WAIT, 43 SYS_IPC_CONNECT_TO_ME, 43 44 SYSCALL_END 44 45 } syscall_t; -
generic/src/ipc/ipc.c
rc23502d r2d5a54f3 72 72 call->callerbox = &TASK->answerbox; 73 73 call->flags = IPC_CALL_STATIC_ALLOC; 74 call->sender = TASK; 74 75 } 75 76 … … 90 91 list_initialize(&box->dispatched_calls); 91 92 list_initialize(&box->answers); 93 box->task = TASK; 92 94 } 93 95 -
generic/src/main/kinit.c
rc23502d r2d5a54f3 46 46 #include <interrupt.h> 47 47 #include <console/kconsole.h> 48 #include <ipc/ns.h>49 48 50 49 #ifdef CONFIG_SMP … … 70 69 { 71 70 thread_t *t; 71 task_t *utask; 72 72 73 73 interrupts_disable(); … … 134 134 interrupts_enable(); 135 135 136 /* Initialize name service */137 ns_start();138 139 136 if (config.init_size > 0) { 140 137 /* … … 145 142 panic("config.init_addr is not frame aligned"); 146 143 147 if (!task_run_program((void *)config.init_addr)) { 144 utask = task_run_program((void *)config.init_addr); 145 if (utask) 146 ipc_phone_0 = &utask->answerbox; 147 else 148 148 printf("Userspace not started.\n"); 149 }150 149 } 151 150 -
generic/src/syscall/syscall.c
rc23502d r2d5a54f3 32 32 #include <print.h> 33 33 #include <putchar.h> 34 #include <ipc/ipc.h>35 34 #include <errno.h> 36 35 #include <proc/task.h> 37 36 #include <arch.h> 38 37 #include <debug.h> 38 #include <ipc/sysipc.h> 39 39 40 40 static __native sys_ctl(void) { … … 57 57 } 58 58 59 static phone_t * get_phone(__native phoneid)60 {61 phone_t *phone;62 63 if (phoneid >= IPC_MAX_PHONES)64 return NULL;65 66 phone = &TASK->phones[phoneid];67 if (!phone->callee)68 return NULL;69 return phone;70 }71 72 /** Send a call over IPC, wait for reply, return to user73 *74 * @return Call identification, returns -1 on fatal error,75 -2 on 'Too many async request, handle answers first76 */77 static __native sys_ipc_call_sync_fast(__native phoneid, __native method,78 __native arg1, __native *data)79 {80 call_t call;81 phone_t *phone;82 /* Special answerbox for synchronous messages */83 84 phone = get_phone(phoneid);85 if (!phone)86 return IPC_CALLRET_FATAL;87 88 ipc_call_init(&call);89 IPC_SET_METHOD(call.data, method);90 IPC_SET_ARG1(call.data, arg1);91 92 ipc_call_sync(phone, &call);93 94 copy_to_uspace(data, &call.data, sizeof(call.data));95 96 return 0;97 }98 99 /** Synchronous IPC call allowing to send whole message */100 static __native sys_ipc_call_sync(__native phoneid, __native *question,101 __native *reply)102 {103 call_t call;104 phone_t *phone;105 /* Special answerbox for synchronous messages */106 107 phone = get_phone(phoneid);108 if (!phone)109 return IPC_CALLRET_FATAL;110 111 ipc_call_init(&call);112 copy_from_uspace(&call.data, question, sizeof(call.data));113 114 ipc_call_sync(phone, &call);115 116 copy_to_uspace(reply, &call.data, sizeof(call.data));117 118 return 0;119 }120 121 /** Check that the task did not exceed allowed limit122 *123 * @return 0 - Limit OK, -1 - limit exceeded124 */125 static int check_call_limit(void)126 {127 if (atomic_preinc(&TASK->active_calls) > IPC_MAX_ASYNC_CALLS) {128 atomic_dec(&TASK->active_calls);129 return -1;130 }131 return 0;132 }133 134 /** Send an asynchronous call over ipc135 *136 * @return Call identification, returns -1 on fatal error,137 -2 on 'Too many async request, handle answers first138 */139 static __native sys_ipc_call_async_fast(__native phoneid, __native method,140 __native arg1, __native arg2)141 {142 call_t *call;143 phone_t *phone;144 145 phone = get_phone(phoneid);146 if (!phone)147 return IPC_CALLRET_FATAL;148 149 if (check_call_limit())150 return IPC_CALLRET_TEMPORARY;151 152 call = ipc_call_alloc();153 IPC_SET_METHOD(call->data, method);154 IPC_SET_ARG1(call->data, arg1);155 IPC_SET_ARG2(call->data, arg2);156 157 ipc_call(phone, call);158 159 return (__native) call;160 }161 162 /** Synchronous IPC call allowing to send whole message163 *164 * @return The same as sys_ipc_call_async165 */166 static __native sys_ipc_call_async(__native phoneid, __native *data)167 {168 call_t *call;169 phone_t *phone;170 171 phone = get_phone(phoneid);172 if (!phone)173 return IPC_CALLRET_FATAL;174 175 if (check_call_limit())176 return IPC_CALLRET_TEMPORARY;177 178 call = ipc_call_alloc();179 copy_from_uspace(&call->data, data, sizeof(call->data));180 181 ipc_call(phone, call);182 183 return (__native) call;184 }185 186 187 /** Send IPC answer */188 static __native sys_ipc_answer_fast(__native callid, __native retval,189 __native arg1, __native arg2)190 {191 call_t *call;192 193 /* Check that the user is not sending us answer callid */194 ASSERT(! (callid & 1));195 /* TODO: Check that the callid is in the dispatch table */196 call = (call_t *) callid;197 198 IPC_SET_RETVAL(call->data, retval);199 IPC_SET_ARG1(call->data, arg1);200 IPC_SET_ARG2(call->data, arg2);201 202 ipc_answer(&TASK->answerbox, call);203 return 0;204 }205 206 /** Send IPC answer */207 static __native sys_ipc_answer(__native callid, __native *data)208 {209 call_t *call;210 211 /* Check that the user is not sending us answer callid */212 ASSERT(! (callid & 1));213 /* TODO: Check that the callid is in the dispatch table */214 call = (call_t *) callid;215 copy_from_uspace(&call->data, data, sizeof(call->data));216 ipc_answer(&TASK->answerbox, call);217 218 return 0;219 }220 221 /** Wait for incoming ipc call or answer222 *223 * @param result224 * @param flags225 * @return Callid, if callid & 1, then the call is answer226 */227 static __native sys_ipc_wait_for_call(__native *calldata, task_id_t *taskid,228 __native flags)229 {230 call_t *call;231 232 call = ipc_wait_for_call(&TASK->answerbox, flags);233 234 copy_to_uspace(calldata, &call->data, sizeof(call->data));235 236 if (call->flags & IPC_CALL_ANSWERED) {237 ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));238 ipc_call_free(call);239 atomic_dec(&TASK->active_calls);240 return ((__native)call) | IPC_CALLID_ANSWERED;241 }242 copy_to_uspace(taskid, (void *)&TASK->taskid, sizeof(TASK->taskid));243 return (__native)call;244 }245 59 246 60 static __native sys_mremap(void *address, size_t size, unsigned long flags) … … 259 73 sys_ipc_answer_fast, 260 74 sys_ipc_answer, 261 sys_ipc_wait_for_call 75 sys_ipc_wait_for_call, 76 sys_ipc_connect_to_me 262 77 };
Note:
See TracChangeset
for help on using the changeset viewer.