1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <mach.h> 5 #define Extern extern 6 #include "mips.h" 7 #undef CHDIR 8 9 char errbuf[ERRLEN]; 10 ulong nofunc; 11 12 #define SYSR1 0 13 #define ERRSTR 1 14 #define BIND 2 15 #define CHDIR 3 16 #define CLOSE 4 17 #define DUP 5 18 #define ALARM 6 19 #define EXEC 7 20 #define EXITS 8 21 #define FORK 9 22 #define FORKPGRP 10 23 #define FSTAT 11 24 #define SEGBRK 12 25 #define MOUNT 13 26 #define OPEN 14 27 #define READ 15 28 #define SEEK 16 29 #define SLEEP 17 30 #define STAT 18 31 #define WAIT 19 32 #define WRITE 20 33 #define PIPE 21 34 #define CREATE 22 35 #define RFORK 23 36 #define BRK_ 24 37 #define REMOVE 25 38 #define WSTAT 26 39 #define FWSTAT 27 40 #define NOTIFY 28 41 #define NOTED 29 42 #define SEGATTACH 30 43 #define SEGDETACH 31 44 #define SEGFREE 32 45 #define SEGFLUSH 33 46 #define RENDEZVOUS 34 47 #define UNMOUNT 35 48 49 char *sysctab[]={ 50 [SYSR1] "Running", 51 [ERRSTR] "Errstr", 52 [BIND] "Bind", 53 [CHDIR] "Chdir", 54 [CLOSE] "Close", 55 [DUP] "Dup", 56 [ALARM] "Alarm", 57 [EXEC] "Exec", 58 [EXITS] "Exits", 59 [FORK] "Fork", 60 [FORKPGRP] "Forkpgrp", 61 [FSTAT] "Fstat", 62 [SEGBRK] "Segbrk", 63 [MOUNT] "Mount", 64 [OPEN] "Open", 65 [READ] "Read", 66 [SEEK] "Seek", 67 [SLEEP] "Sleep", 68 [STAT] "Stat", 69 [WAIT] "Wait", 70 [WRITE] "Write", 71 [PIPE] "Pipe", 72 [CREATE] "Create", 73 [RFORK] "Rfork", 74 [BRK_] "Brk", 75 [REMOVE] "Remove", 76 [WSTAT] "Wstat", 77 [FWSTAT] "Fwstat", 78 [NOTIFY] "Notify", 79 [NOTED] "Noted", 80 [SEGATTACH] "Segattach", 81 [SEGDETACH] "Segdetach", 82 [SEGFREE] "Segfree", 83 [SEGFLUSH] "Segflush", 84 [RENDEZVOUS] "Rendez", 85 [UNMOUNT] "Unmount", 86 }; 87 88 void sys1(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0); } 89 90 void 91 syserrstr(void) 92 { 93 ulong str; 94 95 str = getmem_w(reg.r[29]+4); 96 if(sysdbg) 97 itrace("errstr(0x%lux)", str); 98 99 memio(errbuf, str, ERRLEN, MemWrite); 100 strcpy(errbuf, "no error"); 101 reg.r[1] = 0; 102 103 } 104 void 105 sysbind(void) 106 { 107 ulong pname, pold, flags; 108 char name[1024], old[1024]; 109 int n; 110 111 pname = getmem_w(reg.r[29]+4); 112 pold = getmem_w(reg.r[29]+8); 113 flags = getmem_w(reg.r[29]+12); 114 memio(name, pname, sizeof(name), MemReadstring); 115 memio(old, pold, sizeof(old), MemReadstring); 116 if(sysdbg) 117 itrace("bind(0x%lux='%s', 0x%lux='%s', 0x%lux)", name, old, flags); 118 119 n = bind(name, old, flags); 120 if(n < 0) 121 errstr(errbuf); 122 123 reg.r[1] = n; 124 } 125 126 void 127 syschdir(void) 128 { 129 char file[1024]; 130 int n; 131 ulong name; 132 133 name = getmem_w(reg.r[29]+4); 134 memio(file, name, sizeof(file), MemReadstring); 135 if(sysdbg) 136 itrace("chdir(0x%lux='%s', 0x%lux)", name, file); 137 138 n = chdir(file); 139 if(n < 0) 140 errstr(errbuf); 141 142 reg.r[1] = n; 143 } 144 145 void 146 sysclose(void) 147 { 148 int n; 149 ulong fd; 150 151 fd = getmem_w(reg.r[29]+4); 152 if(sysdbg) 153 itrace("close(%d)", fd); 154 155 n = close(fd); 156 if(n < 0) 157 errstr(errbuf); 158 reg.r[1] = n; 159 } 160 161 void 162 sysdup(void) 163 { 164 int oldfd, newfd; 165 int n; 166 167 oldfd = getmem_w(reg.r[29]+4); 168 newfd = getmem_w(reg.r[29]+8); 169 if(sysdbg) 170 itrace("dup(%d, %d)", oldfd, newfd); 171 172 n = dup(oldfd, newfd); 173 if(n < 0) 174 errstr(errbuf); 175 reg.r[1] = n; 176 } 177 178 void 179 sysexits(void) 180 { 181 char buf[ERRLEN]; 182 ulong str; 183 184 str = getmem_w(reg.r[29]+4); 185 if(sysdbg) 186 itrace("exits(0x%lux)", str); 187 188 count = 1; 189 if(str != 0) { 190 memio(buf, str, ERRLEN, MemRead); 191 Bprint(bioout, "exits(%s)\n", buf); 192 } 193 else 194 Bprint(bioout, "exits(0)\n"); 195 } 196 197 void 198 sysopen(void) 199 { 200 char file[1024]; 201 int n; 202 ulong mode, name; 203 204 name = getmem_w(reg.r[29]+4); 205 mode = getmem_w(reg.r[29]+8); 206 memio(file, name, sizeof(file), MemReadstring); 207 if(sysdbg) 208 itrace("open(0x%lux='%s', 0x%lux)", name, file, mode); 209 210 n = open(file, mode); 211 if(n < 0) 212 errstr(errbuf); 213 214 reg.r[1] = n; 215 }; 216 217 void 218 sysread(void) 219 { 220 int fd; 221 ulong size, a; 222 char *buf, *p; 223 int n, cnt, c; 224 225 fd = getmem_w(reg.r[29]+4); 226 a = getmem_w(reg.r[29]+8); 227 size = getmem_w(reg.r[29]+12); 228 229 buf = emalloc(size); 230 if(fd == 0) { 231 print("\nstdin>>"); 232 p = buf; 233 n = 0; 234 cnt = size; 235 while(cnt) { 236 c = Bgetc(bin); 237 if(c <= 0) 238 break; 239 *p++ = c; 240 n++; 241 cnt--; 242 if(c == '\n') 243 break; 244 } 245 } 246 else 247 n = read(fd, buf, size); 248 249 if(n < 0) 250 errstr(errbuf); 251 else 252 memio(buf, a, n, MemWrite); 253 254 if(sysdbg) 255 itrace("read(%d, 0x%lux, %d) = %d", fd, a, size, n); 256 257 free(buf); 258 reg.r[1] = n; 259 } 260 261 void 262 sysseek(void) 263 { 264 int fd, n; 265 ulong off, mode; 266 267 fd = getmem_w(reg.r[29]+4); 268 off = getmem_w(reg.r[29]+8); 269 mode = getmem_w(reg.r[29]+12); 270 if(sysdbg) 271 itrace("seek(%d, %lud, %d)", fd, off, mode); 272 273 n = seek(fd, off, mode); 274 if(n < 0) 275 errstr(errbuf); 276 277 reg.r[1] = n; 278 } 279 280 void 281 syssleep(void) 282 { 283 ulong len; 284 int n; 285 286 len = getmem_w(reg.r[29]+4); 287 if(sysdbg) 288 itrace("sleep(%d)", len); 289 290 n = sleep(len); 291 if(n < 0) 292 errstr(errbuf); 293 294 reg.r[1] = n; 295 } 296 297 void 298 sysstat(void) 299 { 300 char nambuf[1024]; 301 char buf[DIRLEN]; 302 ulong edir, name; 303 int n; 304 305 name = getmem_w(reg.r[29]+4); 306 edir = getmem_w(reg.r[29]+8); 307 memio(nambuf, name, sizeof(nambuf), MemReadstring); 308 if(sysdbg) 309 itrace("stat(0x%lux='%s', 0x%lux)", name, nambuf, edir); 310 311 n = stat(nambuf, buf); 312 if(n < 0) 313 errstr(errbuf); 314 else 315 memio(buf, edir, DIRLEN, MemWrite); 316 317 reg.r[1] = n; 318 } 319 320 void 321 sysfstat(void) 322 { 323 char buf[DIRLEN]; 324 ulong edir; 325 int n, fd; 326 327 fd = getmem_w(reg.r[29]+4); 328 edir = getmem_w(reg.r[29]+8); 329 if(sysdbg) 330 itrace("fstat(%d, 0x%lux)", fd, edir); 331 332 n = fstat(fd, buf); 333 if(n < 0) 334 errstr(errbuf); 335 else 336 memio(buf, edir, DIRLEN, MemWrite); 337 338 reg.r[1] = n; 339 } 340 341 void 342 syswrite(void) 343 { 344 int fd; 345 ulong size, a; 346 char *buf; 347 int n; 348 349 fd = getmem_w(reg.r[29]+4); 350 a = getmem_w(reg.r[29]+8); 351 size = getmem_w(reg.r[29]+12); 352 if(sysdbg) 353 itrace("write(%d, %lux, %d)", fd, a, size); 354 355 buf = memio(0, a, size, MemRead); 356 n = write(fd, buf, size); 357 if(n < 0) 358 errstr(errbuf); 359 free(buf); 360 361 reg.r[1] = n; 362 } 363 364 void 365 syspipe(void) 366 { 367 int n, p[2]; 368 ulong fd; 369 370 fd = getmem_w(reg.r[29]+4); 371 if(sysdbg) 372 itrace("pipe(%lux)", fd); 373 374 n = pipe(p); 375 if(n < 0) 376 errstr(errbuf); 377 else { 378 putmem_w(fd, p[0]); 379 putmem_w(fd+4, p[1]); 380 } 381 reg.r[1] = n; 382 } 383 384 void 385 syscreate(void) 386 { 387 char file[1024]; 388 int n; 389 ulong mode, name, perm; 390 391 name = getmem_w(reg.r[29]+4); 392 mode = getmem_w(reg.r[29]+8); 393 perm = getmem_w(reg.r[29]+12); 394 memio(file, name, sizeof(file), MemReadstring); 395 if(sysdbg) 396 itrace("create(0x%lux='%s', 0x%lux, 0x%lux)", name, file, mode, perm); 397 398 n = create(file, mode, perm); 399 if(n < 0) 400 errstr(errbuf); 401 402 reg.r[1] = n; 403 } 404 405 void 406 sysbrk_(void) 407 { 408 ulong addr, osize, nsize; 409 Segment *s; 410 411 addr = getmem_w(reg.r[29]+4); 412 if(sysdbg) 413 itrace("brk_(0x%lux)", addr); 414 415 reg.r[1] = -1; 416 if(addr < memory.seg[Data].base+datasize) { 417 strcpy(errbuf, "address below segment"); 418 return; 419 } 420 if(addr > memory.seg[Stack].base) { 421 strcpy(errbuf, "segment too big"); 422 return; 423 } 424 s = &memory.seg[Bss]; 425 if(addr > s->end) { 426 osize = ((s->end-s->base)/BY2PG)*BY2WD; 427 addr = ((addr)+(BY2PG-1))&~(BY2PG-1); 428 s->end = addr; 429 nsize = ((s->end-s->base)/BY2PG)*BY2WD; 430 s->table = erealloc(s->table, osize, nsize); 431 } 432 433 reg.r[1] = 0; 434 } 435 436 void 437 sysremove(void) 438 { 439 char nambuf[1024]; 440 ulong name; 441 int n; 442 443 name = getmem_w(reg.r[29]+4); 444 memio(nambuf, name, sizeof(nambuf), MemReadstring); 445 if(sysdbg) 446 itrace("remove(0x%lux='%s')", name, nambuf); 447 448 n = remove(nambuf); 449 if(n < 0) 450 errstr(errbuf); 451 reg.r[1] = n; 452 } 453 454 void 455 sysnotify(void) 456 { 457 nofunc = getmem_w(reg.r[29]+4); 458 if(sysdbg) 459 itrace("notify(0x%lux)\n", nofunc); 460 461 reg.r[1] = 0; 462 } 463 464 void syswait(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0); } 465 void sysrfork(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 466 void syswstat(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 467 void sysfwstat(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 468 void sysnoted(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 469 void syssegattach(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 470 void syssegdetach(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 471 void syssegfree(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 472 void syssegflush(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 473 void sysrendezvous(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 474 void sysunmount(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 475 void sysfork(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 476 void sysforkpgrp(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 477 void syssegbrk(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 478 void sysmount(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 479 void sysalarm(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 480 void sysexec(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[1]]); exits(0);} 481 482 void (*systab[])(void) ={ 483 [SYSR1] sys1, 484 [ERRSTR] syserrstr, 485 [BIND] sysbind, 486 [CHDIR] syschdir, 487 [CLOSE] sysclose, 488 [DUP] sysdup, 489 [ALARM] sysalarm, 490 [EXEC] sysexec, 491 [EXITS] sysexits, 492 [FORK] sysfork, 493 [FORKPGRP] sysforkpgrp, 494 [FSTAT] sysfstat, 495 [SEGBRK] syssegbrk, 496 [MOUNT] sysmount, 497 [OPEN] sysopen, 498 [READ] sysread, 499 [SEEK] sysseek, 500 [SLEEP] syssleep, 501 [STAT] sysstat, 502 [WAIT] syswait, 503 [WRITE] syswrite, 504 [PIPE] syspipe, 505 [CREATE] syscreate, 506 [RFORK] sysrfork, 507 [BRK_] sysbrk_, 508 [REMOVE] sysremove, 509 [WSTAT] syswstat, 510 [FWSTAT] sysfwstat, 511 [NOTIFY] sysnotify, 512 [NOTED] sysnoted, 513 [SEGATTACH] syssegattach, 514 [SEGDETACH] syssegdetach, 515 [SEGFREE] syssegfree, 516 [SEGFLUSH] syssegflush, 517 [RENDEZVOUS] sysrendezvous, 518 [UNMOUNT] sysunmount, 519 }; 520 521 void 522 Ssyscall(ulong inst) 523 { 524 int call; 525 526 USED(inst); 527 call = reg.r[1]; 528 if(call < 0 || call > UNMOUNT) { 529 Bprint(bioout, "Bad system call\n"); 530 dumpreg(); 531 } 532 if(trace) 533 itrace("sysc\t%s", sysctab[call]); 534 535 (*systab[call])(); 536 Bflush(bioout); 537 } 538