aboutsummaryrefslogtreecommitdiff
path: root/sim/ppc/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'sim/ppc/system.c')
-rw-r--r--sim/ppc/system.c945
1 files changed, 637 insertions, 308 deletions
diff --git a/sim/ppc/system.c b/sim/ppc/system.c
index c032688..25ea8eb 100644
--- a/sim/ppc/system.c
+++ b/sim/ppc/system.c
@@ -30,6 +30,7 @@
#include <signal.h>
#include <sys/errno.h>
#include <sys/param.h>
+#include <fcntl.h>
#if (NetBSD >= 199306) /* here NetBSD as that is what we're emulating */
#include <sys/syscall.h> /* FIXME - should not be including this one */
@@ -45,347 +46,675 @@ extern int errno;
#include "system.h"
-void
-system_call(cpu *processor,
- unsigned_word cia)
-{
- switch (cpu_registers(processor)->gpr[0]) {
-
-
- case 1/*SYS_exit*/:
-#if (NetBSD >= 199306) && (SYS_exit != 1)
-# error "SYS_exit"
+#ifndef STATIC_INLINE_SYSTEM
+#define STATIC_INLINE_SYSTEM STATIC_INLINE
#endif
- {
- int status = (int)cpu_registers(processor)->gpr[3];
- cpu_halt(processor, cia, was_exited, status);
- break;
- }
-
- case 3/*SYS_read*/:
-#if (NetBSD >= 199306) && (SYS_read != 3)
-# error "SYS_read"
-#endif
- {
- void *scratch_buffer;
- int d = (int)cpu_registers(processor)->gpr[3];
- unsigned_word buf = cpu_registers(processor)->gpr[4];
- int nbytes = cpu_registers(processor)->gpr[5];
- int status;
- int nr_moved;
-
- /* get a tempoary bufer */
- scratch_buffer = zalloc(cpu_registers(processor)->gpr[5]);
-
- /* check if buffer exists by reading it */
- nr_moved = vm_data_map_read_buffer(cpu_data_map(processor),
- scratch_buffer,
- buf,
- nbytes,
- raw_transfer);
- if (nr_moved != nbytes)
- error("system_call()read - check on buffer failed\n");
-
- /* read */
- if (d == 0) {
- status = fread (scratch_buffer, 1, nbytes, stdin);
- if (status == 0 && ferror (stdin))
- status = -1;
- } else {
- status = read (d, scratch_buffer, nbytes);
- }
-
- if (status == -1) {
- cpu_registers(processor)->gpr[0] = errno;
- break;
- } else {
- cpu_registers(processor)->gpr[0] = 0;
- cpu_registers(processor)->gpr[3] = status;
-
- if (status > 0) {
- nr_moved = vm_data_map_write_buffer(cpu_data_map(processor),
- scratch_buffer,
- buf,
- status,
- raw_transfer,
- 0/*violate_ro*/);
-
- if (nr_moved != nbytes)
- error("system_call()read - write to buffer failed\n");
- }
- }
-
- zfree(scratch_buffer);
-
- break;
- }
-
- case 4/*SYS_write*/:
-#if (NetBSD >= 199306) && (SYS_write != 4)
-# error "SYS_write"
+#if (NetBSD >= 199306)
+#define SYS(X) ASSERT(call == (SYS_##X))
+#else
+#define SYS(X)
#endif
- {
- void *scratch_buffer;
- int nr_moved;
- int d = (int)cpu_registers(processor)->gpr[3];
- unsigned_word buf = cpu_registers(processor)->gpr[4];
- int nbytes = cpu_registers(processor)->gpr[5];
- int status;
-
- /* get a tempoary bufer */
- scratch_buffer = zalloc(cpu_registers(processor)->gpr[5]);
-
- /* copy in */
- nr_moved = vm_data_map_read_buffer(cpu_data_map(processor),
- scratch_buffer,
- buf,
- nbytes,
- raw_transfer);
- if (nr_moved != nbytes) {
- /* FIXME - should handle better */
- error("system_call()write copy failed (nr_moved=%d != nbytes=%d)\n",
- nr_moved, nbytes);
- }
-
- /* write */
- status = write(d, scratch_buffer, nbytes);
- if (status == -1) {
- cpu_registers(processor)->gpr[0] = errno;
- break;
- }
- cpu_registers(processor)->gpr[0] = 0;
- cpu_registers(processor)->gpr[3] = status;
-
- zfree(scratch_buffer);
-
- break;
- }
-
- case 17/*SYS_break*/:
-#if (NetBSD >= 199306) && (SYS_break != 17)
-# error "SYS_break"
+#if (NetBSD >= 199306 && PATH_MAX != 1024)
+#error "PATH_MAX not 1024"
+#elif !defined(PATH_MAX)
+#define PATH_MAX 1024
#endif
- {
- /* pretend to extend the heap so that it reaches addresss
- new_break while in truth, if growth is needed grow it by a
- page aligned amount */
- unsigned_word new_break = ALIGN_8(cpu_registers(processor)->gpr[3]);
- unsigned_word old_break = core_data_upper_bound(cpu_core(processor));
- signed_word delta = new_break - old_break;
- if (delta > 0)
- core_add_data(cpu_core(processor),
- ALIGN_PAGE(new_break) - old_break);
- cpu_registers(processor)->gpr[0] = 0;
- cpu_registers(processor)->gpr[3] = new_break;
- break;
- }
- case 20/*SYS_getpid*/:
-#if (NetBSD >= 199306) && (SYS_getpid != 20)
-# error "SYS_getpid"
-#endif
- {
- cpu_registers(processor)->gpr[3] = (int)getpid();
+STATIC_INLINE_SYSTEM char *
+read_string(cpu *processor,
+ char *dest,
+ unsigned_word addr,
+ unsigned nr_bytes)
+{
+ unsigned nr_moved = 0;
+ if (addr == 0)
+ return NULL;
+ while (1) {
+ if (vm_data_map_read_buffer(cpu_data_map(processor),
+ &dest[nr_moved],
+ addr + nr_moved,
+ sizeof(dest[nr_moved]))
+ != sizeof(dest[nr_moved]))
+ return NULL;
+ if (dest[nr_moved] == '\0' || nr_moved >= nr_bytes)
break;
- }
-
+ nr_moved++;
+ }
+ dest[nr_moved] = '\0';
+ return dest;
+}
- case 37/*SYS_kill*/:
-#if (NetBSD >= 199306) && (SYS_kill != 37)
-# error "SYS_kill"
-#endif
- {
- pid_t pid = cpu_registers(processor)->gpr[3];
- int sig = cpu_registers(processor)->gpr[4];
- TRACE(trace_tbd, ("SYS_kill - more to this than just a kill\n"));
- cpu_halt(processor, cia, was_signalled, sig);
- break;
- }
-
- case 48/*SYS_sigprocmask*/:
-#if (NetBSD >= 199306) && (SYS_sigprocmask != 48)
-# error "SYS_sigprocmask"
-#endif
- {
- natural_word how = cpu_registers(processor)->gpr[3];
- unsigned_word set = cpu_registers(processor)->gpr[4];
- unsigned_word oset = cpu_registers(processor)->gpr[5];
- TRACE(trace_system, ("SYS_sigprocmask: how=%d, set=0x%x, oset=0x%x\n",
- how, set, oset));
- cpu_registers(processor)->gpr[0] = 0;
- cpu_registers(processor)->gpr[3] = 0;
- cpu_registers(processor)->gpr[4] = set;
- break;
- }
+STATIC_INLINE_SYSTEM void
+write_status(cpu *processor,
+ int status)
+{
+ cpu_registers(processor)->gpr[3] = status;
+ if (status < 0)
+ cpu_registers(processor)->gpr[0] = errno;
+ else
+ cpu_registers(processor)->gpr[0] = 0;
+}
- case 54/*SYS_ioctl*/:
-#if (NetBSD >= 199306) && (SYS_ioctl != 54)
-# error "SYS_ioctl"
+STATIC_INLINE_SYSTEM void
+write_stat(cpu *processor,
+ unsigned_word addr,
+ struct stat buf)
+{
+ int nr_moved;
+ H2T(buf.st_dev);
+ H2T(buf.st_ino);
+ H2T(buf.st_mode);
+ H2T(buf.st_nlink);
+ H2T(buf.st_uid);
+ H2T(buf.st_gid);
+ H2T(buf.st_rdev);
+ H2T(buf.st_size);
+ H2T(buf.st_atime);
+ /* H2T(buf.st_spare1); */
+ H2T(buf.st_mtime);
+ /* H2T(buf.st_spare2); */
+ H2T(buf.st_ctime);
+ /* H2T(buf.st_spare3); */
+ H2T(buf.st_blksize);
+ H2T(buf.st_blocks);
+#if (NetBSD >= 199306)
+ H2T(buf.st_flags);
+ H2T(buf.st_gen);
#endif
- {
- TRACE(trace_system, ("SYS_ioctl: d=%d, request=0x%x, argp=0x%x\n",
- cpu_registers(processor)->gpr[3], cpu_registers(processor)->gpr[4], cpu_registers(processor)->gpr[5]));
- cpu_registers(processor)->gpr[0] = 0;
- cpu_registers(processor)->gpr[3] = 0;
- break;
- }
+ nr_moved = vm_data_map_write_buffer(cpu_data_map(processor),
+ &buf,
+ addr,
+ sizeof(buf),
+ 0/*violate_ro*/);
+ if (nr_moved != sizeof(buf))
+ error("write_stat() write failed\n");
+}
+
+
+STATIC_INLINE_SYSTEM void
+do_exit(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ int status = (int)cpu_registers(processor)->gpr[3];
+ SYS(exit);
+ cpu_halt(processor, cia, was_exited, status);
+}
- case 189/*SYS_fstat*/:
-#if (NetBSD >= 199306) && (SYS_fstat != 189)
-# error "SYS_fstat"
-#endif
- {
- int fd = cpu_registers(processor)->gpr[3];
- unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[4];
- struct stat buf;
- int nr_moved;
- int status;
-
- /* check buffer all there, by reading it */
- nr_moved = vm_data_map_read_buffer(cpu_data_map(processor),
- &buf,
- stat_buf_addr,
- sizeof(buf),
- raw_transfer);
- if (nr_moved != sizeof(buf))
- error("system_call()fstat - check on buffer failed\n");
-
- /* do the fstat call */
- status = fstat(fd, &buf);
- if (status == -1) {
- cpu_registers(processor)->gpr[0] = errno;
- break;
- }
- cpu_registers(processor)->gpr[0] = 0;
- cpu_registers(processor)->gpr[3] = 0;
-
- H2T(buf.st_dev);
- H2T(buf.st_ino);
- H2T(buf.st_mode);
- H2T(buf.st_nlink);
- H2T(buf.st_uid);
- H2T(buf.st_gid);
- H2T(buf.st_rdev);
- H2T(buf.st_size);
- H2T(buf.st_atime);
- /* H2T(buf.st_spare1); */
- H2T(buf.st_mtime);
- /* H2T(buf.st_spare2); */
- H2T(buf.st_ctime);
- /* H2T(buf.st_spare3); */
- H2T(buf.st_blksize);
- H2T(buf.st_blocks);
-#if (NetBSD >= 199306)
- H2T(buf.st_flags);
- H2T(buf.st_gen);
+STATIC_INLINE_SYSTEM void
+do_read(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ void *scratch_buffer;
+ int d = (int)cpu_registers(processor)->gpr[3];
+ unsigned_word buf = cpu_registers(processor)->gpr[4];
+ int nbytes = cpu_registers(processor)->gpr[5];
+ int status;
+ int nr_moved;
+ SYS(read);
+
+ /* get a tempoary bufer */
+ scratch_buffer = zalloc(nbytes);
+
+ /* check if buffer exists by reading it */
+ nr_moved = vm_data_map_read_buffer(cpu_data_map(processor),
+ scratch_buffer,
+ buf,
+ nbytes);
+ if (nr_moved != nbytes)
+ error("system_call()read - check on buffer failed\n");
+
+ /* read */
+#if 0
+ if (d == 0) {
+ status = fread (scratch_buffer, 1, nbytes, stdin);
+ if (status == 0 && ferror (stdin))
+ status = -1;
+ }
#endif
-
+ status = read (d, scratch_buffer, nbytes);
+
+ if (status == -1) {
+ cpu_registers(processor)->gpr[0] = errno;
+ } else {
+ cpu_registers(processor)->gpr[3] = status;
+
+ if (status > 0) {
nr_moved = vm_data_map_write_buffer(cpu_data_map(processor),
- &buf,
- stat_buf_addr,
- sizeof(buf),
- raw_transfer,
+ scratch_buffer,
+ buf,
+ status,
0/*violate_ro*/);
- break;
+ if (nr_moved != status)
+ error("system_call()read - write to buffer failed\n");
}
+ }
+
+ zfree(scratch_buffer);
+}
- case 202/*SYS___sysctl*/:
-#if (NetBSD >= 199306) && (SYS___sysctl != 202)
-# error "SYS__sysctl"
-#endif
- {
- /* call the arguments by their real name */
- unsigned_word name = cpu_registers(processor)->gpr[3];
- natural_word namelen = cpu_registers(processor)->gpr[4];
- unsigned_word oldp = cpu_registers(processor)->gpr[5];
- unsigned_word oldlenp = cpu_registers(processor)->gpr[6];
- natural_word oldlen;
- natural_word mib;
- natural_word int_val;
-
- /* pluck out the management information base id */
- if (namelen < 1
- || sizeof(mib) != vm_data_map_read_buffer(cpu_data_map(processor),
- &mib,
- name,
- sizeof(mib),
- cooked_transfer))
- error("system_call()SYS___sysctl bad name[0]\n");
- name += sizeof(mib);
-
- /* see what to do with it ... */
- switch (mib) {
- case 6/*CTL_HW*/:
+STATIC_INLINE_SYSTEM void
+do_write(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ void *scratch_buffer = NULL;
+ int nr_moved;
+ int d = (int)cpu_registers(processor)->gpr[3];
+ unsigned_word buf = cpu_registers(processor)->gpr[4];
+ int nbytes = cpu_registers(processor)->gpr[5];
+ int status;
+ SYS(write);
+
+ /* get a tempoary bufer */
+ scratch_buffer = zalloc(nbytes); /* FIXME - nbytes == 0 */
+
+ /* copy in */
+ nr_moved = vm_data_map_read_buffer(cpu_data_map(processor),
+ scratch_buffer,
+ buf,
+ nbytes);
+ if (nr_moved != nbytes) {
+ /* FIXME - should handle better */
+ error("system_call()write copy failed (nr_moved=%d != nbytes=%d)\n",
+ nr_moved, nbytes);
+ }
+
+ /* write */
+ status = write(d, scratch_buffer, nbytes);
+ if (status == -1) {
+ cpu_registers(processor)->gpr[0] = errno;
+ }
+ cpu_registers(processor)->gpr[3] = status;
+
+ zfree(scratch_buffer);
+}
+
+
+STATIC_INLINE_SYSTEM void
+do_open(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ unsigned_word path_addr = cpu_registers(processor)->gpr[3];
+ char path_buf[PATH_MAX];
+ char *path = read_string(processor, path_buf, path_addr, PATH_MAX);
+ int flags = (int)cpu_registers(processor)->gpr[4];
+ int mode = (int)cpu_registers(processor)->gpr[4];
+ SYS(open);
+ write_status(processor, open(path, flags, mode));
+}
+
+
+STATIC_INLINE_SYSTEM void
+do_close(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ int d = (int)cpu_registers(processor)->gpr[3];
+ SYS(close);
+ write_status(processor, close(d));
+}
+
+
+STATIC_INLINE_SYSTEM void
+do_break(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+ /* just pass this onto the `vm' device */
+{
+ psim *system = cpu_system(processor);
+ const device *vm = psim_device(system, "/vm");
+ SYS(break);
+ vm->callback->ioctl(vm,
+ system,
+ processor,
+ cia,
+ 0, /*ioctl*/
+ NULL); /*ioctl-data*/
+}
+
+
+STATIC_INLINE_SYSTEM void
+do_getpid(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ SYS(getpid);
+ cpu_registers(processor)->gpr[3] = (int)getpid();
+}
+
+
+STATIC_INLINE_SYSTEM void
+do_getuid(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ SYS(getuid);
+ cpu_registers(processor)->gpr[3] = (int)getuid();
+}
+
+
+STATIC_INLINE_SYSTEM void
+do_geteuid(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ SYS(geteuid);
+ cpu_registers(processor)->gpr[3] = (int)geteuid();
+}
+
+
+STATIC_INLINE_SYSTEM void
+do_kill(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ pid_t pid = cpu_registers(processor)->gpr[3];
+ int sig = cpu_registers(processor)->gpr[4];
+ SYS(kill);
+ error("SYS_kill - more to this than just a kill\n");
+ cpu_halt(processor, cia, was_signalled, sig);
+}
+
+
+STATIC_INLINE_SYSTEM void
+do_sigprocmask(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ natural_word how = cpu_registers(processor)->gpr[3];
+ unsigned_word set = cpu_registers(processor)->gpr[4];
+ unsigned_word oset = cpu_registers(processor)->gpr[5];
+ SYS(sigprocmask);
+ TRACE(trace_system, ("SYS_sigprocmask: how=%d, set=0x%x, oset=0x%x\n",
+ how, set, oset));
+ cpu_registers(processor)->gpr[3] = 0;
+ cpu_registers(processor)->gpr[4] = set;
+}
+
+
+STATIC_INLINE_SYSTEM void
+do_ioctl(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ SYS(ioctl);
+ TRACE(trace_system, ("SYS_ioctl: d=%d, request=0x%x, argp=0x%x\n",
+ cpu_registers(processor)->gpr[3], cpu_registers(processor)->gpr[4], cpu_registers(processor)->gpr[5]));
+ cpu_registers(processor)->gpr[3] = 0;
+}
+
+
+STATIC_INLINE_SYSTEM void
+do_umask(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ SYS(umask);
+ cpu_registers(processor)->gpr[3] = umask(cpu_registers(processor)->gpr[3]);
+}
+
+
+STATIC_INLINE_SYSTEM void
+do_stat(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ char path_buf[PATH_MAX];
+ unsigned_word path_addr = cpu_registers(processor)->gpr[3];
+ unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[4];
+ char *path = read_string(processor, path_buf, path_addr, PATH_MAX);
+ struct stat buf;
+ SYS(stat);
+ write_status(processor, stat(path, &buf));
+ write_stat(processor, stat_buf_addr, buf);
+}
+
+
+STATIC_INLINE_SYSTEM void
+do_fstat(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ int fd = cpu_registers(processor)->gpr[3];
+ unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[4];
+ struct stat buf;
+ SYS(fstat);
+ write_status(processor, fstat(fd, &buf));
+ write_stat(processor, stat_buf_addr, buf);
+}
+
+
+STATIC_INLINE_SYSTEM void
+do_lstat(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ char path_buf[PATH_MAX];
+ unsigned_word path_addr = cpu_registers(processor)->gpr[3];
+ char *path = read_string(processor, path_buf, path_addr, PATH_MAX);
+ unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[4];
+ struct stat buf;
+ SYS(lstat);
+ write_status(processor, stat(path, &buf));
+ write_stat(processor, stat_buf_addr, buf);
+}
+
+
+STATIC_INLINE_SYSTEM void
+do___sysctl(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ /* call the arguments by their real name */
+ unsigned_word name = cpu_registers(processor)->gpr[3];
+ natural_word namelen = cpu_registers(processor)->gpr[4];
+ unsigned_word oldp = cpu_registers(processor)->gpr[5];
+ unsigned_word oldlenp = cpu_registers(processor)->gpr[6];
+ natural_word oldlen;
+ natural_word mib;
+ natural_word int_val;
+ SYS(__sysctl);
+
+ /* pluck out the management information base id */
+ if (namelen < 1)
+ error("system_call()SYS___sysctl bad name[0]\n");
+ mib = vm_data_map_read_word(cpu_data_map(processor),
+ name,
+ processor,
+ cia);
+ name += sizeof(mib);
+
+ /* see what to do with it ... */
+ switch (mib) {
+ case 6/*CTL_HW*/:
#if (NetBSD >= 199306) && (CTL_HW != 6)
# error "CTL_HW"
#endif
- if (namelen < 2
- || sizeof(mib) != vm_data_map_read_buffer(cpu_data_map(processor),
- &mib,
- name,
- sizeof(mib),
- cooked_transfer))
- error("system_call()SYS___sysctl - CTL_HW - bad name[1]\n");
- name += sizeof(mib);
- switch (mib) {
- case 7/*HW_PAGESIZE*/:
+ if (namelen < 2)
+ error("system_call()SYS___sysctl - CTL_HW - bad name[1]\n");
+ mib = vm_data_map_read_word(cpu_data_map(processor),
+ name,
+ processor,
+ cia);
+ name += sizeof(mib);
+ switch (mib) {
+ case 7/*HW_PAGESIZE*/:
#if (NetBSD >= 199306) && (HW_PAGESIZE != 7)
# error "HW_PAGESIZE"
#endif
- if (sizeof(oldlen) != vm_data_map_read_buffer(cpu_data_map(processor),
- &oldlen,
- oldlenp,
- sizeof(oldlen),
- cooked_transfer))
- error("system_call()sysctl - CTL_HW.HW_PAGESIZE - oldlen read\n");
- if (sizeof(natural_word) > oldlen)
- error("system_call()sysctl - CTL_HW.HW_PAGESIZE - to small\n");
- int_val = 8192;
- oldlen = sizeof(int_val);
- if (sizeof(int_val) != vm_data_map_write_buffer(cpu_data_map(processor),
- &int_val,
- oldp,
- sizeof(int_val),
- cooked_transfer,
- 0/*violate_ro*/))
- error("system_call()sysctl - CTL_HW.HW_PAGESIZE - int_val\n");
- if (sizeof(oldlen) != vm_data_map_write_buffer(cpu_data_map(processor),
- &oldlen,
- oldlenp,
- sizeof(oldlen),
- cooked_transfer,
- 0/*violate_ro*/))
- error("system_call()sysctl - CTL_HW.HW_PAGESIZE - oldlen write\n");
- break;
- default:
- error("sysctl() CTL_HW.%d unknown\n", mib);
- break;
- }
- break;
- default:
- error("sysctl() name[0]=%s unknown\n", (int)mib);
- break;
- }
- cpu_registers(processor)->gpr[0] = 0;
- cpu_registers(processor)->gpr[3] = 0;
+ oldlen = vm_data_map_read_word(cpu_data_map(processor),
+ oldlenp,
+ processor,
+ cia);
+ if (sizeof(natural_word) > oldlen)
+ error("system_call()sysctl - CTL_HW.HW_PAGESIZE - to small\n");
+ int_val = 8192;
+ oldlen = sizeof(int_val);
+ vm_data_map_write_word(cpu_data_map(processor),
+ oldp,
+ int_val,
+ processor,
+ cia);
+ vm_data_map_write_word(cpu_data_map(processor),
+ oldlenp,
+ oldlen,
+ processor,
+ cia);
+ break;
+ default:
+ error("sysctl() CTL_HW.%d unknown\n", mib);
break;
}
-
-
+ break;
default:
- error("system_call() unimplemented system call %d, cia=0x%x, arg[0]=0x%x, lr=0x%x\n",
- cpu_registers(processor)->gpr[0], cia, cpu_registers(processor)->gpr[3], LR);
+ error("sysctl() name[0]=%s unknown\n", (int)mib);
break;
-
}
+ cpu_registers(processor)->gpr[3] = 0;
+}
+
+STATIC_INLINE_SYSTEM void
+unimp(unsigned call,
+ cpu *processor,
+ unsigned_word cia)
+{
+ error("unimplemented system call %d, cia=0x%x\n", call, cia);
+}
+
+
+typedef void (sys_handler)
+ (unsigned call,
+ cpu *processor,
+ unsigned_word cia);
+
+static sys_handler *(handlers[]) = {
+ unimp, /* SYS_syscall 0 */
+ do_exit, /* 1*/
+ unimp, /* SYS_fork 2 */
+ do_read, /* 3 */
+ do_write, /* 4 */
+ do_open, /* 5 */
+ do_close, /* 6 */
+ unimp, /* SYS_wait4 7 */
+ unimp, /* 8 is old creat */
+ unimp, /* SYS_link 9 */
+ unimp, /* SYS_unlink 10 */
+ unimp, /* 11 is obsolete execv */
+ unimp, /* SYS_chdir 12 */
+ unimp, /* SYS_fchdir 13 */
+ unimp, /* SYS_mknod 14 */
+ unimp, /* SYS_chmod 15 */
+ unimp, /* SYS_chown 16 */
+ do_break, /* 17 */
+ unimp, /* SYS_getfsstat 18 */
+ unimp, /* 19 is old lseek */
+ do_getpid, /* 20 */
+ unimp, /* SYS_mount 21 */
+ unimp, /* SYS_unmount 22 */
+ unimp, /* SYS_setuid 23 */
+ do_getuid, /* 24 */
+ do_geteuid, /* 25 */
+ unimp, /* SYS_ptrace 26 */
+ unimp, /* SYS_recvmsg 27 */
+ unimp, /* SYS_sendmsg 28 */
+ unimp, /* SYS_recvfrom 29 */
+ unimp, /* SYS_accept 30 */
+ unimp, /* SYS_getpeername 31 */
+ unimp, /* SYS_getsockname 32 */
+ unimp, /* SYS_access 33 */
+ unimp, /* SYS_chflags 34 */
+ unimp, /* SYS_fchflags 35 */
+ unimp, /* SYS_sync 36 */
+ do_kill, /* 37 */
+ unimp, /* 38 is old stat */
+ unimp, /* SYS_getppid 39 */
+ unimp, /* 40 is old lstat */
+ unimp, /* SYS_dup 41 */
+ unimp, /* SYS_pipe 42 */
+ unimp, /* SYS_getegid 43 */
+ unimp, /* SYS_profil 44 */
+ unimp, /* SYS_ktrace 45 */
+ unimp, /* SYS_sigaction 46 */
+ unimp, /* SYS_getgid 47 */
+ do_sigprocmask, /* 48 */
+ unimp, /* SYS_getlogin 49 */
+ unimp, /* SYS_setlogin 50 */
+ unimp, /* SYS_acct 51 */
+ unimp, /* SYS_sigpending 52 */
+ unimp, /* SYS_sigaltstack 53 */
+ do_ioctl, /* 54 */
+ unimp, /* SYS_reboot 55 */
+ unimp, /* SYS_revoke 56 */
+ unimp, /* SYS_symlink 57 */
+ unimp, /* SYS_readlink 58 */
+ unimp, /* SYS_execve 59 */
+ do_umask, /* 60 */
+ unimp, /* SYS_chroot 61 */
+ unimp, /* 62 is old fstat */
+ unimp, /* 63 is old getkerninfo */
+ unimp, /* 64 is old getpagesize */
+ unimp, /* SYS_msync 65 */
+ unimp, /* SYS_vfork 66 */
+ unimp, /* 67 is obsolete vread */
+ unimp, /* 68 is obsolete vwrite */
+ unimp, /* SYS_sbrk 69 */
+ unimp, /* SYS_sstk 70 */
+ unimp, /* 71 is old mmap */
+ unimp, /* SYS_vadvise 72 */
+ unimp, /* SYS_munmap 73 */
+ unimp, /* SYS_mprotect 74 */
+ unimp, /* SYS_madvise 75 */
+ unimp, /* 76 is obsolete vhangup */
+ unimp, /* 77 is obsolete vlimit */
+ unimp, /* SYS_mincore 78 */
+ unimp, /* SYS_getgroups 79 */
+ unimp, /* SYS_setgroups 80 */
+ unimp, /* SYS_getpgrp 81 */
+ unimp, /* SYS_setpgid 82 */
+ unimp, /* SYS_setitimer 83 */
+ unimp, /* 84 is old wait */
+ unimp, /* SYS_swapon 85 */
+ unimp, /* SYS_getitimer 86 */
+ unimp, /* 87 is old gethostname */
+ unimp, /* 88 is old sethostname */
+ unimp, /* 89 is old getdtablesize */
+ unimp, /* SYS_dup2 90 */
+ unimp, /* 91 */
+ unimp, /* SYS_fcntl 92 */
+ unimp, /* SYS_select 93 */
+ unimp, /* 94 */
+ unimp, /* SYS_fsync 95 */
+ unimp, /* SYS_setpriority 96 */
+ unimp, /* SYS_socket 97 */
+ unimp, /* SYS_connect 98 */
+ unimp, /* 99 is old accept */
+ unimp, /* SYS_getpriority 100 */
+ unimp, /* 101 is old send */
+ unimp, /* 102 is old recv */
+ unimp, /* SYS_sigreturn 103 */
+ unimp, /* SYS_bind 104 */
+ unimp, /* SYS_setsockopt 105 */
+ unimp, /* SYS_listen 106 */
+ unimp, /* 107 is obsolete vtimes */
+ unimp, /* 108 is old sigvec */
+ unimp, /* 109 is old sigblock */
+ unimp, /* 110 is old sigsetmask */
+ unimp, /* SYS_sigsuspend 111 */
+ unimp, /* 112 is old sigstack */
+ unimp, /* 113 is old recvmsg */
+ unimp, /* 114 is old sendmsg */
+ unimp, /* SYS_vtrace 115 - is obsolete vtrace */
+ unimp, /* SYS_gettimeofday 116 */
+ unimp, /* SYS_getrusage 117 */
+ unimp, /* SYS_getsockopt 118 */
+ unimp, /* SYS_resuba 119 */
+ unimp, /* SYS_readv 120 */
+ unimp, /* SYS_writev 121 */
+ unimp, /* SYS_settimeofday 122 */
+ unimp, /* SYS_fchown 123 */
+ unimp, /* SYS_fchmod 124 */
+ unimp, /* 125 is old recvfrom */
+ unimp, /* 126 is old setreuid */
+ unimp, /* 127 is old setregid */
+ unimp, /* SYS_rename 128 */
+ unimp, /* 129 is old truncate */
+ unimp, /* 130 is old ftruncate */
+ unimp, /* SYS_flock 131 */
+ unimp, /* SYS_mkfifo 132 */
+ unimp, /* SYS_sendto 133 */
+ unimp, /* SYS_shutdown 134 */
+ unimp, /* SYS_socketpair 135 */
+ unimp, /* SYS_mkdir 136 */
+ unimp, /* SYS_rmdir 137 */
+ unimp, /* SYS_utimes 138 */
+ unimp, /* 139 is obsolete 4.2 sigreturn */
+ unimp, /* SYS_adjtime 140 */
+ unimp, /* 141 is old getpeername */
+ unimp, /* 142 is old gethostid */
+ unimp, /* 143 is old sethostid */
+ unimp, /* 144 is old getrlimit */
+ unimp, /* 145 is old setrlimit */
+ unimp, /* 146 is old killpg */
+ unimp, /* SYS_setsid 147 */
+ unimp, /* SYS_quotactl 148 */
+ unimp, /* 149 is old quota */
+ unimp, /* 150 is old getsockname */
+ unimp, /* 151 */
+ unimp, /* 152 */
+ unimp, /* 153 */
+ unimp, /* 154 */
+ unimp, /* SYS_nfssvc 155 */
+ unimp, /* 156 is old getdirentries */
+ unimp, /* SYS_statfs 157 */
+ unimp, /* SYS_fstatfs 158 */
+ unimp, /* 159 */
+ unimp, /* 160 */
+ unimp, /* SYS_getfh 161 */
+ unimp, /* 162 is old getdomainname */
+ unimp, /* 163 is old setdomainname */
+ unimp, /* 164 is old uname */
+ unimp, /* SYS_sysarch 165 */
+ unimp, /* 166 */
+ unimp, /* 167 */
+ unimp, /* 168 */
+ unimp, /* SYS_semsys 169 */
+ unimp, /* SYS_msgsys 170 */
+ unimp, /* SYS_shmsys 171 */
+ unimp, /* 172 */
+ unimp, /* 173 */
+ unimp, /* 174 */
+ unimp, /* 175 */
+ unimp, /* 176 */
+ unimp, /* 177 */
+ unimp, /* 178 */
+ unimp, /* 179 */
+ unimp, /* 180 */
+ unimp, /* SYS_setgid 181 */
+ unimp, /* SYS_setegid 182 */
+ unimp, /* SYS_seteuid 183 */
+ unimp, /* SYS_lfs_bmapv 184 */
+ unimp, /* SYS_lfs_markv 185 */
+ unimp, /* SYS_lfs_segclean 186 */
+ unimp, /* SYS_lfs_segwait 187 */
+ do_stat, /* 188 */
+ do_fstat, /* 189 */
+ do_lstat, /* 190 */
+ unimp, /* SYS_pathconf 191 */
+ unimp, /* SYS_fpathconf 192 */
+ unimp, /* 193 */
+ unimp, /* SYS_getrlimit 194 */
+ unimp, /* SYS_setrlimit 195 */
+ unimp, /* SYS_getdirentries 196 */
+ unimp, /* SYS_mmap 197 */
+ unimp, /* SYS___syscall 198 */
+ unimp, /* SYS_lseek 199 */
+ unimp, /* SYS_truncate 200 */
+ unimp, /* SYS_ftruncate 201 */
+ do___sysctl, /* 202 */
+ unimp, /* SYS_mlock 203 */
+ unimp, /* SYS_munlock 204 */
+};
+
+INLINE_SYSTEM void
+system_call(cpu *processor,
+ unsigned_word cia)
+{
+ unsigned call = cpu_registers(processor)->gpr[0];
+ if (call >= sizeof(handlers)/sizeof(handlers[0]))
+ error("system call %d out-of-range\n", call);
+ cpu_registers(processor)->gpr[0] = 0; /* default success */
+ handlers[call](call, processor, cia);
}
#endif /* _SYSTEM_C_ */