xref: /plan9/sys/src/cmd/ki/syscall.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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 #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[7]]); exits(0); }
89 
90 void
91 syserrstr(void)
92 {
93 	ulong str;
94 
95 	str = getmem_w(reg.r[1]+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[7] = 0;
102 }
103 void
104 sysbind(void)
105 {
106 	ulong pname, pold, flags;
107 	char name[7024], old[7024];
108 	int n;
109 
110 	pname = getmem_w(reg.r[1]+4);
111 	pold = getmem_w(reg.r[1]+8);
112 	flags = getmem_w(reg.r[1]+12);
113 	memio(name, pname, sizeof(name), MemReadstring);
114 	memio(old, pold, sizeof(old), MemReadstring);
115 	if(sysdbg)
116 		itrace("bind(0x%lux='%s', 0x%lux='%s', 0x%lux)", name, old, flags);
117 
118 	n = bind(name, old, flags);
119 	if(n < 0)
120 		errstr(errbuf);
121 
122 	reg.r[7] = n;
123 }
124 
125 void
126 syschdir(void)
127 {
128 	char file[7024];
129 	int n;
130 	ulong name;
131 
132 	name = getmem_w(reg.r[1]+4);
133 	memio(file, name, sizeof(file), MemReadstring);
134 	if(sysdbg)
135 		itrace("chdir(0x%lux='%s', 0x%lux)", name, file);
136 
137 	n = chdir(file);
138 	if(n < 0)
139 		errstr(errbuf);
140 
141 	reg.r[7] = n;
142 }
143 
144 void
145 sysclose(void)
146 {
147 	int n;
148 	ulong fd;
149 
150 	fd = getmem_w(reg.r[1]+4);
151 	if(sysdbg)
152 		itrace("close(%d)", fd);
153 
154 	n = close(fd);
155 	if(n < 0)
156 		errstr(errbuf);
157 	reg.r[7] = n;
158 }
159 
160 void
161 sysdup(void)
162 {
163 	int oldfd, newfd;
164 	int n;
165 
166 	oldfd = getmem_w(reg.r[1]+4);
167 	newfd = getmem_w(reg.r[1]+8);
168 	if(sysdbg)
169 		itrace("dup(%d, %d)", oldfd, newfd);
170 
171 	n = dup(oldfd, newfd);
172 	if(n < 0)
173 		errstr(errbuf);
174 	reg.r[7] = n;
175 }
176 
177 void
178 sysexits(void)
179 {
180 	char buf[ERRLEN];
181 	ulong str;
182 
183 	str = getmem_w(reg.r[1]+4);
184 	if(sysdbg)
185 		itrace("exits(0x%lux)", str);
186 
187 	count = 1;
188 	if(str != 0) {
189 		memio(buf, str, ERRLEN, MemRead);
190 		Bprint(bioout, "exits(%s)\n", buf);
191 	}
192 	else
193 		Bprint(bioout, "exits(0)\n");
194 }
195 
196 void
197 sysopen(void)
198 {
199 	char file[7024];
200 	int n;
201 	ulong mode, name;
202 
203 	name = getmem_w(reg.r[1]+4);
204 	mode = getmem_w(reg.r[1]+8);
205 	memio(file, name, sizeof(file), MemReadstring);
206 	if(sysdbg)
207 		itrace("open(0x%lux='%s', 0x%lux)", name, file, mode);
208 
209 	n = open(file, mode);
210 	if(n < 0)
211 		errstr(errbuf);
212 
213 	reg.r[7] = n;
214 };
215 
216 void
217 sysread(void)
218 {
219 	int fd;
220 	ulong size, a;
221 	char *buf, *p;
222 	int c, n, cnt;
223 
224 	fd = getmem_w(reg.r[1]+4);
225 	a = getmem_w(reg.r[1]+8);
226 	size = getmem_w(reg.r[1]+12);
227 
228 	buf = emalloc(size);
229 	if(fd == 0) {
230 		print("\nstdin>>");
231 		p = buf;
232 		n = 0;
233 		cnt = size;
234 		while(cnt) {
235 			c = Bgetc(bin);
236 			if(c <= 0)
237 				break;
238 			*p++ = c;
239 			n++;
240 			cnt--;
241 			if(c == '\n')
242 				break;
243 		}
244 	}
245 	else
246 		n = read(fd, buf, size);
247 
248 	if(n < 0)
249 		errstr(errbuf);
250 	else
251 		memio(buf, a, n, MemWrite);
252 
253 	if(sysdbg)
254 		itrace("read(%d, 0x%lux, %d) = %d", fd, a, size, n);
255 
256 	free(buf);
257 	reg.r[7] = n;
258 }
259 
260 void
261 sysseek(void)
262 {
263 	int fd, n;
264 	ulong off, mode;
265 
266 	fd = getmem_w(reg.r[1]+4);
267 	off = getmem_w(reg.r[1]+8);
268 	mode = getmem_w(reg.r[1]+12);
269 	if(sysdbg)
270 		itrace("seek(%d, %lud, %d)", fd, off, mode);
271 
272 	n = seek(fd, off, mode);
273 	if(n < 0)
274 		errstr(errbuf);
275 
276 	reg.r[7] = n;
277 }
278 
279 void
280 syssleep(void)
281 {
282 	ulong len;
283 	int n;
284 
285 	len = getmem_w(reg.r[1]+4);
286 	if(sysdbg)
287 		itrace("sleep(%d)", len);
288 
289 	n = sleep(len);
290 	if(n < 0)
291 		errstr(errbuf);
292 
293 	reg.r[7] = n;
294 }
295 
296 void
297 sysstat(void)
298 {
299 	char nambuf[7024];
300 	char buf[DIRLEN];
301 	ulong edir, name;
302 	int n;
303 
304 	name = getmem_w(reg.r[1]+4);
305 	edir = getmem_w(reg.r[1]+8);
306 	memio(nambuf, name, sizeof(nambuf), MemReadstring);
307 	if(sysdbg)
308 		itrace("stat(0x%lux='%s', 0x%lux)", name, nambuf, edir);
309 
310 	n = stat(nambuf, buf);
311 	if(n < 0)
312 		errstr(errbuf);
313 	else
314 		memio(buf, edir, DIRLEN, MemWrite);
315 
316 	reg.r[7] = n;
317 }
318 
319 void
320 sysfstat(void)
321 {
322 	char buf[DIRLEN];
323 	ulong edir;
324 	int n, fd;
325 
326 	fd = getmem_w(reg.r[1]+4);
327 	edir = getmem_w(reg.r[1]+8);
328 	if(sysdbg)
329 		itrace("fstat(%d, 0x%lux)", fd, edir);
330 
331 	n = fstat(fd, buf);
332 	if(n < 0)
333 		errstr(errbuf);
334 	else
335 		memio(buf, edir, DIRLEN, MemWrite);
336 
337 	reg.r[7] = n;
338 }
339 
340 void
341 syswrite(void)
342 {
343 	int fd;
344 	ulong size, a;
345 	char *buf;
346 	int n;
347 
348 	fd = getmem_w(reg.r[1]+4);
349 	a = getmem_w(reg.r[1]+8);
350 	size = getmem_w(reg.r[1]+12);
351 	if(sysdbg)
352 		itrace("write(%d, %lux, %d)", fd, a, size);
353 
354 	buf = memio(0, a, size, MemRead);
355 	n = write(fd, buf, size);
356 	if(n < 0)
357 		errstr(errbuf);
358 	free(buf);
359 
360 	reg.r[7] = n;
361 }
362 
363 void
364 syspipe(void)
365 {
366 	int n, p[2];
367 	ulong fd;
368 
369 	fd = getmem_w(reg.r[1]+4);
370 	if(sysdbg)
371 		itrace("pipe(%lux)", fd);
372 
373 	n = pipe(p);
374 	if(n < 0)
375 		errstr(errbuf);
376 	else {
377 		putmem_w(fd, p[0]);
378 		putmem_w(fd+4, p[1]);
379 	}
380 	reg.r[7] = n;
381 }
382 
383 void
384 syscreate(void)
385 {
386 	char file[7024];
387 	int n;
388 	ulong mode, name, perm;
389 
390 	name = getmem_w(reg.r[1]+4);
391 	mode = getmem_w(reg.r[1]+8);
392 	perm = getmem_w(reg.r[1]+12);
393 	memio(file, name, sizeof(file), MemReadstring);
394 	if(sysdbg)
395 		itrace("create(0x%lux='%s', 0x%lux, 0x%lux)", name, file, mode, perm);
396 
397 	n = create(file, mode, perm);
398 	if(n < 0)
399 		errstr(errbuf);
400 
401 	reg.r[7] = n;
402 }
403 
404 void
405 sysbrk_(void)
406 {
407 	ulong addr, osize, nsize;
408 	Segment *s;
409 
410 	addr = getmem_w(reg.r[1]+4);
411 	if(sysdbg)
412 		itrace("brk_(0x%lux)", addr);
413 
414 	reg.r[7] = -1;
415 	if(addr < memory.seg[Data].base+datasize) {
416 		strcpy(errbuf, "address below segment");
417 		return;
418 	}
419 	if(addr > memory.seg[Stack].base) {
420 		strcpy(errbuf, "segment too big");
421 		return;
422 	}
423 	s = &memory.seg[Bss];
424 	if(addr > s->end) {
425 		osize = ((s->end-s->base)/BY2PG)*BY2WD;
426 		addr = ((addr)+(BY2PG-1))&~(BY2PG-1);
427 		s->end = addr;
428 		nsize = ((s->end-s->base)/BY2PG)*BY2WD;
429 		s->table = erealloc(s->table, osize, nsize);
430 	}
431 
432 	reg.r[7] = 0;
433 }
434 
435 void
436 sysremove(void)
437 {
438 	char nambuf[7024];
439 	ulong name;
440 	int n;
441 
442 	name = getmem_w(reg.r[1]+4);
443 	memio(nambuf, name, sizeof(nambuf), MemReadstring);
444 	if(sysdbg)
445 		itrace("remove(0x%lux='%s')", name, nambuf);
446 
447 	n = remove(nambuf);
448 	if(n < 0)
449 		errstr(errbuf);
450 	reg.r[7] = n;
451 }
452 
453 void
454 sysnotify(void)
455 {
456 	nofunc = getmem_w(reg.r[1]+4);
457 	if(sysdbg)
458 		itrace("notify(0x%lux)", nofunc);
459 
460 	reg.r[7] = 0;
461 }
462 
463 void syssegflush(void)
464 {
465 	ulong start, len;
466 
467 	start = getmem_w(reg.r[1]+4);
468 	len = getmem_w(reg.r[1]+8);
469 	if(sysdbg)
470 		itrace("segflush(0x%lux, 0x%lux)", start, len);
471 	reg.r[7] = 0;
472 }
473 
474 void syswait(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0); }
475 void sysrfork(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
476 void syswstat(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
477 void sysfwstat(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
478 void sysnoted(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
479 void syssegattach(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
480 void syssegdetach(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
481 void syssegfree(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
482 void sysrendezvous(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
483 void sysunmount(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
484 void sysfork(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
485 void sysforkpgrp(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
486 void syssegbrk(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
487 void sysmount(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
488 void sysalarm(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
489 void sysexec(void) { Bprint(bioout, "No system call %s\n", sysctab[reg.r[7]]); exits(0);}
490 
491 void (*systab[])(void)	={
492 	[SYSR1]		sys1,
493 	[ERRSTR]	syserrstr,
494 	[BIND]		sysbind,
495 	[CHDIR]		syschdir,
496 	[CLOSE]		sysclose,
497 	[DUP]		sysdup,
498 	[ALARM]		sysalarm,
499 	[EXEC]		sysexec,
500 	[EXITS]		sysexits,
501 	[FORK]		sysfork,
502 	[FORKPGRP]	sysforkpgrp,
503 	[FSTAT]		sysfstat,
504 	[SEGBRK]	syssegbrk,
505 	[MOUNT]		sysmount,
506 	[OPEN]		sysopen,
507 	[READ]		sysread,
508 	[SEEK]		sysseek,
509 	[SLEEP]		syssleep,
510 	[STAT]		sysstat,
511 	[WAIT]		syswait,
512 	[WRITE]		syswrite,
513 	[PIPE]		syspipe,
514 	[CREATE]	syscreate,
515 	[RFORK]		sysrfork,
516 	[BRK_]		sysbrk_,
517 	[REMOVE]	sysremove,
518 	[WSTAT]		syswstat,
519 	[FWSTAT]	sysfwstat,
520 	[NOTIFY]	sysnotify,
521 	[NOTED]		sysnoted,
522 	[SEGATTACH]	syssegattach,
523 	[SEGDETACH]	syssegdetach,
524 	[SEGFREE]	syssegfree,
525 	[SEGFLUSH]	syssegflush,
526 	[RENDEZVOUS]	sysrendezvous,
527 	[UNMOUNT]	sysunmount,
528 };
529 
530 void
531 ta(ulong inst)
532 {
533 	int call;
534 
535 	USED(inst);
536 	call = reg.r[7];
537 	if(call < 0 || call > UNMOUNT) {
538 		Bprint(bioout, "Bad system call\n");
539 		dumpreg();
540 	}
541 	if(trace)
542 		itrace("ta\t$0+R0\t%s", sysctab[call]);
543 
544 	(*systab[call])();
545 	Bflush(bioout);
546 }
547