diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-03-27 20:57:01 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-03-27 20:57:01 +0200 |
commit | 04c3a6f66e3b895a087124ed415f01e23e21ee10 (patch) | |
tree | 7efd53b8b1d4cc461401ef5a2ecb2fdba13b70f8 /sys/src/9/port/proc.c | |
parent | bf2195b88c9c1483d97cb4578f81467cad73c39e (diff) |
zynq: introduce SG_FAULT to prevent access to AXI segment while PL is not ready
access to the axi segment hangs the machine when the fpga
is not programmed yet. to prevent access, we introduce a
new SG_FAULT flag, that when set on the Segment.type or
Physseg.attr, causes the fault handler to immidiately
return with an error (as if the segment would not be mapped).
during programming, we temporarily set the SG_FAULT flag
on the axi physseg, flush all processes tlb's that have
the segment mapped and when programming is done, we clear
the flag again.
Diffstat (limited to 'sys/src/9/port/proc.c')
-rw-r--r-- | sys/src/9/port/proc.c | 67 |
1 files changed, 49 insertions, 18 deletions
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) { |