www.pudn.com > vxworks0108.rar > sysCache.c
/* sysCache.c - secondary (L2) cache library for MPC750/MPC7410 */
/* Copyright 1984-1999 Wind River Systems, Inc. */
/* Copyright 1996-2000 Motorola, Inc., All Rights Reserved. */
/*
modification history
--------------------
01e,25sep02,mbrandt rewrote sysL2CacheInit(). Removed all references to
sysL2BackCache.s. sysL2CacheDisable() from Motorola.
01d,16sep02,mbrandt added 7410 cache handling.
01c,08feb01,bm moved main L2 cache handling to sysL2BackCache.s
01b,22aug00,bm disabled L2 cache operations for MPC7400
01a,25nov99,bm written.
*/
/*
DESCRIPTION
This library provides L2 cache support, and is derived from
code supplied by Motorola.
*/
/* includes */
#include "type.h"
#include "reg.h"
#include "ppc750.h"
#include "config.h"
#include "vg4.h"
#include "sysCache.h"
#if defined (INCLUDE_CACHE_SUPPORT) && defined (INCLUDE_CACHE_L2)
/* forward declarations */
STATUS sysL2CacheInit (void);
void sysL2CacheEnable (void);
void sysL2CacheDisable (void);
UINT32 sysL2CacheSizeGet(void);
/* externals */
IMPORT UINT32 sysL2crGet (void);
IMPORT void sysL2crSet (UINT32 regVal);
IMPORT void sysMaxL2Disable(void);
/******************************************************************************
*
* sysL2CacheInit - initialize the L2 cache
*
* This routine initializes and enables L2 cache support. It should be
* called at startup.
* It is assumed that board with MPC7400 and 7410 always have 2MB L2 cache.
*
* RETURNS: OK, or ERROR if cache cannot be initialized.
*
* SEE ALSO: sysL2CacheDisable(), sysL2CacheEnable()
*
*/
STATUS sysL2CacheInit (void)
{
int cpuMhz;
UINT32 l2clk, l2cr;
/* get L2CR to check if cache is already enabled */
l2cr = sysL2crGet();
if (l2cr & MPC750_L2CR_E) {
/* already enabled */
return (OK);
}
/* assuming PB2 sram types */
/*
* L2PE = No parity enable
* L2RAM = Pipe reg-reg sync burst
* L2OH = 0.5ns
* L2DF = Nondiff clock
*/
/* XXX: should WT (write through) be enabled ? */
l2cr = MPC750_L2CR_RAM_PBRST;
cpuMhz = sysCpuSpeedMhzGet();
if (cpuMhz < 0) {
/* invalid speed */
return (ERROR);
}
if (CPU_TYPE == CPU_TYPE_750) {
/* size is assumed to be always 1 MB */
l2cr |= MPC750_L2CR_1024K;
/* L2 clock must be 200 MHz */
if (cpuMhz <= 200) {
l2clk = 1; /* /1 */
} else if (cpuMhz <= 300) {
l2clk = 2; /* /1.5 */
} else if (cpuMhz <= 400) {
l2clk = 4; /* /2 */
} else if (cpuMhz <= 500) {
l2clk = 5; /* /2.5 */
} else if (cpuMhz <= 600) {
l2clk = 6; /* /3 */
} else {
/* OOPS, overclocked ? */
/* sysCpuSpeedMhzGet() should have returned -1 */
return (ERROR);
}
} else {
/* on 7400 and 7410 boards 2 MB L2 cache is assumed */
l2cr |= MPC750_L2CR_2048K;
/* For 2MB 7410 L2 the clock must be 166MHz. */
if (cpuMhz <= 166) {
l2clk = 1; /* /1 */
} else if (cpuMhz <= 249) {
l2clk = 2; /* /1.5 */
} else if (cpuMhz <= 332) {
l2clk = 4; /* /2 */
} else if (cpuMhz <= 416) {
l2clk = 5; /* /2.5 */
} else if (cpuMhz <= 500) {
l2clk = 6; /* /3 */
} else if (cpuMhz <= 583) {
l2clk = 3; /* /3.5 */
} else if (cpuMhz <= 667) {
l2clk = 7; /* /4 */
} else {
/* OOPS, overclocked ? */
/* sysCpuSpeedMhzGet() should have returned -1 */
return (ERROR);
}
}
/* set l2clk */
l2cr |= (l2clk << 25);
/* set L2CR */
sysL2crSet(l2cr);
/* Invalidate the L2 cache */
l2cr |= MPC750_L2CR_I;
sysL2crSet(l2cr);
__asm__("sync"); /* wait for all memory transactions to finish */
while (sysL2crGet() & MPC750_L2CR_IP)
;
l2cr &= ~MPC750_L2CR_I;
sysL2crSet(l2cr);
/* Enable the L2 cache */
sysL2CacheEnable();
return (OK);
}
/******************************************************************************
*
* sysL2CacheEnable - enable the L2 cache
*
* RETURNS: N/A
*/
void sysL2CacheEnable (void)
{
UINT32 l2crVal;
/* make sure L2 is already disabled */
if ( ((l2crVal = sysL2crGet()) & MPC750_L2CR_E) == 0)
{
l2crVal |= MPC750_L2CR_E;
sysL2crSet(l2crVal);
}
}
/******************************************************************************
*
* sysL2CacheDisable - disable the L2 cache
*
* If the in-line cache is enabled, this routine disables it via the following
* steps:
*
* .IP "1."
* Flush by reading one word from each cache line within a cache
* enabled buffer. Note that this buffer should be twice the size of
* the L2 cache to override the pseudo-LRU replacement algorithm.
* .IP "2."
* Turn off the cache enable bit in the L2CR.
* .IP "3."
* Invalidate the L2 cache contents.
*
* RETURNS: N/A
*
* SEE ALSO: sysL2CacheEnable(), sysL2CacheInit()
*/
void sysL2CacheDisable (void)
{
register UINT32 tmp;
register UINT32 l2crVal;
register int i;
int lockKey; /* interrupt lock key */
lockKey = intLock(); /* disable interrupts */
if ((l2crVal = sysL2crGet()) & MPC750_L2CR_E)
{
if (CPU_TYPE == CPU_TYPE_750)
{
if (vxHid0Get() & _PPC_HID0_DCE)
{
/* flush the inline L2 cache */
for (i = 2*sysL2CacheSizeGet() - 32; i >= 0; i -= 32 )
tmp = *(UINT32 *)(RAM_LOW_ADRS + i);
}
/* disable the inline L2 cache */
__asm__("sync");
l2crVal &= ~MPC750_L2CR_E;
sysL2crSet(l2crVal);
__asm__("sync");
/* invalidate the inline L2 cache */
sysL2crSet(l2crVal | MPC750_L2CR_I);
__asm__("sync"); /* wait for all memory transactions to finish */
while (sysL2crGet() & MPC750_L2CR_IP)
;
sysL2crSet(l2crVal);
}
else
{
sysMaxL2Disable();
l2crVal &= ~MPC750_L2CR_E;
/* invalidate the inline L2 cache */
sysL2crSet(l2crVal | MPC750_L2CR_I);
__asm__("sync"); /* wait for all memory transactions to finish */
}
}
intUnlock(lockKey); /* re-enable interrupts */
}
/******************************************************************************
*
* sysL2CacheSizeGet() - Determine size of the L2 in-line cache.
*
* This function returns the size of the L2 in-line cache by reading the
* L2 cache control register.
*
* RETURNS: Size of L2 in-line cache in bytes.
*
*/
UINT32 sysL2CacheSizeGet(void)
{
UINT32 size;
register UINT32 l2crVal;
l2crVal = sysL2crGet();
switch (l2crVal & MPC750_L2CR_SIZE_MSK)
{
case MPC750_L2CR_256K:
size = 0x40000;
break;
case MPC750_L2CR_512K:
size = 0x80000;
break;
case MPC750_L2CR_1024K:
size = 0x100000;
break;
/* 74xx */
case MPC750_L2CR_2048K:
size = 0x200000;
break;
default:
size = 0;
break ;
}
return size;
}
#endif /* INCLUDE_CACHE_SUPPORT && INCLUDE_CACHE_L2 */