From 2c1a832f25bef8c40c5cc8f6f06d510baff1b5d8 Mon Sep 17 00:00:00 2001 From: simonb Date: Tue, 17 Dec 2002 12:04:29 +0000 Subject: [PATCH] Add support for caches where the data cache is fully coherent, and either requires flushing either only when the I cache ops are used or not at all. Currently only used by MIPS32/MIPS64 cache code. --- sys/arch/mips/include/cache.h | 54 +++++++++++++++++++++++-------- sys/arch/mips/include/cpu.h | 4 ++- sys/arch/mips/mips/cache.c | 41 ++++++++++++++++++++--- sys/arch/mips/mips/cache_mipsNN.c | 14 ++++---- 4 files changed, 87 insertions(+), 26 deletions(-) diff --git a/sys/arch/mips/include/cache.h b/sys/arch/mips/include/cache.h index 1f0d0a9f40b4..e36e802a32cd 100644 --- a/sys/arch/mips/include/cache.h +++ b/sys/arch/mips/include/cache.h @@ -1,4 +1,4 @@ -/* $NetBSD: cache.h,v 1.4 2002/11/09 19:34:40 thorpej Exp $ */ +/* $NetBSD: cache.h,v 1.5 2002/12/17 12:04:29 simonb Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -134,11 +134,21 @@ struct mips_cache_ops { void (*mco_pdcache_inv_range)(vaddr_t, vsize_t); void (*mco_pdcache_wb_range)(vaddr_t, vsize_t); + /* These are called only by the (mipsNN) icache functions. */ + void (*mco_intern_pdcache_wbinv_all)(void); + void (*mco_intern_pdcache_wbinv_range_index)(vaddr_t, vsize_t); + void (*mco_intern_pdcache_wb_range)(vaddr_t, vsize_t); + void (*mco_sdcache_wbinv_all)(void); void (*mco_sdcache_wbinv_range)(vaddr_t, vsize_t); void (*mco_sdcache_wbinv_range_index)(vaddr_t, vsize_t); void (*mco_sdcache_inv_range)(vaddr_t, vsize_t); void (*mco_sdcache_wb_range)(vaddr_t, vsize_t); + + /* These are called only by the (mipsNN) icache functions. */ + void (*mco_intern_sdcache_wbinv_all)(void); + void (*mco_intern_sdcache_wbinv_range_index)(vaddr_t, vsize_t); + void (*mco_intern_sdcache_wb_range)(vaddr_t, vsize_t); }; #ifdef _KERNEL @@ -195,18 +205,18 @@ extern u_int mips_cache_prefer_mask; */ #define mips_cache_indexof(x) (((vaddr_t)(x)) & mips_cache_alias_mask) -#define __mco_noargs(x) \ +#define __mco_noargs(prefix, x) \ do { \ - (*mips_cache_ops.mco_p ## x )(); \ - if (*mips_cache_ops.mco_s ## x ) \ - (*mips_cache_ops.mco_s ## x )(); \ + (*mips_cache_ops.mco_ ## prefix ## p ## x )(); \ + if (*mips_cache_ops.mco_ ## prefix ## s ## x ) \ + (*mips_cache_ops.mco_ ## prefix ## s ## x )(); \ } while (/*CONSTCOND*/0) -#define __mco_2args(x, a, b) \ +#define __mco_2args(prefix, x, a, b) \ do { \ - (*mips_cache_ops.mco_p ## x )((a), (b)); \ - if (*mips_cache_ops.mco_s ## x ) \ - (*mips_cache_ops.mco_s ## x )((a), (b)); \ + (*mips_cache_ops.mco_ ## prefix ## p ## x )((a), (b)); \ + if (*mips_cache_ops.mco_ ## prefix ## s ## x ) \ + (*mips_cache_ops.mco_ ## prefix ## s ## x )((a), (b)); \ } while (/*CONSTCOND*/0) #define mips_icache_sync_all() \ @@ -219,21 +229,37 @@ do { \ (*mips_cache_ops.mco_icache_sync_range_index)((v), (s)) #define mips_dcache_wbinv_all() \ - __mco_noargs(dcache_wbinv_all) + __mco_noargs(, dcache_wbinv_all) #define mips_dcache_wbinv_range(v, s) \ - __mco_2args(dcache_wbinv_range, (v), (s)) + __mco_2args(, dcache_wbinv_range, (v), (s)) #define mips_dcache_wbinv_range_index(v, s) \ - __mco_2args(dcache_wbinv_range_index, (v), (s)) + __mco_2args(, dcache_wbinv_range_index, (v), (s)) #define mips_dcache_inv_range(v, s) \ - __mco_2args(dcache_inv_range, (v), (s)) + __mco_2args(, dcache_inv_range, (v), (s)) #define mips_dcache_wb_range(v, s) \ - __mco_2args(dcache_wb_range, (v), (s)) + __mco_2args(, dcache_wb_range, (v), (s)) + + +/* + * Private D-cache functions only called from (currently only the + * mipsNN) I-cache functions. + */ +#define mips_intern_dcache_wbinv_all() \ + __mco_noargs(intern_, dcache_wbinv_all) + +#define mips_intern_dcache_wbinv_range_index(v, s) \ + __mco_2args(intern_, dcache_wbinv_range_index, (v), (s)) + +#define mips_intern_dcache_wb_range(v, s) \ + __mco_2args(intern_, dcache_wb_range, (v), (s)) void mips_config_cache(void); void mips_dcache_compute_align(void); +#include + #endif /* _KERNEL */ diff --git a/sys/arch/mips/include/cpu.h b/sys/arch/mips/include/cpu.h index d1c0779fa8d7..e5ab426f0c39 100644 --- a/sys/arch/mips/include/cpu.h +++ b/sys/arch/mips/include/cpu.h @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.68 2002/11/24 07:26:04 simonb Exp $ */ +/* $NetBSD: cpu.h,v 1.69 2002/12/17 12:04:29 simonb Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -163,6 +163,8 @@ extern int mips3_pg_cached; #define CPU_MIPS_DOUBLE_COUNT 0x0080 /* 1 cp0 count == 2 clock cycles */ #define CPU_MIPS_USE_WAIT 0x0100 /* Use "wait"-based cpu_idle() */ #define CPU_MIPS_NO_WAIT 0x0200 /* Inverse of previous, for mips32/64 */ +#define CPU_MIPS_D_CACHE_COHERENT 0x0400 /* D-cache is fully coherent */ +#define CPU_MIPS_I_D_CACHE_COHERENT 0x0800 /* I-cache funcs don't need to flush the D-cache */ #define MIPS_NOT_SUPP 0x8000 #ifdef _LKM diff --git a/sys/arch/mips/mips/cache.c b/sys/arch/mips/mips/cache.c index 1a3807c0492d..25826d56fe24 100644 --- a/sys/arch/mips/mips/cache.c +++ b/sys/arch/mips/mips/cache.c @@ -1,4 +1,4 @@ -/* $NetBSD: cache.c,v 1.14 2002/11/24 07:41:30 simonb Exp $ */ +/* $NetBSD: cache.c,v 1.15 2002/12/17 12:04:30 simonb Exp $ */ /* * Copyright 2001, 2002 Wasabi Systems, Inc. @@ -825,10 +825,8 @@ mips3_get_cache_config(int csizebase) #if defined(MIPS32) || defined(MIPS64) -#ifdef MIPS_DISABLE_L1_CACHE -static void cache_noop(void); +static void cache_noop(void) __attribute__((__unused__)); static void cache_noop(void) {} -#endif static void mips_config_cache_modern(void) @@ -957,36 +955,47 @@ mips_config_cache_modern(void) switch (mips_pdcache_line_size) { case 16: mips_cache_ops.mco_pdcache_wbinv_all = + mips_cache_ops.mco_intern_pdcache_wbinv_all = mipsNN_pdcache_wbinv_all_16; mips_cache_ops.mco_pdcache_wbinv_range = mipsNN_pdcache_wbinv_range_16; mips_cache_ops.mco_pdcache_wbinv_range_index = + mips_cache_ops.mco_intern_pdcache_wbinv_range_index = mipsNN_pdcache_wbinv_range_index_16; mips_cache_ops.mco_pdcache_inv_range = mipsNN_pdcache_inv_range_16; mips_cache_ops.mco_pdcache_wb_range = + mips_cache_ops.mco_intern_pdcache_wb_range = mipsNN_pdcache_wb_range_16; break; case 32: mips_cache_ops.mco_pdcache_wbinv_all = + mips_cache_ops.mco_intern_pdcache_wbinv_all = mipsNN_pdcache_wbinv_all_32; mips_cache_ops.mco_pdcache_wbinv_range = mipsNN_pdcache_wbinv_range_32; mips_cache_ops.mco_pdcache_wbinv_range_index = + mips_cache_ops.mco_intern_pdcache_wbinv_range_index = mipsNN_pdcache_wbinv_range_index_32; mips_cache_ops.mco_pdcache_inv_range = mipsNN_pdcache_inv_range_32; mips_cache_ops.mco_pdcache_wb_range = + mips_cache_ops.mco_intern_pdcache_wb_range = mipsNN_pdcache_wb_range_32; break; #ifdef MIPS_DISABLE_L1_CACHE case 0: mips_cache_ops.mco_pdcache_wbinv_all = (void *)cache_noop; + mips_cache_ops.mco_intern_pdcache_wbinv_all = + (void *)cache_noop; mips_cache_ops.mco_pdcache_wbinv_range = (void *)cache_noop; mips_cache_ops.mco_pdcache_wbinv_range_index = (void *)cache_noop; + mips_cache_ops.mco_intern_pdcache_wbinv_range_index = + (void *)cache_noop; mips_cache_ops.mco_pdcache_inv_range = (void *)cache_noop; mips_cache_ops.mco_pdcache_wb_range = (void *)cache_noop; + mips_cache_ops.mco_intern_pdcache_wb_range = (void *)cache_noop; break; #endif default: @@ -995,5 +1004,29 @@ mips_config_cache_modern(void) } mipsNN_cache_init(cfg, cfg1); + + if (mips_cpu_flags & + (CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_I_D_CACHE_COHERENT)) { +#ifdef CACHE_DEBUG + printf(" Dcache is coherent\n"); +#endif + mips_cache_ops.mco_pdcache_wbinv_all = (void *)cache_noop; + mips_cache_ops.mco_pdcache_wbinv_range = (void *)cache_noop; + mips_cache_ops.mco_pdcache_wbinv_range_index = + (void *)cache_noop; + mips_cache_ops.mco_pdcache_inv_range = (void *)cache_noop; + mips_cache_ops.mco_pdcache_wb_range = (void *)cache_noop; + } + if (mips_cpu_flags & CPU_MIPS_I_D_CACHE_COHERENT) { +#ifdef CACHE_DEBUG + printf(" Icache is coherent against Dcache\n"); +#endif + mips_cache_ops.mco_intern_pdcache_wbinv_all = + (void *)cache_noop; + mips_cache_ops.mco_intern_pdcache_wbinv_range_index = + (void *)cache_noop; + mips_cache_ops.mco_intern_pdcache_wb_range = + (void *)cache_noop; + } } #endif /* MIPS32 || MIPS64 */ diff --git a/sys/arch/mips/mips/cache_mipsNN.c b/sys/arch/mips/mips/cache_mipsNN.c index 37bc79dd18a6..49d80e6d9d7c 100644 --- a/sys/arch/mips/mips/cache_mipsNN.c +++ b/sys/arch/mips/mips/cache_mipsNN.c @@ -1,4 +1,4 @@ -/* $NetBSD: cache_mipsNN.c,v 1.6 2002/11/24 07:41:31 simonb Exp $ */ +/* $NetBSD: cache_mipsNN.c,v 1.7 2002/12/17 12:04:30 simonb Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -120,7 +120,7 @@ mipsNN_icache_sync_all_16(void) * worry about the N different "ways". */ - mips_dcache_wbinv_all(); + mips_intern_dcache_wbinv_all(); while (va < eva) { cache_r4k_op_32lines_16(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV); @@ -143,7 +143,7 @@ mipsNN_icache_sync_all_32(void) * worry about the N different "ways". */ - mips_dcache_wbinv_all(); + mips_intern_dcache_wbinv_all(); while (va < eva) { cache_r4k_op_32lines_32(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV); @@ -161,7 +161,7 @@ mipsNN_icache_sync_range_16(vaddr_t va, vsize_t size) eva = round_line16(va + size); va = trunc_line16(va); - mips_dcache_wb_range(va, (eva - va)); + mips_intern_dcache_wb_range(va, (eva - va)); while ((eva - va) >= (32 * 16)) { cache_r4k_op_32lines_16(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV); @@ -184,7 +184,7 @@ mipsNN_icache_sync_range_32(vaddr_t va, vsize_t size) eva = round_line32(va + size); va = trunc_line32(va); - mips_dcache_wb_range(va, (eva - va)); + mips_intern_dcache_wb_range(va, (eva - va)); while ((eva - va) >= (32 * 32)) { cache_r4k_op_32lines_32(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV); @@ -223,7 +223,7 @@ mipsNN_icache_sync_range_index_16(vaddr_t va, vsize_t size) stride = picache_stride; loopcount = picache_loopcount; - mips_dcache_wbinv_range_index(va, (eva - va)); + mips_intern_dcache_wbinv_range_index(va, (eva - va)); while ((eva - va) >= (8 * 16)) { tmpva = va; @@ -266,7 +266,7 @@ mipsNN_icache_sync_range_index_32(vaddr_t va, vsize_t size) stride = picache_stride; loopcount = picache_loopcount; - mips_dcache_wbinv_range_index(va, (eva - va)); + mips_intern_dcache_wbinv_range_index(va, (eva - va)); while ((eva - va) >= (8 * 32)) { tmpva = va;