Subversion Repositories HelenOS

Rev

Rev 2952 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2005 Martin Decky
  3.  * Copyright (c) 2008 Jakub Jermar
  4.  * Copyright (c) 2008 Jiri Svoboda
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * - Redistributions of source code must retain the above copyright
  12.  *   notice, this list of conditions and the following disclaimer.
  13.  * - Redistributions in binary form must reproduce the above copyright
  14.  *   notice, this list of conditions and the following disclaimer in the
  15.  *   documentation and/or other materials provided with the distribution.
  16.  * - The name of the author may not be used to endorse or promote products
  17.  *   derived from this software without specific prior written permission.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  21.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  23.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  24.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  28.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  */
  30.  
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <ipc/ipc.h>
  35. #include <syscall.h>
  36. #include <libc.h>
  37. #include <console.h>
  38. #include <ipc/services.h>
  39. #include <vfs/vfs.h>
  40. #include <errno.h>
  41. #include <fcntl.h>
  42. #include "../../srv/vfs/vfs.h"
  43.  
  44.  
  45. static void kputint(unsigned i)
  46. {
  47.     unsigned dummy;
  48.     asm volatile (
  49.         "movl $30, %%eax;"
  50.         "int $0x30"
  51.         : "=d" (dummy) /* output - %edx clobbered */
  52.         : "d" (i) /* input */
  53.         : "%eax","%ecx" /* all scratch registers clobbered */
  54.     ); 
  55. }
  56.  
  57. int
  58. ipc_call_sync_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
  59.     ipcarg_t arg3, ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3,
  60.     ipcarg_t *result4, ipcarg_t *result5)
  61. {
  62.     ipc_call_t resdata;
  63.     int callres;
  64.    
  65.     callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
  66.         arg2, arg3, (sysarg_t) &resdata);
  67.     if (callres)
  68.         return callres;
  69.     if (result1)
  70.         *result1 = IPC_GET_ARG1(resdata);
  71.     if (result2)
  72.         *result2 = IPC_GET_ARG2(resdata);
  73.     if (result3)
  74.         *result3 = IPC_GET_ARG3(resdata);
  75.     if (result4)
  76.         *result4 = IPC_GET_ARG4(resdata);
  77.     if (result5)
  78.         *result5 = IPC_GET_ARG5(resdata);
  79.  
  80.     return IPC_GET_RETVAL(resdata);
  81. }
  82.  
  83. int ipc_connect_me_to(int phoneid, int arg1, int arg2, int arg3)
  84. {
  85.     ipcarg_t newphid;
  86.     int res;
  87.  
  88.     res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
  89.         NULL, NULL, NULL, NULL, &newphid);
  90.     if (res)
  91.         return res;
  92.     return newphid;
  93. }
  94.  
  95. ipc_callid_t ipc_wait_cycle(ipc_call_t *call, uint32_t usec, int flags)
  96. {
  97.     ipc_callid_t callid;
  98.  
  99.     callid = __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags);
  100.  
  101.     return callid;
  102. }
  103.  
  104. ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, uint32_t usec)
  105. {
  106.     ipc_callid_t callid;
  107.  
  108.     callid = ipc_wait_cycle(call, usec, SYNCH_FLAGS_NONE);
  109.  
  110.     return callid;
  111. }
  112.  
  113. ipc_callid_t ipc_purge_answers(void)
  114. {
  115.     ipc_callid_t callid;
  116.     ipc_call_t call;
  117.  
  118.     do {
  119.         callid = ipc_wait_cycle(&call, 0, SYNCH_FLAGS_NON_BLOCKING);
  120.         printf("ipc_wait_cycle->%d\n", callid);
  121.     } while (callid != 0);
  122.  
  123.     return callid;
  124. }
  125.  
  126. ipc_callid_t ipc_wait_for_answer(ipc_callid_t req, ipc_call_t *call)
  127. {
  128.     ipc_callid_t callid;
  129.  
  130.     do {
  131.         callid = ipc_wait_cycle(call, 0, SYNCH_FLAGS_NONE);
  132.     } while ((callid & ~IPC_CALLID_ANSWERED) != req);
  133.  
  134.     return callid;
  135. }
  136.  
  137. static ipc_callid_t async_rid;
  138.  
  139. void ipc_call_async_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
  140.     ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, void *private,
  141.     ipc_async_callback_t callback, int can_preempt)
  142. {
  143.     ipc_purge_answers();
  144.     async_rid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid, method, arg1,
  145.         arg2, arg3, arg4);
  146.     printf("ipc_call_async_fast->%d\n", async_rid);
  147. }
  148.  
  149. int ipc_data_write_start(int phoneid, void *src, size_t size)
  150. {
  151.     return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src,
  152.         (ipcarg_t) size);
  153. }
  154.  
  155. int ipc_data_read_start(int phoneid, void *dst, size_t size)
  156. {
  157.     return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst,
  158.         (ipcarg_t) size);
  159. }
  160.  
  161. static int console_phone = -1;
  162.  
  163. ssize_t write_stderr(const void *buf, size_t count)
  164. {
  165.     return count;
  166. }
  167.  
  168. ssize_t read_stdin(void *buf, size_t count)
  169. {
  170.     ipcarg_t r0, r1;
  171.     size_t i = 0;
  172.  
  173.     while (i < count) {
  174.         if (ipc_call_sync_0_2(console_phone, CONSOLE_GETCHAR, &r0,
  175.             &r1) < 0) {
  176.             return -1;
  177.         }
  178.         ((char *) buf)[i++] = r0;
  179.     }
  180.     return i;
  181. }
  182.  
  183. ssize_t write_stdout(const void *buf, size_t count)
  184. {
  185.     int i;
  186.  
  187.     for (i = 0; i < count; i++)
  188.         ipc_call_sync_1_0(console_phone, CONSOLE_PUTCHAR,
  189.             ((const char *) buf)[i]);
  190.    
  191.     return count;
  192. }
  193.  
  194. void open_stdin(void)
  195. {
  196.     kputint(0x1234);
  197.     if (console_phone < 0) {
  198.         while ((console_phone = ipc_connect_me_to(PHONE_NS,
  199.             SERVICE_CONSOLE, 0, 0)) < 0) {
  200.             //usleep(10000);
  201.         }
  202.         kputint(console_phone);
  203.     }
  204. }
  205.  
  206. void open_stdout(void)
  207. {
  208.     kputint(0x1235);
  209.     if (console_phone < 0) {
  210.         while ((console_phone = ipc_connect_me_to(PHONE_NS,
  211.             SERVICE_CONSOLE, 0, 0)) < 0) {
  212.             //usleep(10000);
  213.         }
  214.         kputint(console_phone);
  215.     }
  216. }
  217.  
  218. int get_cons_phone(void)
  219. {
  220.     return console_phone;
  221. }
  222.  
  223.  
  224. void __main(void)
  225. {
  226.     kputint(0x110);
  227. }
  228.  
  229. void __io_init(void)
  230. {
  231.     open_stdin();
  232.     open_stdout();
  233. }
  234.  
  235. void __exit(void)
  236. {
  237.     kputint(0x112);
  238. }
  239.  
  240. int putchar(int c)
  241. {
  242.     unsigned char ch = c;
  243.     if (write_stdout((void *) &ch, 1) == 1)
  244.         return c;
  245.    
  246.     return EOF;
  247. }
  248.  
  249. int getchar(void)
  250. {
  251.     unsigned char c;
  252.     if (read_stdin((void *) &c, 1) == 1)
  253.         return c;
  254.    
  255.     return EOF;
  256. }
  257.  
  258. void _putint(int i)
  259. {
  260.     if (i == 0) {
  261.         putchar('0');
  262.         return;
  263.     }
  264.  
  265.     if (i < 0) {
  266.         i = -i;
  267.         putchar('-');
  268.     }
  269.  
  270.     if (i >= 10) {
  271.         _putint(i/10);
  272.     }
  273.     putchar('0' + (i%10));
  274. }
  275.  
  276. int printf(const char *fmt, ...)
  277. {
  278.     int c;
  279.     int i;
  280.  
  281.     va_list ap;
  282.     va_start(ap, fmt);
  283.     while (*fmt) {
  284.         c = *fmt++;
  285.         if (c == '%') {
  286.             c = *fmt++;
  287.             if (c == 'd') {
  288.                 i = va_arg(ap, int);
  289.                 _putint(i);
  290.             } else if (c == '\0') {
  291.                 break;
  292.             } else {
  293.                 putchar('%');
  294.                 putchar(c);
  295.             }
  296.         } else {
  297.             putchar(c);
  298.         }
  299.     }
  300.     va_end(ap);
  301.     return 0;
  302. }
  303.  
  304. size_t strlen(const char *s)
  305. {
  306.     int l = 0;
  307.  
  308.     while (*s) { ++s; ++l; }
  309.     return l;
  310. }
  311.  
  312. //int vfs_phone = -1;
  313. int vfs_phone = 2;  /* reuse phone from loader */
  314.  
  315. static int vfs_connect(void)
  316. {
  317.     if (vfs_phone < 0)
  318.         vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0);
  319.     return vfs_phone;
  320. }
  321.  
  322. static int _open(const char *path, int lflag, int oflag, ...)
  323. {
  324.     int res;
  325.     ipcarg_t rc;
  326.     ipc_call_t answer;
  327.    
  328.     const char *pa = path;
  329.     int pa_len = strlen(path);
  330.    
  331.     if (vfs_phone < 0) {
  332.         res = vfs_connect();
  333.         if (res < 0) {
  334.             return res;
  335.         }
  336.     }
  337.     ipc_call_async_3(vfs_phone, VFS_OPEN, lflag, oflag, 0, NULL, NULL,0);
  338.     rc = ipc_data_write_start(vfs_phone, (char *)pa, pa_len);
  339.     if (rc != EOK) {
  340.         ipc_wait_for_answer(async_rid, &answer);
  341.         return (int) rc;
  342.     }
  343.     ipc_wait_for_answer(async_rid, &answer);
  344.     return (int) IPC_GET_ARG1(answer);
  345. }
  346.  
  347. int open(const char *path, int oflag, ...)
  348. {
  349.     return _open(path, L_FILE, oflag);
  350. }
  351.  
  352. int close(int fildes)
  353. {
  354.     int res;
  355.     ipcarg_t rc;
  356.  
  357.     if (vfs_phone < 0) {
  358.         res = vfs_connect();
  359.         if (res < 0) {
  360.             return res;
  361.         }
  362.     }
  363.        
  364.     rc = ipc_call_sync_1_0(vfs_phone, VFS_CLOSE, fildes);
  365.    
  366.     return (int)rc;
  367. }
  368.  
  369. ssize_t read(int fildes, void *buf, size_t nbyte)
  370. {
  371.     int res;
  372.     ipcarg_t rc;
  373.     ipc_call_t answer;
  374.  
  375.     if (vfs_phone < 0) {
  376.         res = vfs_connect();
  377.         if (res < 0) {
  378.             return res;
  379.         }
  380.     }
  381.     ipc_call_async_1(vfs_phone, VFS_READ, fildes, NULL, NULL, 0);
  382.     rc = ipc_data_read_start(vfs_phone, (void *)buf, nbyte);
  383.     if (rc != EOK) {
  384.         ipc_wait_for_answer(async_rid, &answer);
  385.         return (ssize_t) rc;
  386.     }
  387.     ipc_wait_for_call(&answer);
  388.     if (rc == EOK)
  389.         return (ssize_t) IPC_GET_ARG1(answer);
  390.     else
  391.         return -1;
  392. }
  393.