| plan 9 kernel history: overview | file list | diff list |
1990/1212/port/fault.c (diff list | history)
| 1990/1202/sys/src/9/port/fault.c:6,16 – 1990/1212/sys/src/9/port/fault.c:6,15 (short | long | prev | next) | ||
|
Created.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1990/0227 | #include "ureg.h" #include "errno.h" | |
| 1990/1212 | int fault(ulong addr, int read) | |
| 1990/0227 | { | |
| 1990/1212 | ulong mmuvirt, mmuphys, n; | |
| 1990/0227 | Seg *s; PTE *opte, *pte, *npte; Orig *o; | |
| 1990/1202/sys/src/9/port/fault.c:18,51 – 1990/1212/sys/src/9/port/fault.c:17,37 | ||
| 1990/0227 | Page *pg; int zeroed = 0, head = 1; int i; | |
| 1990/1212 | KMap *k, *k1; | |
| 1990/0227 |
| |
| 1990/1212 | if(addr>USTKTOP) return -1; | |
| 1990/0227 | s = &u->p->seg[SSEG]; | |
| 1990/0821 | if(s->o==0 || addr<s->maxva-USTACKSIZE || addr>=s->maxva) | |
| 1990/0227 |
| |
| 1990/1212 | return -1; | |
| 1990/0227 | /* grow stack */ o = s->o; n = o->npte; | |
| 1990/0802 | if(waserror()){ pprint("can't allocate stack page\n"); | |
| 1990/1212 | return -1; | |
| 1990/0802 | } | |
| 1990/0227 | growpte(o, (s->maxva-addr)>>PGSHIFT); | |
| 1990/0802 | poperror(); | |
| 1990/1202/sys/src/9/port/fault.c:58,65 – 1990/1212/sys/src/9/port/fault.c:44,51 | ||
| 1990/0227 | o->va = addr; }else o = s->o; | |
| 1990/1212 | if(!read && (o->flag&OWRPERM)==0) return -1; | |
| 1990/0227 | lock(o); opte = &o->pte[(addr-o->va)>>PGSHIFT]; pte = opte; | |
| 1990/1202/sys/src/9/port/fault.c:92,99 – 1990/1212/sys/src/9/port/fault.c:78,87 | ||
| 1990/0227 | if(n > BY2PG) n = BY2PG; pg = newpage(1, o, addr); | |
| 1990/1212 | k = kmap(pg); | |
| 1990/0227 | qlock(o->chan); if(waserror()){ | |
| 1990/1212 | kunmap(k); | |
| 1990/0227 | qunlock(o->chan); pg->o = 0; pg->ref--; | |
| 1990/1202/sys/src/9/port/fault.c:100,114 – 1990/1212/sys/src/9/port/fault.c:88,102 | ||
| 1990/1113 | pexit("load i/o error", 0); | |
| 1990/0227 | } o->chan->offset = (addr-o->va) + o->minca; | |
| 1990/1212 | l = (char*)VA(k); | |
| 1990/0227 | if((*devtab[o->chan->type].read)(o->chan, l, n) != n) | |
| 1990/11211 | error(Eioload); | |
| 1990/0227 | qunlock(o->chan); | |
| 1990/1212 | kunmap(k); poperror(); | |
| 1990/0227 | opte = &o->pte[(addr-s->minva)>>PGSHIFT]; /* could move */ pte = opte; if(pte->page == 0){ | |
| 1990/1202/sys/src/9/port/fault.c:121,129 – 1990/1212/sys/src/9/port/fault.c:109,117 | ||
| 1990/0227 | } } /* | |
| 1990/1212 | * Copy on reference (conf.copymode==1) or write (conf.copymode==0) | |
| 1990/0227 | */ | |
| 1990/1212 | if((o->flag & OWRPERM) && (conf.copymode || !read) | |
| 1990/0227 | && ((head && ((o->flag&OPURE) || o->nproc>1)) || (!head && pte->page->ref>1))){ | |
| 1990/1202/sys/src/9/port/fault.c:173,179 – 1990/1212/sys/src/9/port/fault.c:161,171 | ||
| 1990/0227 | opte->page = 0; }else{ /* copy page */ pte->page = newpage(1, o, addr); | |
| 1990/1212 | k = kmap(pte->page); k1 = kmap(pg); memcpy((void*)VA(k), (void*)VA(k1), BY2PG); kunmap(k); kunmap(k1); | |
| 1990/0227 | if(pg->ref <= 1) panic("pg->ref <= 1"); pg->ref--; | |
| 1990/1202/sys/src/9/port/fault.c:181,187 – 1990/1212/sys/src/9/port/fault.c:173,179 | ||
| 1990/0227 | easy: mmuphys = PTEWRITE; }else{ | |
| 1990/1212 | mmuphys = PTERONLY; | |
| 1990/0227 | if(o->flag & OWRPERM) if(o->flag & OPURE){ if(!head && pte->page->ref==1) | |
| 1990/1202/sys/src/9/port/fault.c:192,198 – 1990/1212/sys/src/9/port/fault.c:184,190 | ||
| 1990/0227 | mmuphys = PTEWRITE; } mmuvirt = addr; | |
| 1990/1212 | mmuphys |= PPN(pte->page->pa) | PTEVALID; | |
| 1990/0227 | usepage(pte->page, 1); if(pte->page->va != addr) panic("wrong addr in tail %lux %lux", pte->page->va, addr); | |
| 1990/1202/sys/src/9/port/fault.c:203,208 – 1990/1212/sys/src/9/port/fault.c:195,201 | ||
| 1990/0227 | } unlock(o); putmmu(mmuvirt, mmuphys); | |
| 1990/1212 | return 0; | |
| 1990/0227 | } /* | |
| 1990/1202/sys/src/9/port/fault.c:232,246 – 1990/1212/sys/src/9/port/fault.c:225,230 | ||
| 1990/0617 | len -= s->maxva - addr; addr = s->maxva; goto Again; | |
| 1990/0227 |
| |
| 1990/1110 |
| |
| 1990/11211 |
| |
| 1990/0227 | } } | |