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