summaryrefslogtreecommitdiff
path: root/sys/arch/sgi
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2014-07-17 19:51:59 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2014-07-17 19:51:59 +0000
commit664939c8a986fc4b514a7cc7be94d8704f2528be (patch)
tree16bfca599cbc516ffa885138ec2121095dbad3f2 /sys/arch/sgi
parentd7626e862ad0b803b14e1650021f4cce3f38e3eb (diff)
Rework management of the external L2 cache on the few Indy/Indigo2 systems
which have it. Instead of implementing external L2 maintainance at the cache routine level, let bus_dmamap_sync(9) know about the possible existence of an external L2, and invoke a dedicated routine to perform the necessary cache operations. This way, the external L2 dmamap_sync function pointer can get invoked with the physical address to operate on; this saves the pmap_extract() calls the previous cache routine had to do.
Diffstat (limited to 'sys/arch/sgi')
-rw-r--r--sys/arch/sgi/sgi/bus_dma.c55
-rw-r--r--sys/arch/sgi/sgi/ip22.h3
-rw-r--r--sys/arch/sgi/sgi/ip22_machdep.c49
3 files changed, 52 insertions, 55 deletions
diff --git a/sys/arch/sgi/sgi/bus_dma.c b/sys/arch/sgi/sgi/bus_dma.c
index a6cf5ed7c62..1b5bce22c17 100644
--- a/sys/arch/sgi/sgi/bus_dma.c
+++ b/sys/arch/sgi/sgi/bus_dma.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bus_dma.c,v 1.36 2014/07/12 18:44:42 tedu Exp $ */
+/* $OpenBSD: bus_dma.c,v 1.37 2014/07/17 19:51:58 miod Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -68,7 +68,7 @@
#include <machine/bus.h>
-#if defined(TGT_INDIGO2)
+#if defined(TGT_INDY) || defined(TGT_INDIGO2)
#include <sgi/sgi/ip22.h>
#endif
@@ -311,11 +311,33 @@ _dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t addr,
{
int nsegs;
int curseg;
+ int how;
struct cpu_info *ci;
#ifdef TGT_COHERENT
+ /* we only need to writeback here */
if ((op & BUS_DMASYNC_PREWRITE) == 0)
return;
+ else
+ how = CACHE_SYNC_W;
+#else
+ /*
+ * If only PREWRITE is requested, writeback.
+ * PREWRITE with PREREAD writebacks and invalidates (since noncoherent)
+ * *all* cache levels.
+ * Otherwise, just invalidate (since noncoherent).
+ */
+ if (op & BUS_DMASYNC_PREWRITE) {
+ if (op & BUS_DMASYNC_PREREAD)
+ how = CACHE_SYNC_X;
+ else
+ how = CACHE_SYNC_W;
+ } else {
+ if (op & (BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTREAD))
+ how = CACHE_SYNC_R;
+ else
+ return;
+ }
#endif
ci = curcpu();
@@ -353,28 +375,17 @@ _dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t addr,
#endif
if (ssize != 0) {
-#ifdef TGT_COHERENT
- /* we only need to writeback here */
- Mips_IOSyncDCache(ci, vaddr, ssize, CACHE_SYNC_W);
-#else
+ Mips_IOSyncDCache(ci, vaddr, ssize, how);
+#if defined(TGT_INDY) || defined(TGT_INDIGO2)
/*
- * If only PREWRITE is requested, writeback.
- * PREWRITE with PREREAD writebacks
- * and invalidates (if noncoherent) *all* cache levels.
- * Otherwise, just invalidate (if noncoherent).
+ * Also flush external L2 if available - this could
+ * (and used to) be done in Mips_IOSyncDCache, but
+ * as the external L2 is physically addressed, this
+ * would require the physical address to be
+ * recomputed, although we know it here.
*/
- if (op & BUS_DMASYNC_PREWRITE) {
- if (op & BUS_DMASYNC_PREREAD)
- Mips_IOSyncDCache(ci, vaddr,
- ssize, CACHE_SYNC_X);
- else
- Mips_IOSyncDCache(ci, vaddr,
- ssize, CACHE_SYNC_W);
- } else
- if (op & (BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTREAD)) {
- Mips_IOSyncDCache(ci, vaddr,
- ssize, CACHE_SYNC_R);
- }
+ if (ip22_extsync != NULL)
+ (*ip22_extsync)(ci, paddr, ssize, how);
#endif
size -= ssize;
}
diff --git a/sys/arch/sgi/sgi/ip22.h b/sys/arch/sgi/sgi/ip22.h
index a01127eaf3c..8885c0c4512 100644
--- a/sys/arch/sgi/sgi/ip22.h
+++ b/sys/arch/sgi/sgi/ip22.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip22.h,v 1.8 2012/09/29 21:46:02 miod Exp $ */
+/* $OpenBSD: ip22.h,v 1.9 2014/07/17 19:51:58 miod Exp $ */
/*
* Copyright (c) 2012 Miodrag Vallat.
@@ -46,3 +46,4 @@ int ip22_slow_mode(void);
int ip22_restore_mode(int);
void ip22_ConfigCache(struct cpu_info *);
+extern void (*ip22_extsync)(struct cpu_info *, paddr_t, size_t, int);
diff --git a/sys/arch/sgi/sgi/ip22_machdep.c b/sys/arch/sgi/sgi/ip22_machdep.c
index 2326c50a9a4..00c5da60322 100644
--- a/sys/arch/sgi/sgi/ip22_machdep.c
+++ b/sys/arch/sgi/sgi/ip22_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip22_machdep.c,v 1.19 2014/07/02 17:44:35 miod Exp $ */
+/* $OpenBSD: ip22_machdep.c,v 1.20 2014/07/17 19:51:58 miod Exp $ */
/*
* Copyright (c) 2012 Miodrag Vallat.
@@ -62,9 +62,12 @@ int hpc_old = 0;
int bios_year;
int ip22_ecc = 0;
+void (*ip22_extsync)(struct cpu_info *, paddr_t, size_t, int);
+
void ip22_arcbios_walk(void);
int ip22_arcbios_walk_component(arc_config_t *);
void ip22_cache_halt(int);
+void ip22_cache_sync(struct cpu_info *, paddr_t, size_t, int);
void ip22_ecc_halt(int);
void ip22_ecc_init(int);
void ip22_memory_setup(void);
@@ -780,7 +783,7 @@ ip22_ConfigCache(struct cpu_info *ci)
ci->ci_l2 = l2;
ci->ci_SyncCache = ip22_SyncCache;
- ci->ci_IOSyncDCache = ip22_IOSyncDCache;
+ ip22_extsync = ip22_cache_sync;
md_halt = ip22_cache_halt;
ip22_l2_enable();
@@ -803,14 +806,10 @@ ip22_SyncCache(struct cpu_info *ci)
}
void
-ip22_IOSyncDCache(struct cpu_info *ci, vaddr_t _va, size_t _sz, int how)
+ip22_cache_sync(struct cpu_info *ci, paddr_t _pa, size_t _sz, int how)
{
- vaddr_t va;
size_t sz;
- paddr_t pa;
-
- /* do whatever L1 work is necessary */
- Mips5k_IOSyncDCache(ci, _va, _sz, how);
+ paddr_t pa, tagbase;
switch (how) {
default:
@@ -819,34 +818,20 @@ ip22_IOSyncDCache(struct cpu_info *ci, vaddr_t _va, size_t _sz, int how)
case CACHE_SYNC_X:
case CACHE_SYNC_R:
/* extend the range to integral cache lines */
- va = _va & ~(IP22_L2_LINE - 1);
- sz = ((_va + _sz + IP22_L2_LINE - 1) & ~(IP22_L2_LINE - 1)) -
- va;
+ pa = _pa & ~(IP22_L2_LINE - 1);
+ sz = ((_pa + _sz + IP22_L2_LINE - 1) & ~(IP22_L2_LINE - 1)) -
+ pa;
+
+ pa &= ci->ci_l2.size - 1;
+ tagbase = PHYS_TO_XKPHYS(IP22_CACHE_TAG_ADDRESS, CCA_NC);
while (sz != 0) {
- /* get the proper physical address */
- if (pmap_extract(pmap_kernel(), va, &pa) == 0) {
-#ifdef DIAGNOSTIC
- panic("%s: invalid va %p",
- __func__, (void *)va);
-#else
- /* should not happen */
-#endif
- }
+ /* word write: invalidate line */
+ *(volatile uint32_t *)(tagbase | pa) = 0;
+ pa += IP22_L2_LINE;
pa &= ci->ci_l2.size - 1;
- pa |= PHYS_TO_XKPHYS(IP22_CACHE_TAG_ADDRESS, CCA_NC);
-
- while (sz != 0) {
- /* word write: invalidate line */
- *(volatile uint32_t *)pa = 0;
-
- pa += IP22_L2_LINE;
- va += IP22_L2_LINE;
- sz -= IP22_L2_LINE;
- if ((va & PAGE_MASK) == 0)
- break; /* need pmap_extract() */
- }
+ sz -= IP22_L2_LINE;
}
break;
}