98 lines
2.6 KiB
C
98 lines
2.6 KiB
C
/*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file "COPYING" in the main directory of this archive
|
|
* for more details.
|
|
*
|
|
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
|
* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org)
|
|
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
|
|
*/
|
|
#include <common.h>
|
|
#include <asm/io.h>
|
|
#include <asm/mipsregs.h>
|
|
#include <asm/cpu.h>
|
|
#include <asm/cpu-info.h>
|
|
#include <asm/bitops.h>
|
|
|
|
void r4k_cache_init(void);
|
|
|
|
static void probe_pcache(void)
|
|
{
|
|
struct cpuinfo_mips *c = ¤t_cpu_data;
|
|
unsigned int icache_size, dcache_size;
|
|
unsigned int config = read_c0_config();
|
|
unsigned long config1;
|
|
unsigned int lsize;
|
|
|
|
switch (c->cputype) {
|
|
|
|
default:
|
|
/*
|
|
* So we seem to be a MIPS32 or MIPS64 CPU
|
|
* So let's probe the I-cache ...
|
|
*/
|
|
config1 = read_c0_config1();
|
|
|
|
if ((lsize = ((config1 >> 19) & 7)))
|
|
c->icache.linesz = 2 << lsize;
|
|
else
|
|
c->icache.linesz = lsize;
|
|
c->icache.sets = 64 << ((config1 >> 22) & 7);
|
|
c->icache.ways = 1 + ((config1 >> 16) & 7);
|
|
|
|
icache_size = c->icache.sets *
|
|
c->icache.ways *
|
|
c->icache.linesz;
|
|
c->icache.waybit = __ffs(icache_size/c->icache.ways);
|
|
|
|
if (config & 0x8) /* VI bit */
|
|
c->icache.flags |= MIPS_CACHE_VTAG;
|
|
|
|
/*
|
|
* Now probe the MIPS32 / MIPS64 data cache.
|
|
*/
|
|
c->dcache.flags = 0;
|
|
|
|
if ((lsize = ((config1 >> 10) & 7)))
|
|
c->dcache.linesz = 2 << lsize;
|
|
else
|
|
c->dcache.linesz= lsize;
|
|
c->dcache.sets = 64 << ((config1 >> 13) & 7);
|
|
c->dcache.ways = 1 + ((config1 >> 7) & 7);
|
|
|
|
dcache_size = c->dcache.sets *
|
|
c->dcache.ways *
|
|
c->dcache.linesz;
|
|
c->dcache.waybit = __ffs(dcache_size/c->dcache.ways);
|
|
|
|
c->options |= MIPS_CPU_PREFETCH;
|
|
break;
|
|
}
|
|
|
|
/* compute a couple of other cache variables */
|
|
c->icache.waysize = icache_size / c->icache.ways;
|
|
c->dcache.waysize = dcache_size / c->dcache.ways;
|
|
|
|
c->icache.sets = c->icache.linesz ?
|
|
icache_size / (c->icache.linesz * c->icache.ways) : 0;
|
|
c->dcache.sets = c->dcache.linesz ?
|
|
dcache_size / (c->dcache.linesz * c->dcache.ways) : 0;
|
|
|
|
/*
|
|
* R10000 and R12000 P-caches are odd in a positive way. They're 32kB
|
|
* 2-way virtually indexed so normally would suffer from aliases. So
|
|
* normally they'd suffer from aliases but magic in the hardware deals
|
|
* with that for us so we don't need to take care ourselves.
|
|
*/
|
|
switch (c->cputype) {
|
|
default:
|
|
if (c->dcache.waysize > PAGE_SIZE)
|
|
c->dcache.flags |= MIPS_CACHE_ALIASES;
|
|
}
|
|
}
|
|
|
|
void r4k_cache_init(void)
|
|
{
|
|
probe_pcache();
|
|
}
|