Warning, cross-references for /kernel/sched/ipc.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include "sched/vcpu.h"
0019 #include "sched/sched.h"
0020 #include "util/debug.h"
0021 #include "util/printf.h"
0022 #include "smp/semaphore.h"
0023
0024 #define DEBUG_IPC
0025
0026 #ifdef DEBUG_IPC
0027 #define DLOG(fmt,...) DLOG_PREFIX("IPC",fmt,##__VA_ARGS__)
0028 #else
0029 #define DLOG(fmt,...) ;
0030 #endif
0031
0032 inline int
0033 fast_send_m (task_id dst_id, u32 arg1, u32 arg2)
0034 {
0035 quest_tss *src = lookup_TSS (str ());
0036 quest_tss *dst = lookup_TSS (dst_id);
0037
0038 semaphore_wait (&dst->Msem, 1, -1);
0039 wakeup (str ());
0040 dst->M[0] = arg1;
0041 dst->M[1] = arg2;
0042 ltr (dst_id);
0043 asm volatile ("call _sw_ipc"
0044 :
0045 :"S" (src), "D" (dst)
0046 :"eax", "ebx", "ecx", "edx");
0047 return 0;
0048 }
0049
0050 inline int
0051 fast_call_m (task_id dst_id, u32 arg1, u32 arg2, u32 *r_arg1, u32 *r_arg2)
0052 {
0053 quest_tss *src = lookup_TSS (str ());
0054 quest_tss *dst = lookup_TSS (dst_id);
0055
0056 semaphore_wait (&dst->Msem, 1, -1);
0057 dst->M[0] = arg1;
0058 dst->M[1] = arg2;
0059 semaphore_signal (&src->Msem, 1);
0060 ltr (dst_id);
0061 asm volatile ("call _sw_ipc"
0062 :"+S" (src), "+D" (dst)
0063 :
0064 :"eax", "ebx", "ecx", "edx", "cc", "memory");
0065
0066 *r_arg1 = dst->M[0];
0067 *r_arg2 = dst->M[1];
0068 return 0;
0069 }
0070
0071 inline int
0072 fast_recv_m (u32 *arg1, u32 *arg2)
0073 {
0074 quest_tss *cur;
0075 semaphore_signal (&lookup_TSS (str ())->Msem, 1);
0076 asm volatile ("call *%1"
0077 :"=D" (cur)
0078 :"m" (schedule)
0079 :"eax", "ebx", "ecx", "edx", "esi", "cc", "memory");
0080 *arg1 = cur->M[0];
0081 *arg2 = cur->M[1];
0082 return 0;
0083 }
0084
0085 inline int
0086 fast_sendrecv_m (task_id dst_id, u32 arg1, u32 arg2, u32 *r_arg1, u32 *r_arg2)
0087 {
0088 quest_tss *src = lookup_TSS (str ());
0089 quest_tss *dst = lookup_TSS (dst_id);
0090
0091 semaphore_wait (&dst->Msem, 1, -1);
0092 dst->M[0] = arg1;
0093 dst->M[1] = arg2;
0094 semaphore_signal (&src->Msem, 1);
0095 ltr (dst_id);
0096 asm volatile ("call _sw_ipc"
0097 :"+S" (src), "+D" (dst)
0098 :
0099 :"eax", "ebx", "ecx", "edx", "cc", "memory");
0100
0101 *r_arg1 = dst->M[0];
0102 *r_arg2 = dst->M[1];
0103 return 0;
0104 }
0105
0106
0107
0108 static u32 testS_stack[1024] ALIGNED (0x1000);
0109 static u32 testR_stack[1024] ALIGNED (0x1000);
0110
0111 static task_id testR_id = 0, testS_id = 0;
0112 static u64 start, finish;
0113 extern u32 tsc_freq_msec;
0114
0115 static void
0116 testS (void)
0117 {
0118 u32 arg1, arg2;
0119 DLOG ("testS: hello from 0x%x", testS_id);
0120 for (;;) {
0121 RDTSC (start);
0122 fast_call_m (testR_id, 0xCAFEBABE, 0xDEADBEEF, &arg1, &arg2);
0123 RDTSC (finish);
0124 DLOG ("testS: MEM: cycles=0x%.08llX: answer was 0x%X and 0x%X", finish - start, arg1, arg2);
0125 sched_usleep (1000000);
0126 }
0127 }
0128
0129 static void
0130 testR (void)
0131 {
0132 u32 arg1, arg2;
0133 DLOG ("testR: hello from 0x%x", testR_id);
0134 fast_recv_m (&arg1, &arg2);
0135 for (;;) {
0136 RDTSC (finish);
0137 DLOG ("testR: MEM: cycles=0x%.08llX: got 0x%X and 0x%X", finish - start, arg1, arg2);
0138 RDTSC (start);
0139 fast_sendrecv_m (testS_id, arg1 + arg2, arg1 | arg2, &arg1, &arg2);
0140 }
0141 }
0142
0143 extern bool
0144 ipc_init (void)
0145 {
0146 DLOG ("hello");
0147 testS_id = start_kernel_thread ((u32) testS, (u32) &testS_stack[1023]);
0148 testR_id = start_kernel_thread ((u32) testR, (u32) &testR_stack[1023]);
0149 lookup_TSS (testS_id)->cpu = 0;
0150 lookup_TSS (testR_id)->cpu = 0;
0151 return TRUE;
0152 }
0153
0154 #include "module/header.h"
0155
0156 static const struct module_ops mod_ops = {
0157 .init = ipc_init
0158 };
0159
0160 DEF_MODULE (ipc, "IPC manager", &mod_ops, {});
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171