diff options
Diffstat (limited to 'emu')
| -rw-r--r-- | emu/AIX/asm-power.s | 108 | ||||
| -rw-r--r-- | emu/AIX/cmd.c | 213 | ||||
| -rw-r--r-- | emu/AIX/deveia.c | 40 | ||||
| -rw-r--r-- | emu/AIX/devfs.c | 7 | ||||
| -rw-r--r-- | emu/AIX/emu | 104 | ||||
| -rw-r--r-- | emu/AIX/emu-g | 100 | ||||
| -rw-r--r-- | emu/AIX/mkfile | 52 | ||||
| -rw-r--r-- | emu/AIX/mkfile-power | 0 | ||||
| -rw-r--r-- | emu/AIX/os.c | 300 | ||||
| -rw-r--r-- | emu/AIX/segflush-power.c | 33 | ||||
| -rw-r--r-- | emu/OpenBSD/asm-386.S | 2 | ||||
| -rw-r--r-- | emu/OpenBSD/mkfile | 3 | ||||
| -rw-r--r-- | emu/OpenBSD/os.c | 224 | ||||
| -rw-r--r-- | emu/OpenBSD/rfork_thread.S | 104 | ||||
| -rw-r--r-- | emu/port/devfs-posix.c | 2 | ||||
| -rw-r--r-- | emu/port/win-x11a.c | 40 |
16 files changed, 1006 insertions, 326 deletions
diff --git a/emu/AIX/asm-power.s b/emu/AIX/asm-power.s new file mode 100644 index 00000000..024c058b --- /dev/null +++ b/emu/AIX/asm-power.s @@ -0,0 +1,108 @@ +.set r0,0; .set SP,1; .set RTOC,2; .set r3,3; .set r4,4 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 +.set r30,30; .set r31,31 +.set fp0,0; .set fp1,1; .set fp2,2; .set fp3,3; .set fp4,4 +.set fp5,5; .set fp6,6; .set fp7,7; .set fp8,8; .set fp9,9 +.set fp10,10; .set fp11,11; .set fp12,12; .set fp13,13; .set fp14,14 +.set fp15,15; .set fp16,16; .set fp17,17; .set fp18,18; .set fp19,19 +.set fp20,20; .set fp21,21; .set fp22,22; .set fp23,23; .set fp24,24 +.set fp25,25; .set fp26,26; .set fp27,27; .set fp28,28; .set fp29,29 +.set fp30,30; .set fp31,31 +.set v0,0; .set v1,1; .set v2,2; .set v3,3; .set v4,4 +.set v5,5; .set v6,6; .set v7,7; .set v8,8; .set v9,9 +.set v10,10; .set v11,11; .set v12,12; .set v13,13; .set v14,14 +.set v15,15; .set v16,16; .set v17,17; .set v18,18; .set v19,19 +.set v20,20; .set v21,21; .set v22,22; .set v23,23; .set v24,24 +.set v25,25; .set v26,26; .set v27,27; .set v28,28; .set v29,29 +.set v30,30; .set v31,31 +.set LR,8; .set CTR,9; .set TID,17; .set DSISR,18; .set DAR,19; .set TO_RTCU,20 + +.machine "ppc" + + .align 2 + .globl .FPsave +.FPsave: + stfd fp14,0*8(r3) + stfd fp15,1*8(r3) + stfd fp16,2*8(r3) + stfd fp17,3*8(r3) + stfd fp18,4*8(r3) + stfd fp19,5*8(r3) + stfd fp20,6*8(r3) + stfd fp21,7*8(r3) + stfd fp22,8*8(r3) + stfd fp23,9*8(r3) + stfd fp24,10*8(r3) + stfd fp25,11*8(r3) + stfd fp26,12*8(r3) + stfd fp27,13*8(r3) + stfd fp28,14*8(r3) + stfd fp29,15*8(r3) + stfd fp30,16*8(r3) + stfd fp31,17*8(r3) + blr + + .align 2 + .globl .FPrestore +.FPrestore: + lfd fp14,0*8(r3) + lfd fp15,1*8(r3) + lfd fp16,2*8(r3) + lfd fp17,3*8(r3) + lfd fp18,4*8(r3) + lfd fp19,5*8(r3) + lfd fp20,6*8(r3) + lfd fp21,7*8(r3) + lfd fp22,8*8(r3) + lfd fp23,9*8(r3) + lfd fp24,10*8(r3) + lfd fp25,11*8(r3) + lfd fp26,12*8(r3) + lfd fp27,13*8(r3) + lfd fp28,14*8(r3) + lfd fp29,15*8(r3) + lfd fp30,16*8(r3) + lfd fp31,17*8(r3) + blr + + .align 2 + .globl ._tas +._tas: + sync + mr r4, r3 + addi r5,0,0x1 +_tas_1: + lwarx r3, 0, r4 + cmpwi r3, 0 + bne- _tas_2 + stwcx. r5, 0, r4 + bne- _tas_1 +_tas_2: + sync + blr + + .align 2 + .globl .executeonnewstack +.executeonnewstack: + mr SP,r3 # change stacks + stwu LR,-16(SP) # save lr to aid the traceback + li r0,0 + stw r0,20(SP) + mr r3,r5 + mtctr r4 + bctrl # tramp(arg) + br + + .align 2 + .globl .unlockandexit +.unlockandexit: + li r0,0x0 + stw r0,0(r3) # unlock + li r0,1 # sys exit; 234 is exit group + li r3,0 # exit status + sc + br diff --git a/emu/AIX/cmd.c b/emu/AIX/cmd.c new file mode 100644 index 00000000..ed4cabab --- /dev/null +++ b/emu/AIX/cmd.c @@ -0,0 +1,213 @@ +#include <sys/types.h> +#include <signal.h> +#include <pwd.h> +#include <sys/resource.h> +#include <sys/wait.h> +#include <fcntl.h> + +#include "dat.h" +#include "fns.h" +#include "error.h" + +enum +{ + Debug = 0 +}; + +/* + * os-specific devcmd support. + * this version should be reasonably portable across Unix systems. + */ +typedef struct Targ Targ; +struct Targ +{ + int fd[3]; /* fd[0] is standard input, fd[1] is standard output, fd[2] is standard error */ + char** args; + char* dir; + int pid; + int wfd; /* child writes errors that occur after the fork or on exec */ + int uid; + int gid; +}; + +extern int gidnobody; +extern int uidnobody; + +static int +childproc(Targ *t) +{ + int i, nfd; + + if(Debug) + print("devcmd: '%s'", t->args[0]); + + nfd = getdtablesize(); + for(i = 0; i < nfd; i++) + if(i != t->fd[0] && i != t->fd[1] && i != t->fd[2] && i != t->wfd) + close(i); + + dup2(t->fd[0], 0); + dup2(t->fd[1], 1); + dup2(t->fd[2], 2); + close(t->fd[0]); + close(t->fd[1]); + close(t->fd[2]); + + /* should have an auth file to do host-specific authorisation? */ + if(t->gid != -1){ + if(setgid(t->gid) < 0 && getegid() == 0){ + fprint(t->wfd, "can't set gid %d: %s", t->gid, strerror(errno)); + _exit(1); + } + } + + if(t->uid != -1){ + if(setuid(t->uid) < 0 && geteuid() == 0){ + fprint(t->wfd, "can't set uid %d: %s", t->uid, strerror(errno)); + _exit(1); + } + } + + if(t->dir != nil && chdir(t->dir) < 0){ + fprint(t->wfd, "can't chdir to %s: %s", t->dir, strerror(errno)); + _exit(1); + } + + signal(SIGPIPE, SIG_DFL); + + execvp(t->args[0], t->args); + if(Debug) + print("execvp: %s\n",strerror(errno)); + fprint(t->wfd, "exec failed: %s", strerror(errno)); + + _exit(1); +} + +void* +oscmd(char **args, int nice, char *dir, int *fd) +{ + Targ *t; + int r, fd0[2], fd1[2], fd2[2], wfd[2], n, pid; + + t = mallocz(sizeof(*t), 1); + if(t == nil) + return nil; + + fd0[0] = fd0[1] = -1; + fd1[0] = fd1[1] = -1; + fd2[0] = fd2[1] = -1; + wfd[0] = wfd[1] = -1; + if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(fd2) < 0 || pipe(wfd) < 0) + goto Error; + if(fcntl(wfd[1], F_SETFD, FD_CLOEXEC) < 0) /* close on exec to give end of file on success */ + goto Error; + + t->fd[0] = fd0[0]; + t->fd[1] = fd1[1]; + t->fd[2] = fd2[1]; + t->wfd = wfd[1]; + t->args = args; + t->dir = dir; + t->gid = up->env->gid; + if(t->gid == -1) + t->gid = gidnobody; + t->uid = up->env->uid; + if(t->uid == -1) + t->uid = uidnobody; + + signal(SIGCHLD, SIG_DFL); + switch(pid = fork()) { + case -1: + goto Error; + case 0: + setpgid(0, getpid()); + if(nice) + oslopri(); + childproc(t); + _exit(1); + default: + t->pid = pid; + if(Debug) + print("cmd pid %d\n", t->pid); + break; + } + + close(fd0[0]); + close(fd1[1]); + close(fd2[1]); + close(wfd[1]); + + n = read(wfd[0], up->genbuf, sizeof(up->genbuf)-1); + close(wfd[0]); + if(n > 0){ + close(fd0[1]); + close(fd1[0]); + close(fd2[0]); + free(t); + up->genbuf[n] = 0; + if(Debug) + print("oscmd: bad exec: %q\n", up->genbuf); + error(up->genbuf); + return nil; + } + + fd[0] = fd0[1]; + fd[1] = fd1[0]; + fd[2] = fd2[0]; + return t; + +Error: + r = errno; + if(Debug) + print("oscmd: %q\n",strerror(r)); + close(fd0[0]); + close(fd0[1]); + close(fd1[0]); + close(fd1[1]); + close(fd2[0]); + close(fd2[1]); + close(wfd[0]); + close(wfd[1]); + error(strerror(r)); + return nil; +} + +int +oscmdkill(void *a) +{ + Targ *t = a; + + if(Debug) + print("kill: %d\n", t->pid); + return kill(-t->pid, SIGTERM); +} + +int +oscmdwait(void *a, char *buf, int n) +{ + Targ *t = a; + int s; + + if(waitpid(t->pid, &s, 0) == -1){ + if(Debug) + print("wait error: %d [in %d] %q\n", t->pid, getpid(), strerror(errno)); + return -1; + } + if(WIFEXITED(s)){ + if(WEXITSTATUS(s) == 0) + return snprint(buf, n, "%d 0 0 0 ''", t->pid); + return snprint(buf, n, "%d 0 0 0 'exit: %d'", t->pid, WEXITSTATUS(s)); + } + if(WIFSIGNALED(s)){ + if(WTERMSIG(s) == SIGTERM || WTERMSIG(s) == SIGKILL) + return snprint(buf, n, "%d 0 0 0 killed", t->pid); + return snprint(buf, n, "%d 0 0 0 'signal: %d'", t->pid, WTERMSIG(s)); + } + return snprint(buf, n, "%d 0 0 0 'odd status: 0x%x'", t->pid, s); +} + +void +oscmdfree(void *a) +{ + free(a); +} diff --git a/emu/AIX/deveia.c b/emu/AIX/deveia.c new file mode 100644 index 00000000..3e00ca3f --- /dev/null +++ b/emu/AIX/deveia.c @@ -0,0 +1,40 @@ +/* + * AIX serial port definitions + */ + +static char *sysdev[] = { + "/dev/tty0", + "/dev/tty1", + "/dev/tty2", + "/dev/tty3", + "/dev/tty4", + "/dev/tty5", + "/dev/tty6", + "/dev/tty7", +}; + +#include <sys/ioctl.h> +#include "deveia-posix.c" +#include "deveia-bsd.c" + + +static struct tcdef_t bps[] = { + {0, B0}, + {50, B50}, + {75, B75}, + {110, B110}, + {134, B134}, + {150, B150}, + {200, B200}, + {300, B300}, + {600, B600}, + {1200, B1200}, + {1800, B1800}, + {2400, B2400}, + {4800, B4800}, + {9600, B9600}, + {19200, B19200}, + {38400, B38400}, + {-1, -1} +}; + diff --git a/emu/AIX/devfs.c b/emu/AIX/devfs.c new file mode 100644 index 00000000..194c1090 --- /dev/null +++ b/emu/AIX/devfs.c @@ -0,0 +1,7 @@ +#include "devfs-posix.c" + +static vlong +osdisksize(int fd) +{ + return 0; +} diff --git a/emu/AIX/emu b/emu/AIX/emu new file mode 100644 index 00000000..43f6e128 --- /dev/null +++ b/emu/AIX/emu @@ -0,0 +1,104 @@ +dev + root + cons + env + mnt + pipe + prog + prof + srv + dup + ssl + cap + fs + cmd cmd + indir + + draw win-x11a + pointer + snarf + + ip ipif6-posix ipaux + eia + mem + +lib + interp + tk + freetype + math + draw + + memlayer + memdraw + keyring + sec + mp + + 9 + +link + +mod + sys + draw + + tk + math + srv srv + keyring + crypt + ipints + loader + freetype + +port + alloc + cache + chan + dev + devtab + + dial + dis + discall + env + error + errstr + exception + exportfs + inferno + latin1 + main + parse + pgrp + print + proc + qio + random + sysfile + uqid + +code + +init + emuinit + +root + /dev / + /fd / + /prog / + /prof / + /net / + /net.alt / + /chan / + /nvfs / + /env / +# /dis +# /n +# /icons +# /osinit.dis +# /dis/emuinit.dis +# /dis/lib/auth.dis +# /dis/lib/ssl.dis +# /n/local / diff --git a/emu/AIX/emu-g b/emu/AIX/emu-g new file mode 100644 index 00000000..41831fa9 --- /dev/null +++ b/emu/AIX/emu-g @@ -0,0 +1,100 @@ +env + X11LIBS= +dev + root + cons + env + mnt + pipe + prog + prof + srv + dup + ssl + cap + fs + cmd cmd + indir + + ip ipif6-posix ipaux + eia + mem + +lib + interp + math + keyring + sec + mp + + 9 + +link + +mod + sys + math + srv srv + keyring + crypt + ipints + loader + +port + alloc + cache + chan + dev + devtab + + dial + dis + discall + env + error + errstr + exception + exportfs + inferno + latin1 + main + parse + pgrp + print + proc + qio + random + sysfile + uqid + +code + void setpointer(int x, int y){USED(x); USED(y);} + ulong strtochan(char *s){USED(s); return ~0;} + +init + emuinit + +root + /dev / + /fd / + /prog / + /prof / + /net / + /net.alt / + /chan / + /nvfs / + /env / +# /chan +# /dev +# /dis +# /env +# /n +# /net +# /nvfs / +# /prog +# /icons +# /osinit.dis +# /dis/emuinit.dis +# /dis/lib/auth.dis +# /dis/lib/ssl.dis +# /n/local / diff --git a/emu/AIX/mkfile b/emu/AIX/mkfile new file mode 100644 index 00000000..2089bd28 --- /dev/null +++ b/emu/AIX/mkfile @@ -0,0 +1,52 @@ +SYSTARG=AIX +<../../mkconfig +SYSTARG=AIX + +#Configurable parameters + +CONF=emu #default configuration +CONFLIST=emu +CLEANCONFLIST= + +INSTALLDIR=$ROOT/$SYSTARG/$OBJTYPE/bin #path of directory where kernel is installed + +#end configurable parameters + +X11LIBS= -lX11 -lXext + +<$ROOT/mkfiles/mkfile-$SYSTARG-$OBJTYPE #set vars based on target system + +<| $SHELLNAME ../port/mkdevlist $CONF #sets $IP, $DEVS, $PORT, $LIBS +<mkfile-$OBJTYPE + +OBJ=\ + asm-$OBJTYPE.$O\ + $ARCHFILES\ + os.$O\ + kproc-pthreads.$O\ + segflush-$OBJTYPE.$O\ + $CONF.root.$O\ + lock.$O\ + $DEVS\ + $PORT\ + +LIBNAMES=${LIBS:%=lib%.a} + +HFILES=\ + +CFLAGS='-DROOT="'$ROOT'"' -DEMU -I. -I../port -I$ROOT/$SYSTARG/$OBJTYPE/include -I$ROOT/include -I$ROOT/libinterp $CTHREADFLAGS $CFLAGS $EMUOPTIONS +SYSLIBS= $X11LIBS -lm -lpthread +KERNDATE=`{$NDATE} + +default:V: $O.$CONF + +$O.$CONF: $OBJ $CONF.c $CONF.root.h $LIBNAMES + $CC $CFLAGS '-DKERNDATE='$KERNDATE $CONF.c + $LD $LDFLAGS -o $target $OBJ $CONF.$O $LIBFILES $SYSLIBS + +install:V: $O.$CONF + cp $O.$CONF $INSTALLDIR/$CONF + +<../port/portmkfile + +devfs.$O: ../port/devfs-posix.c diff --git a/emu/AIX/mkfile-power b/emu/AIX/mkfile-power new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/emu/AIX/mkfile-power diff --git a/emu/AIX/os.c b/emu/AIX/os.c new file mode 100644 index 00000000..83bf0901 --- /dev/null +++ b/emu/AIX/os.c @@ -0,0 +1,300 @@ +#include <sys/types.h> +#include <time.h> +#include <termios.h> +#include <signal.h> +#include <pwd.h> +#include <sched.h> +#include <sys/resource.h> +#include <sys/wait.h> +#include <sys/time.h> + +#include <stdint.h> + +#include "dat.h" +#include "fns.h" +#include "error.h" + +#include <semaphore.h> + +#include <raise.h> + +enum +{ + DELETE = 0x7f, + CTRLC = 'C'-'@', + NSTACKSPERALLOC = 16, + X11STACK= 256*1024 +}; +char *hosttype = "Linux"; + +typedef sem_t Sem; + +extern int dflag; + +int gidnobody = -1; +int uidnobody = -1; +static struct termios tinit; + +static void +sysfault(char *what, void *addr) +{ + char buf[64]; + + snprint(buf, sizeof(buf), "sys: %s%#p", what, addr); + disfault(nil, buf); +} + +static void +trapILL(int signo, siginfo_t *si, void *a) +{ + USED(signo); + USED(a); + sysfault("illegal instruction pc=", si->si_addr); +} + +static int +isnilref(siginfo_t *si) +{ + return si != 0 && (si->si_addr == (void*)~(uintptr_t)0 || (uintptr_t)si->si_addr < 512); +} + +static void +trapmemref(int signo, siginfo_t *si, void *a) +{ + USED(a); /* ucontext_t*, could fetch pc in machine-dependent way */ + if(isnilref(si)) + disfault(nil, exNilref); + else if(signo == SIGBUS) + sysfault("bad address addr=", si->si_addr); /* eg, misaligned */ + else + sysfault("segmentation violation addr=", si->si_addr); +} + +static void +trapFPE(int signo, siginfo_t *si, void *a) +{ + char buf[64]; + + USED(signo); + USED(a); + snprint(buf, sizeof(buf), "sys: fp: exception status=%.4lux pc=%#p", getfsr(), si->si_addr); + disfault(nil, buf); +} + +static void +trapUSR1(int signo) +{ + int intwait; + + USED(signo); + + intwait = up->intwait; + up->intwait = 0; /* clear it to let proc continue in osleave */ + + if(up->type != Interp) /* Used to unblock pending I/O */ + return; + + if(intwait == 0) /* Not posted so it's a sync error */ + disfault(nil, Eintr); /* Should never happen */ +} + +void +oslongjmp(void *regs, osjmpbuf env, int val) +{ + USED(regs); + siglongjmp(env, val); +} + +static void +termset(void) +{ + struct termios t; + + tcgetattr(0, &t); + tinit = t; + t.c_lflag &= ~(ICANON|ECHO|ISIG); + t.c_cc[VMIN] = 1; + t.c_cc[VTIME] = 0; + tcsetattr(0, TCSANOW, &t); +} + +static void +termrestore(void) +{ + tcsetattr(0, TCSANOW, &tinit); +} + +void +cleanexit(int x) +{ + USED(x); + + if(up->intwait) { + up->intwait = 0; + return; + } + + if(dflag == 0) + termrestore(); + + kill(0, SIGKILL); + exit(0); +} + +void +osreboot(char *file, char **argv) +{ + if(dflag == 0) + termrestore(); + execvp(file, argv); + error("reboot failure"); +} + +void +libinit(char *imod) +{ + struct sigaction act; + struct passwd *pw; + Proc *p; + char sys[64]; + + setsid(); + + gethostname(sys, sizeof(sys)); + kstrdup(&ossysname, sys); + pw = getpwnam("nobody"); + if(pw != nil) { + uidnobody = pw->pw_uid; + gidnobody = pw->pw_gid; + } + + if(dflag == 0) + termset(); + + memset(&act, 0, sizeof(act)); + act.sa_handler = trapUSR1; + sigaction(SIGUSR1, &act, nil); + + act.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &act, nil); + + /* + * For the correct functioning of devcmd in the + * face of exiting slaves + */ + signal(SIGPIPE, SIG_IGN); + if(signal(SIGTERM, SIG_IGN) != SIG_IGN) + signal(SIGTERM, cleanexit); + if(signal(SIGINT, SIG_IGN) != SIG_IGN) + signal(SIGINT, cleanexit); + + if(sflag == 0) { + act.sa_flags = SA_SIGINFO; + act.sa_sigaction = trapILL; + sigaction(SIGILL, &act, nil); + act.sa_sigaction = trapFPE; + sigaction(SIGFPE, &act, nil); + act.sa_sigaction = trapmemref; + sigaction(SIGBUS, &act, nil); + sigaction(SIGSEGV, &act, nil); + act.sa_flags &= ~SA_SIGINFO; + } + + p = newproc(); + kprocinit(p); + + pw = getpwuid(getuid()); + if(pw != nil) + kstrdup(&eve, pw->pw_name); + else + print("cannot getpwuid\n"); + + p->env->uid = getuid(); + p->env->gid = getgid(); + + emuinit(imod); +} + +int +readkbd(void) +{ + int n; + char buf[1]; + + n = read(0, buf, sizeof(buf)); + if(n < 0) + print("keyboard close (n=%d, %s)\n", n, strerror(errno)); + if(n <= 0) + pexit("keyboard thread", 0); + + switch(buf[0]) { + case '\r': + buf[0] = '\n'; + break; + case DELETE: + buf[0] = 'H' - '@'; + break; + case CTRLC: + cleanexit(0); + break; + } + return buf[0]; +} + +/* + * Return an abitrary millisecond clock time + */ +long +osmillisec(void) +{ + static long sec0 = 0, usec0; + struct timeval t; + + if(gettimeofday(&t,(struct timezone*)0)<0) + return 0; + + if(sec0 == 0) { + sec0 = t.tv_sec; + usec0 = t.tv_usec; + } + return (t.tv_sec-sec0)*1000+(t.tv_usec-usec0+500)/1000; +} + +/* + * Return the time since the epoch in nanoseconds and microseconds + * The epoch is defined at 1 Jan 1970 + */ +vlong +osnsec(void) +{ + struct timeval t; + + gettimeofday(&t, nil); + return (vlong)t.tv_sec*1000000000L + t.tv_usec*1000; +} + +vlong +osusectime(void) +{ + struct timeval t; + + gettimeofday(&t, nil); + return (vlong)t.tv_sec * 1000000 + t.tv_usec; +} + +int +osmillisleep(ulong milsec) +{ + struct timespec time; + + time.tv_sec = milsec/1000; + time.tv_nsec= (milsec%1000)*1000000; + nanosleep(&time, NULL); + return 0; +} + +int +limbosleep(ulong milsec) +{ + return osmillisleep(milsec); +} diff --git a/emu/AIX/segflush-power.c b/emu/AIX/segflush-power.c new file mode 100644 index 00000000..5029b0aa --- /dev/null +++ b/emu/AIX/segflush-power.c @@ -0,0 +1,33 @@ +#include <sys/types.h> + +#include "dat.h" + + +/* + * from geoff collyer's port + * invalidate instruction cache and write back data cache from a to a+n-1, + * at least. + */ +int +segflush(void *a, ulong n) +{ + ulong *p; + + // cache blocks are often eight words (32 bytes) long, sometimes 16 bytes. + // need to determine it dynamically? + for (p = (ulong *)((ulong)a & ~7UL); (char *)p < (char *)a + n; p++) + __asm__("dcbst 0,r0\n\t" // not dcbf, which writes back, then invalidates + "icbi 0,r0\n\t" + : // no output + : "ar" (p) + ); + __asm__("sync\n\t" + : // no output + : + ); + __asm__("isync\n\t" + : // no output + : + ); + return 0; +} diff --git a/emu/OpenBSD/asm-386.S b/emu/OpenBSD/asm-386.S index f3a3f9cf..e7c9fa3e 100644 --- a/emu/OpenBSD/asm-386.S +++ b/emu/OpenBSD/asm-386.S @@ -3,8 +3,6 @@ #include <sys/syscall.h> #include <machine/asm.h> -#include "rfork_thread.S" - /* * executeonnewstack(void *tos, void (*tramp)(void *arg), void *arg) */ diff --git a/emu/OpenBSD/mkfile b/emu/OpenBSD/mkfile index ad4e3155..a030c95e 100644 --- a/emu/OpenBSD/mkfile +++ b/emu/OpenBSD/mkfile @@ -19,6 +19,7 @@ INSTALLDIR=$ROOT/$SYSTARG/$OBJTYPE/bin #path of directory where kernel is instal OBJ=\ asm-$OBJTYPE.$O\ os.$O\ + kproc-pthreads.$O\ win-x11a.$O\ $CONF.root.$O\ lock.$O\ @@ -28,7 +29,7 @@ OBJ=\ HFILES=\ CFLAGS='-DROOT="'$ROOT'"' -DEMU -I. -I../port -I$ROOT/$SYSTARG/$OBJTYPE/include -I$ROOT/include -I$ROOT/libinterp $CTHREADFLAGS $CFLAGS $EMUOPTIONS -SYSLIBS= -lm -lX11 -lXext -lossaudio +SYSLIBS= -lm -lX11 -lXext -lossaudio -lpthread KERNDATE=`{$NDATE} default:V: $O.$CONF diff --git a/emu/OpenBSD/os.c b/emu/OpenBSD/os.c index f45e69d6..fc16cc30 100644 --- a/emu/OpenBSD/os.c +++ b/emu/OpenBSD/os.c @@ -24,60 +24,16 @@ enum }; char *hosttype = "OpenBSD"; -int rfork_thread(int, void *, void (*)(void *), void *); - -extern void unlockandexit(int*); -extern void executeonnewstack(void*, void (*f)(void*), void*); -static void *stackalloc(Proc *p, void **tos); -static void stackfreeandexit(void *stack); - extern int dflag; void -pexit(char *msg, int t) -{ - Osenv *e; - Proc *p; - void *kstack; - - lock(&procs.l); - p = up; - if(p->prev) - p->prev->next = p->next; - else - procs.head = p->next; - - if(up->next) - p->next->prev = p->prev; - else - procs.tail = p->prev; - unlock(&procs.l); - - if(0) - print("pexit: %s: %s\n", up->text, msg); - - e = up->env; - if(e != nil) { - closefgrp(e->fgrp); - closepgrp(e->pgrp); - closeegrp(e->egrp); - closesigs(e->sigs); - } - kstack = p->kstack; - free(p->prog); - free(p); - if(kstack != nil) - stackfreeandexit(kstack); -} - -void trapBUS(int signo, siginfo_t *info, void *context) { if(info) print("trapBUS: signo: %d code: %d addr: %lx\n", info->si_signo, info->si_code, info->si_addr); else - print("trapBUS: no info\n"); + print("trapBUS: no info\n"); disfault(nil, "Bus error"); } @@ -135,7 +91,7 @@ setsigs(void) memset(&act, 0 , sizeof(act)); sigemptyset(&initmask); - + signal(SIGPIPE, SIG_IGN); /* prevent signal when devcmd child exits */ if(signal(SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, cleanexit); @@ -180,101 +136,6 @@ setsigs(void) panic("sigprocmask"); } -static void -tramp(void *arg) -{ - Proc *p; - - p = arg; - p->pid = p->sigid = getpid(); - sigprocmask(SIG_BLOCK, &initmask, nil); /* in 5.3, rfork_thread doesn't copy from parent, contrary to docs? */ - (*p->func)(p->arg); - pexit("{Tramp}", 0); - _exit(0); -} - -void -kproc(char *name, void (*func)(void*), void *arg, int flags) -{ - Proc *p; - Pgrp *pg; - Fgrp *fg; - Egrp *eg; - int pid; - void *tos; - - p = newproc(); - - if(flags & KPDUPPG) { - pg = up->env->pgrp; - incref(&pg->r); - p->env->pgrp = pg; - } - if(flags & KPDUPFDG) { - fg = up->env->fgrp; - incref(&fg->r); - p->env->fgrp = fg; - } - if(flags & KPDUPENVG) { - eg = up->env->egrp; - incref(&eg->r); - p->env->egrp = eg; - } - - p->env->uid = up->env->uid; - p->env->gid = up->env->gid; - kstrdup(&p->env->user, up->env->user); - - strcpy(p->text, name); - - p->func = func; - p->arg = arg; - - lock(&procs.l); - if(procs.tail != nil) { - p->prev = procs.tail; - procs.tail->next = p; - } - else { - procs.head = p; - p->prev = nil; - } - procs.tail = p; - unlock(&procs.l); - - if(flags & KPX11){ - p->kstack = nil; /* never freed; also up not defined */ - tos = (char*)mallocz(X11STACK, 0) + X11STACK - sizeof(void*); - }else - p->kstack = stackalloc(p, &tos); - pid = rfork_thread(RFPROC|RFMEM|RFNOWAIT, tos, tramp, p); - if(pid < 0) - panic("rfork"); -} - -void -oshostintr(Proc *p) -{ - kill(p->sigid, SIGUSR1); -} - -void -osblock(void) -{ - sigset_t mask; - - sigprocmask(SIG_SETMASK, NULL, &mask); - sigdelset(&mask, SIGUSR2); - sigsuspend(&mask); -} - -void -osready(Proc *p) -{ - if(kill(p->sigid, SIGUSR2) < 0) - fprint(2, "emu: osready failed: pid %d: %s\n", p->sigid, strerror(errno)); -} - void oslongjmp(void *regs, osjmpbuf env, int val) { @@ -335,7 +196,7 @@ void getnobody() { struct passwd *pwd; - + if(pwd = getpwnam("nobody")) { uidnobody = pwd->pw_uid; gidnobody = pwd->pw_gid; @@ -347,7 +208,6 @@ libinit(char *imod) { struct passwd *pw; Proc *p; - void *tos; char sys[64]; setsid(); @@ -362,18 +222,18 @@ libinit(char *imod) setsigs(); p = newproc(); - p->kstack = stackalloc(p, &tos); + kprocinit(p); pw = getpwuid(getuid()); if(pw != nil) kstrdup(&eve, pw->pw_name); else print("cannot getpwuid\n"); - + p->env->uid = getuid(); p->env->gid = getgid(); - executeonnewstack(tos, emuinit, imod); + emuinit(imod); } int @@ -440,7 +300,7 @@ vlong osusectime(void) { struct timeval t; - + gettimeofday(&t, nil); return (vlong)t.tv_sec * 1000000 + t.tv_usec; } @@ -456,76 +316,6 @@ osmillisleep(ulong milsec) return 0; } -void -osyield(void) -{ - sched_yield(); -} - -void -ospause(void) -{ - for(;;) - pause(); -} - -void -oslopri(void) -{ - setpriority(PRIO_PROCESS, 0, getpriority(PRIO_PROCESS,0)+4); -} - -static struct { - Lock l; - void *free; -} stacklist; - -static void -_stackfree(void *stack) -{ - *((void **)stack) = stacklist.free; - stacklist.free = stack; -} - -static void -stackfreeandexit(void *stack) -{ - lock(&stacklist.l); - _stackfree(stack); - unlockandexit(&stacklist.l.val); -} - -static void * -stackalloc(Proc *p, void **tos) -{ - void *rv; - lock(&stacklist.l); - if (stacklist.free == 0) { - int x; - /* - * obtain some more by using sbrk() - */ - void *more = sbrk(KSTACK * (NSTACKSPERALLOC + 1)); - if (more == 0) - panic("stackalloc: no more stacks"); - /* - * align to KSTACK - */ - more = (void *)((((unsigned long)more) + (KSTACK - 1)) & ~(KSTACK - 1)); - /* - * free all the new stacks onto the freelist - */ - for (x = 0; x < NSTACKSPERALLOC; x++) - _stackfree((char *)more + KSTACK * x); - } - rv = stacklist.free; - stacklist.free = *(void **)rv; - unlock(&stacklist.l); - *tos = rv + KSTACK - sizeof(void*); - *(Proc **)rv = p; - return rv; -} - int segflush(void *p, ulong n) { diff --git a/emu/OpenBSD/rfork_thread.S b/emu/OpenBSD/rfork_thread.S deleted file mode 100644 index bb7cd010..00000000 --- a/emu/OpenBSD/rfork_thread.S +++ /dev/null @@ -1,104 +0,0 @@ -/*- - * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * 8 12 16 20 - * rfork_thread(flags, stack_addr, start_fnc, start_arg); - * - * flags: Flags to rfork system call. See rfork(2). - * stack_addr: Top of stack for thread. - * start_fnc: Address of thread function to call in child. - * start_arg: Argument to pass to the thread function in child. - */ - -ENTRY(rfork_thread) - pushl %ebp - movl %esp, %ebp - pushl %esi - - /* - * Push thread info onto the new thread's stack - */ - movl 12(%ebp), %esi # get stack addr - - subl $4, %esi - movl 20(%ebp), %eax # get start argument - movl %eax, (%esi) - - subl $4, %esi - movl 16(%ebp), %eax # get start thread address - movl %eax, (%esi) - - /* - * Prepare and execute the thread creation syscall - */ - pushl 8(%ebp) - pushl $0 - movl $SYS_rfork, %eax - int $0x80 - jb 2f - - /* - * Check to see if we are in the parent or child - */ - cmpl $0, %edx - jnz 1f - addl $8, %esp - popl %esi - movl %ebp, %esp - popl %ebp - ret - .p2align 2 - - /* - * If we are in the child (new thread), then - * set-up the call to the internal subroutine. If it - * returns, then call __exit. - */ -1: - movl %esi,%esp - popl %eax - call *%eax - addl $4, %esp - - /* - * Exit system call - */ - pushl %eax - pushl $0 - movl $SYS_threxit, %eax - int $0x80 - - /* - * Branch here if the thread creation fails: - */ -2: - addl $8, %esp - popl %esi - movl %ebp, %esp - popl %ebp - PIC_PROLOGUE - jmp PIC_PLT(_C_LABEL(__cerror)) diff --git a/emu/port/devfs-posix.c b/emu/port/devfs-posix.c index 02c842f4..14cce877 100644 --- a/emu/port/devfs-posix.c +++ b/emu/port/devfs-posix.c @@ -9,7 +9,7 @@ #include <sys/types.h> #include <sys/stat.h> -#include <sys/fcntl.h> +#include <fcntl.h> #include <sys/socket.h> #include <sys/un.h> #include <utime.h> diff --git a/emu/port/win-x11a.c b/emu/port/win-x11a.c index 4fdd295a..569287b6 100644 --- a/emu/port/win-x11a.c +++ b/emu/port/win-x11a.c @@ -304,7 +304,7 @@ copy32to32(Rectangle r) lp = dp + width; while(dp < lp){ v = *dp++; - w = infernortox11[(v>>16)&0xff]<<16|infernogtox11[(v>>8)&0xff]<<8|infernobtox11[(v>>0)&0xff]<<0; + w = v&(0xff<<24)|infernortox11[(v>>16)&0xff]<<16|infernogtox11[(v>>8)&0xff]<<8|infernobtox11[(v>>0)&0xff]<<0; *wp++ = w; } dp += dx; @@ -313,6 +313,33 @@ copy32to32(Rectangle r) } static void +copy16to16(Rectangle r) +{ + int dx, width; + u16int *dp, *wp, *edp, *lp; + + width = Dx(r); + dx = Xsize - width; + dp = (u16int*)(gscreendata + ((r.min.y * Xsize) + r.min.x) * 2); + wp = (u16int*)(xscreendata + ((r.min.y * Xsize) + r.min.x) * 2); + edp = (u16int*)(gscreendata + ((r.max.y * Xsize) + r.max.x) * 2); + + /* The pixel format should be the same as the underlying X display (see + the xtruevisual function) unless a different channel format is + explicitly specified on the command line, so just copy the pixel data + without any processing. */ + + while(dp < edp) { + lp = dp + width; + while(dp < lp){ + *wp++ = *dp++; + } + dp += dx; + wp += dx; + } +} + +static void copy8to32(Rectangle r) { int dx, width; @@ -435,6 +462,17 @@ flushmemscreen(Rectangle r) case 32: copy32to32(r); break; + case 16: + switch(xscreendepth){ + case 16: + copy16to16(r); + break; + default: + fprint(2, "emu: bad display depth %d chan %s xscreendepth %d\n", displaydepth, + chantostr(chanbuf, displaychan), xscreendepth); + cleanexit(0); + } + break; case 8: switch(xscreendepth){ case 24: |
