diff options
| -rw-r--r-- | sys/src/9/pc/devlml.c | 4 | ||||
| -rw-r--r-- | sys/src/9/port/devsegment.c | 2 | ||||
| -rw-r--r-- | sys/src/9/port/fault.c | 21 | ||||
| -rw-r--r-- | sys/src/9/port/portdat.h | 1 | ||||
| -rw-r--r-- | sys/src/9/port/portfns.h | 5 | ||||
| -rw-r--r-- | sys/src/9/port/proc.c | 67 | ||||
| -rw-r--r-- | sys/src/9/port/segment.c | 35 | ||||
| -rw-r--r-- | sys/src/9/ppc/m8260.c | 2 | ||||
| -rw-r--r-- | sys/src/9/zynq/devarch.c | 26 |
9 files changed, 100 insertions, 63 deletions
diff --git a/sys/src/9/pc/devlml.c b/sys/src/9/pc/devlml.c index df96bbda2..8aba39836 100644 --- a/sys/src/9/pc/devlml.c +++ b/sys/src/9/pc/devlml.c @@ -179,7 +179,7 @@ lmlreset(void) kstrdup(&segbuf.name, name); segbuf.pa = PADDR(lml->codedata); segbuf.size = Codedatasize; - if(addphysseg(&segbuf) == -1){ + if(addphysseg(&segbuf) == nil){ print("lml: physsegment: %s\n", name); return; } @@ -190,7 +190,7 @@ lmlreset(void) kstrdup(&segbuf.name, name); segbuf.pa = (ulong)regpa; segbuf.size = pcidev->mem[0].size; - if(addphysseg(&segbuf) == -1){ + if(addphysseg(&segbuf) == nil){ print("lml: physsegment: %s\n", name); return; } diff --git a/sys/src/9/port/devsegment.c b/sys/src/9/port/devsegment.c index 384d54aa6..b712e1878 100644 --- a/sys/src/9/port/devsegment.c +++ b/sys/src/9/port/devsegment.c @@ -232,7 +232,7 @@ segmentcreate(Chan *c, char *name, int omode, ulong perm) if(TYPE(c) != Qtopdir) error(Eperm); - if(isphysseg(name)) + if(findphysseg(name) != nil) error(Eexist); if((perm & DMDIR) == 0) diff --git a/sys/src/9/port/fault.c b/sys/src/9/port/fault.c index 0d5e1ac5a..da343e079 100644 --- a/sys/src/9/port/fault.c +++ b/sys/src/9/port/fault.c @@ -10,7 +10,7 @@ fault(uintptr addr, int read) { Segment *s; char *sps; - int pnd; + int pnd, attr; if(up == nil) panic("fault: nil up"); @@ -34,7 +34,10 @@ fault(uintptr addr, int read) return -1; } - if(!read && (s->type&SG_RONLY)) { + attr = s->type; + if((attr & SG_TYPE) == SG_PHYSICAL) + attr |= s->pseg->attr; + if((attr & SG_FAULT) != 0 || !read && (attr & SG_RONLY) != 0) { qunlock(s); up->psstate = sps; return -1; @@ -62,15 +65,16 @@ faulterror(char *s, Chan *c) { char buf[ERRMAX]; - if(c != nil && c->path != nil){ - snprint(buf, sizeof buf, "%s accessing %s: %s", s, c->path->s, up->errstr); - s = buf; - } + if(c != nil) + snprint(buf, sizeof buf, "sys: %s accessing %s: %s", s, chanpath(c), up->errstr); + else + snprint(buf, sizeof buf, "sys: %s", s); if(up->nerrlab) { if(up->kp == 0) - postnote(up, 1, s, NDebug); + postnote(up, 1, buf, NDebug); error(s); } + pprint("suicide: %s\n", buf); pexit(s, 1); } @@ -208,13 +212,12 @@ fixfault(Segment *s, uintptr addr, int read) *pte = etp = ptealloc(); pg = &etp->pages[(soff&(PTEMAPMEM-1))/BY2PG]; - type = s->type&SG_TYPE; - if(pg < etp->first) etp->first = pg; if(pg > etp->last) etp->last = pg; + type = s->type & SG_TYPE; switch(type) { default: panic("fault"); diff --git a/sys/src/9/port/portdat.h b/sys/src/9/port/portdat.h index ae047da66..9d2337f5f 100644 --- a/sys/src/9/port/portdat.h +++ b/sys/src/9/port/portdat.h @@ -377,6 +377,7 @@ enum SG_RONLY = 0040, /* Segment is read only */ SG_CEXEC = 0100, /* Detach at exec */ + SG_FAULT = 0200, /* Fault on access */ }; #define PG_ONSWAP 1 diff --git a/sys/src/9/port/portfns.h b/sys/src/9/port/portfns.h index 0c1ce0bfc..36eb2a0fd 100644 --- a/sys/src/9/port/portfns.h +++ b/sys/src/9/port/portfns.h @@ -1,7 +1,7 @@ void _assert(char*); void accounttime(void); Timer* addclock0link(void (*)(void), int); -int addphysseg(Physseg*); +Physseg* addphysseg(Physseg*); void addbootfile(char*, uchar*, ulong); void addwatchdog(Watchdog*); Block* adjustblock(Block*, int); @@ -141,7 +141,7 @@ void isdir(Chan*); int iseve(void); int islo(void); Segment* isoverlap(Proc*, uintptr, uintptr); -int isphysseg(char*); +Physseg* findphysseg(char*); void ixsummary(void); void kickpager(void); void killbig(char*); @@ -231,6 +231,7 @@ void procctl(void); void procdump(void); int procfdprint(Chan*, int, char*, int); void procflushseg(Segment*); +void procflushpseg(Physseg*); int procindex(ulong); void procinit0(void); ulong procpagecount(Proc*); diff --git a/sys/src/9/port/proc.c b/sys/src/9/port/proc.c index 3012cbeaa..bfe9fe778 100644 --- a/sys/src/9/port/proc.c +++ b/sys/src/9/port/proc.c @@ -1321,35 +1321,30 @@ procdump(void) } /* - * wait till all processes have flushed their mmu - * state about segement s + * wait till all matching processes have flushed their mmu */ -void -procflushseg(Segment *s) +static void +procflushmmu(int (*match)(Proc*, void*), void *a) { - int i, ns, nm, nwait; + int i, nm, nwait; Proc *p; /* - * tell all processes with this - * segment to flush their mmu's + * tell all matching processes to flush their mmu's */ nwait = 0; for(i=0; i<conf.nproc; i++) { p = &procalloc.arena[i]; - if(p->state == Dead) - continue; - for(ns = 0; ns < NSEG; ns++) - if(p->seg[ns] == s){ - p->newtlb = 1; - for(nm = 0; nm < conf.nmach; nm++){ - if(MACHP(nm)->proc == p){ - MACHP(nm)->flushmmu = 1; - nwait++; - } + if(p->state != Dead && (*match)(p, a)){ + p->newtlb = 1; + for(nm = 0; nm < conf.nmach; nm++){ + if(MACHP(nm)->proc == p){ + MACHP(nm)->flushmmu = 1; + nwait++; } - break; } + break; + } } if(nwait == 0) @@ -1364,6 +1359,42 @@ procflushseg(Segment *s) sched(); } +static int +matchseg(Proc *p, void *a) +{ + int ns; + + for(ns = 0; ns < NSEG; ns++){ + if(p->seg[ns] == a) + return 1; + } + return 0; +} +void +procflushseg(Segment *s) +{ + procflushmmu(matchseg, s); +} + +static int +matchpseg(Proc *p, void *a) +{ + Segment *s; + int ns; + + for(ns = 0; ns < NSEG; ns++){ + s = p->seg[ns]; + if(s != nil && s->pseg == a) + return 1; + } + return 0; +} +void +procflushpseg(Physseg *ps) +{ + procflushmmu(matchpseg, ps); +} + void scheddump(void) { diff --git a/sys/src/9/port/segment.c b/sys/src/9/port/segment.c index e9e8959df..e257e47b3 100644 --- a/sys/src/9/port/segment.c +++ b/sys/src/9/port/segment.c @@ -551,7 +551,7 @@ isoverlap(Proc *p, uintptr va, uintptr len) return nil; } -int +Physseg* addphysseg(Physseg* new) { Physseg *ps; @@ -564,34 +564,29 @@ addphysseg(Physseg* new) for(ps = physseg; ps->name; ps++){ if(strcmp(ps->name, new->name) == 0){ unlock(&physseglock); - return -1; + return nil; } } if(ps-physseg >= nelem(physseg)-2){ unlock(&physseglock); - return -1; + return nil; } *ps = *new; unlock(&physseglock); - return 0; + return ps; } -int -isphysseg(char *name) +Physseg* +findphysseg(char *name) { Physseg *ps; - int rv = 0; - lock(&physseglock); - for(ps = physseg; ps->name; ps++){ - if(strcmp(ps->name, name) == 0){ - rv = 1; - break; - } - } - unlock(&physseglock); - return rv; + for(ps = physseg; ps->name; ps++) + if(strcmp(ps->name, name) == 0) + return ps; + + return nil; } uintptr @@ -654,12 +649,10 @@ segattach(Proc *p, ulong attr, char *name, uintptr va, uintptr len) if(isoverlap(p, va, len) != nil) error(Esoverlap); - for(ps = physseg; ps->name; ps++) - if(strcmp(name, ps->name) == 0) - goto found; + ps = findphysseg(name); + if(ps == nil) + error(Ebadarg); - error(Ebadarg); -found: if(len > ps->size) error(Enovmem); diff --git a/sys/src/9/ppc/m8260.c b/sys/src/9/ppc/m8260.c index 0c441a209..4b283266a 100644 --- a/sys/src/9/ppc/m8260.c +++ b/sys/src/9/ppc/m8260.c @@ -445,7 +445,7 @@ addseg(char *name, ulong start, ulong length) kstrdup(&segbuf.name, name); segbuf.pa = start; segbuf.size = length; - if (addphysseg(&segbuf) == -1) { + if (addphysseg(&segbuf) == nil) { print("addphysseg: %s\n", name); return; } diff --git a/sys/src/9/zynq/devarch.c b/sys/src/9/zynq/devarch.c index c5c4ea0b9..ccd513b26 100644 --- a/sys/src/9/zynq/devarch.c +++ b/sys/src/9/zynq/devarch.c @@ -25,14 +25,15 @@ static Dirtab archdir[Qmax] = { }; static int narchdir = Qbase; -int temp = -128; -ulong *devc; -int dmadone; +static int temp = -128; +static ulong *devc; +static int dmadone; enum { PLBUFSIZ = 8192 }; -uchar *plbuf; -Rendez plinitr, pldoner, pldmar; -QLock plrlock, plwlock; -Ref plwopen; +static uchar *plbuf; +static Rendez plinitr, pldoner, pldmar; +static QLock plrlock, plwlock; +static Ref plwopen; +static Physseg *axi; enum { DEVCTRL = 0, @@ -164,6 +165,8 @@ plirq(Ureg *, void *) slcr[0x900/4] = 0xf; slcr[0x240/4] = 0; devc[DEVMASK] |= DONE; + if(axi != nil) + axi->attr &= ~SG_FAULT; wakeup(&pldoner); } if((fl & DMADONE) != 0){ @@ -187,16 +190,21 @@ plinit(void) slcr[FPGA0_CLK_CTRL] = 1<<20 | 10<<8; memset(&seg, 0, sizeof seg); - seg.attr = SG_PHYSICAL; + seg.attr = SG_PHYSICAL | SG_FAULT; seg.name = "axi"; seg.pa = 0x40000000; seg.size = 0x8000000; - addphysseg(&seg); + axi = addphysseg(&seg); } static void plconf(void) { + if(axi != nil){ + axi->attr |= SG_FAULT; + procflushpseg(axi); + } + slcr[0x240/4] = 0xf; slcr[0x900/4] = 0xa; devc[DEVISTS] = DONE|INITPE|DMADONE; |
