From dc0969855e9f491891933e441941a4562b40c336 Mon Sep 17 00:00:00 2001 From: miod Date: Thu, 17 Jul 2014 19:51:58 +0000 Subject: [PATCH] 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. --- sys/arch/sgi/sgi/bus_dma.c | 55 ++++++++++++++++++++------------- sys/arch/sgi/sgi/ip22.h | 3 +- sys/arch/sgi/sgi/ip22_machdep.c | 49 ++++++++++------------------- 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 -#if defined(TGT_INDIGO2) +#if defined(TGT_INDY) || defined(TGT_INDIGO2) #include #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; } -- 2.20.1