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.
-/* $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)
#include <machine/bus.h>
-#if defined(TGT_INDIGO2)
+#if defined(TGT_INDY) || defined(TGT_INDIGO2)
#include <sgi/sgi/ip22.h>
#endif
{
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();
#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;
}
-/* $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.
int ip22_restore_mode(int);
void ip22_ConfigCache(struct cpu_info *);
+extern void (*ip22_extsync)(struct cpu_info *, paddr_t, size_t, int);
-/* $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.
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);
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();
}
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:
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;
}