From 5a0c2e2d17617ece4819e2f66514a498849ee088 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Thu, 25 Jul 2019 08:41:37 +0200 Subject: [PATCH] bcm, bcm64: add dmaflush() function and make virtio size and virtual address configurable in Soc.virtio and Soc.iosize --- sys/src/9/bcm/archbcm.c | 4 ++- sys/src/9/bcm/archbcm2.c | 4 ++- sys/src/9/bcm/dat.h | 6 ++--- sys/src/9/bcm/dma.c | 50 ++++++++++++++++++++++++++++++++------ sys/src/9/bcm/fns.h | 1 + sys/src/9/bcm/io.h | 2 ++ sys/src/9/bcm/mmu.c | 6 ++--- sys/src/9/bcm64/archbcm3.c | 8 +++--- sys/src/9/bcm64/dat.h | 7 +++--- sys/src/9/bcm64/fns.h | 1 + 10 files changed, 68 insertions(+), 21 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; } diff --git a/sys/src/9/bcm64/archbcm3.c b/sys/src/9/bcm64/archbcm3.c index 33dcc46ed..9cff462ed 100644 --- a/sys/src/9/bcm64/archbcm3.c +++ b/sys/src/9/bcm64/archbcm3.c @@ -17,10 +17,12 @@ typedef struct Mboxes Mboxes; #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 @@ wakecpu(uint cpu) void archbcm3link(void) { - addclock0link(wdogfeed, HZ); + // addclock0link(wdogfeed, HZ); } diff --git a/sys/src/9/bcm64/dat.h b/sys/src/9/bcm64/dat.h index 82fe13f09..459f30f36 100644 --- a/sys/src/9/bcm64/dat.h +++ b/sys/src/9/bcm64/dat.h @@ -241,15 +241,16 @@ struct DevConf 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 */ diff --git a/sys/src/9/bcm64/fns.h b/sys/src/9/bcm64/fns.h index 280e74821..cb5b389a5 100644 --- a/sys/src/9/bcm64/fns.h +++ b/sys/src/9/bcm64/fns.h @@ -144,6 +144,7 @@ extern void wdogoff(void); /* dma */ extern uintptr dmaaddr(void*); +extern void dmaflush(int, void*, ulong); extern void dmastart(int, int, int, void*, void*, int); extern int dmawait(int);