summaryrefslogtreecommitdiff
path: root/sys/src/9/bcm
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2019-07-25 08:41:37 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2019-07-25 08:41:37 +0200
commit5a0c2e2d17617ece4819e2f66514a498849ee088 (patch)
tree5bf2e35026e3eb4ed3657f57637965a2e6731b3d /sys/src/9/bcm
parent4983adfa2cd403eda22d862917c2ff5ed35b48b3 (diff)
bcm, bcm64: add dmaflush() function and make virtio size and virtual address configurable in Soc.virtio and Soc.iosize
Diffstat (limited to 'sys/src/9/bcm')
-rw-r--r--sys/src/9/bcm/archbcm.c4
-rw-r--r--sys/src/9/bcm/archbcm2.c4
-rw-r--r--sys/src/9/bcm/dat.h6
-rw-r--r--sys/src/9/bcm/dma.c50
-rw-r--r--sys/src/9/bcm/fns.h1
-rw-r--r--sys/src/9/bcm/io.h2
-rw-r--r--sys/src/9/bcm/mmu.c6
7 files changed, 58 insertions, 15 deletions
diff --git a/sys/src/9/bcm/archbcm.c b/sys/src/9/bcm/archbcm.c
index 443a9b709..dd480bc43 100644
--- a/sys/src/9/bcm/archbcm.c
+++ b/sys/src/9/bcm/archbcm.c
@@ -15,8 +15,10 @@
Soc soc = {
.dramsize = 512*MiB,
- .physio = 0x20000000,
.busdram = 0x40000000,
+ .iosize = 16*MiB,
+ .virtio = VIRTIO,
+ .physio = 0x20000000,
.busio = 0x7E000000,
.armlocal = 0,
.l1ptedramattrs = Cached | Buffered,
diff --git a/sys/src/9/bcm/archbcm2.c b/sys/src/9/bcm/archbcm2.c
index 15d8e4ec7..05c7e9d55 100644
--- a/sys/src/9/bcm/archbcm2.c
+++ b/sys/src/9/bcm/archbcm2.c
@@ -20,8 +20,10 @@ typedef struct Mboxes Mboxes;
Soc soc = {
.dramsize = 0x3F000000, /* was 1024*MiB, but overlaps with physio */
- .physio = 0x3F000000,
.busdram = 0xC0000000,
+ .iosize = 16*MiB,
+ .virtio = VIRTIO,
+ .physio = 0x3F000000,
.busio = 0x7E000000,
.armlocal = 0x40000000,
.l1ptedramattrs = Cached | Buffered | L1wralloc | L1sharable,
diff --git a/sys/src/9/bcm/dat.h b/sys/src/9/bcm/dat.h
index bbb287e6a..0c4f7351f 100644
--- a/sys/src/9/bcm/dat.h
+++ b/sys/src/9/bcm/dat.h
@@ -281,17 +281,17 @@ struct DevConf
struct Soc { /* SoC dependent configuration */
ulong dramsize;
- uintptr physio;
+ ulong iosize;
uintptr busdram;
uintptr busio;
+ uintptr physio;
+ uintptr virtio;
uintptr armlocal;
u32int l1ptedramattrs;
u32int l2ptedramattrs;
};
extern Soc soc;
-#define BUSUNKNOWN -1
-
/*
* GPIO
*/
diff --git a/sys/src/9/bcm/dma.c b/sys/src/9/bcm/dma.c
index e0d073ae1..81b68199f 100644
--- a/sys/src/9/bcm/dma.c
+++ b/sys/src/9/bcm/dma.c
@@ -82,6 +82,8 @@ struct Ctlr {
Cb *cb;
Rendez r;
int dmadone;
+ void *flush;
+ int len;
};
struct Cb {
@@ -108,7 +110,7 @@ dmaaddr(void *va)
static uintptr
dmaioaddr(void *va)
{
- return soc.busio | ((uintptr)va - VIRTIO);
+ return soc.busio | ((uintptr)va - soc.virtio);
}
static void
@@ -164,26 +166,28 @@ dmastart(int chan, int dev, int dir, void *src, void *dst, int len)
ctlr->regs[Cs] = Reset;
while(ctlr->regs[Cs] & Reset)
;
- intrenable(IRQDMA(chan), dmainterrupt, ctlr, 0, "dma");
+ intrenable(IRQDMA(chan), dmainterrupt, ctlr, BUSUNKNOWN, "dma");
}
+ ctlr->len = len;
cb = ctlr->cb;
ti = 0;
switch(dir){
case DmaD2M:
- cachedwbinvse(dst, len);
+ ctlr->flush = dst;
ti = Srcdreq | Destinc;
cb->sourcead = dmaioaddr(src);
cb->destad = dmaaddr(dst);
break;
case DmaM2D:
- cachedwbse(src, len);
+ ctlr->flush = nil;
+ dmaflush(1, src, len);
ti = Destdreq | Srcinc;
cb->sourcead = dmaaddr(src);
cb->destad = dmaioaddr(dst);
break;
case DmaM2M:
- cachedwbse(src, len);
- cachedwbinvse(dst, len);
+ ctlr->flush = dst;
+ dmaflush(1, src, len);
ti = Srcinc | Destinc;
cb->sourcead = dmaaddr(src);
cb->destad = dmaaddr(dst);
@@ -193,7 +197,7 @@ dmastart(int chan, int dev, int dir, void *src, void *dst, int len)
cb->txfrlen = len;
cb->stride = 0;
cb->nextconbk = 0;
- cachedwbse(cb, sizeof(Cb));
+ dmaflush(1, cb, sizeof(Cb));
ctlr->regs[Cs] = 0;
microdelay(1);
ctlr->regs[Conblkad] = dmaaddr(cb);
@@ -220,6 +224,10 @@ dmawait(int chan)
ctlr = &dma[chan];
tsleep(&ctlr->r, dmadone, ctlr, 3000);
ctlr->dmadone = 0;
+ if(ctlr->flush != nil){
+ dmaflush(0, ctlr->flush, ctlr->len);
+ ctlr->flush = nil;
+ }
r = ctlr->regs;
DBG dumpdregs("after sleep", r);
s = r[Cs];
@@ -233,3 +241,31 @@ dmawait(int chan)
r[Cs] = Int|End;
return 0;
}
+
+void
+dmaflush(int clean, void *p, ulong len)
+{
+ uintptr s = (uintptr)p;
+ uintptr e = (uintptr)p + len;
+
+ if(clean){
+ s &= ~(BLOCKALIGN-1);
+ e += BLOCKALIGN-1;
+ e &= ~(BLOCKALIGN-1);
+ cachedwbse((void*)s, e - s);
+ return;
+ }
+ if(s & BLOCKALIGN-1){
+ s &= ~(BLOCKALIGN-1);
+ cachedwbinvse((void*)s, BLOCKALIGN);
+ s += BLOCKALIGN;
+ }
+ if(e & BLOCKALIGN-1){
+ e &= ~(BLOCKALIGN-1);
+ if(e < s)
+ return;
+ cachedwbinvse((void*)e, BLOCKALIGN);
+ }
+ if(s < e)
+ cachedinvse((void*)s, e - s);
+}
diff --git a/sys/src/9/bcm/fns.h b/sys/src/9/bcm/fns.h
index 6e35a2401..3801948e1 100644
--- a/sys/src/9/bcm/fns.h
+++ b/sys/src/9/bcm/fns.h
@@ -28,6 +28,7 @@ extern u32int cpidget(void);
extern void cpwr(int cp, int op1, int crn, int crm, int op2, ulong val);
extern void cpwrsc(int op1, int crn, int crm, int op2, ulong val);
#define cycles(ip) *(ip) = lcycles()
+extern void dmaflush(int, void*, ulong);
extern void dmastart(int, int, int, void*, void*, int);
extern int dmawait(int);
extern uintptr dmaaddr(void *va);
diff --git a/sys/src/9/bcm/io.h b/sys/src/9/bcm/io.h
index c98f3ea25..3bdcf71f5 100644
--- a/sys/src/9/bcm/io.h
+++ b/sys/src/9/bcm/io.h
@@ -63,3 +63,5 @@ enum {
ClkPixel,
ClkPwm,
};
+
+#define BUSUNKNOWN (-1)
diff --git a/sys/src/9/bcm/mmu.c b/sys/src/9/bcm/mmu.c
index 614a6fb4f..8d23e84ae 100644
--- a/sys/src/9/bcm/mmu.c
+++ b/sys/src/9/bcm/mmu.c
@@ -49,8 +49,8 @@ mmuinit(void *a)
/*
* map i/o registers
*/
- va = VIRTIO;
- for(pa = soc.physio; pa < soc.physio+IOSIZE; pa += MiB){
+ va = soc.virtio;
+ for(pa = soc.physio; pa < soc.physio+soc.iosize; pa += MiB){
l1[L1X(va)] = pa|Dom0|L1AP(Krw)|Section;
va += MiB;
}
@@ -305,7 +305,7 @@ uintptr
cankaddr(uintptr pa)
{
if(pa < PHYSDRAM+soc.dramsize)
- return PHYSDRAM+soc.dramsize - pa;
+ return ((uintptr)PHYSDRAM+soc.dramsize) - pa;
return 0;
}