summaryrefslogtreecommitdiff
path: root/sys/src/9/zynq/devarch.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2016-03-27 20:57:01 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2016-03-27 20:57:01 +0200
commit04c3a6f66e3b895a087124ed415f01e23e21ee10 (patch)
tree7efd53b8b1d4cc461401ef5a2ecb2fdba13b70f8 /sys/src/9/zynq/devarch.c
parentbf2195b88c9c1483d97cb4578f81467cad73c39e (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/zynq/devarch.c')
-rw-r--r--sys/src/9/zynq/devarch.c26
1 files changed, 17 insertions, 9 deletions
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;