missing files and previous update were fixed
[ZeXOS.git] / kernel / arch / i386 / syscall.c
blob1af035b3a9fdc574a22665500fb47940eaa11365
1 /*
2 * ZeX/OS
3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <system.h>
23 #include <arch/io.h>
24 #include <string.h>
25 #include <tty.h>
26 #include <proc.h>
27 #include <net/socket.h>
28 #include <file.h>
29 #include <signal.h>
30 #include <module.h>
31 #include <rs232.h>
32 #include <ioctl.h>
33 #include <fd.h>
34 #include <paging.h>
36 extern task_t *_curr_task;
38 void sys_exit (struct regs *r)
40 task_t *taskc = task_find (0);
42 if (!taskc)
43 return;
45 page_dir_switch (taskc->page_cover->page_dir);
47 proc_t *proc = proc_find (_curr_task);
49 if (!proc)
50 return;
52 task_t *task = proc->tty->task;
54 proc->pid = 0;
56 if (int_disable ())
57 longjmp (task->state, 1);
58 else
59 while (1)
60 schedule ();
63 void sys_getch (struct regs *r)
65 proc_t *proc = proc_find (_curr_task);
67 if (!proc)
68 return;
70 if (proc->tty != currtty)
71 return;
73 unsigned char c = (unsigned char) getkey ();
75 if (c)
76 setkey (0);
78 //r->eax = (unsigned) &c;
80 unsigned char *memptr = (unsigned char *) 0x905d;
81 *memptr = c;
84 extern unsigned long timer_ticks;
85 void sys_sleep (struct regs *r)
87 unsigned long timer_start = timer_ticks + ((unsigned) r->ebx * 1000);
89 while (timer_start > timer_ticks)
90 schedule ();
93 void sys_putch (struct regs *r)
95 task_t *taskc = task_find (0);
97 if (!taskc)
98 return;
100 //page_dir_switch (taskc->page_cover->page_dir);
102 proc_t *proc = proc_find (_curr_task);
104 if (!proc)
105 return;
107 int c = r->ebx;
109 tty_putnch (proc->tty, c);
111 //page_dir_switch (proc->task->page_cover->page_dir);
114 void sys_color (struct regs *r)
116 video_color (r->ebx, r->ecx);
120 void sys_cls (struct regs *r)
122 proc_t *proc = proc_find (_curr_task);
124 if (!proc)
125 return;
127 if (proc->tty != currtty)
128 return;
130 /* NOTE: Why we should disable interrupts ? Nobody know, but works better */
131 if (int_disable ()) {
132 tty_cls (proc->tty);
133 int_enable ();
137 extern unsigned char scancode;
138 void sys_getkey (struct regs *r)
140 proc_t *proc = proc_find (_curr_task);
142 if (!proc)
143 return;
145 if (proc->tty != currtty)
146 return;
148 unsigned char c = (unsigned char) scancode;
150 scancode = 0;
152 unsigned char *memptr = (unsigned char *) 0x9060;
153 *memptr = c;
156 void sys_gotoxy (struct regs *r)
158 proc_t *proc = proc_find (_curr_task);
160 if (!proc)
161 return;
163 tty_gotoxy (proc->tty, r->ebx, r->ecx);
166 void sys_fork (struct regs *r)
168 unsigned short *where;
169 unsigned char c = (unsigned char) fork ();
171 unsigned short *memptr = (unsigned short *) 0x9000;
172 where = memptr;
173 *where = c;
176 void sys_schedule (struct regs *r)
178 schedule ();
181 extern kbd_quaue kbd_q;
182 void sys_write (struct regs *r)
184 unsigned len = r->ecx;
185 unsigned fd = r->edx;
187 unsigned char *buf = (unsigned char *) r->ebx;
189 if (!buf)
190 return;
192 // kprintf ("#buf: 0x%x / '%s'\n", buf, buf);
194 /*char buf[len+1];
195 if (!memcpy_to_user (&buf, (char *) r->ebx, len))
196 return;*/
198 int ret = 0;
200 proc_t *proc = 0;
201 char *mem = 0;
203 switch (fd) {
204 case 0:
205 proc = proc_find (_curr_task);
207 if (!proc) {
208 ret = -1;
209 break;
212 //if (buf >= proc->data && buf < (proc->data+proc->data_off)) {
213 // kprintf ("Je to staticky retezec :) - 0x%x - '%s'\n", buf+proc->code, buf+proc->code);
216 mem = (char *) buf;//vmem_proc_check (proc, buf);
218 //if (proc->tty != currtty)
219 // return;
221 //printf ("data: 0x%x | 0x%x\n", buf, proc->data);
223 //if (!memtest_data (buf, (void *) proc->data, proc->data_off))
224 tty_write (proc->tty, (char *) mem, len);
225 //else {
226 // tty_write (proc->tty, (char *) buf+proc->code, len);
228 ret = len;
229 //timer_wait (5000);
231 break;
232 case 1:
233 proc = proc_find (_curr_task);
235 if (!proc) {
236 ret = -1;
237 break;
240 if (len > KBD_MAX_QUAUE)
241 len = KBD_MAX_QUAUE;
243 mem = (char *) buf;
245 int i = 0;
246 for (i = len; i >= 0; i --)
247 setkey (buf[i]);
249 mem[len] = '\0';
251 ret = len;
252 break;
253 default:
254 mem = (char *) buf; //vmem_proc_check (proc, buf);
255 //printf ("hehe: 0x%x / '%s' len: %d\n", mem, mem, len);
256 ret = write (fd, (char *) mem, len);
257 break;
260 int *where;
261 int *memptr = (int *) 0x9000;
262 where = memptr;
263 *where = ret;
266 void sys_socket (struct regs *r)
268 int ret = socket (r->ebx, r->ecx, r->edx);
270 int *where;
271 int *memptr = (int *) 0x9000;
272 where = memptr;
273 *where = ret;
276 void sys_connect (struct regs *r)
278 sockaddr *addr = (sockaddr *) r->ebx;
280 int ret = connect (r->ecx, addr, r->edx);
282 int *where;
283 int *memptr = (int *) 0x9000;
284 where = memptr;
285 *where = ret;
288 void sys_malloc (struct regs *r)
290 paging_disable ();
291 r->eax = (unsigned) kmalloc ((int) r->ebx);
292 paging_enable ();
294 DPRINT ("malloc (): 0x%x\n", r->eax);
297 void sys_send (struct regs *r)
299 /* char msg[r->edx+1];
300 if (!memcpy_to_user (&msg, (char *) r->ebx, r->edx))
301 return;*/
303 int ret = send ((int) r->ecx, (char *) r->ebx, (unsigned) r->edx, 0);
305 int *where;
306 int *memptr = (int *) 0x9040;
307 where = memptr;
308 *where = ret;
311 void sys_recv (struct regs *r)
313 unsigned char *msg = (unsigned char *) r->ebx;
314 unsigned size = (unsigned) r->edx;
315 int fd = (int) r->ecx;
317 int ret = recv (fd, (char *) msg, size, 0);
319 /* if (ret > 0) {
320 printf ("recv> r->ebx: %d, r->edx: %u, ret: %d\n", (int) r->ecx, (unsigned) r->edx, ret);
323 //printf ("recv> r->ebx: %d, r->edx: %u, ret: %d\n", (int) r->ecx, (unsigned) r->edx, ret);
325 int *memptr = (int *) 0x9030;
326 *memptr = ret;
329 void sys_close (struct regs *r)
331 close (r->ebx);
334 void sys_open (struct regs *r)
336 unsigned char *pathname = (unsigned char *) r->ebx;
338 int ret = open ((char *) pathname, (unsigned) r->ecx);
340 // printf ("%d = sys_open (%s, %u)\n", ret, (char *) pathname, (unsigned) r->ecx);
342 int *where;
343 int *memptr = (int *) 0x9000;
344 where = memptr;
345 *where = ret;
348 void sys_pcspk (struct regs *r)
350 dev_t *dev = dev_find ("/dev/pcspk");
352 if (dev)
353 dev->handler (DEV_ACT_PLAY, (unsigned) r->ebx);
356 void sys_usleep (struct regs *r)
358 //unsigned long timer_start = timer_ticks + ((unsigned) r->ebx);
360 //while (timer_start > timer_ticks)
361 // schedule ();
362 usleep ((unsigned) r->ebx);
365 void sys_read (struct regs *r)
367 unsigned fd = r->ecx;
368 unsigned len = r->edx;
370 unsigned char *buf = (unsigned char *) r->ebx;
372 int ret = 0;
374 proc_t *proc = 0;
376 switch (fd) {
377 case 0:
378 break;
379 case 1:
380 proc = proc_find (_curr_task);
382 if (!proc)
383 break;
385 //if (proc->tty != currtty)
386 // return;
388 ret = tty_read (proc->tty, (char *) buf, len);
389 break;
390 default:
391 ret = read (fd, (char *) buf, len);
392 break;
395 int *where;
396 int *memptr = (int *) 0x9000;
397 where = memptr;
398 *where = ret;
401 void sys_time (struct regs *r)
403 time_t *memptr = (time_t *) 0x9005;
405 tm *t = rtc_getcurrtime ();
407 if (t)
408 *memptr = (time_t) t->__tm_gmtoff;
411 void sys_system (struct regs *r)
413 task_t *task = task_find (0);
415 if (!task)
416 return;
418 proc_t *proc = proc_find (_curr_task);
420 if (!proc)
421 return;
423 task_t *oldtask = _curr_task;
425 page_dir_switch (task->page_cover->page_dir);
427 unsigned char *cmd = (unsigned char *) r->ebx;
429 command_parser ((char *) cmd, strlen (cmd));
431 page_dir_switch (oldtask->page_cover->page_dir);
433 /* needed for correct scheduling (when you execute new process, _curr_task is tasj of current tty) */
434 _curr_task = oldtask;
436 schedule ();
440 void sys_chdir (struct regs *r)
442 unsigned char *dir = (unsigned char *) r->ebx;
444 cd ((char *) dir);
447 void sys_getdir (struct regs *r)
449 r->eax = (unsigned) vfs_dirent ();
452 void sys_procarg (struct regs *r)
454 proc_t *proc = proc_find (_curr_task);
456 if (!proc)
457 return;
459 switch (r->ecx) {
460 case 0:
461 r->eax = (unsigned) proc->argv;
462 break;
463 case 1:
464 r->eax = (unsigned) proc->argc;
465 break;
466 default:
467 r->eax = 0;
471 void sys_signal (struct regs *r)
473 signal (r->ebx, (sighandler_t) r->ecx);
476 void sys_mount (struct regs *r)
478 partition_t *p = partition_find ((char *) r->ebx);
480 if (p) {
481 mount (p, "", (char *) r->ecx);
482 r->eax = 1;
483 } else
484 r->eax = 0;
487 void sys_kputs (struct regs *r)
489 int_disable ();
491 module_t *kmod = module_find (_curr_task);
493 if (!kmod)
494 return;
496 if (kmod->task != _curr_task)
497 return;
499 unsigned char *buf = (unsigned char *) r->ebx;
500 kprintf (buf);
502 //kprintf ("yeah, sys_kputs: '%s' '0x%x'\n", buf, buf);
504 int_enable ();
507 void sys_bind (struct regs *r)
509 int ret = bind (r->ecx, (sockaddr *) r->ebx, r->edx);
511 int *where;
512 int *memptr = (int *) 0x9000;
513 where = memptr;
514 *where = ret;
517 void sys_listen (struct regs *r)
519 int ret = listen (r->ebx, r->ecx);
521 int *where;
522 int *memptr = (int *) 0x9000;
523 where = memptr;
524 *where = ret;
527 void sys_accept (struct regs *r)
529 int ret = accept (r->ecx, r->ebx, r->edx);
531 int *where;
532 int *memptr = (int *) 0x9000;
533 where = memptr;
534 *where = ret;
537 void sys_fcntl (struct regs *r)
539 int ret = fcntl (r->ebx, r->ecx, r->edx);
541 int *where;
542 int *memptr = (int *) 0x9000;
543 where = memptr;
544 *where = ret;
547 void sys_gvgafb (struct regs *r)
549 proc_t *proc = proc_find (_curr_task);
551 if (!proc)
552 return;
554 if (vgagui != 2) {
555 printf ("Please start this program in graphical VESA mode\n");
556 sys_exit (r);
557 return;
560 unsigned p = (unsigned) palign ((void *) (proc->end - proc->start));
562 unsigned *memptr = (unsigned *) 0x900a;
563 *memptr = (unsigned) init_vgafb () + p;
566 void sys_gcls (struct regs *r)
568 //gcls (r->ebx);
571 void sys_gfbswap (struct regs *r)
573 proc_t *proc = proc_find (_curr_task);
575 if (!proc)
576 return;
578 if (proc->tty == currtty)
579 video_gfx_fbswap ();
581 schedule ();
584 void sys_rs232read (struct regs *r)
586 char *where;
587 char *memptr = (char *) 0x9000;
588 where = memptr;
589 *where = rs232_read ();
592 void sys_rs232write (struct regs *r)
594 rs232_write ((char) r->ebx);
597 void sys_gttyexit (struct regs *r)
599 proc_t *proc = proc_find (_curr_task);
601 if (!proc)
602 return;
604 tty_change (proc->tty);
607 void sys_gexit (struct regs *r)
609 video_gfx_exit ();
612 extern unsigned char vgagui;
613 extern tty_t *gtty;
614 void sys_gttyinit (struct regs *r)
616 tty_t *tty = gtty_init ();
618 if (!tty)
619 return;
621 r->eax = (unsigned) &tty->screen;
624 void sys_mkdir (struct regs *r)
626 unsigned char *dir = (unsigned char *) r->ebx;
628 mkdir ((char *) dir);
631 void sys_free (struct regs *r)
633 paging_disable ();
635 kfree ((void *) r->ebx);
637 DPRINT ("free (): 0x%x\n", r->ebx);
639 paging_enable ();
642 void sys_realloc (struct regs *r)
644 r->eax = (unsigned) krealloc ((void *) r->ebx, (size_t) r->ecx);
646 DPRINT ("realloc (): 0x%x\n", r->eax);
649 void sys_gethostbyname (struct regs *r)
651 char *buf = (char *) r->ebx;
653 if (!buf) {
654 r->eax = 0;
655 return;
658 r->eax = (unsigned) gethostbyname (buf);
661 void sys_procmap (struct regs *r)
663 proc_t *proc = proc_find (_curr_task);
665 if (!proc)
666 return;
668 printf ("LOL: '%s'\n", proc->data-0x1000);
669 //proc_vmem_map (proc);
672 void sys_sendto (struct regs *r)
674 /* HACK: bleeh, there is problem with fourth argument,
675 so we need to use another way to getting address */
676 unsigned *addr = (unsigned *) 0x9020;
678 sockaddr_in *to = (sockaddr_in *) *addr;
680 int ret = sendto ((int) r->ecx, (char *) r->ebx, (unsigned) r->edx, 0, to, 0);
682 int *where;
683 int *memptr = (int *) 0x9000;
684 where = memptr;
685 *where = ret;
688 void sys_recvfrom (struct regs *r)
690 unsigned char *msg = (unsigned char *) r->ebx;
692 /* HACK: bleeh, there is problem with fourth argument,
693 so we need to use another way to getting address */
694 unsigned *addr = (unsigned *) 0x9010;
696 sockaddr_in *from = (sockaddr_in *) *addr;
698 int ret = recvfrom ((int) r->ecx, (char *) msg, (unsigned) r->edx, 0, from, 0);
700 int *where;
701 int *memptr = (int *) 0x9000;
702 where = memptr;
703 *where = ret;
706 void sys_getchar (struct regs *r)
708 proc_t *proc = proc_find (_curr_task);
710 int i = 1;
711 unsigned char s = '\n';
713 int *memptr = (int *) 0x9064;
715 /* non-blocking mode */
716 if (stdin->flags & O_NONBLOCK) {
717 if (!proc)
718 return;
720 if (proc->tty != currtty)
721 return;
723 char c = getkey ();
725 if (!c) {
726 c = -1;
727 *memptr = c;
728 return;
731 tty_write (proc->tty, &c, 1);
733 *memptr = c;
735 return;
738 /* blocking - clasical mode */
739 while (1) {
740 if (!proc)
741 return;
743 if (proc->tty != currtty)
744 return;
746 char c = getkey ();
748 if (c) {
749 if (i > 0 && c != '\b')
750 tty_write (proc->tty, &c, 1);
752 if (c == '\n')
753 break;
754 else if (i == 1)
755 s = c;
757 if (c == '\b') {
758 if (i > 1) {
759 i --;
760 tty_write (proc->tty, "\b", 1);
762 } else
763 i ++;
767 *memptr = (int) s;
770 void sys_threadopen (struct regs *r)
772 void *ptr = (void *) r->ebx;
774 unsigned *memptr = (unsigned *) 0x9050;
776 unsigned ret = proc_thread_create (ptr, (void *) *memptr);
778 *memptr = ret;
781 void sys_threadclose (struct regs *r)
783 proc_t *proc = proc_find (_curr_task);
785 if (!proc)
786 return;
788 unsigned *memptr = (unsigned *) 0x9050;
790 task_t *task = _curr_task;
792 /* free child process thread */
793 *memptr = proc_thread_destroy (proc, task);
795 task = proc->tty->task;
797 if (int_disable ())
798 longjmp (task->state, 1);
799 else
800 while (1)
801 schedule ();
805 void sys_ioctl (struct regs *r)
807 void *s = (void *) r->ebx;
808 unsigned id = r->ecx;
809 int l = r->edx;
811 int ret = ioctl_call (id, s, l);
813 r->eax = (int) &ret;
816 void sys_getpid (struct regs *r)
818 proc_t *proc = proc_find (_curr_task);
820 if (!proc)
821 return;
823 r->eax = (int) &proc->pid;
826 void sys_lseek (struct regs *r)
828 int fd = r->ebx;
829 long offset = r->ecx;
830 int whence = r->edx;
832 long ret = lseek (fd, offset, whence);
834 long *memptr = (long *) 0x9006;
836 *memptr = ret;
840 void syscall_handler (struct regs *r)
842 switch (r->eax) {
843 case 1:
844 return sys_exit (r);
845 case 2:
846 return sys_getch (r);
847 case 3:
848 return sys_sleep (r);
849 case 4:
850 return sys_putch (r);
851 case 5:
852 return sys_color (r);
853 case 6:
854 return sys_cls (r);
855 case 7:
856 return sys_getkey (r);
857 case 8:
858 return sys_gotoxy (r);
859 case 9:
860 return sys_fork (r);
861 case 10:
862 return sys_schedule (r);
863 case 11:
864 return sys_write (r);
865 case 12:
866 return sys_socket (r);
867 case 13:
868 return sys_connect (r);
869 case 14:
870 return sys_malloc (r);
871 case 15:
872 return sys_send (r);
873 case 16:
874 return sys_recv (r);
875 case 17:
876 return sys_close (r);
877 case 18:
878 return sys_open (r);
879 case 19:
880 return sys_pcspk (r);
881 case 20:
882 return sys_usleep (r);
883 case 21:
884 return sys_read (r);
885 case 22:
886 return sys_time (r);
887 case 23:
888 return sys_system (r);
889 case 24:
890 return sys_chdir (r);
891 case 25:
892 return sys_getdir (r);
893 case 26:
894 return sys_procarg (r);
895 case 27:
896 return sys_signal (r);
897 case 28:
898 return sys_mount (r);
899 case 29:
900 return sys_kputs (r);
901 case 30:
902 return sys_bind (r);
903 case 31:
904 return sys_listen (r);
905 case 32:
906 return sys_accept (r);
907 case 33:
908 return sys_fcntl (r);
909 case 34:
910 return sys_gvgafb (r);
911 case 35:
912 return sys_gcls (r);
913 case 36:
914 return sys_gfbswap (r);
915 case 37:
916 return sys_rs232read (r);
917 case 38:
918 return sys_rs232write (r);
919 case 39:
920 return sys_gttyexit (r);
921 case 40:
922 return sys_gexit (r);
923 case 41:
924 return sys_gttyinit (r);
925 case 42:
926 return sys_mkdir (r);
927 case 43:
928 return sys_free (r);
929 case 44:
930 return sys_realloc (r);
931 case 45:
932 return sys_gethostbyname (r);
933 case 46:
934 return sys_procmap (r);
935 case 47:
936 return sys_sendto (r);
937 case 48:
938 return sys_recvfrom (r);
939 case 49:
940 return sys_getchar (r);
941 case 50:
942 return sys_threadopen (r);
943 case 51:
944 return sys_threadclose (r);
945 case 52:
946 return sys_ioctl (r);
947 case 53:
948 return sys_getpid (r);
949 case 54:
950 return sys_lseek (r);