static void do_ioctl(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { int d = cpu_registers(processor)->gpr[arg0]; unsigned request = cpu_registers(processor)->gpr[arg0+1]; unsigned_word argp_addr = cpu_registers(processor)->gpr[arg0+2]; #if !WITH_NetBSD_HOST cpu_registers(processor)->gpr[arg0] = 0; /* just succeed */ #else unsigned dir = request & IOC_DIRMASK; int status; SYS(ioctl); /* what we haven't done */ if (dir & IOC_IN /* write into the io device */ || dir & IOC_OUT || !(dir & IOC_VOID)) error("do_ioctl() read or write of parameter not implemented\n"); status = ioctl(d, request, NULL); emul_write_status(processor, status, errno); #endif if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d, 0x%x, 0x%lx", d, request, (long)argp_addr); }
static void do_write(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { void *scratch_buffer = NULL; int d = (int)cpu_registers(processor)->gpr[arg0]; unsigned_word buf = cpu_registers(processor)->gpr[arg0+1]; int nbytes = cpu_registers(processor)->gpr[arg0+2]; int status; SYS(write); if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes); /* get a tempoary bufer */ scratch_buffer = zalloc(nbytes); /* FIXME - nbytes == 0 */ /* copy in */ emul_read_buffer(scratch_buffer, buf, nbytes, processor, cia); /* write */ status = write(d, scratch_buffer, nbytes); emul_write_status(processor, status, errno); free(scratch_buffer); flush_stdoutput(); }
static void do_gettimeofday(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { unsigned_word t_addr = cpu_registers(processor)->gpr[arg0]; unsigned_word tz_addr = cpu_registers(processor)->gpr[arg0+1]; struct timeval t; struct timezone tz; int status = gettimeofday((t_addr != 0 ? &t : NULL), (tz_addr != 0 ? &tz : NULL)); int err = errno; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx, 0x%lx", (long)t_addr, (long)tz_addr); SYS(gettimeofday); emul_write_status(processor, status, err); if (status == 0) { if (t_addr != 0) write_timeval(t_addr, t, processor, cia); if (tz_addr != 0) write_timezone(tz_addr, tz, processor, cia); } }
static void do_getdirentries(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { int fd = cpu_registers(processor)->gpr[arg0]; unsigned_word buf_addr = cpu_registers(processor)->gpr[arg0+1]; char *buf; int nbytes = cpu_registers(processor)->gpr[arg0+2]; unsigned_word basep_addr = cpu_registers(processor)->gpr[arg0+3]; long basep; int status; #ifdef SYS_getdirentries SYS(getdirentries); #endif if (buf_addr != 0 && nbytes >= 0) buf = zalloc(nbytes); else buf = NULL; status = getdirentries(fd, (buf_addr == 0 ? NULL : buf), nbytes, (basep_addr == 0 ? NULL : &basep)); emul_write_status(processor, status, errno); if (basep_addr != 0) emul_write_word(basep_addr, basep, processor, cia); if (status > 0) write_direntries(buf_addr, buf, status, processor, cia); if (buf != NULL) free(buf); }
static void do_getgid(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { SYS(getgid); emul_write_status(processor, (int)getgid(), 0); }
static void do_lseek(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { int fildes = cpu_registers(processor)->gpr[arg0]; off_t offset = emul_read_gpr64(processor, arg0+2); int whence = cpu_registers(processor)->gpr[arg0+4]; off_t status; SYS(lseek); status = lseek(fildes, offset, whence); if (status == -1) emul_write_status(processor, -1, errno); else { emul_write_status(processor, 0, 0); /* success */ emul_write_gpr64(processor, 3, status); } }
static void do_umask(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { int mask = cpu_registers(processor)->gpr[arg0]; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0%o", mask); SYS(umask); emul_write_status(processor, umask(mask), 0); }
static void do_fstat(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { int fd = cpu_registers(processor)->gpr[arg0]; unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1]; struct stat buf; int status; SYS(fstat); /* Can't combine these statements, cuz fstat sets errno. */ status = fstat(fd, &buf); emul_write_status(processor, status, errno); write_stat(stat_buf_addr, buf, processor, cia); }
static void do_dup(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { int oldd = cpu_registers(processor)->gpr[arg0]; int status = dup(oldd); int err = errno; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d", oldd); SYS(dup); emul_write_status(processor, status, err); }
static void do_sigprocmask(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { natural_word how = cpu_registers(processor)->gpr[arg0]; unsigned_word set = cpu_registers(processor)->gpr[arg0+1]; unsigned_word oset = cpu_registers(processor)->gpr[arg0+2]; SYS(sigprocmask); if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%ld, 0x%ld, 0x%ld", (long)how, (long)set, (long)oset); emul_write_status(processor, 0, 0); cpu_registers(processor)->gpr[4] = set; }
static void do_stat(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { char path_buf[PATH_MAX]; unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1]; char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); struct stat buf; int status; SYS(stat); status = stat(path, &buf); emul_write_status(processor, status, errno); if (status == 0) write_stat(stat_buf_addr, buf, processor, cia); }
static void do_fcntl(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { int fd = cpu_registers(processor)->gpr[arg0]; int cmd = cpu_registers(processor)->gpr[arg0+1]; int arg = cpu_registers(processor)->gpr[arg0+2]; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d, %d, %d", fd, cmd, arg); SYS(fcntl); status = fcntl(fd, cmd, arg); emul_write_status(processor, status, errno); }
static void do_lstat(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { char path_buf[PATH_MAX]; unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1]; struct stat buf; int status; SYS(lstat); /* Can't combine these statements, cuz lstat sets errno. */ status = lstat(path, &buf); emul_write_status(processor, status, errno); write_stat(stat_buf_addr, buf, processor, cia); }
static void do_close(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { int d = (int)cpu_registers(processor)->gpr[arg0]; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d", d); SYS(close); /* Can't combine these statements, cuz close sets errno. */ status = close(d); emul_write_status(processor, status, errno); }
static void do_open(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; char path_buf[PATH_MAX]; char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); int flags = (int)cpu_registers(processor)->gpr[arg0+1]; int mode = (int)cpu_registers(processor)->gpr[arg0+2]; int hostflags; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx [%s], 0x%x, 0x%x", (long)path_addr, path, flags, mode); SYS(open); /* Do some translation on 'flags' to match it to the host's version. */ /* These flag values were taken from the NetBSD 1.4 header files. */ if ((flags & 3) == 0) hostflags = O_RDONLY; else if ((flags & 3) == 1) hostflags = O_WRONLY; else hostflags = O_RDWR; if (flags & 0x00000008) hostflags |= O_APPEND; if (flags & 0x00000200) hostflags |= O_CREAT; if (flags & 0x00000400) hostflags |= O_TRUNC; if (flags & 0x00000800) hostflags |= O_EXCL; /* Can't combine these statements, cuz open sets errno. */ status = open(path, hostflags, mode); emul_write_status(processor, status, errno); }
static void do_break(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { /* just pass this onto the `vm' device */ unsigned_word new_break = cpu_registers(processor)->gpr[arg0]; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx", (long)cpu_registers(processor)->gpr[arg0]); SYS(break); status = device_ioctl(emul->vm, processor, cia, device_ioctl_break, new_break); /*ioctl-data*/ emul_write_status(processor, 0, status); }
static void do_read(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { void *scratch_buffer; int d = (int)cpu_registers(processor)->gpr[arg0]; unsigned_word buf = cpu_registers(processor)->gpr[arg0+1]; int nbytes = cpu_registers(processor)->gpr[arg0+2]; int status; SYS(read); if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes); /* get a tempoary bufer */ scratch_buffer = zalloc(nbytes); /* check if buffer exists by reading it */ emul_read_buffer(scratch_buffer, buf, nbytes, processor, cia); /* 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); emul_write_status(processor, status, errno); if (status > 0) emul_write_buffer(scratch_buffer, buf, status, processor, cia); free(scratch_buffer); }
static void do_fstatfs(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { int fd = cpu_registers(processor)->gpr[arg0]; unsigned_word buf_addr = cpu_registers(processor)->gpr[arg0+1]; struct statfs buf; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d, 0x%lx", fd, (long)buf_addr); SYS(fstatfs); status = fstatfs(fd, (buf_addr == 0 ? NULL : &buf)); emul_write_status(processor, status, errno); if (status == 0) { if (buf_addr != 0) write_statfs(buf_addr, buf, processor, cia); } }
static void do_getrusage(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { int who = cpu_registers(processor)->gpr[arg0]; unsigned_word rusage_addr = cpu_registers(processor)->gpr[arg0+1]; struct rusage rusage; int status = getrusage(who, (rusage_addr != 0 ? &rusage : NULL)); int err = errno; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d, 0x%lx", who, (long)rusage_addr); SYS(getrusage); emul_write_status(processor, status, err); if (status == 0) { if (rusage_addr != 0) write_rusage(rusage_addr, rusage, processor, cia); } }
static void do_open(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; char path_buf[PATH_MAX]; char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); int flags = (int)cpu_registers(processor)->gpr[arg0+1]; int mode = (int)cpu_registers(processor)->gpr[arg0+2]; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx [%s], 0x%x, 0x%x", (long)path_addr, path, flags, mode); SYS(open); /* Can't combine these statements, cuz open sets errno. */ status = open(path, flags, mode); emul_write_status(processor, status, errno); }
static void do___sysctl(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { /* call the arguments by their real name */ unsigned_word name = cpu_registers(processor)->gpr[arg0]; natural_word namelen = cpu_registers(processor)->gpr[arg0+1]; unsigned_word oldp = cpu_registers(processor)->gpr[arg0+2]; unsigned_word oldlenp = cpu_registers(processor)->gpr[arg0+3]; 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 ((int)mib) { case 6/*CTL_HW*/: #if WITH_NetBSD_HOST && (CTL_HW != 6) # error "CTL_HW" #endif 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 ((int)mib) { case 7/*HW_PAGESIZE*/: #if WITH_NetBSD_HOST && (HW_PAGESIZE != 7) # error "HW_PAGESIZE" #endif 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); emul_write_word(oldp, int_val, processor, cia); emul_write_word(oldlenp, oldlen, processor, cia); break; default: error("sysctl() CTL_HW.%d unknown\n", mib); break; } break; default: error("sysctl() name[0]=%d unknown\n", (int)mib); break; } emul_write_status(processor, 0, 0); /* always succeed */ }