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.
This commit is contained in:
simonb 2002-12-17 12:04:29 +00:00
parent 4ec8d15e0d
commit 2c1a832f25
4 changed files with 87 additions and 26 deletions

View File

@ -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 <mips/cache_mipsNN.h>
#endif /* _KERNEL */

View File

@ -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

View File

@ -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 */

View File

@ -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;