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