Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/sched/ipc.c need to be fixed.

0001 /*                    The Quest Operating System
0002  *  Copyright (C) 2005-2010  Richard West, Boston University
0003  *
0004  *  This program is free software: you can redistribute it and/or modify
0005  *  it under the terms of the GNU General Public License as published by
0006  *  the Free Software Foundation, either version 3 of the License, or
0007  *  (at your option) any later version.
0008  *
0009  *  This program is distributed in the hope that it will be useful,
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *  GNU General Public License for more details.
0013  *
0014  *  You should have received a copy of the GNU General Public License
0015  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
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   /* after _sw_ipc dst and src are swapped */
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   /* after _sw_ipc dst and src are swapped */
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  * Local Variables:
0164  * indent-tabs-mode: nil
0165  * mode: C
0166  * c-file-style: "gnu"
0167  * c-basic-offset: 2
0168  * End:
0169  */
0170 
0171 /* vi: set et sw=2 sts=2: */