ref: 5a0c2e2d17617ece4819e2f66514a498849ee088
parent: 4983adfa2cd403eda22d862917c2ff5ed35b48b3
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Jul 25 04:41:37 EDT 2019
bcm, bcm64: add dmaflush() function and make virtio size and virtual address configurable in Soc.virtio and Soc.iosize
--- 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,
--- a/sys/src/9/bcm/archbcm2.c
+++ b/sys/src/9/bcm/archbcm2.c
@@ -20,8 +20,10 @@
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,
--- a/sys/src/9/bcm/dat.h
+++ b/sys/src/9/bcm/dat.h
@@ -281,16 +281,16 @@
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
--- a/sys/src/9/bcm/dma.c
+++ b/sys/src/9/bcm/dma.c
@@ -82,6 +82,8 @@
Cb *cb;
Rendez r;
int dmadone;
+ void *flush;
+ int len;
};
struct Cb {
@@ -108,7 +110,7 @@
static uintptr
dmaioaddr(void *va)
{
- return soc.busio | ((uintptr)va - VIRTIO);
+ return soc.busio | ((uintptr)va - soc.virtio);
}
static void
@@ -164,26 +166,28 @@
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 @@
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 @@
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];
@@ -232,4 +240,32 @@
}
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);
}
--- a/sys/src/9/bcm/fns.h
+++ b/sys/src/9/bcm/fns.h
@@ -28,6 +28,7 @@
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);
--- a/sys/src/9/bcm/io.h
+++ b/sys/src/9/bcm/io.h
@@ -63,3 +63,5 @@
ClkPixel,
ClkPwm,
};
+
+#define BUSUNKNOWN (-1)
--- a/sys/src/9/bcm/mmu.c
+++ b/sys/src/9/bcm/mmu.c
@@ -49,8 +49,8 @@
/*
* 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 @@
cankaddr(uintptr pa)
{
if(pa < PHYSDRAM+soc.dramsize)
- return PHYSDRAM+soc.dramsize - pa;
+ return ((uintptr)PHYSDRAM+soc.dramsize) - pa;
return 0;
}
--- a/sys/src/9/bcm64/archbcm3.c
+++ b/sys/src/9/bcm64/archbcm3.c
@@ -17,10 +17,12 @@
#define POWERREGS (VIRTIO+0x100000)
Soc soc = {
- .dramsize = 0x3F000000,
- .physio = 0x3F000000,
+ .dramsize = 0x3E000000,
.busdram = 0xC0000000,
+ .iosize = 0x01000000,
.busio = 0x7E000000,
+ .physio = 0x3F000000,
+ .virtio = VIRTIO,
.armlocal = 0x40000000,
};
@@ -164,5 +166,5 @@
void
archbcm3link(void)
{
- addclock0link(wdogfeed, HZ);
+ // addclock0link(wdogfeed, HZ);
}
--- a/sys/src/9/bcm64/dat.h
+++ b/sys/src/9/bcm64/dat.h
@@ -241,14 +241,15 @@
struct Soc { /* SoC dependent configuration */
ulong dramsize;
- uintptr physio;
uintptr busdram;
+ ulong iosize;
uintptr busio;
+ uintptr physio;
+ uintptr virtio;
uintptr armlocal;
+ uintptr pciwin;
};
extern Soc soc;
-
-#define BUSUNKNOWN -1
/*
* GPIO
--- a/sys/src/9/bcm64/fns.h
+++ b/sys/src/9/bcm64/fns.h
@@ -144,6 +144,7 @@
/* dma */
extern uintptr dmaaddr(void*);
+extern void dmaflush(int, void*, ulong);
extern void dmastart(int, int, int, void*, void*, int);
extern int dmawait(int);
--
⑨