static void vbecall(Ureg *u) { Proc *up = externup(); Chan *creg, *cmem; uint32_t pa; cmem = namec("/dev/realmodemem", Aopen, ORDWR, 0); if(waserror()){ cclose(cmem); nexterror(); } creg = namec("/dev/realmode", Aopen, ORDWR, 0); if(waserror()){ cclose(creg); nexterror(); } pa = PADDR(RMBUF); cmem->dev->write(cmem, modebuf, sizeof modebuf, pa); u->trap = 0x10; print("vbecall: sizeof u is %d\n", sizeof *u); creg->dev->write(creg, u, sizeof *u, 0); creg->dev->read(creg, u, sizeof *u, 0); if((u->ax&0xFFFF) != 0x004F) error("vesa bios error"); cmem->dev->read(cmem, modebuf, sizeof modebuf, pa); poperror(); cclose(creg); poperror(); cclose(cmem); }
long sysunmount(ulong *arg) { Chan *cmount, *cmounted; cmounted = 0; validaddr(arg[1], 1, 0); cmount = namec((char *)arg[1], Amount, 0, 0); if(waserror()) { cclose(cmount); if(cmounted) cclose(cmounted); nexterror(); } if(arg[0]) { /* * This has to be namec(..., Aopen, ...) because * if arg[0] is something like /srv/cs or /fd/0, * opening it is the only way to get at the real * Chan underneath. */ validaddr(arg[0], 1, 0); cmounted = namec((char*)arg[0], Aopen, OREAD, 0); } cunmount(cmount, cmounted); poperror(); cclose(cmount); if(cmounted) cclose(cmounted); return 0; }
void sysunmount(Ar0* ar0, ...) { Proc *up = externup(); char *name, *old; Chan *cmount, *cmounted; va_list list; va_start(list, ar0); /* * int unmount(char* name, char* old); */ name = va_arg(list, char*); old = va_arg(list, char*); cmount = namec(validaddr(old, 1, 0), Amount, 0, 0); va_end(list); cmounted = nil; if(name != nil) { if(waserror()) { cclose(cmount); nexterror(); } /* * This has to be namec(..., Aopen, ...) because * if arg[0] is something like /srv/cs or /fd/0, * opening it is the only way to get at the real * Chan underneath. */ cmounted = namec(validaddr(name, 1, 0), Aopen, OREAD, 0); poperror(); } if(waserror()) { cclose(cmount); if(cmounted != nil) cclose(cmounted); nexterror(); } cunmount(cmount, cmounted); cclose(cmount); if(cmounted != nil) cclose(cmounted); poperror(); ar0->i = 0; }
static SDev* aoeprobe(char *path, SDev *s) { int n, i; char *p; Chan *c; Ctlr *ctlr; if((p = strrchr(path, '/')) == 0) error(Ebadarg); *p = 0; uprint("%s/ctl", path); *p = '/'; c = namec(up->genbuf, Aopen, OWRITE, 0); if(waserror()) { cclose(c); nexterror(); } n = uprint("discover %s", p+1); devtab[c->type]->write(c, up->genbuf, n, 0); poperror(); cclose(c); for(i = 0;; i += Probeintvl) { if(i > Probemax || waserror()) error(Etimedout); tsleep(&up->sleep, return0, 0, Probeintvl); poperror(); uprint("%s/ident", path); if(waserror()) continue; c = namec(up->genbuf, Aopen, OREAD, 0); poperror(); cclose(c); ctlr = newctlr(path); break; } if(s == nil && (s = malloc(sizeof *s)) == nil) return nil; s->ctlr = ctlr; s->ifc = &sdaoeifc; s->nunit = 1; return s; }
long _syspipe(int fd[2]) { Chan *c[2]; Dev *d; static char *datastr[] = {"data", "data1"}; d = devtab[devno('|', 0)]; c[0] = namec("#|", Atodir, 0, 0); c[1] = 0; fd[0] = -1; fd[1] = -1; if(waserror()){ cclose(c[0]); if(c[1]) cclose(c[1]); nexterror(); } c[1] = cclone(c[0]); if(walk(&c[0], datastr+0, 1, 1, nil) < 0) error(Egreg); if(walk(&c[1], datastr+1, 1, 1, nil) < 0) error(Egreg); c[0] = d->open(c[0], ORDWR); c[1] = d->open(c[1], ORDWR); if(newfd2(fd, c) < 0) error(Enofd); poperror(); return 0; }
/* * starting place for first process */ void init0(void) { up->nerrlab = 0; spllo(); /* * These are o.k. because rootinit is null. * Then early kproc's will have a root and dot. */ up->slash = namec("#/", Atodir, 0, 0); pathclose(up->slash->path); up->slash->path = newpath("/"); up->dot = cclone(up->slash); chandevinit(); if(!waserror()){ ksetenv("terminal", "bitsy", 0); ksetenv("cputype", "arm", 0); if(cpuserver) ksetenv("service", "cpu", 0); else ksetenv("service", "terminal", 0); poperror(); } kproc("alarm", alarmkproc, 0); kproc("power", powerkproc, 0); touser(sp); }
/* must call with d qlocked */ static int aoeidentify(Ctlr *d, SDunit *u) { Chan *c; c = nil; if(waserror()){ if(c) cclose(c); iprint("aoeidentify: %s\n", up->errstr); nexterror(); } uprint("%s/ident", d->path); c = namec(up->genbuf, Aopen, OREAD, 0); devtab[c->type]->read(c, d->ident, sizeof d->ident, 0); poperror(); cclose(c); d->feat = 0; d->smart = 0; identify(d, (ushort*)d->ident); memset(u->inquiry, 0, sizeof u->inquiry); u->inquiry[2] = 2; u->inquiry[3] = 2; u->inquiry[4] = sizeof u->inquiry - 4; memmove(u->inquiry+8, d->model, 40); return 0; }
int syscreate(char *path, int mode, uint32_t perm) { ERRSTACK(2); int fd; struct chan *c; if (waserror()) { poperror(); return -1; } openmode(mode & ~OEXCL); /* error check only; OEXCL okay here */ c = namec(path, Acreate, mode, perm); if (waserror()) { cclose(c); nexterror(); } fd = newfd(c); if (fd < 0) error(Enofd); poperror(); poperror(); return fd; }
void init0(void) { Osenv *o; up->nerrlab = 0; print("before spllo"); spllo(); print("Sun Sparc %s\n", sparam->name); print("bank 0: %ldM 1: %ldM\n", bank[0], bank[1]); print("frame buffer id %lux slot %ld %s\n",conf.monitor,fbslot,fbstr); if(waserror()) panic("init0"); /* * These are o.k. because rootinit is null. * Then early kproc's will have a root and dot. */ o = up->env; o->pgrp->slash = namec("#/", Atodir, 0, 0); cnameclose(o->pgrp->slash->name); o->pgrp->slash->name = newcname("/"); o->pgrp->dot = cclone(o->pgrp->slash); chandevinit(); poperror(); disinit("/osinit.dis"); }
void syswstat(Ar0* ar0, ...) { Chan *c; char *aname; uint8_t *p; usize n; va_list list; va_start(list, ar0); /* * int wstat(char* name, uchar* edir, int nedir); * should really be * usize wstat(char* name, uchar* edir, usize nedir); * but returning an unsigned is probably too * radical. */ aname = va_arg(list, char*); p = va_arg(list, uint8_t*); n = va_arg(list, usize); p = validaddr(p, n, 0); validstat(p, n); c = namec(validaddr(aname, 1, 0), Aaccess, 0, 0); va_end(list); ar0->l = wstat(c, p, n); }
long sys_stat(ulong *arg) { Chan *c; uint l; uchar buf[128]; /* old DIRLEN plus a little should be plenty */ char strs[128], *name; Dir d; char old[] = "old stat system call - recompile"; validaddr(arg[1], 116, 1); validaddr(arg[0], 1, 0); c = namec((char*)arg[0], Aaccess, 0, 0); if(waserror()){ cclose(c); nexterror(); } l = devtab[c->type]->stat(c, buf, sizeof buf); /* buf contains a new stat buf; convert to old. yuck. */ if(l <= BIT16SZ) /* buffer too small; time to face reality */ error(old); name = pathlast(c->path); if(name) l = dirsetname(name, strlen(name), buf, l, sizeof buf); l = convM2D(buf, l, &d, strs); if(l == 0) error(old); packoldstat((uchar*)arg[1], &d); poperror(); cclose(c); return 0; }
long sysremove(ulong *arg) { Chan *c; validaddr(arg[0], 1, 0); c = namec((char*)arg[0], Aremove, 0, 0); /* * Removing mount points is disallowed to avoid surprises * (which should be removed: the mount point or the mounted Chan?). */ if(c->ismtpt){ cclose(c); error(Eismtpt); } if(waserror()){ c->type = 0; /* see below */ cclose(c); nexterror(); } devtab[c->type]->remove(c); /* * Remove clunks the fid, but we need to recover the Chan * so fake it up. rootclose() is known to be a nop. */ c->type = 0; poperror(); cclose(c); return 0; }
void sysopen(Ar0* ar0, ...) { Proc *up = externup(); va_list list; char *aname; int fd, omode; Chan *c; /* * int open(char* file, int omode); */ va_start(list, ar0); aname = va_arg(list, char*); omode = va_arg(list, int); va_end(list); openmode(omode); /* error check only */ c = nil; if(waserror()){ if(c != nil) cclose(c); nexterror(); } aname = validaddr(aname, 1, 0); c = namec(aname, Aopen, omode, 0); fd = newfd(c); if(fd < 0) error(Enofd); poperror(); ar0->i = fd; }
static Ctlr* newctlr(char *path) { Ctlr *c; if(ctlrlookup(path)) error(Eexist); if((c = malloc(sizeof *c)) == nil) error(Enomem); if(waserror()){ free(c); nexterror(); } c->c = namec(path, Aopen, ORDWR, 0); poperror(); kstrcpy(c->path, path, sizeof c->path); lock(&ctlrlock); if(head != nil) tail->next = c; else head = c; tail = c; unlock(&ctlrlock); return c; }
int syscreate(char *path, int mode, uint32_t perm) { ERRSTACK(2); int fd; struct chan *c; if (waserror()) { poperror(); return -1; } openmode(mode & ~O_EXCL); /* error check only; OEXCL okay here */ c = namec(path, Acreate, mode, perm); if (waserror()) { cclose(c); nexterror(); } fd = newfd(c, mode); /* 9ns mode is the O_FLAGS and perm is glibc mode */ if (fd < 0) error(-fd, ERROR_FIXME); poperror(); poperror(); return fd; }
long sysstat(uint32 *arg) { char *name; Chan *c; uint l; uchar *p; l = arg[2]; p = uvalidaddr(arg[1], l, 1); name = uvalidaddr(arg[0], 1, 0); c = namec(name, Aaccess, 0, 0); if(waserror()){ cclose(c); nexterror(); } l = devtab[c->type]->stat(c, p, l); name = pathlast(c->path); if(name) l = dirsetname(name, strlen(name), p, l, arg[2]); poperror(); cclose(c); return l; }
void syscreate(Ar0* ar0, ...) { Proc *up = externup(); char *aname; int fd, omode, perm; Chan *c; va_list list; va_start(list, ar0); /* * int create(char* file, int omode, uint32_t perm); * should be * int create(char* file, int omode, int perm); */ aname = va_arg(list, char*); omode = va_arg(list, int); perm = va_arg(list, int); va_end(list); openmode(omode & ~OEXCL); /* error check only; OEXCL okay here */ c = nil; if(waserror()) { if(c != nil) cclose(c); nexterror(); } c = namec(validaddr(aname, 1, 0), Acreate, omode, perm); fd = newfd(c); if(fd < 0) error(Enofd); poperror(); ar0->i = fd; }
static FWImage* readfirmware(void) { uchar dirbuf[sizeof(Dir)+100], *data; char *err; FWImage *fw; int n, r; Chan *c; Dir d; if(!iseve()) error(Eperm); if(!waserror()){ c = namec("/boot/wpi-3945abg", Aopen, OREAD, 0); poperror(); }else c = namec("/lib/firmware/wpi-3945abg", Aopen, OREAD, 0); if(waserror()){ cclose(c); nexterror(); } n = devtab[c->type]->stat(c, dirbuf, sizeof dirbuf); if(n <= 0) error("can't stat firmware"); convM2D(dirbuf, n, &d, nil); fw = smalloc(sizeof(*fw) + 16 + d.length); data = (uchar*)(fw+1); if(waserror()){ free(fw); nexterror(); } r = 0; while(r < d.length){ n = devtab[c->type]->read(c, data+r, d.length-r, (vlong)r); if(n <= 0) break; r += n; } if((err = crackfw(fw, data, r)) != nil) error(err); poperror(); poperror(); cclose(c); return fw; }
static Chan* call(char *clone, char *dest, DS *ds) { Proc *up = externup(); int n; Chan *dchan, *cchan; char name[Maxpath], data[Maxpath], *p; cchan = namec(clone, Aopen, ORDWR, 0); /* get directory name */ if(waserror()){ cclose(cchan); nexterror(); } n = cchan->dev->read(cchan, name, sizeof(name)-1, 0); name[n] = 0; for(p = name; *p == ' '; p++) ; snprint(name, sizeof name, "%lu", strtoul(p, 0, 0)); p = strrchr(clone, '/'); *p = 0; if(ds->dir) snprint(ds->dir, Maxpath, "%s/%s", clone, name); snprint(data, sizeof(data), "%s/%s/data", clone, name); /* connect */ if(ds->local) snprint(name, sizeof(name), "connect %s %s", dest, ds->local); else snprint(name, sizeof(name), "connect %s", dest); cchan->dev->write(cchan, name, strlen(name), 0); /* open data connection */ dchan = namec(data, Aopen, ORDWR, 0); if(ds->ctlp) *ds->ctlp = cchan; else cclose(cchan); poperror(); return dchan; }
/* * to let the kernel set environment variables */ void ksetenv(char *ename, char *eval, int conf) { Chan *c; char buf[2*KNAMELEN]; snprint(buf, sizeof(buf), "#e%s/%s", conf?"c":"", ename); c = namec(buf, Acreate, OWRITE, 0600); c->dev->write(c, eval, strlen(eval), 0); cclose(c); }
long _syschdir(char *name) { Chan *c; validaddr(name, 1, 0); c = namec(name, Atodir, 0, 0); cclose(up->dot); up->dot = c; return 0; }
long syschdir(ulong *arg) { Chan *c; validaddr(arg[0], 1, 0); c = namec((char*)arg[0], Atodir, 0, 0); cclose(up->dot); up->dot = c; return 0; }
void init0(void) { // char **p, *q, name[KNAMELEN]; // int n; char buf[2*KNAMELEN]; up->nerrlab = 0; spllo(); /* * These are o.k. because rootinit is null. * Then early kproc's will have a root and dot. */ up->slash = namec("#/", Atodir, 0, 0); pathclose(up->slash->path); up->slash->path = newpath("/"); up->dot = cclone(up->slash); chandevinit(); if(!waserror()){ snprint(buf, sizeof(buf), "power %s mtx", conffile); ksetenv("terminal", buf, 0); ksetenv("cputype", "power", 0); if(cpuserver) ksetenv("service", "cpu", 0); else ksetenv("service", "terminal", 0); /* for(p = confenv; *p; p++) { q = strchr(p[0], '='); if(q == 0) continue; n = q-p[0]; if(n >= KNAMELEN) n = KNAMELEN-1; memmove(name, p[0], n); name[n] = 0; if(name[0] != '*') ksetenv(name, q+1, 0); ksetenv(name, q+1, 1); } */ poperror(); } kproc("alarm", alarmkproc, 0); kproc("mmusweep", mmusweep, 0); touser((void*)(USTKTOP-8)); }
long syschdir(uint32 *arg) { Chan *c; char *name; name = uvalidaddr(arg[0], 1, 0); c = namec(name, Atodir, 0, 0); cclose(up->dot); up->dot = c; return 0; }
long syswstat(ulong *arg) { Chan *c; uint l; l = arg[2]; validaddr(arg[1], l, 0); validstat((uchar*)arg[1], l); validaddr(arg[0], 1, 0); c = namec((char*)arg[0], Aaccess, 0, 0); return wstat(c, (uchar*)arg[1], l); }
long syswstat(uint32 *arg) { Chan *c; uint l; char *name; uchar *p; l = arg[2]; p = uvalidaddr(arg[1], l, 0); validstat(p, l); name = uvalidaddr(arg[0], 1, 0); c = namec(name, Aaccess, 0, 0); return wstat(c, p, l); }
void rebootcmd(int argc, char *argv[]) { Chan *c; Exec exec; ulong magic, text, rtext, entry, data, size; uchar *p; if(argc == 0) exit(0); c = namec(argv[0], Aopen, OEXEC, 0); if(waserror()){ cclose(c); nexterror(); } readn(c, &exec, sizeof(Exec)); magic = l2be(exec.magic); entry = l2be(exec.entry); text = l2be(exec.text); data = l2be(exec.data); if(magic != AOUT_MAGIC) error(Ebadexec); /* round text out to page boundary */ rtext = ROUNDUP(entry+text, PGSZ)-entry; size = rtext + data; p = malloc(size); if(p == nil) error(Enomem); if(waserror()){ free(p); nexterror(); } memset(p, 0, size); readn(c, p, text); readn(c, p + rtext, data); ksetenv("bootfile", argv[0], 1); setbootcmd(argc-1, argv+1); reboot((void*)entry, p, size); panic("return from reboot!"); }
int kchdir(char *path) { Chan *c; Pgrp *pg; if(waserror()) return -1; c = namec(path, Atodir, 0, 0); pg = up->env->pgrp; cclose(pg->dot); pg->dot = c; poperror(); return 0; }
int syspipe(int fd[2]) { ERRSTACK(1); struct dev *d; struct chan *c[2]; static char *names[] = { "data", "data1" }; d = &devtab[devno("pipe", 0)]; c[0] = 0; c[1] = 0; fd[0] = -1; fd[1] = -1; if (waserror()) { /* need to remove from the fd table and make sure the chan is closed * exactly once. if fd[i] >= 0, then the fd is valid (or it was!) and * the fd table has the only ref (newfd() currently decrefs/consumes the * reference). cclose() doesn't care if you pass it 0 (like kfree()). */ if (fd[0] >= 0) close_fd(¤t->open_files, fd[0]); else cclose(c[0]); if (fd[1] >= 0) close_fd(¤t->open_files, fd[1]); else cclose(c[1]); poperror(); return -1; } c[0] = namec("#pipe", Atodir, 0, 0); c[1] = cclone(c[0]); if (walk(&c[0], &names[0], 1, FALSE, NULL) < 0) error(EINVAL, ERROR_FIXME); if (walk(&c[1], &names[1], 1, FALSE, NULL) < 0) error(EINVAL, ERROR_FIXME); c[0] = d->open(c[0], O_RDWR); c[1] = d->open(c[1], O_RDWR); fd[0] = newfd(c[0], 0); if (fd[0] < 0) error(-fd[0], ERROR_FIXME); fd[1] = newfd(c[1], 0); if (fd[1] < 0) error(-fd[1], ERROR_FIXME); poperror(); return 0; }
void syspipe(Ar0* ar0, ...) { Proc *up = externup(); int *a, fd[2]; Chan *c[2]; static char *datastr[] = {"data", "data1"}; va_list list; va_start(list, ar0); /* * int pipe(int fd[2]); */ a = va_arg(list, int*); va_end(list); a = validaddr(a, sizeof(fd), 1); evenaddr(PTR2UINT(a)); c[0] = namec("#|", Atodir, 0, 0); c[1] = nil; fd[0] = -1; fd[1] = -1; if(waserror()){ cclose(c[0]); if(c[1]) cclose(c[1]); nexterror(); } c[1] = cclone(c[0]); if(walk(&c[0], datastr+0, 1, 1, nil) < 0) error(Egreg); if(walk(&c[1], datastr+1, 1, 1, nil) < 0) error(Egreg); c[0] = c[0]->dev->open(c[0], ORDWR); c[1] = c[1]->dev->open(c[1], ORDWR); if(newfd2(fd, c) < 0) error(Enofd); poperror(); a[0] = fd[0]; a[1] = fd[1]; ar0->i = 0; }