| plan 9 kernel history: overview | file list | diff list |
1997/0327/pc/trap.c (diff list | history)
| 1996/0802/sys/src/9/pc/trap.c:9,230 – 1997/0327/sys/src/9/pc/trap.c:9,77 (short | long | prev | next) | ||
| 1991/0613 | ||
| 1991/0720 | void noted(Ureg*, ulong); | |
| 1991/0731 |
| |
| 1994/1029 |
| |
| 1991/0731 |
| |
| 1991/0904 |
| |
| 1991/0731 |
| |
| 1997/0327 | static void debugbpt(Ureg*, void*); static void fault386(Ureg*, void*); static void syscall(Ureg*, void*); | |
| 1991/0731 | ||
| 1991/0613 |
| |
| 1991/0709 |
| |
| 1997/0327 | static Lock irqctllock; static Irqctl *irqctl[256]; | |
| 1991/0709 | ||
| 1995/0222 |
| |
| 1991/0709 |
| |
| 1993/0217 |
| |
| 1991/0709 |
| |
| 1991/1001 |
| |
| 1991/0709 |
| |
| 1991/0614 |
| |
| 1991/0613 |
| |
| 1991/0703 |
| |
| 1993/0224 |
| |
| 1991/0703 | ||
| 1993/0217 |
| |
| 1993/1124 |
| |
| 1993/0217 |
| |
| 1991/0703 | void | |
| 1991/0710 |
| |
| 1997/0327 | intrenable(int v, void (*f)(Ureg*, void*), void* a, int tbdf) | |
| 1991/0613 | { | |
| 1991/0703 |
| |
| 1991/0710 |
| |
| 1991/0703 |
| |
| 1997/0327 | Irq * irq; Irqctl *ctl; | |
| 1991/0614 | ||
| 1991/0703 |
| |
| 1993/1124 |
| |
| 1991/0703 |
| |
| 1993/0217 |
| |
| 1991/0709 | ||
| 1993/0217 |
| |
| 1993/1124 |
| |
| 1993/0217 |
| |
| 1991/0709 |
| |
| 1991/0731 |
| |
| 1997/0327 | lock(&irqctllock); if(irqctl[v] == 0){ ctl = xalloc(sizeof(Irqctl)); if(arch->intrenable(v, tbdf, ctl) == -1){ unlock(&irqctllock); /* print("intrenable: didn't find v %d, tbdf 0x%uX\n", v, tbdf); */ xfree(ctl); return; } irqctl[v] = ctl; | |
| 1991/0709 | } | |
| 1997/0327 | ctl = irqctl[v]; irq = xalloc(sizeof(Irq)); irq->f = f; irq->a = a; irq->next = ctl->irq; ctl->irq = irq; unlock(&irqctllock); | |
| 1991/0703 | } | |
| 1991/1112 | void | |
| 1993/1124 |
| |
| 1991/1112 |
| |
| 1993/1124 |
| |
| 1993/0915 |
| |
| 1991/1112 |
| |
| 1991/1218 |
| |
| 1993/1013 |
| |
| 1991/1112 |
| |
| 1991/0614 |
| |
| 1991/0703 |
| |
| 1991/0614 |
| |
| 1991/0703 |
| |
| 1997/0327 | int v, pri; ulong vaddr; Segdesc *idt; | |
| 1991/0614 | ||
| 1991/0703 |
| |
| 1991/0731 |
| |
| 1991/0904 |
| |
| 1993/1114 |
| |
| 1997/0327 | idt = (Segdesc*)IDTADDR; vaddr = (ulong)vectortable; for(v = 0; v < 256; v++){ if(v == VectorBPT || v == VectorSYSCALL) pri = 3; else pri = 0; idt[v].d0 = (vaddr & 0xFFFF)|(KESEL<<16); idt[v].d1 = (vaddr & 0xFFFF0000)|SEGP|SEGPL(pri)|SEGIG; vaddr += 6; } | |
| 1991/0731 |
| |
| 1991/0904 |
| |
| 1991/0703 |
| |
| 1993/1114 |
| |
| 1993/1115 |
| |
| 1993/1114 |
| |
| 1993/1115 |
| |
| 1994/1029 |
| |
| 1991/0731 |
| |
| 1991/0904 |
| |
| 1991/0731 |
| |
| 1991/0904 |
| |
| 1991/0913 |
| |
| 1991/0904 |
| |
| 1991/0703 |
| |
| 1991/1214 |
| |
| 1991/0710 |
| |
| 1993/1114 |
| |
| 1993/1124 |
| |
| 1993/1114 |
| |
| 1993/1124 |
| |
| 1991/0710 | ||
| 1994/1007 | ||
| 1991/0710 |
| |
| 1991/0703 |
| |
| 1991/0718 |
| |
| 1991/0704 |
| |
| 1991/0709 |
| |
| 1991/0704 |
| |
| 1994/0603 |
| |
| 1994/0512 |
| |
| 1991/0709 |
| |
| 1991/0731 |
| |
| 1991/0709 |
| |
| 1991/0731 |
| |
| 1994/0824 |
| |
| 1995/0331 |
| |
| 1991/0731 |
| |
| 1995/0502 |
| |
| 1994/0512 |
| |
| 1991/0731 |
| |
| 1995/0222 |
| |
| 1997/0327 | intrenable(VectorBPT, debugbpt, 0, BUSUNKNOWN); intrenable(VectorPF, fault386, 0, BUSUNKNOWN); intrenable(VectorSYSCALL, syscall, 0, BUSUNKNOWN); | |
| 1991/0703 | } | |
| 1994/0722 | char *excname[] = { [0] "divide error", [1] "debug exception", | |
| 1997/0327 | [2] "nonmaskable interrupt", | |
| 1994/0722 | [3] "breakpoint", [4] "overflow", [5] "bounds check", | |
| 1996/0802/sys/src/9/pc/trap.c:231,237 – 1997/0327/sys/src/9/pc/trap.c:78,84 | ||
| 1994/0722 | [6] "invalid opcode", [7] "coprocessor not available", [8] "double fault", | |
| 1997/0327 | [9] "coprocessor segment overrun", | |
| 1994/0722 | [10] "invalid TSS", [11] "segment not present", [12] "stack exception", | |
| 1996/0802/sys/src/9/pc/trap.c:240,250 – 1997/0327/sys/src/9/pc/trap.c:87,96 | ||
| 1994/0722 | [15] "15 (reserved)", [16] "coprocessor error", | |
| 1994/1029 | [17] "alignment check", | |
| 1997/0327 | [18] "machine check", | |
| 1991/1113 | }; | |
| 1994/1029 |
| |
| 1997/0327 | static int nspuriousintr; | |
| 1994/1029 | ||
| 1991/0614 | /* | |
| 1993/1124 | * All traps come here. It is slower to have all traps call trap() rather than | |
| 1996/0802/sys/src/9/pc/trap.c:252,349 – 1997/0327/sys/src/9/pc/trap.c:98,159 | ||
| 1994/0715 | * and possible bugs. trap is called splhi(). | |
| 1991/0614 | */ | |
| 1991/0710 | void | |
| 1991/0703 |
| |
| 1997/0327 | trap(Ureg* ureg) | |
| 1991/0614 | { | |
| 1991/1112 | int v, user; | |
| 1991/0731 |
| |
| 1991/1113 | char buf[ERRLEN]; | |
| 1993/0217 |
| |
| 1993/1116 |
| |
| 1995/0223 |
| |
| 1997/0327 | Irqctl *ctl; Irq *irq; | |
| 1991/0703 | ||
| 1991/0731 |
| |
| 1993/1113 |
| |
| 1997/0327 | user = (ureg->cs & 0xFFFF) == UESEL; | |
| 1991/1112 | if(user) | |
| 1993/0915 |
| |
| 1993/1116 |
| |
| 1996/0626 |
| |
| 1993/1116 |
| |
| 1997/0327 | up->dbgreg = ureg; | |
| 1991/1112 | ||
| 1991/0709 |
| |
| 1991/0801 |
| |
| 1991/0709 |
| |
| 1991/0731 |
| |
| 1995/0223 |
| |
| 1991/0731 |
| |
| 1995/0223 |
| |
| 1993/0225 |
| |
| 1995/0222 |
| |
| 1995/0223 |
| |
| 1991/0731 |
| |
| 1995/0222 |
| |
| 1991/1113 |
| |
| 1997/0327 | v = ureg->trap; if(ctl = irqctl[v]){ if(ctl->isintr) m->intr++; if(ctl->isr) ctl->isr(v); | |
| 1991/1113 | ||
| 1993/0217 |
| |
| 1997/0327 | for(irq = ctl->irq; irq; irq = irq->next) irq->f(ureg, irq->a); | |
| 1993/0224 |
| |
| 1991/1113 |
| |
| 1996/0626 |
| |
| 1991/1218 |
| |
| 1993/1013 |
| |
| 1994/1029 |
| |
| 1991/1113 |
| |
| 1993/0224 | ||
| 1995/0223 |
| |
| 1994/0722 |
| |
| 1993/0224 |
| |
| 1995/0222 |
| |
| 1995/0223 |
| |
| 1995/0222 |
| |
| 1995/0223 |
| |
| 1996/0626 |
| |
| 1995/0222 |
| |
| 1993/0224 |
| |
| 1995/0223 |
| |
| 1995/0222 |
| |
| 1993/0224 |
| |
| 1996/0626 |
| |
| 1997/0327 | if(ctl->eoi) ctl->eoi(v); | |
| 1991/0731 | } | |
| 1997/0327 | else if(v <= 16 && user){ spllo(); sprint(buf, "sys: trap: %s", excname[v]); postnote(up, 1, buf, NDebug); } else if(v >= VectorPIC && v <= MaxVectorPIC){ /* * An unknown interrupt. * Check for a default IRQ7. This can happen when * the IRQ input goes away before the acknowledge. * In this case, a 'default IRQ7' is generated, but * the corresponding bit in the ISR isn't set. * In fact, just ignore all such interrupts. */ if(nspuriousintr < 2) print("spurious interrupt %d\n", v-VectorPIC); nspuriousintr++; return; } else{ dumpregs(ureg); if(v < nelem(excname)) panic("%s", excname[v]); panic("unknown trap/intr: %d\n", v); } | |
| 1991/0801 | ||
| 1993/0224 |
| |
| 1993/0217 |
| |
| 1993/1124 |
| |
| 1993/0217 |
| |
| 1991/0910 | ||
| 1994/0715 | /* * check user since syscall does its own notifying */ | |
| 1996/0626 |
| |
| 1993/0915 | splhi(); | |
| 1994/0715 |
| |
| 1991/0910 |
| |
| 1996/0626 |
| |
| 1994/1029 |
| |
| 1997/0327 | if(v != VectorSYSCALL && user && (up->procctl || up->nnote)) notify(ureg); | |
| 1991/0806 | } /* | |
| 1996/0802/sys/src/9/pc/trap.c:350,394 – 1997/0327/sys/src/9/pc/trap.c:160,214 | ||
| 1991/0718 | * dump registers */ void | |
| 1993/0915 |
| |
| 1997/0327 | dumpregs2(Ureg* ureg) | |
| 1991/0718 | { | |
| 1993/1115 |
| |
| 1997/0327 | ureg->cs &= 0xFFFF; ureg->ds &= 0xFFFF; ureg->es &= 0xFFFF; ureg->fs &= 0xFFFF; ureg->gs &= 0xFFFF; | |
| 1993/1115 | ||
| 1993/0915 | if(up) | |
| 1997/0327 | print("cpu%d: registers for %s %d\n", m->machno, up->text, up->pid); | |
| 1991/0718 | else | |
| 1993/1115 |
| |
| 1993/1113 |
| |
| 1993/1115 |
| |
| 1991/0718 |
| |
| 1991/1214 |
| |
| 1993/1113 |
| |
| 1997/0327 | print("cpu%d: registers for kernel\n", m->machno); print("FLAGS=%luX TRAP=%luX ECODE=%luX PC=%luX", ureg->flags, ureg->trap, ureg->ecode, ureg->pc); print(" SS=%4.4luX USP=%luX\n", ureg->ss & 0xFFFF, ureg->usp); print(" AX %8.8luX BX %8.8luX CX %8.8luX DX %8.8luX\n", ureg->ax, ureg->bx, ureg->cx, ureg->dx); print(" SI %8.8luX DI %8.8luX BP %8.8luX\n", ureg->si, ureg->di, ureg->bp); print(" CS %4.4uX DS %4.4uX ES %4.4uX FS %4.4uX GS %4.4uX\n", ureg->cs, ureg->ds, ureg->es, ureg->fs, ureg->gs); | |
| 1991/0718 | } | |
| 1991/0720 | void | |
| 1993/0915 |
| |
| 1997/0327 | dumpregs(Ureg* ureg) | |
| 1993/0915 | { | |
| 1994/0813 | extern ulong etext; | |
| 1993/1113 |
| |
| 1997/0327 | ulong mca[2], mct[2]; | |
| 1993/1113 | ||
| 1997/0327 | dumpregs2(ureg); | |
| 1994/0813 | ||
| 1993/1113 |
| |
| 1996/0802 |
| |
| 1994/1029 |
| |
| 1996/0802 |
| |
| 1993/0915 |
| |
| 1994/0902 |
| |
| 1993/1113 |
| |
| 1997/0327 | /* * Processor control registers. * If machine check exception, time stamp counter, page size extensions or * enhanced virtual 8086 mode extensions are supported, there is a CR4. * If there is a CR4 and machine check extensions, read the machine check * address and machine check type registers if RDMSR supported. */ print(" CR0 %8.8lux CR2 %8.8lux CR3 %8.8lux", getcr0(), getcr2(), getcr3()); if(m->cpuiddx & 0x9A){ print(" CR4 %8.8luX", getcr4()); if((m->cpuiddx & 0xA0) == 0xA0){ rdmsr(0x00, &mca[1], &mca[0]); rdmsr(0x01, &mct[1], &mct[0]); print("\n MCA %8.8luX:%8.8luX MCT %8.8luX", mca[1], mca[0], mct[0]); } } print("\n ur %luX up %luX\n", ureg, up); | |
| 1993/0915 | } void | |
| 1996/0802/sys/src/9/pc/trap.c:395,400 – 1997/0327/sys/src/9/pc/trap.c:215,221 | ||
| 1991/0720 | dumpstack(void) { | |
| 1992/0804 | ulong l, v, i; | |
| 1997/0327 | uchar *p; | |
| 1992/0804 | extern ulong etext; | |
| 1993/0915 | if(up == 0) | |
| 1996/0802/sys/src/9/pc/trap.c:404,411 – 1997/0327/sys/src/9/pc/trap.c:225,235 | ||
| 1994/0816 | for(l=(ulong)&l; l<(ulong)(up->kstack+KSTACK); l+=4){ | |
| 1992/0804 | v = *(ulong*)l; if(KTZERO < v && v < (ulong)&etext){ | |
| 1997/0327 | p = (uchar*)v; if(*(p-5) == 0xE8){ print("%lux ", p-5); i++; } | |
| 1992/0804 | } | |
| 1993/1113 | if(i == 8){ | |
| 1992/0804 | i = 0; | |
| 1996/0802/sys/src/9/pc/trap.c:414,419 – 1997/0327/sys/src/9/pc/trap.c:238,283 | ||
| 1992/0804 | } | |
| 1991/0720 | } | |
| 1997/0327 | static void debugbpt(Ureg* ureg, void*) { char buf[ERRLEN]; if(up == 0) panic("kernel bpt"); /* restore pc to instruction that caused the trap */ ureg->pc--; sprint(buf, "sys: breakpoint"); postnote(up, 1, buf, NDebug); } static void fault386(Ureg* ureg, void*) { ulong addr; int read, user, n, insyscall; char buf[ERRLEN]; insyscall = up->insyscall; up->insyscall = 1; addr = getcr2(); read = !(ureg->ecode & 2); user = (ureg->cs&0xffff) == UESEL; spllo(); n = fault(addr, read); if(n < 0){ if(user){ sprint(buf, "sys: trap: fault %s addr=0x%lux", read? "read" : "write", addr); postnote(up, 1, buf, NDebug); return; } dumpregs(ureg); panic("fault: 0x%lux\n", addr); } up->insyscall = insyscall; } | |
| 1991/0718 | /* | |
| 1991/0710 | * system calls */ | |
| 1996/0802/sys/src/9/pc/trap.c:422,445 – 1997/0327/sys/src/9/pc/trap.c:286,307 | ||
| 1992/0103 | /* | |
| 1994/0715 | * syscall is called splhi() | |
| 1992/0103 | */ | |
| 1993/1124 |
| |
| 1997/0327 | static void syscall(Ureg* ureg, void*) | |
| 1991/0710 | { | |
| 1991/0720 | ulong sp; long ret; int i; | |
| 1993/1124 |
| |
| 1994/0715 | ||
| 1997/0327 | m->syscall++; | |
| 1993/0915 | up->insyscall = 1; | |
| 1993/1225 |
| |
| 1997/0327 | up->pc = ureg->pc; up->dbgreg = ureg; | |
| 1993/1225 | ||
| 1991/0720 |
| |
| 1997/0327 | if((ureg->cs)&0xffff == KESEL) | |
| 1991/0720 | panic("recursive system call"); | |
| 1991/0718 | ||
| 1993/0915 |
| |
| 1997/0327 | up->scallnr = ureg->ax; | |
| 1993/0915 | if(up->scallnr == RFORK && up->fpstate == FPactive){ | |
| 1992/0805 | /* * so that the child starts out with the | |
| 1996/0802/sys/src/9/pc/trap.c:454,465 – 1997/0327/sys/src/9/pc/trap.c:316,327 | ||
| 1992/0805 | } | |
| 1994/0715 | spllo(); | |
| 1991/0720 |
| |
| 1997/0327 | sp = ureg->usp; | |
| 1993/0915 | up->nerrlab = 0; | |
| 1991/0720 | ret = -1; if(!waserror()){ | |
| 1994/0407 | if(up->scallnr >= nsyscall){ | |
| 1993/0915 |
| |
| 1997/0327 | pprint("bad sys call number %d pc %lux\n", up->scallnr, ureg->pc); | |
| 1993/1013 | postnote(up, 1, "sys: bad sys call", NDebug); | |
| 1991/0720 | error(Ebadarg); } | |
| 1996/0802/sys/src/9/pc/trap.c:470,476 – 1997/0327/sys/src/9/pc/trap.c:332,338 | ||
| 1993/0915 | up->s = *((Sargs*)(sp+1*BY2WD)); up->psstate = sysctab[up->scallnr]; | |
| 1992/0625 | ||
| 1993/0915 |
| |
| 1997/0327 | ret = systab[up->scallnr](up->s.args); | |
| 1991/0720 | poperror(); } | |
| 1993/0915 | if(up->nerrlab){ | |
| 1996/0802/sys/src/9/pc/trap.c:489,502 – 1997/0327/sys/src/9/pc/trap.c:351,364 | ||
| 1992/0609 | * ignored. On other machines the return value is put into * the results register by caller of syscall. */ | |
| 1991/0801 |
| |
| 1997/0327 | ureg->ax = ret; | |
| 1992/0609 | ||
| 1993/0915 | if(up->scallnr == NOTED) | |
| 1991/0720 |
| |
| 1997/0327 | noted(ureg, *(ulong*)(sp+BY2WD)); | |
| 1995/0105 | splhi(); | |
| 1991/1114 | ||
| 1993/0915 | if(up->scallnr!=RFORK && (up->procctl || up->nnote)) | |
| 1991/0720 |
| |
| 1997/0327 | notify(ureg); | |
| 1995/0115 | ||
| 1991/0710 | } | |
| 1996/0802/sys/src/9/pc/trap.c:505,511 – 1997/0327/sys/src/9/pc/trap.c:367,373 | ||
| 1991/0720 | * Pass user the Ureg struct and the note on his stack. */ | |
| 1992/0108 | int | |
| 1991/0720 |
| |
| 1997/0327 | notify(Ureg* ureg) | |
| 1991/0710 | { | |
| 1995/0202 | int l; | |
| 1991/1114 | ulong s, sp; | |
| 1996/0802/sys/src/9/pc/trap.c:524,530 – 1997/0327/sys/src/9/pc/trap.c:386,392 | ||
| 1991/1218 | l = strlen(n->msg); if(l > ERRLEN-15) /* " pc=0x12345678\0" */ l = ERRLEN-15; | |
| 1997/0327 | sprint(n->msg+l, " pc=0x%.8lux", ureg->pc); | |
| 1991/1218 | } | |
| 1995/0202 | ||
| 1993/0915 | if(n->flag!=NUser && (up->notified || up->notify==0)){ | |
| 1996/0802/sys/src/9/pc/trap.c:544,550 – 1997/0327/sys/src/9/pc/trap.c:406,412 | ||
| 1995/0202 | qunlock(&up->debug); pexit(n->msg, n->flag!=NDebug); } | |
| 1997/0327 | sp = ureg->usp; | |
| 1995/0202 | sp -= sizeof(Ureg); if(!okaddr((ulong)up->notify, 1, 0) | |
| 1996/0802/sys/src/9/pc/trap.c:555,561 – 1997/0327/sys/src/9/pc/trap.c:417,423 | ||
| 1995/0202 | } up->ureg = (void*)sp; | |
| 1997/0327 | memmove((Ureg*)sp, ureg, sizeof(Ureg)); | |
| 1995/0202 | *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */ up->ureg = (void*)sp; sp -= BY2WD+ERRLEN; | |
| 1996/0802/sys/src/9/pc/trap.c:564,571 – 1997/0327/sys/src/9/pc/trap.c:426,433 | ||
| 1995/0202 | *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */ *(ulong*)(sp+1*BY2WD) = (ulong)up->ureg; /* arg 1 is ureg* */ *(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */ | |
| 1997/0327 | ureg->usp = sp; ureg->pc = (ulong)up->notify; | |
| 1995/0202 | up->notified = 1; up->nnote--; memmove(&up->lastnote, &up->note[0], sizeof(Note)); | |
| 1996/0802/sys/src/9/pc/trap.c:580,588 – 1997/0327/sys/src/9/pc/trap.c:442,450 | ||
| 1991/0720 | * Return user to state before notify() */ | |
| 1991/0710 | void | |
| 1991/0720 |
| |
| 1997/0327 | noted(Ureg* ureg, ulong arg0) | |
| 1991/0710 | { | |
| 1991/0720 |
| |
| 1997/0327 | Ureg *nureg; | |
| 1995/0202 | ulong oureg, sp; | |
| 1991/0720 | ||
| 1993/0915 | qlock(&up->debug); | |
| 1996/0802/sys/src/9/pc/trap.c:593,602 – 1997/0327/sys/src/9/pc/trap.c:455,464 | ||
| 1991/0720 | } | |
| 1993/0915 | up->notified = 0; | |
| 1994/0513 |
| |
| 1997/0327 | nureg = up->ureg; /* pointer to user returned Ureg struct */ | |
| 1995/0202 | /* sanity clause */ | |
| 1997/0327 | oureg = (ulong)nureg; | |
| 1995/02021 | if(!okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){ | |
| 1995/0202 | pprint("bad ureg in noted or call to noted() when not notified\n"); | |
| 1994/0513 | qunlock(&up->debug); | |
| 1996/0802/sys/src/9/pc/trap.c:604,621 – 1997/0327/sys/src/9/pc/trap.c:466,483 | ||
| 1994/0513 | } | |
| 1995/0202 | /* don't let user change text or stack segments */ | |
| 1997/0327 | nureg->cs = ureg->cs; nureg->ss = ureg->ss; | |
| 1995/0202 | /* don't let user change system flags */ | |
| 1997/0327 | nureg->flags = (ureg->flags & ~0xCD5) | (nureg->flags & 0xCD5); | |
| 1995/0202 | ||
| 1992/0609 |
| |
| 1997/0327 | memmove(ureg, nureg, sizeof(Ureg)); | |
| 1995/0105 | ||
| 1991/0720 | switch(arg0){ case NCONT: | |
| 1995/0202 | case NRSTR: | |
| 1992/0616 |
| |
| 1997/0327 | if(!okaddr(nureg->pc, 1, 0) || !okaddr(nureg->usp, BY2WD, 0)){ | |
| 1991/0814 | pprint("suicide: trap in noted\n"); | |
| 1995/0202 | qunlock(&up->debug); | |
| 1994/0513 | pexit("Suicide", 0); | |
| 1996/0802/sys/src/9/pc/trap.c:625,631 – 1997/0327/sys/src/9/pc/trap.c:487,493 | ||
| 1995/0105 | break; | |
| 1991/0720 | ||
| 1995/0202 | case NSAVE: | |
| 1997/0327 | if(!okaddr(nureg->pc, BY2WD, 0) || !okaddr(nureg->usp, BY2WD, 0)){ | |
| 1995/0202 | pprint("suicide: trap in noted\n"); qunlock(&up->debug); pexit("Suicide", 0); | |
| 1996/0802/sys/src/9/pc/trap.c:633,639 – 1997/0327/sys/src/9/pc/trap.c:495,501 | ||
| 1995/0202 | qunlock(&up->debug); sp = oureg-4*BY2WD-ERRLEN; splhi(); | |
| 1997/0327 | ureg->sp = sp; | |
| 1995/0202 | ((ulong*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */ ((ulong*)sp)[0] = 0; /* arg 0 is pc */ break; | |
| 1996/0802/sys/src/9/pc/trap.c:655,668 – 1997/0327/sys/src/9/pc/trap.c:517,530 | ||
| 1993/1113 | execregs(ulong entry, ulong ssize, ulong nargs) { ulong *sp; | |
| 1997/0327 | Ureg *ureg; | |
| 1993/1113 | sp = (ulong*)(USTKTOP - ssize); *--sp = nargs; | |
| 1997/0327 | ureg = up->dbgreg; ureg->usp = (ulong)sp; ureg->pc = entry; | |
| 1994/0513 | return USTKTOP-BY2WD; /* address of user-level clock */ | |
| 1993/1113 | } | |
| 1996/0802/sys/src/9/pc/trap.c:669,697 – 1997/0327/sys/src/9/pc/trap.c:531,559 | ||
| 1993/1113 | ulong userpc(void) { | |
| 1997/0327 | Ureg *ureg; | |
| 1993/1113 |
| |
| 1997/0327 | ureg = (Ureg*)up->dbgreg; return ureg->pc; | |
| 1993/1113 | } | |
| 1991/1112 | /* This routine must save the values of registers the user is not permitted to write | |
| 1997/0327 | * from devproc and then restore the saved values before returning | |
| 1991/1112 | */ void | |
| 1997/0327 | setregisters(Ureg* ureg, char* pureg, char* uva, int n) | |
| 1991/1112 | { ulong flags; ulong cs; ulong ss; | |
| 1997/0327 | flags = ureg->flags; cs = ureg->cs; ss = ureg->ss; | |
| 1991/1112 | memmove(pureg, uva, n); | |
| 1997/0327 | ureg->flags = (ureg->flags & 0x00FF) | (flags & 0xFF00); ureg->cs = cs; ureg->ss = ss; | |
| 1993/1113 | } static void | |
| 1996/0802/sys/src/9/pc/trap.c:698,708 – 1997/0327/sys/src/9/pc/trap.c:560,570 | ||
| 1993/1113 | linkproc(void) { spllo(); | |
| 1997/0327 | up->kpfun(up->kparg); | |
| 1993/1113 | } void | |
| 1997/0327 | kprocchild(Proc* p, void (*func)(void*), void* arg) | |
| 1993/1113 | { p->sched.pc = (ulong)linkproc; p->sched.sp = (ulong)p->kstack+KSTACK; | |
| 1996/0802/sys/src/9/pc/trap.c:712,723 – 1997/0327/sys/src/9/pc/trap.c:574,585 | ||
| 1993/1113 | } void | |
| 1997/0327 | forkchild(Proc *p, Ureg *ureg) | |
| 1993/1113 | { | |
| 1997/0327 | Ureg *cureg; | |
| 1993/1113 | /* | |
| 1997/0327 | * Add 2*BY2WD to the stack to account for | |
| 1993/1113 | * - the return PC * - trap's argument (ur) */ | |
| 1996/0802/sys/src/9/pc/trap.c:724,734 – 1997/0327/sys/src/9/pc/trap.c:586,596 | ||
| 1993/1113 | p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Ureg)+2*BY2WD); p->sched.pc = (ulong)forkret; | |
| 1997/0327 | cureg = (Ureg*)(p->sched.sp+2*BY2WD); memmove(cureg, ureg, sizeof(Ureg)); cureg->ax = 0; /* return value of syscall in child */ | |
| 1993/1113 |
| |
| 1997/0327 | /* Things from bottom of syscall which were never executed */ | |
| 1993/1113 | p->psstate = 0; p->insyscall = 0; | |
| 1991/0614 | } | |
| 1996/0802/sys/src/9/pc/trap.c:737,756 – 1997/0327/sys/src/9/pc/trap.c:599,618 | ||
| 1993/1022 | * a sleeping process */ void | |
| 1997/0327 | setkernur(Ureg* ureg, Proc* p) | |
| 1993/1022 | { | |
| 1994/0219 |
| |
| 1997/0327 | ureg->pc = p->sched.pc; ureg->sp = p->sched.sp+4; | |
| 1993/1022 | } | |
| 1995/1024 | ulong dbgpc(Proc *p) { | |
| 1997/0327 | Ureg *ureg; | |
| 1995/1024 |
| |
| 1997/0327 | ureg = p->dbgreg; if(ureg == 0) | |
| 1995/1024 | return 0; | |
| 1997/0327 | return ureg->pc; | |
| 1995/1024 | } | |