xref: /plan9-contrib/sys/src/cmd/5i/syscall.c (revision ec59a3ddbfceee0efe34584c2c9981a5e5ff1ec4)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <mach.h>
5 #define	EXTERN
6 #include "arm.h"
7 
8 #define	ODIRLEN	116	/* compatibility; used in _stat etc. */
9 #define	OERRLEN	64	/* compatibility; used in _stat etc. */
10 
11 char 	errbuf[ERRMAX];
12 ulong	nofunc;
13 
14 #include "/sys/src/libc/9syscall/sys.h"
15 
16 
17 char*	sysctab[] =
18 {
19 	[SYSR1]		"Running",
20 	[_ERRSTR]		"_errstr",
21 	[BIND]		"Bind",
22 	[CHDIR]		"Chdir",
23 	[CLOSE]		"Close",
24 	[DUP]		"Dup",
25 	[ALARM]		"Alarm",
26 	[EXEC]		"Exec",
27 	[EXITS]		"Exits",
28 	[_FSESSION]	"_Fsession",
29 	[FAUTH]		"Fauth",
30 	[_FSTAT]		"_fstat",
31 	[SEGBRK]		"Segbrk",
32 	[MOUNT]		"Mount",
33 	[OPEN]		"Open",
34 	[_READ]		"_Read",
35 	[OSEEK]		"Oseek",
36 	[SLEEP]		"Sleep",
37 	[_STAT]		"_Stat",
38 	[RFORK]		"Rfork",
39 	[_WRITE]		"_Write",
40 	[PIPE]		"Pipe",
41 	[CREATE]		"Create",
42 	[FD2PATH]	"Fd2path",
43 	[BRK_]		"Brk_",
44 	[REMOVE]		"Remove",
45 	[_WSTAT]		"_Wstat",
46 	[_FWSTAT]	"_Fwstat",
47 	[NOTIFY]		"Notify",
48 	[NOTED]		"Noted",
49 	[SEGATTACH]	"Segattach",
50 	[SEGDETACH]	"Segdetach",
51 	[SEGFREE]		"Segfree",
52 	[SEGFLUSH]	"Segflush",
53 	[RENDEZVOUS]	"Rendezvous",
54 	[UNMOUNT]	"Unmount",
55 	[_WAIT]		"_Wait",
56 	[SEEK]		"Seek",
57 	[FVERSION]	"Fversion",
58 	[ERRSTR]		"Errstr",
59 	[STAT]		"Stat",
60 	[FSTAT]		"Fstat",
61 	[WSTAT]		"Wstat",
62 	[FWSTAT]		"Fwstat",
63 	[PREAD]		"Pread",
64 	[PWRITE]		"Pwrite",
65 	[AWAIT]		"Await",
66 };
67 
68 void
69 sys1(void)
70 {
71 	Bprint(bioout, "no system call %s\n", sysctab[reg.r[1]]);
72 	exits(0);
73 }
74 
75 void
76 sys_errstr(void)
77 {
78 	ulong str;
79 
80 	str = getmem_w(reg.r[13]+4);
81 	if(sysdbg)
82 		itrace("errstr(0x%lux)", str);
83 
84 	memio(errbuf, str, OERRLEN, MemWrite);
85 	strcpy(errbuf, "no error");
86 	reg.r[REGRET] = 0;
87 
88 }
89 
90 void
91 syserrstr(void)
92 {
93 	ulong str;
94 	int n;
95 
96 	str = getmem_w(reg.r[13]+4);
97 	n = getmem_w(reg.r[13]+8);
98 	if(sysdbg)
99 		itrace("errstr(0x%lux, 0x%lux)", str, n);
100 
101 	if(n > strlen(errbuf)+1)
102 		n = strlen(errbuf)+1;
103 	memio(errbuf, str, n, MemWrite);
104 	strcpy(errbuf, "no error");
105 	reg.r[REGRET] = n;
106 
107 }
108 void
109 sysbind(void)
110 {
111 	ulong pname, pold, flags;
112 	char name[1024], old[1024];
113 	int n;
114 
115 	pname = getmem_w(reg.r[13]+4);
116 	pold = getmem_w(reg.r[13]+8);
117 	flags = getmem_w(reg.r[13]+12);
118 	memio(name, pname, sizeof(name), MemReadstring);
119 	memio(old, pold, sizeof(old), MemReadstring);
120 	if(sysdbg)
121 		itrace("bind(0x%lux='%s', 0x%lux='%s', 0x%lux)", name, name, old, old, flags);
122 
123 	n = bind(name, old, flags);
124 	if(n < 0)
125 		errstr(errbuf, sizeof errbuf);
126 
127 	reg.r[REGRET] = n;
128 }
129 
130 void
131 sysfd2path(void)
132 {
133 	ulong str;
134 	uint fd, n;
135 	char buf[1024];
136 
137 	fd = getmem_w(reg.r[13]+4);
138 	str = getmem_w(reg.r[13]+8);
139 	n = getmem_w(reg.r[13]+12);
140 	if(sysdbg)
141 		itrace("fd2path(0x%lux, 0x%lux, 0x%lux)", fd, str, n);
142 	reg.r[1] = -1;
143 	if(n > sizeof buf){
144 		strcpy(errbuf, "buffer too big");
145 		return;
146 	}
147 	n = fd2path(fd, buf, sizeof buf);
148 	if(n < 0)
149 		errstr(buf, sizeof buf);
150 	else
151 		memio(errbuf, str, n, MemWrite);
152 	reg.r[REGRET] = n;
153 
154 }
155 
156 void
157 syschdir(void)
158 {
159 	char file[1024];
160 	int n;
161 	ulong name;
162 
163 	name = getmem_w(reg.r[13]+4);
164 	memio(file, name, sizeof(file), MemReadstring);
165 	if(sysdbg)
166 		itrace("chdir(0x%lux='%s', 0x%lux)", name, file);
167 
168 	n = chdir(file);
169 	if(n < 0)
170 		errstr(errbuf, sizeof errbuf);
171 
172 	reg.r[REGRET] = n;
173 }
174 
175 void
176 sysclose(void)
177 {
178 	int n;
179 	ulong fd;
180 
181 	fd = getmem_w(reg.r[13]+4);
182 	if(sysdbg)
183 		itrace("close(%d)", fd);
184 
185 	n = close(fd);
186 	if(n < 0)
187 		errstr(errbuf, sizeof errbuf);
188 	reg.r[REGRET] = n;
189 }
190 
191 void
192 sysdup(void)
193 {
194 	int oldfd, newfd;
195 	int n;
196 
197 	oldfd = getmem_w(reg.r[13]+4);
198 	newfd = getmem_w(reg.r[13]+8);
199 	if(sysdbg)
200 		itrace("dup(%d, %d)", oldfd, newfd);
201 
202 	n = dup(oldfd, newfd);
203 	if(n < 0)
204 		errstr(errbuf, sizeof errbuf);
205 	reg.r[REGRET] = n;
206 }
207 
208 void
209 sysexits(void)
210 {
211 	char buf[OERRLEN];
212 	ulong str;
213 
214 	str = getmem_w(reg.r[13]+4);
215 	if(sysdbg)
216 		itrace("exits(0x%lux)", str);
217 
218 	count = 1;
219 	if(str != 0) {
220 		memio(buf, str, sizeof buf, MemRead);
221 		Bprint(bioout, "exits(%s)\n", buf);
222 	}
223 	else
224 		Bprint(bioout, "exits(0)\n");
225 }
226 
227 void
228 sysopen(void)
229 {
230 	char file[1024];
231 	int n;
232 	ulong mode, name;
233 
234 	name = getmem_w(reg.r[13]+4);
235 	mode = getmem_w(reg.r[13]+8);
236 	memio(file, name, sizeof(file), MemReadstring);
237 
238 	n = open(file, mode);
239 	if(n < 0)
240 		errstr(errbuf, sizeof errbuf);
241 
242 	if(sysdbg)
243 		itrace("open(0x%lux='%s', 0x%lux) = %d", name, file, mode, n);
244 
245 	reg.r[REGRET] = n;
246 };
247 
248 
249 void
250 sysread(vlong offset)
251 {
252 	int fd;
253 	ulong size, a;
254 	char *buf, *p;
255 	int n, cnt, c;
256 
257 	fd = getmem_w(reg.r[13]+4);
258 	a = getmem_w(reg.r[13]+8);
259 	size = getmem_w(reg.r[13]+12);
260 
261 	buf = emalloc(size);
262 	if(fd == 0) {
263 		print("\nstdin>>");
264 		p = buf;
265 		n = 0;
266 		cnt = size;
267 		while(cnt) {
268 			c = Bgetc(bin);
269 			if(c <= 0)
270 				break;
271 			*p++ = c;
272 			n++;
273 			cnt--;
274 			if(c == '\n')
275 				break;
276 		}
277 	}
278 	else
279 		n = pread(fd, buf, size, offset);
280 
281 	if(n < 0)
282 		errstr(errbuf, sizeof errbuf);
283 	else
284 		memio(buf, a, n, MemWrite);
285 
286 	if(sysdbg)
287 		itrace("read(%d, 0x%lux, %d, 0x%llx) = %d", fd, a, size, offset, n);
288 
289 	free(buf);
290 	reg.r[REGRET] = n;
291 }
292 
293 void
294 sys_read(void)
295 {
296 	sysread(-1LL);
297 }
298 
299 void
300 syspread(void)
301 {
302 	union {
303 		vlong v;
304 		ulong u[2];
305 	} o;
306 
307 	o.u[0] = getmem_w(reg.r[13]+16);
308 	o.u[1] = getmem_w(reg.r[13]+20);
309 	sysread(o.v);
310 }
311 
312 void
313 sysseek(void)
314 {
315 	int fd;
316 	ulong mode;
317 	ulong retp;
318 	union {
319 		vlong v;
320 		ulong u[2];
321 	} o;
322 
323 	retp = getmem_w(reg.r[13]+4);
324 	fd = getmem_w(reg.r[13]+8);
325 	o.u[0] = getmem_w(reg.r[13]+12);
326 	o.u[1] = getmem_w(reg.r[13]+16);
327 	mode = getmem_w(reg.r[13]+20);
328 	if(sysdbg)
329 		itrace("seek(%d, %lld, %d)", fd, o.v, mode);
330 
331 	o.v = seek(fd, o.v, mode);
332 	if(o.v < 0)
333 		errstr(errbuf, sizeof errbuf);
334 
335 	memio((char*)o.u, retp, sizeof(vlong), MemWrite);
336 }
337 
338 void
339 sysoseek(void)
340 {
341 	int fd, n;
342 	ulong off, mode;
343 
344 	fd = getmem_w(reg.r[13]+4);
345 	off = getmem_w(reg.r[13]+8);
346 	mode = getmem_w(reg.r[13]+12);
347 	if(sysdbg)
348 		itrace("seek(%d, %lud, %d)", fd, off, mode);
349 
350 	n = seek(fd, off, mode);
351 	if(n < 0)
352 		errstr(errbuf, sizeof errbuf);
353 
354 	reg.r[REGRET] = n;
355 }
356 
357 void
358 syssleep(void)
359 {
360 	ulong len;
361 	int n;
362 
363 	len = getmem_w(reg.r[13]+4);
364 	if(sysdbg)
365 		itrace("sleep(%d)", len);
366 
367 	n = sleep(len);
368 	if(n < 0)
369 		errstr(errbuf, sizeof errbuf);
370 
371 	reg.r[REGRET] = n;
372 }
373 
374 void
375 sys_stat(void)
376 {
377 	char nambuf[1024];
378 	char buf[ODIRLEN];
379 	ulong edir, name;
380 	extern int _stat(char*, char*);	/* old system call */
381 	int n;
382 
383 	name = getmem_w(reg.r[13]+4);
384 	edir = getmem_w(reg.r[13]+8);
385 	memio(nambuf, name, sizeof(nambuf), MemReadstring);
386 	if(sysdbg)
387 		itrace("stat(0x%lux='%s', 0x%lux)", name, nambuf, edir);
388 
389 	n = _stat(nambuf, buf);
390 	if(n < 0)
391 		errstr(errbuf, sizeof errbuf);
392 	else
393 		memio(buf, edir, ODIRLEN, MemWrite);
394 
395 	reg.r[REGRET] = n;
396 }
397 
398 void
399 sysstat(void)
400 {
401 	char nambuf[1024];
402 	uchar buf[STATMAX];
403 	ulong edir, name;
404 	int n;
405 
406 	name = getmem_w(reg.r[13]+4);
407 	edir = getmem_w(reg.r[13]+8);
408 	n = getmem_w(reg.r[13]+12);
409 	memio(nambuf, name, sizeof(nambuf), MemReadstring);
410 	if(sysdbg)
411 		itrace("stat(0x%lux='%s', 0x%lux, 0x%lux)", name, nambuf, edir, n);
412 	if(n > sizeof buf)
413 		errstr(errbuf, sizeof errbuf);
414 	else{
415 		n = stat(nambuf, buf, n);
416 		if(n < 0)
417 			errstr(errbuf, sizeof errbuf);
418 		else
419 			memio((char*)buf, edir, n, MemWrite);
420 	}
421 	reg.r[REGRET] = n;
422 }
423 
424 void
425 sys_fstat(void)
426 {
427 	char buf[ODIRLEN];
428 	extern int _fstat(int, char*);	/* old system call */
429 	ulong edir;
430 	int n, fd;
431 
432 	fd = getmem_w(reg.r[13]+4);
433 	edir = getmem_w(reg.r[13]+8);
434 	if(sysdbg)
435 		itrace("fstat(%d, 0x%lux)", fd, edir);
436 
437 	n = _fstat(fd, buf);
438 	if(n < 0)
439 		errstr(errbuf, sizeof errbuf);
440 	else
441 		memio(buf, edir, ODIRLEN, MemWrite);
442 
443 	reg.r[REGRET] = n;
444 }
445 
446 void
447 sysfstat(void)
448 {
449 	uchar buf[STATMAX];
450 	ulong edir;
451 	int n, fd;
452 
453 	fd = getmem_w(reg.r[13]+4);
454 	edir = getmem_w(reg.r[13]+8);
455 	n = getmem_w(reg.r[13]+12);
456 	if(sysdbg)
457 		itrace("fstat(%d, 0x%lux, 0x%lux)", fd, edir, n);
458 
459 	reg.r[REGRET] = -1;
460 	if(n > sizeof buf){
461 		strcpy(errbuf, "stat buffer too big");
462 		return;
463 	}
464 	n = fstat(fd, buf, n);
465 	if(n < 0)
466 		errstr(errbuf, sizeof errbuf);
467 	else
468 		memio((char*)buf, edir, n, MemWrite);
469 	reg.r[REGRET] = n;
470 }
471 
472 void
473 syswrite(vlong offset)
474 {
475 	int fd;
476 	ulong size, a;
477 	char *buf;
478 	int n;
479 
480 	fd = getmem_w(reg.r[13]+4);
481 	a = getmem_w(reg.r[13]+8);
482 	size = getmem_w(reg.r[13]+12);
483 
484 	Bflush(bioout);
485 	buf = memio(0, a, size, MemRead);
486 	n = pwrite(fd, buf, size, offset);
487 	if(n < 0)
488 		errstr(errbuf, sizeof errbuf);
489 
490 	if(sysdbg)
491 		itrace("write(%d, %lux, %d, 0x%llx) = %d", fd, a, size, offset, n);
492 
493 	free(buf);
494 
495 	reg.r[REGRET] = n;
496 }
497 
498 void
499 sys_write(void)
500 {
501 	syswrite(-1LL);
502 }
503 
504 void
505 syspwrite(void)
506 {
507 	union {
508 		vlong v;
509 		ulong u[2];
510 	} o;
511 
512 	o.u[0] = getmem_w(reg.r[13]+16);
513 	o.u[1] = getmem_w(reg.r[13]+20);
514 	syswrite(o.v);
515 }
516 
517 void
518 syspipe(void)
519 {
520 	int n, p[2];
521 	ulong fd;
522 
523 	fd = getmem_w(reg.r[13]+4);
524 	if(sysdbg)
525 		itrace("pipe(%lux)", fd);
526 
527 	n = pipe(p);
528 	if(n < 0)
529 		errstr(errbuf, sizeof errbuf);
530 	else {
531 		putmem_w(fd, p[0]);
532 		putmem_w(fd+4, p[1]);
533 	}
534 	reg.r[REGRET] = n;
535 }
536 
537 void
538 syscreate(void)
539 {
540 	char file[1024];
541 	int n;
542 	ulong mode, name, perm;
543 
544 	name = getmem_w(reg.r[13]+4);
545 	mode = getmem_w(reg.r[13]+8);
546 	perm = getmem_w(reg.r[13]+12);
547 	memio(file, name, sizeof(file), MemReadstring);
548 	if(sysdbg)
549 		itrace("create(0x%lux='%s', 0x%lux, 0x%lux)", name, file, mode, perm);
550 
551 	n = create(file, mode, perm);
552 	if(n < 0)
553 		errstr(errbuf, sizeof errbuf);
554 
555 	reg.r[REGRET] = n;
556 }
557 
558 void
559 sysbrk_(void)
560 {
561 	ulong addr, osize, nsize;
562 	Segment *s;
563 
564 	addr = getmem_w(reg.r[13]+4);
565 	if(sysdbg)
566 		itrace("brk_(0x%lux)", addr);
567 
568 	reg.r[REGRET] = -1;
569 	if(addr < memory.seg[Data].base+datasize) {
570 		strcpy(errbuf, "address below segment");
571 		return;
572 	}
573 	if(addr > memory.seg[Stack].base) {
574 		strcpy(errbuf, "segment too big");
575 		return;
576 	}
577 	s = &memory.seg[Bss];
578 	if(addr > s->end) {
579 		osize = ((s->end-s->base)/BY2PG)*sizeof(uchar*);
580 		addr = ((addr)+(BY2PG-1))&~(BY2PG-1);
581 		s->end = addr;
582 		nsize = ((s->end-s->base)/BY2PG)*sizeof(uchar*);
583 		s->table = erealloc(s->table, osize, nsize);
584 	}
585 
586 	reg.r[REGRET] = 0;
587 }
588 
589 void
590 sysremove(void)
591 {
592 	char nambuf[1024];
593 	ulong name;
594 	int n;
595 
596 	name = getmem_w(reg.r[13]+4);
597 	memio(nambuf, name, sizeof(nambuf), MemReadstring);
598 	if(sysdbg)
599 		itrace("remove(0x%lux='%s')", name, nambuf);
600 
601 	n = remove(nambuf);
602 	if(n < 0)
603 		errstr(errbuf, sizeof errbuf);
604 	reg.r[REGRET] = n;
605 }
606 
607 void
608 sysnotify(void)
609 {
610 	nofunc = getmem_w(reg.r[13]+4);
611 	if(sysdbg)
612 		itrace("notify(0x%lux)\n", nofunc);
613 
614 	reg.r[REGRET] = 0;
615 }
616 
617 void
618 sys_wait(void)
619 {
620 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
621 	exits(0);
622 }
623 void
624 sysawait(void)
625 {
626 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
627 	exits(0);
628 }
629 void
630 sysrfork(void)
631 {
632 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
633 	exits(0);
634 }
635 void
636 syswstat(void)
637 {
638 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
639 	exits(0);
640 }
641 void
642 sys_wstat(void)
643 {
644 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
645 	exits(0);
646 }
647 void
648 sysfwstat(void)
649 {
650 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
651 	exits(0);
652 }
653 void
654 sys_fwstat(void)
655 {
656 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
657 	exits(0);
658 }
659 void
660 sysnoted(void)
661 {
662 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
663 	exits(0);
664 }
665 void
666 syssegattach(void)
667 {
668 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
669 	exits(0);
670 }
671 void
672 syssegdetach(void)
673 {
674 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
675 	exits(0);
676 }
677 void
678 syssegfree(void)
679 {
680 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
681 	exits(0);
682 }
683 void
684 syssegflush(void)
685 {
686 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
687 	exits(0);
688 }
689 void
690 sysrendezvous(void)
691 {
692 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
693 	exits(0);
694 }
695 void
696 sysunmount(void)
697 {
698 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
699 	exits(0);
700 }
701 void
702 sysfork(void)
703 {
704 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
705 	exits(0);
706 }
707 void
708 sysforkpgrp(void)
709 {
710 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
711 	exits(0);
712 }
713 void
714 syssegbrk(void)
715 {
716 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
717 	exits(0);
718 }
719 void
720 sysmount(void)
721 {
722 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
723 	exits(0);
724 }
725 void
726 sysalarm(void)
727 {
728 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
729 	exits(0);
730 }
731 void
732 sysexec(void)
733 {
734 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
735  	exits(0);
736 }
737 void
738 sys_fsession(void)
739 {
740 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
741  	exits(0);
742 }
743 void
744 sysfauth(void)
745 {
746 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
747  	exits(0);
748 }
749 void
750 sysfversion(void)
751 {
752 	Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]);
753  	exits(0);
754 }
755 
756 void	(*systab[])(void) =
757 {
758 	[SYSR1]		sys1,
759 	[_ERRSTR]		sys_errstr,
760 	[BIND]		sysbind,
761 	[CHDIR]		syschdir,
762 	[CLOSE]		sysclose,
763 	[DUP]		sysdup,
764 	[ALARM]		sysalarm,
765 	[EXEC]		sysexec,
766 	[EXITS]		sysexits,
767 	[_FSESSION]	sys_fsession,
768 	[FAUTH]		sysfauth,
769 	[_FSTAT]		sys_fstat,
770 	[SEGBRK]		syssegbrk,
771 	[MOUNT]		sysmount,
772 	[OPEN]		sysopen,
773 	[_READ]		sys_read,
774 	[OSEEK]		sysoseek,
775 	[SLEEP]		syssleep,
776 	[_STAT]		sys_stat,
777 	[RFORK]		sysrfork,
778 	[_WRITE]		sys_write,
779 	[PIPE]		syspipe,
780 	[CREATE]		syscreate,
781 	[FD2PATH]	sysfd2path,
782 	[BRK_]		sysbrk_,
783 	[REMOVE]		sysremove,
784 	[_WSTAT]		sys_wstat,
785 	[_FWSTAT]	sys_fwstat,
786 	[NOTIFY]		sysnotify,
787 	[NOTED]		sysnoted,
788 	[SEGATTACH]	syssegattach,
789 	[SEGDETACH]	syssegdetach,
790 	[SEGFREE]		syssegfree,
791 	[SEGFLUSH]	syssegflush,
792 	[RENDEZVOUS]	sysrendezvous,
793 	[UNMOUNT]	sysunmount,
794 	[_WAIT]		sys_wait,
795 	[SEEK]		sysseek,
796 	[FVERSION]	sysfversion,
797 	[ERRSTR]		syserrstr,
798 	[STAT]		sysstat,
799 	[FSTAT]		sysfstat,
800 	[WSTAT]		syswstat,
801 	[FWSTAT]		sysfwstat,
802 	[PREAD]		syspread,
803 	[PWRITE]		syspwrite,
804 	[AWAIT]		sysawait,
805 };
806 
807 void
808 Ssyscall(ulong)
809 {
810 	int call;
811 
812 	call = reg.r[REGARG];
813 	if(call < 0 || call > PWRITE || systab[call] == nil) {
814 		Bprint(bioout, "bad system call\n");
815 		dumpreg();
816 	}
817 
818 	if(trace)
819 		itrace("SWI\t%s", sysctab[call]);
820 	(*systab[call])();
821 	Bflush(bioout);
822 }
823