summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/9/pc/devlml.c4
-rw-r--r--sys/src/9/port/devsegment.c2
-rw-r--r--sys/src/9/port/fault.c21
-rw-r--r--sys/src/9/port/portdat.h1
-rw-r--r--sys/src/9/port/portfns.h5
-rw-r--r--sys/src/9/port/proc.c67
-rw-r--r--sys/src/9/port/segment.c35
-rw-r--r--sys/src/9/ppc/m8260.c2
-rw-r--r--sys/src/9/zynq/devarch.c26
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;